@@ -35,6 +35,15 @@ impl DefaultRuntime {
3535 ExecResult :: Ok => {
3636 cf. instr_ptr += 1 ;
3737 }
38+
39+ // trap the program
40+ ExecResult :: Trap ( trap) => {
41+ cf. instr_ptr += 1 ;
42+ // push the call frame back onto the stack so that it can be resumed
43+ // if the trap can be handled
44+ stack. call_stack . push ( cf) ;
45+ return Err ( Error :: Trap ( trap) ) ;
46+ }
3847 }
3948 }
4049
@@ -50,6 +59,7 @@ enum ExecResult {
5059 Ok ,
5160 Return ,
5261 Call ,
62+ Trap ( crate :: Trap ) ,
5363}
5464
5565#[ inline]
@@ -63,9 +73,21 @@ fn exec_one(
6373) -> Result < ExecResult > {
6474 use tinywasm_types:: Instruction :: * ;
6575 match instr {
66- Nop => { } // do nothing
67- Unreachable => return Err ( Error :: Trap ( crate :: Trap :: Unreachable ) ) ,
68-
76+ Nop => { /* do nothing */ }
77+ Unreachable => return Ok ( ExecResult :: Trap ( crate :: Trap :: Unreachable ) ) , // we don't need to include the call frame here because it's already on the stack
78+ Drop => {
79+ stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?;
80+ }
81+ Select => {
82+ let cond: i32 = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?. into ( ) ;
83+ let val2 = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?;
84+
85+ // if cond != 0, we already have the right value on the stack
86+ if cond == 0 {
87+ let _ = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?;
88+ stack. values . push ( val2) ;
89+ }
90+ }
6991 Return => {
7092 debug ! ( "return" ) ;
7193 }
@@ -117,7 +139,6 @@ fn exec_one(
117139
118140 todo ! ( )
119141 }
120-
121142 Br ( v) => cf. break_to ( * v, & mut stack. values ) ?,
122143 BrIf ( v) => {
123144 let val: i32 = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?. into ( ) ;
@@ -164,19 +185,16 @@ fn exec_one(
164185 LocalGet ( local_index) => {
165186 debug ! ( "local.get: {:?}" , local_index) ;
166187 let val = cf. get_local ( * local_index as usize ) ;
167- debug ! ( "local: {:#?}" , val) ;
168188 stack. values . push ( val) ;
169189 }
170190 LocalSet ( local_index) => {
171- debug ! ( "local.set: {:?}" , local_index) ;
172191 let val = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?;
173192 cf. set_local ( * local_index as usize , val) ;
174193 }
194+ // Equivalent to local.set, local.get
175195 LocalTee ( local_index) => {
176- debug ! ( "local.tee: {:?}" , local_index) ;
177- let val = stack. values . pop ( ) . ok_or ( Error :: StackUnderflow ) ?;
178- cf. set_local ( * local_index as usize , val) ;
179- stack. values . push ( val) ;
196+ let val = stack. values . last ( ) . ok_or ( Error :: StackUnderflow ) ?;
197+ cf. set_local ( * local_index as usize , * val) ;
180198 }
181199 I32Const ( val) => stack. values . push ( ( * val) . into ( ) ) ,
182200 I64Const ( val) => stack. values . push ( ( * val) . into ( ) ) ,
0 commit comments