Upon encountering an `Err`, dispose of the current AVM2 stack.

In the future, the `unwrap_stack_frame` mechanism should be expanded upon to allow running exception handlers and recovering from a Rust error - but not today.
This commit is contained in:
David Wendt 2020-02-23 17:28:28 -05:00
parent a7ff2de476
commit 68cf9e8869
1 changed files with 17 additions and 1 deletions

View File

@ -145,7 +145,7 @@ impl<'gc> Avm2<'gc> {
Ok(())
}
/// Destroy the current stack frame (if there is one).
/// Destroy the current stack frame (if there is one) with a return value.
///
/// The given return value will be pushed on the stack if there is a
/// function to return it to. Otherwise, it will be discarded.
@ -175,6 +175,21 @@ impl<'gc> Avm2<'gc> {
Ok(())
}
/// Destroy the current stack frame (if there is one) with an exception.
///
/// TODO: This function should allow exception recovery at some point in
/// the future.
///
/// NOTE: This means that if you are starting a brand new AVM stack just to
/// get it's return value, you won't get that value. Instead, retain a cell
/// referencing the oldest activation frame and use that to retrieve the
/// return value.
fn unwind_stack_frame(&mut self) {
if let Some(_frame) = self.current_stack_frame() {
self.stack_frames.pop();
}
}
/// Perform some action with the current stack frame's reader.
///
/// This function constructs a reader based off the current stack frame's
@ -449,6 +464,7 @@ impl<'gc> Avm2<'gc> {
if let Err(ref e) = result {
log::error!("AVM2 error: {}", e);
self.unwind_stack_frame();
return result;
}
}