mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Implement stack unwinding
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user