@@ -114,36 +114,36 @@ impl<'store> Executor<'store> {
114114 return ControlFlow :: Continue ( ( ) ) ;
115115 }
116116 DropKeepSmall { base32, keep32, base64, keep64, base128, keep128, base_ref, keep_ref } => {
117- let b32 = self . cf . stack_base . s32 + * base32 as usize ;
117+ let b32 = self . cf . stack_base ( ) . s32 + * base32 as usize ;
118118 let k32 = * keep32 as usize ;
119119 self . store . stack . values . stack_32 . truncate_keep ( b32, k32) ;
120- let b64 = self . cf . stack_base . s64 + * base64 as usize ;
120+ let b64 = self . cf . stack_base ( ) . s64 + * base64 as usize ;
121121 let k64 = * keep64 as usize ;
122122 self . store . stack . values . stack_64 . truncate_keep ( b64, k64) ;
123- let b128 = self . cf . stack_base . s128 + * base128 as usize ;
123+ let b128 = self . cf . stack_base ( ) . s128 + * base128 as usize ;
124124 let k128 = * keep128 as usize ;
125125 self . store . stack . values . stack_128 . truncate_keep ( b128, k128) ;
126- let bref = self . cf . stack_base . sref + * base_ref as usize ;
126+ let bref = self . cf . stack_base ( ) . sref + * base_ref as usize ;
127127 let kref = * keep_ref as usize ;
128128 self . store . stack . values . stack_ref . truncate_keep ( bref, kref) ;
129129 }
130130 DropKeep32 ( base, keep) => {
131- let b = self . cf . stack_base . s32 + * base as usize ;
131+ let b = self . cf . stack_base ( ) . s32 + * base as usize ;
132132 let k = * keep as usize ;
133133 self . store . stack . values . stack_32 . truncate_keep ( b, k) ;
134134 }
135135 DropKeep64 ( base, keep) => {
136- let b = self . cf . stack_base . s64 + * base as usize ;
136+ let b = self . cf . stack_base ( ) . s64 + * base as usize ;
137137 let k = * keep as usize ;
138138 self . store . stack . values . stack_64 . truncate_keep ( b, k) ;
139139 }
140140 DropKeep128 ( base, keep) => {
141- let b = self . cf . stack_base . s128 + * base as usize ;
141+ let b = self . cf . stack_base ( ) . s128 + * base as usize ;
142142 let k = * keep as usize ;
143143 self . store . stack . values . stack_128 . truncate_keep ( b, k) ;
144144 }
145145 DropKeepRef ( base, keep) => {
146- let b = self . cf . stack_base . sref + * base as usize ;
146+ let b = self . cf . stack_base ( ) . sref + * base as usize ;
147147 let k = * keep as usize ;
148148 self . store . stack . values . stack_ref . truncate_keep ( b, k) ;
149149 }
@@ -163,22 +163,58 @@ impl<'store> Executor<'store> {
163163 return ControlFlow :: Continue ( ( ) ) ;
164164 }
165165 Return => return self . exec_return ( ) ,
166- LocalGet32 ( local_index) => self . store . stack . values . push ( self . cf . locals . get :: < Value32 > ( * local_index) ) . to_cf ( ) ?,
167- LocalGet64 ( local_index) => self . store . stack . values . push ( self . cf . locals . get :: < Value64 > ( * local_index) ) . to_cf ( ) ?,
168- LocalGet128 ( local_index) => self . store . stack . values . push ( self . cf . locals . get :: < Value128 > ( * local_index) ) . to_cf ( ) ?,
169- LocalGetRef ( local_index) => self . store . stack . values . push ( self . cf . locals . get :: < ValueRef > ( * local_index) ) . to_cf ( ) ?,
170- LocalSet32 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . pop :: < Value32 > ( ) ) ,
171- LocalSet64 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . pop :: < Value64 > ( ) ) ,
172- LocalSet128 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . pop :: < Value128 > ( ) ) ,
173- LocalSetRef ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . pop :: < ValueRef > ( ) ) ,
174- LocalCopy32 ( from, to) => self . cf . locals . set ( * to, self . cf . locals . get :: < Value32 > ( * from) ) ,
175- LocalCopy64 ( from, to) => self . cf . locals . set ( * to, self . cf . locals . get :: < Value64 > ( * from) ) ,
176- LocalCopy128 ( from, to) => self . cf . locals . set ( * to, self . cf . locals . get :: < Value128 > ( * from) ) ,
177- LocalCopyRef ( from, to) => self . cf . locals . set ( * to, self . cf . locals . get :: < ValueRef > ( * from) ) ,
178- LocalTee32 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . peek :: < Value32 > ( ) ) ,
179- LocalTee64 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . peek :: < Value64 > ( ) ) ,
180- LocalTee128 ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . peek :: < Value128 > ( ) ) ,
181- LocalTeeRef ( local_index) => self . cf . locals . set ( * local_index, self . store . stack . values . peek :: < ValueRef > ( ) ) ,
166+ LocalGet32 ( local_index) => self . store . stack . values . push ( self . store . stack . values . local_get_32 ( & self . cf , * local_index) ) . to_cf ( ) ?,
167+ LocalGet64 ( local_index) => self . store . stack . values . push ( self . store . stack . values . local_get_64 ( & self . cf , * local_index) ) . to_cf ( ) ?,
168+ LocalGet128 ( local_index) => self . store . stack . values . push ( self . store . stack . values . local_get_128 ( & self . cf , * local_index) ) . to_cf ( ) ?,
169+ LocalGetRef ( local_index) => self . store . stack . values . push ( self . store . stack . values . local_get_ref ( & self . cf , * local_index) ) . to_cf ( ) ?,
170+ LocalSet32 ( local_index) => {
171+ let val = self . store . stack . values . pop :: < Value32 > ( ) ;
172+ self . store . stack . values . local_set_32 ( & self . cf , * local_index, val) ;
173+ }
174+ LocalSet64 ( local_index) => {
175+ let val = self . store . stack . values . pop :: < Value64 > ( ) ;
176+ self . store . stack . values . local_set_64 ( & self . cf , * local_index, val) ;
177+ }
178+ LocalSet128 ( local_index) => {
179+ let val = self . store . stack . values . pop :: < Value128 > ( ) ;
180+ self . store . stack . values . local_set_128 ( & self . cf , * local_index, val) ;
181+ }
182+ LocalSetRef ( local_index) => {
183+ let val = self . store . stack . values . pop :: < ValueRef > ( ) ;
184+ self . store . stack . values . local_set_ref ( & self . cf , * local_index, val) ;
185+ }
186+ LocalCopy32 ( from, to) => {
187+ let val = self . store . stack . values . local_get_32 ( & self . cf , * from) ;
188+ self . store . stack . values . local_set_32 ( & self . cf , * to, val) ;
189+ }
190+ LocalCopy64 ( from, to) => {
191+ let val = self . store . stack . values . local_get_64 ( & self . cf , * from) ;
192+ self . store . stack . values . local_set_64 ( & self . cf , * to, val) ;
193+ }
194+ LocalCopy128 ( from, to) => {
195+ let val = self . store . stack . values . local_get_128 ( & self . cf , * from) ;
196+ self . store . stack . values . local_set_128 ( & self . cf , * to, val) ;
197+ }
198+ LocalCopyRef ( from, to) => {
199+ let val = self . store . stack . values . local_get_ref ( & self . cf , * from) ;
200+ self . store . stack . values . local_set_ref ( & self . cf , * to, val) ;
201+ }
202+ LocalTee32 ( local_index) => {
203+ let val = self . store . stack . values . peek :: < Value32 > ( ) ;
204+ self . store . stack . values . local_set_32 ( & self . cf , * local_index, val) ;
205+ }
206+ LocalTee64 ( local_index) => {
207+ let val = self . store . stack . values . peek :: < Value64 > ( ) ;
208+ self . store . stack . values . local_set_64 ( & self . cf , * local_index, val) ;
209+ }
210+ LocalTee128 ( local_index) => {
211+ let val = self . store . stack . values . peek :: < Value128 > ( ) ;
212+ self . store . stack . values . local_set_128 ( & self . cf , * local_index, val) ;
213+ }
214+ LocalTeeRef ( local_index) => {
215+ let val = self . store . stack . values . peek :: < ValueRef > ( ) ;
216+ self . store . stack . values . local_set_ref ( & self . cf , * local_index, val) ;
217+ }
182218 GlobalGet ( global_index) => self . exec_global_get ( * global_index) . to_cf ( ) ?,
183219 GlobalSet32 ( global_index) => self . exec_global_set :: < Value32 > ( * global_index) ,
184220 GlobalSet64 ( global_index) => self . exec_global_set :: < Value64 > ( * global_index) ,
@@ -627,20 +663,35 @@ impl<'store> Executor<'store> {
627663 func_addr : FuncAddr ,
628664 owner : ModuleInstanceAddr ,
629665 ) -> ControlFlow < Option < Error > > {
666+ if !IS_RETURN_CALL && self . store . stack . call_stack . is_full ( ) {
667+ return ControlFlow :: Break ( Some ( Trap :: CallStackOverflow . into ( ) ) ) ;
668+ }
669+
630670 if !Rc :: ptr_eq ( & self . func , & wasm_func) {
631671 self . func = wasm_func. clone ( ) ;
632672 }
633673
634674 if IS_RETURN_CALL {
635- let locals = self . store . stack . values . pop_locals ( wasm_func. params , wasm_func. locals ) ;
636- let stack_base = self . store . stack . values . height ( ) ;
637- self . cf . reuse_for ( func_addr, locals, owner, stack_base) ;
675+ self . store . stack . values . truncate_keep_counts ( self . cf . locals_base , wasm_func. params ) ;
676+ }
677+
678+ let ( locals_base, _stack_base, stack_offset) =
679+ match self . store . stack . values . enter_locals ( wasm_func. params , wasm_func. locals ) {
680+ Ok ( v) => v,
681+ Err ( Error :: Trap ( Trap :: ValueStackOverflow ) ) if !IS_RETURN_CALL => {
682+ return ControlFlow :: Break ( Some ( Trap :: CallStackOverflow . into ( ) ) ) ;
683+ }
684+ Err ( err) => return ControlFlow :: Break ( Some ( err) ) ,
685+ } ;
686+
687+ let new_call_frame = CallFrame :: new ( func_addr, owner, locals_base, stack_offset) ;
688+
689+ if IS_RETURN_CALL {
690+ self . cf = new_call_frame;
638691 } else {
639- let locals = self . store . stack . values . pop_locals ( wasm_func. params , wasm_func. locals ) ;
640- let stack_base = self . store . stack . values . height ( ) ;
641- let new_call_frame = CallFrame :: new ( func_addr, owner, locals, stack_base) ;
642692 self . cf . incr_instr_ptr ( ) ; // skip the call instruction
643- self . store . stack . call_stack . push ( core:: mem:: replace ( & mut self . cf , new_call_frame) ) . to_cf ( ) ?;
693+ self . store . stack . call_stack . push ( self . cf ) . to_cf ( ) ?;
694+ self . cf = new_call_frame;
644695 }
645696
646697 if self . cf . module_addr != self . module . idx {
@@ -709,6 +760,9 @@ impl<'store> Executor<'store> {
709760 }
710761
711762 fn exec_return ( & mut self ) -> ControlFlow < Option < Error > > {
763+ let result_counts = ValueCountsSmall :: from ( self . func . ty . results . iter ( ) ) ;
764+ self . store . stack . values . truncate_keep_counts ( self . cf . locals_base , result_counts) ;
765+
712766 let Some ( cf) = self . store . stack . call_stack . pop ( ) else { return ControlFlow :: Break ( None ) } ;
713767
714768 if cf. func_addr != self . cf . func_addr {
@@ -718,7 +772,6 @@ impl<'store> Executor<'store> {
718772 self . module = self . store . get_module_instance_raw ( cf. module_addr ) . clone ( ) ;
719773 }
720774 }
721-
722775 self . cf = cf;
723776 ControlFlow :: Continue ( ( ) )
724777 }
0 commit comments