@@ -3,52 +3,45 @@ use crate::{
33 runtime:: { BlockType , RawWasmValue } ,
44 Error , FunctionInstance , Result , Trap ,
55} ;
6+ use alloc:: vec;
67use alloc:: { boxed:: Box , rc:: Rc , vec:: Vec } ;
78use tinywasm_types:: { ValType , WasmValue } ;
89
910use super :: { blocks:: Labels , LabelFrame } ;
1011
1112// minimum call stack size
12- const CALL_STACK_SIZE : usize = 128 ;
13+ const CALL_STACK_SIZE : usize = 256 ;
1314const CALL_STACK_MAX_SIZE : usize = 1024 ;
1415
1516#[ derive( Debug ) ]
1617pub ( crate ) struct CallStack {
1718 stack : Vec < CallFrame > ,
18- top : usize ,
1919}
2020
2121impl Default for CallStack {
2222 fn default ( ) -> Self {
23- Self { stack : Vec :: with_capacity ( CALL_STACK_SIZE ) , top : 0 }
23+ Self { stack : Vec :: with_capacity ( CALL_STACK_SIZE ) }
2424 }
2525}
2626
2727impl CallStack {
28+ #[ inline]
2829 pub ( crate ) fn is_empty ( & self ) -> bool {
29- self . top == 0
30+ self . stack . is_empty ( )
3031 }
3132
33+ #[ inline]
3234 pub ( crate ) fn pop ( & mut self ) -> Result < CallFrame > {
33- assert ! ( self . top <= self . stack. len( ) ) ;
34- if self . top == 0 {
35- return Err ( Error :: CallStackEmpty ) ;
36- }
37-
38- self . top -= 1 ;
39- Ok ( self . stack . pop ( ) . unwrap ( ) )
35+ self . stack . pop ( ) . ok_or_else ( || Error :: CallStackEmpty )
4036 }
4137
4238 #[ inline]
4339 pub ( crate ) fn push ( & mut self , call_frame : CallFrame ) -> Result < ( ) > {
44- assert ! ( self . top <= self . stack. len( ) , "stack is too small" ) ;
45-
4640 log:: debug!( "stack size: {}" , self . stack. len( ) ) ;
4741 if self . stack . len ( ) >= CALL_STACK_MAX_SIZE {
4842 return Err ( Trap :: CallStackOverflow . into ( ) ) ;
4943 }
5044
51- self . top += 1 ;
5245 self . stack . push ( call_frame) ;
5346 Ok ( ( ) )
5447 }
@@ -79,7 +72,6 @@ impl CallFrame {
7972 /// Break to a block at the given index (relative to the current frame)
8073 /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller)
8174 pub ( crate ) fn break_to ( & mut self , break_to_relative : u32 , value_stack : & mut super :: ValueStack ) -> Option < ( ) > {
82- log:: debug!( "break_to_relative: {}" , break_to_relative) ;
8375 let break_to = self . labels . get_relative_to_top ( break_to_relative as usize ) ?;
8476
8577 // instr_ptr points to the label instruction, but the next step
@@ -111,14 +103,15 @@ impl CallFrame {
111103 Some ( ( ) )
112104 }
113105
106+ // TOOD: perf: this function is pretty hot
107+ // Especially the two `extend` calls
114108 pub ( crate ) fn new_raw (
115109 func_instance_ptr : Rc < FunctionInstance > ,
116110 params : & [ RawWasmValue ] ,
117111 local_types : Vec < ValType > ,
118112 ) -> Self {
119- let mut locals = Vec :: with_capacity ( local_types. len ( ) + params. len ( ) ) ;
120- locals. extend ( params. iter ( ) . cloned ( ) ) ;
121- locals. extend ( local_types. iter ( ) . map ( |_| RawWasmValue :: default ( ) ) ) ;
113+ let mut locals = vec ! [ RawWasmValue :: default ( ) ; local_types. len( ) + params. len( ) ] ;
114+ locals[ ..params. len ( ) ] . copy_from_slice ( params) ;
122115
123116 Self {
124117 instr_ptr : 0 ,
0 commit comments