Add global scope which is automatically included on all new activations.
This commit is contained in:
parent
984e701142
commit
7d75255a1a
|
@ -8,7 +8,7 @@ use crate::avm2::scope::Scope;
|
||||||
use crate::avm2::value::Value;
|
use crate::avm2::value::Value;
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::tag_utils::SwfSlice;
|
use crate::tag_utils::SwfSlice;
|
||||||
use gc_arena::{Collect, GcCell};
|
use gc_arena::{Collect, GcCell, MutationContext};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use swf::avm2::read::Reader;
|
use swf::avm2::read::Reader;
|
||||||
|
@ -19,6 +19,7 @@ use swf::read::SwfRead;
|
||||||
|
|
||||||
mod activation;
|
mod activation;
|
||||||
mod function;
|
mod function;
|
||||||
|
mod globals;
|
||||||
mod names;
|
mod names;
|
||||||
mod object;
|
mod object;
|
||||||
mod return_value;
|
mod return_value;
|
||||||
|
@ -48,14 +49,18 @@ pub struct Avm2<'gc> {
|
||||||
|
|
||||||
/// Values currently present on the operand stack.
|
/// Values currently present on the operand stack.
|
||||||
stack: Vec<Value<'gc>>,
|
stack: Vec<Value<'gc>>,
|
||||||
|
|
||||||
|
/// Global scope object.
|
||||||
|
globals: Object<'gc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> Avm2<'gc> {
|
impl<'gc> Avm2<'gc> {
|
||||||
/// Construct a new AVM interpreter.
|
/// Construct a new AVM interpreter.
|
||||||
pub fn new() -> Self {
|
pub fn new(mc: MutationContext<'gc, '_>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
stack_frames: Vec::new(),
|
stack_frames: Vec::new(),
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
|
globals: globals::construct_global_scope(mc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +85,10 @@ impl<'gc> Avm2<'gc> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn globals(&self) -> Object<'gc> {
|
||||||
|
self.globals
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the current stack frame (`Activation` object).
|
/// Get the current stack frame (`Activation` object).
|
||||||
pub fn current_stack_frame(&self) -> Option<GcCell<'gc, Activation<'gc>>> {
|
pub fn current_stack_frame(&self) -> Option<GcCell<'gc, Activation<'gc>>> {
|
||||||
self.stack_frames.last().copied()
|
self.stack_frames.last().copied()
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::avm2::object::Object;
|
||||||
use crate::avm2::scope::Scope;
|
use crate::avm2::scope::Scope;
|
||||||
use crate::avm2::script_object::ScriptObject;
|
use crate::avm2::script_object::ScriptObject;
|
||||||
use crate::avm2::value::Value;
|
use crate::avm2::value::Value;
|
||||||
use crate::avm2::Error;
|
use crate::avm2::{Avm2, Error};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -96,6 +96,7 @@ impl<'gc> Activation<'gc> {
|
||||||
action: Gc<'gc, Avm2Function>,
|
action: Gc<'gc, Avm2Function>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
arguments: Option<Object<'gc>>,
|
arguments: Option<Object<'gc>>,
|
||||||
|
avm2: &mut Avm2<'gc>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let abc = action.abc.clone();
|
let abc = action.abc.clone();
|
||||||
let method_body = abc
|
let method_body = abc
|
||||||
|
@ -115,7 +116,7 @@ impl<'gc> Activation<'gc> {
|
||||||
),
|
),
|
||||||
return_value: None,
|
return_value: None,
|
||||||
local_scope: ScriptObject::bare_object(context.gc_context),
|
local_scope: ScriptObject::bare_object(context.gc_context),
|
||||||
scope: None,
|
scope: Some(Scope::push_scope(None, avm2.globals(), context.gc_context)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
|
||||||
Executable::Action(a2f) => {
|
Executable::Action(a2f) => {
|
||||||
let activation = GcCell::allocate(
|
let activation = GcCell::allocate(
|
||||||
context.gc_context,
|
context.gc_context,
|
||||||
Activation::from_action(context, a2f, reciever, None)?,
|
Activation::from_action(context, a2f, reciever, None, avm)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
avm.insert_stack_frame(activation);
|
avm.insert_stack_frame(activation);
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -247,7 +247,7 @@ impl Player {
|
||||||
mouse_hovered_object: None,
|
mouse_hovered_object: None,
|
||||||
drag_object: None,
|
drag_object: None,
|
||||||
avm1: Avm1::new(gc_context, NEWEST_PLAYER_VERSION),
|
avm1: Avm1::new(gc_context, NEWEST_PLAYER_VERSION),
|
||||||
avm2: Avm2::new(),
|
avm2: Avm2::new(gc_context),
|
||||||
action_queue: ActionQueue::new(),
|
action_queue: ActionQueue::new(),
|
||||||
load_manager: LoadManager::new(),
|
load_manager: LoadManager::new(),
|
||||||
shared_objects: HashMap::new(),
|
shared_objects: HashMap::new(),
|
||||||
|
|
Loading…
Reference in New Issue