diff --git a/core/src/avm1.rs b/core/src/avm1.rs index afc5c3ab2..5927eb24a 100644 --- a/core/src/avm1.rs +++ b/core/src/avm1.rs @@ -108,8 +108,16 @@ impl<'gc> Avm1<'gc> { form_values } - /// Add a stack frame that executes code directly from a SwfSlice. - pub fn insert_stack_frame_from_action(&mut self, swf_version: u8, code: SwfSlice, gc_context: MutationContext<'gc, '_>) { + /// Add a stack frame that executes code in timeline scope + pub fn insert_stack_frame_for_action(&mut self, swf_version: u8, code: SwfSlice, action_context: &mut ActionContext<'_, 'gc, '_>) { + let global_scope = GcCell::allocate(action_context.gc_context, Scope::from_global_object(self.globals)); + let clip_obj = action_context.active_clip.read().object().as_object().unwrap().to_owned(); + let child_scope = GcCell::allocate(action_context.gc_context, Scope::from_parent_scope_with_object(global_scope, clip_obj)); + self.stack_frames.push(Activation::from_action(swf_version, code, child_scope)); + } + + /// Add a stack frame that executes code in function scope + pub fn insert_stack_frame_for_function(&mut self, swf_version: u8, code: SwfSlice, gc_context: MutationContext<'gc, '_>) { let scope = GcCell::allocate(gc_context, Scope::from_global_object(self.globals)); self.stack_frames.push(Activation::from_action(swf_version, code, scope)); } diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index e5b4884e8..05d8bbe2c 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -68,7 +68,7 @@ impl<'gc> Executable<'gc> { match self { Executable::Native(nf) => Some(nf(avm, ac, this, args)), Executable::Action(af) => { - avm.insert_stack_frame_from_action(af.swf_version, af.data.clone(), ac.gc_context); + avm.insert_stack_frame_for_function(af.swf_version, af.data.clone(), ac.gc_context); for i in 0..args.len() { avm.push(args.get(i).unwrap().clone()); diff --git a/core/src/avm1/scope.rs b/core/src/avm1/scope.rs index 2300a7a38..733fdd625 100644 --- a/core/src/avm1/scope.rs +++ b/core/src/avm1/scope.rs @@ -27,7 +27,7 @@ impl<'gc> Scope<'gc> { } } - /// Construct a child scope (one with a parent). + /// Construct a child scope of another scope. pub fn from_parent_scope(parent: GcCell<'gc, Self>, mc: MutationContext<'gc, '_>) -> Scope<'gc> { Scope { parent: Some(parent.clone()), @@ -35,6 +35,16 @@ impl<'gc> Scope<'gc> { } } + /// Construct a child scope with a given object + /// + /// Rejected titles: `from_oyako_scope` + pub fn from_parent_scope_with_object(parent: GcCell<'gc, Self>, with_object: GcCell<'gc, Object<'gc>>) -> Scope<'gc> { + Scope { + parent: Some(parent), + values: with_object + } + } + /// Returns a reference to the current local scope object. pub fn locals(&self) -> Ref> { self.values.read() diff --git a/core/src/player.rs b/core/src/player.rs index 1c6c3412f..c0a9171f2 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -515,7 +515,7 @@ impl action_context.start_clip = active_clip; action_context.active_clip = active_clip; action_context.target_clip = Some(active_clip); - update_context.avm.insert_stack_frame_from_action(update_context.swf_version, action, update_context.gc_context); + update_context.avm.insert_stack_frame_for_action(update_context.swf_version, action, &mut action_context); let _ = update_context.avm.run_stack_till_empty(&mut action_context); } }