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");
|
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>> {
|
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);
|
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>> {
|
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>> {
|
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
|
e
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
return self.continue_if_base_clip_exists();
|
||||||
return Ok(FrameControl::Continue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fscommand) = fscommand::parse(url) {
|
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);
|
self.context.navigator.spawn_future(process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return self.continue_if_base_clip_exists();
|
||||||
return Ok(FrameControl::Continue);
|
|
||||||
} else if window_target.starts_with("_level") && url.len() > 6 {
|
} else if window_target.starts_with("_level") && url.len() > 6 {
|
||||||
// target of `_level#` indicates a `loadMovieNum` call.
|
// target of `_level#` indicates a `loadMovieNum` call.
|
||||||
match window_target[6..].parse::<u32>() {
|
match window_target[6..].parse::<u32>() {
|
||||||
|
@ -1344,7 +1342,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
} else {
|
} else {
|
||||||
avm_error!(self, "GotoFrame failed: Invalid target");
|
avm_error!(self, "GotoFrame failed: Invalid target");
|
||||||
}
|
}
|
||||||
Ok(FrameControl::Continue)
|
self.continue_if_base_clip_exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_goto_frame_2(
|
fn action_goto_frame_2(
|
||||||
|
@ -1370,7 +1368,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
} else {
|
} else {
|
||||||
avm_warn!(self, "GotoFrame2: Invalid target");
|
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>> {
|
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 {
|
} else {
|
||||||
avm_warn!(self, "GoToLabel: Invalid target");
|
avm_warn!(self, "GoToLabel: Invalid target");
|
||||||
}
|
}
|
||||||
Ok(FrameControl::Continue)
|
self.continue_if_base_clip_exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_if(
|
fn action_if(
|
||||||
|
@ -1615,7 +1613,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
} else {
|
} else {
|
||||||
avm_warn!(self, "NextFrame: Invalid target");
|
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>> {
|
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);
|
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>> {
|
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);
|
self.context.avm1.push(this);
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
self.continue_if_base_clip_exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_or(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
|
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 {
|
} else {
|
||||||
avm_warn!(self, "PrevFrame: Invalid target");
|
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>> {
|
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 {
|
} else {
|
||||||
avm_warn!(self, "RemoveSprite: Source is not a movie clip");
|
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>> {
|
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>>) {
|
pub fn set_constant_pool(&mut self, constant_pool: GcCell<'gc, Vec<String>>) {
|
||||||
self.constant_pool = constant_pool;
|
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