@@ -2,16 +2,18 @@ use crate::{cold, runtime::RawWasmValue, unlikely, Error, Result};
22use alloc:: vec:: Vec ;
33use tinywasm_types:: { ValType , WasmValue } ;
44
5+ use super :: BlockFrame ;
6+
57pub ( crate ) const MIN_VALUE_STACK_SIZE : usize = 1024 * 128 ;
68
7- #[ cfg( all ( nightly , feature = "simd" ) ) ]
9+ #[ cfg( feature = "simd" ) ]
810pub ( crate ) const MIN_SIMD_VALUE_STACK_SIZE : usize = 1024 * 32 ;
911
1012#[ derive( Debug ) ]
1113pub ( crate ) struct ValueStack {
1214 stack : Vec < RawWasmValue > ,
1315
14- #[ cfg( all ( nightly , feature = "simd" ) ) ]
16+ #[ cfg( feature = "simd" ) ]
1517 simd_stack : Vec < RawSimdWasmValue > ,
1618}
1719
@@ -20,7 +22,7 @@ impl Default for ValueStack {
2022 Self {
2123 stack : Vec :: with_capacity ( MIN_VALUE_STACK_SIZE ) ,
2224
23- #[ cfg( all ( nightly , feature = "simd" ) ) ]
25+ #[ cfg( feature = "simd" ) ]
2426 simd_stack : Vec :: with_capacity ( MIN_SIMD_VALUE_STACK_SIZE ) ,
2527 }
2628 }
@@ -29,7 +31,16 @@ impl Default for ValueStack {
2931impl ValueStack {
3032 #[ inline]
3133 pub ( crate ) fn extend_from_typed ( & mut self , values : & [ WasmValue ] ) {
34+ #[ cfg( not( feature = "simd" ) ) ]
3235 self . stack . extend ( values. iter ( ) . map ( |v| RawWasmValue :: from ( * v) ) ) ;
36+
37+ #[ cfg( feature = "simd" ) ]
38+ {
39+ values. iter ( ) . for_each ( |v| match v {
40+ WasmValue :: V128 ( v) => self . simd_stack . push ( * v) ,
41+ v => self . stack . push ( RawWasmValue :: from ( * v) ) ,
42+ } ) ;
43+ }
3344 }
3445
3546 #[ inline( always) ]
@@ -65,18 +76,13 @@ impl ValueStack {
6576
6677 #[ inline]
6778 pub ( crate ) fn truncate_keep ( & mut self , n : u32 , end_keep : u32 ) {
68- let total_to_keep = n + end_keep;
69- let len = self . stack . len ( ) as u32 ;
70- assert ! ( len >= total_to_keep, "RawWasmValueotal to keep should be less than or equal to self.top" ) ;
71-
72- if len <= total_to_keep {
73- return ; // No need to truncate if the current size is already less than or equal to total_to_keep
74- }
79+ truncate_keep ( & mut self . stack , n, end_keep) ;
80+ }
7581
76- let items_to_remove = len - total_to_keep ;
77- let remove_start_index = ( len - items_to_remove - end_keep ) as usize ;
78- let remove_end_index = ( len - end_keep) as usize ;
79- self . stack . drain ( remove_start_index..remove_end_index ) ;
82+ # [ cfg ( feature = "simd" ) ]
83+ # [ inline ]
84+ pub ( crate ) fn truncate_keep_simd ( & mut self , n : u32 , end_keep : u32 ) {
85+ truncate_keep ( & mut self . simd_stack , n , end_keep ) ;
8086 }
8187
8288 #[ inline( always) ]
@@ -124,14 +130,44 @@ impl ValueStack {
124130
125131 #[ inline]
126132 pub ( crate ) fn pop_params ( & mut self , types : & [ ValType ] ) -> Result < Vec < WasmValue > > {
127- Ok ( self . pop_n_rev ( types. len ( ) ) ?. zip ( types. iter ( ) ) . map ( |( v, ty) | v. attach_type ( * ty) ) . collect ( ) )
133+ #[ cfg( not( feature = "simd" ) ) ]
134+ return Ok ( self . pop_n_rev ( types. len ( ) ) ?. zip ( types. iter ( ) ) . map ( |( v, ty) | v. attach_type ( * ty) ) . collect ( ) ) ;
135+
136+ #[ cfg( feature = "simd" ) ]
137+ {
138+ let mut values = Vec :: with_capacity ( types. len ( ) ) ;
139+ for ty in types {
140+ match ty {
141+ ValType :: V128 => values. push ( WasmValue :: V128 ( self . simd_stack . pop ( ) . unwrap ( ) ) ) ,
142+ ty => values. push ( self . pop ( ) ?. attach_type ( * ty) ) ,
143+ }
144+ }
145+ Ok ( values)
146+ }
128147 }
129148
130149 #[ inline]
131- pub ( crate ) fn break_to ( & mut self , new_stack_size : u32 , result_count : u8 ) {
132- let start = new_stack_size as usize ;
133- let end = self . stack . len ( ) - result_count as usize ;
134- self . stack . drain ( start..end) ;
150+ pub ( crate ) fn break_to_results ( & mut self , bf : & BlockFrame ) {
151+ let end = self . stack . len ( ) - bf. results as usize ;
152+ self . stack . drain ( bf. stack_ptr as usize ..end) ;
153+
154+ #[ cfg( feature = "simd" ) ]
155+ {
156+ let end = self . simd_stack . len ( ) - bf. simd_results as usize ;
157+ self . simd_stack . drain ( bf. simd_stack_ptr as usize ..end) ;
158+ }
159+ }
160+
161+ #[ inline]
162+ pub ( crate ) fn break_to_params ( & mut self , bf : & BlockFrame ) {
163+ let end = self . stack . len ( ) - bf. params as usize ;
164+ self . stack . drain ( bf. stack_ptr as usize ..end) ;
165+
166+ #[ cfg( feature = "simd" ) ]
167+ {
168+ let end = self . simd_stack . len ( ) - bf. simd_params as usize ;
169+ self . simd_stack . drain ( bf. simd_stack_ptr as usize ..end) ;
170+ }
135171 }
136172
137173 #[ inline]
@@ -152,6 +188,22 @@ impl ValueStack {
152188 }
153189}
154190
191+ #[ inline( always) ]
192+ fn truncate_keep < T > ( data : & mut Vec < T > , n : u32 , end_keep : u32 ) {
193+ let total_to_keep = n + end_keep;
194+ let len = data. len ( ) as u32 ;
195+ assert ! ( len >= total_to_keep, "RawWasmValueotal to keep should be less than or equal to self.top" ) ;
196+
197+ if len <= total_to_keep {
198+ return ; // No need to truncate if the current size is already less than or equal to total_to_keep
199+ }
200+
201+ let items_to_remove = len - total_to_keep;
202+ let remove_start_index = ( len - items_to_remove - end_keep) as usize ;
203+ let remove_end_index = ( len - end_keep) as usize ;
204+ data. drain ( remove_start_index..remove_end_index) ;
205+ }
206+
155207#[ cfg( test) ]
156208mod tests {
157209 use super :: * ;
0 commit comments