avm1: Implement Action::Throw
This commit is contained in:
parent
70e4a40f01
commit
463b79f063
|
@ -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, '_>,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Oh no!
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Oh no!
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue