avm1: Implement Action::Throw

This commit is contained in:
Nathan Adams 2020-06-21 01:02:45 +02:00 committed by Mike Welsh
parent 70e4a40f01
commit 463b79f063
9 changed files with 38 additions and 7 deletions

View File

@ -499,9 +499,17 @@ impl<'gc> Avm1<'gc> {
return Ok(());
}
while !self.stack_frames.is_empty() {
self.with_current_reader_mut(context, |this, r, context| {
if let Err(e) = self.with_current_reader_mut(context, |this, r, context| {
this.do_next_action(context, r)
})?;
}) {
if let Error::ThrownValue(error) = &e {
let string = error
.coerce_to_string(self, context)
.unwrap_or_else(|_| Cow::Borrowed("undefined"));
log::info!(target: "avm_trace", "{}", string);
}
return Err(e);
}
}
// Operand stack should be empty at this point.
@ -688,10 +696,14 @@ impl<'gc> Avm1<'gc> {
num_actions_to_skip,
} => self.action_wait_for_frame_2(context, num_actions_to_skip, reader),
Action::With { actions } => self.action_with(context, actions),
Action::Throw => self.action_throw(context),
_ => self.unknown_op(context, action),
};
if let Err(e) = result {
log::error!("AVM1 error: {}", e);
match &e {
Error::ThrownValue(_) => {}
e => log::error!("AVM1 error: {}", e),
}
if e.is_halting() {
self.halt();
}
@ -2849,6 +2861,18 @@ impl<'gc> Avm1<'gc> {
Ok(())
}
fn action_throw(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error<'gc>> {
let value = self.pop();
avm_debug!(
"Thrown exception: {}",
value
.coerce_to_string(self, context)
.unwrap_or_else(|_| Cow::Borrowed("undefined"))
);
self.retire_stack_frame(context, Value::Undefined);
Err(Error::ThrownValue(value))
}
fn action_with(
&mut self,
context: &mut UpdateContext<'_, 'gc, '_>,

View File

@ -93,10 +93,13 @@ impl<'gc> ReturnValue<'gc> {
match self {
Immediate(val) => Ok(val),
ResultOf(frame) => {
avm.run_current_frame(context, frame)?;
Ok(avm.pop())
}
ResultOf(frame) => match avm.run_current_frame(context, frame) {
Ok(_) => Ok(avm.pop()),
Err(e) => {
avm.retire_stack_frame(context, Value::Undefined);
Err(e)
}
},
}
}

View File

@ -173,6 +173,8 @@ swf_tests! {
(define_function2_preload, "avm1/define_function2_preload", 1),
(define_function2_preload_order, "avm1/define_function2_preload_order", 1),
(mcl_as_broadcaster, "avm1/mcl_as_broadcaster", 1),
(uncaught_exception, "avm1/uncaught_exception", 1),
(uncaught_exception_bubbled, "avm1/uncaught_exception_bubbled", 1),
(loadmovie, "avm1/loadmovie", 2),
(loadmovienum, "avm1/loadmovienum", 2),
(loadmovie_method, "avm1/loadmovie_method", 2),

View File

@ -0,0 +1 @@
Oh no!

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
Oh no!