diff --git a/core/src/avm2.rs b/core/src/avm2.rs index 0dee2ee44..a72f5280c 100644 --- a/core/src/avm2.rs +++ b/core/src/avm2.rs @@ -8,7 +8,7 @@ use crate::avm2::scope::Scope; use crate::avm2::value::Value; use crate::context::UpdateContext; use crate::tag_utils::SwfSlice; -use gc_arena::{Collect, GcCell}; +use gc_arena::{Collect, GcCell, MutationContext}; use std::io::Cursor; use std::rc::Rc; use swf::avm2::read::Reader; @@ -19,6 +19,7 @@ use swf::read::SwfRead; mod activation; mod function; +mod globals; mod names; mod object; mod return_value; @@ -48,14 +49,18 @@ pub struct Avm2<'gc> { /// Values currently present on the operand stack. stack: Vec>, + + /// Global scope object. + globals: Object<'gc>, } impl<'gc> Avm2<'gc> { /// Construct a new AVM interpreter. - pub fn new() -> Self { + pub fn new(mc: MutationContext<'gc, '_>) -> Self { Self { stack_frames: Vec::new(), stack: Vec::new(), + globals: globals::construct_global_scope(mc), } } @@ -80,6 +85,10 @@ impl<'gc> Avm2<'gc> { Ok(()) } + pub fn globals(&self) -> Object<'gc> { + self.globals + } + /// Get the current stack frame (`Activation` object). pub fn current_stack_frame(&self) -> Option>> { self.stack_frames.last().copied() diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 965f0d4ea..ada84e518 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -5,7 +5,7 @@ use crate::avm2::object::Object; use crate::avm2::scope::Scope; use crate::avm2::script_object::ScriptObject; use crate::avm2::value::Value; -use crate::avm2::Error; +use crate::avm2::{Avm2, Error}; use crate::context::UpdateContext; use gc_arena::{Collect, Gc, GcCell, MutationContext}; use smallvec::SmallVec; @@ -96,6 +96,7 @@ impl<'gc> Activation<'gc> { action: Gc<'gc, Avm2Function>, this: Object<'gc>, arguments: Option>, + avm2: &mut Avm2<'gc>, ) -> Result { let abc = action.abc.clone(); let method_body = abc @@ -115,7 +116,7 @@ impl<'gc> Activation<'gc> { ), return_value: None, local_scope: ScriptObject::bare_object(context.gc_context), - scope: None, + scope: Some(Scope::push_scope(None, avm2.globals(), context.gc_context)), }) } diff --git a/core/src/avm2/function.rs b/core/src/avm2/function.rs index 8746a0198..c7af70de5 100644 --- a/core/src/avm2/function.rs +++ b/core/src/avm2/function.rs @@ -136,7 +136,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { Executable::Action(a2f) => { let activation = GcCell::allocate( context.gc_context, - Activation::from_action(context, a2f, reciever, None)?, + Activation::from_action(context, a2f, reciever, None, avm)?, ); avm.insert_stack_frame(activation); diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs new file mode 100644 index 000000000..24119d5c8 --- /dev/null +++ b/core/src/avm2/globals.rs @@ -0,0 +1,11 @@ +//! Global scope built-ins + +use crate::avm2::object::{Object, TObject}; +use crate::avm2::script_object::ScriptObject; +use gc_arena::MutationContext; + +pub fn construct_global_scope<'gc>(mc: MutationContext<'gc, '_>) -> Object<'gc> { + let global_scope = ScriptObject::bare_object(mc); + + global_scope +} diff --git a/core/src/player.rs b/core/src/player.rs index 475a21f33..1753b4a1e 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -247,7 +247,7 @@ impl Player { mouse_hovered_object: None, drag_object: None, avm1: Avm1::new(gc_context, NEWEST_PLAYER_VERSION), - avm2: Avm2::new(), + avm2: Avm2::new(gc_context), action_queue: ActionQueue::new(), load_manager: LoadManager::new(), shared_objects: HashMap::new(),