avm1: Stop execution if base clip is removed (fix #893)
Stop execution of the current stack frame if the base clip was removed (for example, due to a goto).
This commit is contained in:
parent
3f46567fc1
commit
0482d1c290
|
@ -678,7 +678,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
avm_warn!(self, "CloneSprite: Source is not a movie clip");
|
||||
}
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_bit_and(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -796,7 +796,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
|
||||
self.context.avm1.push(result);
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_call_method(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -834,7 +834,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_cast_op(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1201,8 +1201,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
e
|
||||
),
|
||||
}
|
||||
|
||||
return Ok(FrameControl::Continue);
|
||||
return self.continue_if_base_clip_exists();
|
||||
}
|
||||
|
||||
if let Some(fscommand) = fscommand::parse(url) {
|
||||
|
@ -1291,8 +1290,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
self.context.navigator.spawn_future(process);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(FrameControl::Continue);
|
||||
return self.continue_if_base_clip_exists();
|
||||
} else if window_target.starts_with("_level") && url.len() > 6 {
|
||||
// target of `_level#` indicates a `loadMovieNum` call.
|
||||
match window_target[6..].parse::<u32>() {
|
||||
|
@ -1344,7 +1342,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_error!(self, "GotoFrame failed: Invalid target");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_goto_frame_2(
|
||||
|
@ -1370,7 +1368,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_warn!(self, "GotoFrame2: Invalid target");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_goto_label(&mut self, label: &str) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1387,7 +1385,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_warn!(self, "GoToLabel: Invalid target");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_if(
|
||||
|
@ -1615,7 +1613,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_warn!(self, "NextFrame: Invalid target");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_new_method(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1643,7 +1641,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
self.context.avm1.push(Value::Undefined);
|
||||
}
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_new_object(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1662,7 +1660,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
|
||||
self.context.avm1.push(this);
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_or(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1698,7 +1696,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_warn!(self, "PrevFrame: Invalid target");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_pop(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -1772,7 +1770,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else {
|
||||
avm_warn!(self, "RemoveSprite: Source is not a movie clip");
|
||||
}
|
||||
Ok(FrameControl::Continue)
|
||||
self.continue_if_base_clip_exists()
|
||||
}
|
||||
|
||||
fn action_return(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
|
@ -2875,4 +2873,15 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
pub fn set_constant_pool(&mut self, constant_pool: GcCell<'gc, Vec<String>>) {
|
||||
self.constant_pool = constant_pool;
|
||||
}
|
||||
|
||||
/// Checks that the clip executing a script still exists.
|
||||
/// If the clip executing a script is removed during exectuion, return from this activation.
|
||||
/// Should be called after any action that could potentially destroy a clip (gotos, etc.)
|
||||
fn continue_if_base_clip_exists(&self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
if self.base_clip.removed() {
|
||||
Ok(FrameControl::Return(ReturnType::Explicit(Value::Undefined)))
|
||||
} else {
|
||||
Ok(FrameControl::Continue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue