diff --git a/valuescript_vm/src/array_higher_functions/array_mapping_frame.rs b/valuescript_vm/src/array_higher_functions/array_mapping_frame.rs index 0735a84..1b5ae0f 100644 --- a/valuescript_vm/src/array_higher_functions/array_mapping_frame.rs +++ b/valuescript_vm/src/array_higher_functions/array_mapping_frame.rs @@ -137,4 +137,8 @@ impl StackFrameTrait for ArrayMappingFrame { fn get_call_result(&mut self) -> CallResult { panic!("Not appropriate for MapFrame") } + + fn catch_exception(&mut self, _exception: Val) -> bool { + return false; + } } diff --git a/valuescript_vm/src/array_higher_functions/array_reduce.rs b/valuescript_vm/src/array_higher_functions/array_reduce.rs index 1032ecd..15ce3a7 100644 --- a/valuescript_vm/src/array_higher_functions/array_reduce.rs +++ b/valuescript_vm/src/array_higher_functions/array_reduce.rs @@ -105,4 +105,8 @@ impl StackFrameTrait for ReduceFrame { fn get_call_result(&mut self) -> CallResult { panic!("Not appropriate for ReduceFrame") } + + fn catch_exception(&mut self, _exception: Val) -> bool { + return false; + } } diff --git a/valuescript_vm/src/array_higher_functions/array_reduce_right.rs b/valuescript_vm/src/array_higher_functions/array_reduce_right.rs index 6da6f69..c83ab91 100644 --- a/valuescript_vm/src/array_higher_functions/array_reduce_right.rs +++ b/valuescript_vm/src/array_higher_functions/array_reduce_right.rs @@ -119,4 +119,8 @@ impl StackFrameTrait for ReduceRightFrame { fn get_call_result(&mut self) -> CallResult { panic!("Not appropriate for ReduceRightFrame") } + + fn catch_exception(&mut self, _exception: Val) -> bool { + return false; + } } diff --git a/valuescript_vm/src/array_higher_functions/array_sort.rs b/valuescript_vm/src/array_higher_functions/array_sort.rs index c83657e..9520e0d 100644 --- a/valuescript_vm/src/array_higher_functions/array_sort.rs +++ b/valuescript_vm/src/array_higher_functions/array_sort.rs @@ -304,4 +304,8 @@ impl StackFrameTrait for SortFrame { fn get_call_result(&mut self) -> CallResult { panic!("Not appropriate for SortFrame") } + + fn catch_exception(&mut self, _exception: Val) -> bool { + return false; + } } diff --git a/valuescript_vm/src/bytecode_stack_frame.rs b/valuescript_vm/src/bytecode_stack_frame.rs index 2c4e1b1..05fbb0d 100644 --- a/valuescript_vm/src/bytecode_stack_frame.rs +++ b/valuescript_vm/src/bytecode_stack_frame.rs @@ -445,6 +445,10 @@ impl StackFrameTrait for BytecodeStackFrame { fn get_call_result(&mut self) -> CallResult { panic!("Not appropriate for BytecodeStackFrame") } + + fn catch_exception(&mut self, _exception: Val) -> bool { + return false; // TODO + } } enum ThisArg { diff --git a/valuescript_vm/src/first_stack_frame.rs b/valuescript_vm/src/first_stack_frame.rs index de0f957..9862cd1 100644 --- a/valuescript_vm/src/first_stack_frame.rs +++ b/valuescript_vm/src/first_stack_frame.rs @@ -36,4 +36,8 @@ impl StackFrameTrait for FirstStackFrame { fn get_call_result(&mut self) -> CallResult { return self.call_result.clone(); } + + fn catch_exception(&mut self, _exception: Val) -> bool { + panic!("Not appropriate for FirstStackFrame"); + } } diff --git a/valuescript_vm/src/stack_frame.rs b/valuescript_vm/src/stack_frame.rs index a56a774..2b32c8f 100644 --- a/valuescript_vm/src/stack_frame.rs +++ b/valuescript_vm/src/stack_frame.rs @@ -22,4 +22,5 @@ pub trait StackFrameTrait { fn step(&mut self) -> FrameStepResult; fn apply_call_result(&mut self, call_result: CallResult); fn get_call_result(&mut self) -> CallResult; + fn catch_exception(&mut self, exception: Val) -> bool; } diff --git a/valuescript_vm/src/virtual_machine.rs b/valuescript_vm/src/virtual_machine.rs index 4542742..09c4166 100644 --- a/valuescript_vm/src/virtual_machine.rs +++ b/valuescript_vm/src/virtual_machine.rs @@ -50,7 +50,12 @@ impl VirtualMachine { } pub fn step(&mut self) -> Result<(), Val> { - match self.frame.step()? { + let step_ok = match self.frame.step() { + Ok(step_ok) => step_ok, + Err(e) => return self.handle_exception(e), + }; + + match step_ok { FrameStepOk::Continue => {} FrameStepOk::Pop(call_result) => { self.pop(); @@ -74,4 +79,22 @@ impl VirtualMachine { let mut old_frame = self.stack.pop().unwrap(); std::mem::swap(&mut self.frame, &mut old_frame); } + + pub fn handle_exception(&mut self, exception: Val) -> Result<(), Val> { + while !self.stack.is_empty() { + let handled = self.frame.catch_exception(exception.clone()); + + if handled { + return Ok(()); + } + + if self.stack.is_empty() { + return Err(exception); + } + + self.pop(); + } + + Err(exception) + } }