avm2: Remove SystemPrototypes.
This commit is contained in:
parent
1c5312d6c8
commit
f31d4c2498
|
@ -1,6 +1,6 @@
|
||||||
//! ActionScript Virtual Machine 2 (AS3) support
|
//! ActionScript Virtual Machine 2 (AS3) support
|
||||||
|
|
||||||
use crate::avm2::globals::{SystemClasses, SystemPrototypes};
|
use crate::avm2::globals::SystemClasses;
|
||||||
use crate::avm2::method::Method;
|
use crate::avm2::method::Method;
|
||||||
use crate::avm2::object::EventObject;
|
use crate::avm2::object::EventObject;
|
||||||
use crate::avm2::script::{Script, TranslationUnit};
|
use crate::avm2::script::{Script, TranslationUnit};
|
||||||
|
@ -72,9 +72,6 @@ pub struct Avm2<'gc> {
|
||||||
/// Global scope object.
|
/// Global scope object.
|
||||||
globals: Domain<'gc>,
|
globals: Domain<'gc>,
|
||||||
|
|
||||||
/// System prototypes.
|
|
||||||
system_prototypes: Option<SystemPrototypes<'gc>>,
|
|
||||||
|
|
||||||
/// System classes.
|
/// System classes.
|
||||||
system_classes: Option<SystemClasses<'gc>>,
|
system_classes: Option<SystemClasses<'gc>>,
|
||||||
|
|
||||||
|
@ -100,7 +97,6 @@ impl<'gc> Avm2<'gc> {
|
||||||
Self {
|
Self {
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
globals,
|
globals,
|
||||||
system_prototypes: None,
|
|
||||||
system_classes: None,
|
system_classes: None,
|
||||||
broadcast_list: Default::default(),
|
broadcast_list: Default::default(),
|
||||||
|
|
||||||
|
@ -115,13 +111,6 @@ impl<'gc> Avm2<'gc> {
|
||||||
globals::load_player_globals(&mut activation, globals)
|
globals::load_player_globals(&mut activation, globals)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current set of system prototypes.
|
|
||||||
///
|
|
||||||
/// This function panics if the interpreter has not yet been initialized.
|
|
||||||
pub fn prototypes(&self) -> &SystemPrototypes<'gc> {
|
|
||||||
self.system_prototypes.as_ref().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the current set of system classes.
|
/// Return the current set of system classes.
|
||||||
///
|
///
|
||||||
/// This function panics if the interpreter has not yet been initialized.
|
/// This function panics if the interpreter has not yet been initialized.
|
||||||
|
|
|
@ -44,124 +44,6 @@ const NS_VECTOR: &str = "__AS3__.vec";
|
||||||
|
|
||||||
pub use flash::utils::NS_FLASH_PROXY;
|
pub use flash::utils::NS_FLASH_PROXY;
|
||||||
|
|
||||||
/// This structure represents all system builtins' prototypes.
|
|
||||||
#[derive(Clone, Collect)]
|
|
||||||
#[collect(no_drop)]
|
|
||||||
pub struct SystemPrototypes<'gc> {
|
|
||||||
pub object: Object<'gc>,
|
|
||||||
pub function: Object<'gc>,
|
|
||||||
pub class: Object<'gc>,
|
|
||||||
pub global: Object<'gc>,
|
|
||||||
pub string: Object<'gc>,
|
|
||||||
pub boolean: Object<'gc>,
|
|
||||||
pub number: Object<'gc>,
|
|
||||||
pub int: Object<'gc>,
|
|
||||||
pub uint: Object<'gc>,
|
|
||||||
pub namespace: Object<'gc>,
|
|
||||||
pub array: Object<'gc>,
|
|
||||||
pub movieclip: Object<'gc>,
|
|
||||||
pub framelabel: Object<'gc>,
|
|
||||||
pub scene: Object<'gc>,
|
|
||||||
pub application_domain: Object<'gc>,
|
|
||||||
pub event: Object<'gc>,
|
|
||||||
pub fullscreenevent: Object<'gc>,
|
|
||||||
pub video: Object<'gc>,
|
|
||||||
pub xml: Object<'gc>,
|
|
||||||
pub xml_list: Object<'gc>,
|
|
||||||
pub display_object: Object<'gc>,
|
|
||||||
pub shape: Object<'gc>,
|
|
||||||
pub textfield: Object<'gc>,
|
|
||||||
pub textformat: Object<'gc>,
|
|
||||||
pub graphics: Object<'gc>,
|
|
||||||
pub loaderinfo: Object<'gc>,
|
|
||||||
pub bytearray: Object<'gc>,
|
|
||||||
pub stage: Object<'gc>,
|
|
||||||
pub sprite: Object<'gc>,
|
|
||||||
pub simplebutton: Object<'gc>,
|
|
||||||
pub regexp: Object<'gc>,
|
|
||||||
pub vector: Object<'gc>,
|
|
||||||
pub soundtransform: Object<'gc>,
|
|
||||||
pub soundchannel: Object<'gc>,
|
|
||||||
pub bitmap: Object<'gc>,
|
|
||||||
pub bitmapdata: Object<'gc>,
|
|
||||||
pub date: Object<'gc>,
|
|
||||||
pub qname: Object<'gc>,
|
|
||||||
pub sharedobject: Object<'gc>,
|
|
||||||
pub nativemenu: Object<'gc>,
|
|
||||||
pub contextmenu: Object<'gc>,
|
|
||||||
pub mouseevent: Object<'gc>,
|
|
||||||
pub textevent: Object<'gc>,
|
|
||||||
pub errorevent: Object<'gc>,
|
|
||||||
pub ioerrorevent: Object<'gc>,
|
|
||||||
pub securityerrorevent: Object<'gc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'gc> SystemPrototypes<'gc> {
|
|
||||||
/// Construct a minimal set of system prototypes necessary for
|
|
||||||
/// bootstrapping player globals.
|
|
||||||
///
|
|
||||||
/// All other system prototypes aside from the three given here will be set
|
|
||||||
/// to the empty object also handed to this function. It is the caller's
|
|
||||||
/// responsibility to instantiate each class and replace the empty object
|
|
||||||
/// with that.
|
|
||||||
fn new(
|
|
||||||
object: Object<'gc>,
|
|
||||||
function: Object<'gc>,
|
|
||||||
class: Object<'gc>,
|
|
||||||
global: Object<'gc>,
|
|
||||||
empty: Object<'gc>,
|
|
||||||
) -> Self {
|
|
||||||
SystemPrototypes {
|
|
||||||
object,
|
|
||||||
function,
|
|
||||||
class,
|
|
||||||
global,
|
|
||||||
string: empty,
|
|
||||||
boolean: empty,
|
|
||||||
number: empty,
|
|
||||||
int: empty,
|
|
||||||
uint: empty,
|
|
||||||
namespace: empty,
|
|
||||||
array: empty,
|
|
||||||
movieclip: empty,
|
|
||||||
framelabel: empty,
|
|
||||||
scene: empty,
|
|
||||||
application_domain: empty,
|
|
||||||
event: empty,
|
|
||||||
fullscreenevent: empty,
|
|
||||||
video: empty,
|
|
||||||
xml: empty,
|
|
||||||
xml_list: empty,
|
|
||||||
display_object: empty,
|
|
||||||
shape: empty,
|
|
||||||
textfield: empty,
|
|
||||||
textformat: empty,
|
|
||||||
graphics: empty,
|
|
||||||
loaderinfo: empty,
|
|
||||||
bytearray: empty,
|
|
||||||
stage: empty,
|
|
||||||
sprite: empty,
|
|
||||||
simplebutton: empty,
|
|
||||||
regexp: empty,
|
|
||||||
vector: empty,
|
|
||||||
soundtransform: empty,
|
|
||||||
soundchannel: empty,
|
|
||||||
bitmap: empty,
|
|
||||||
bitmapdata: empty,
|
|
||||||
date: empty,
|
|
||||||
qname: empty,
|
|
||||||
sharedobject: empty,
|
|
||||||
nativemenu: empty,
|
|
||||||
contextmenu: empty,
|
|
||||||
mouseevent: empty,
|
|
||||||
textevent: empty,
|
|
||||||
errorevent: empty,
|
|
||||||
ioerrorevent: empty,
|
|
||||||
securityerrorevent: empty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This structure represents all system builtin classes.
|
/// This structure represents all system builtin classes.
|
||||||
#[derive(Clone, Collect)]
|
#[derive(Clone, Collect)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
|
@ -319,13 +201,13 @@ fn dynamic_class<'gc>(
|
||||||
|
|
||||||
/// Add a class builtin to the global scope.
|
/// Add a class builtin to the global scope.
|
||||||
///
|
///
|
||||||
/// This function returns the class object and class prototype as a pair, which
|
/// This function returns the class object and class prototype as a class, which
|
||||||
/// may be stored in `SystemClasses` and `SystemPrototypes`, respectively.
|
/// may be stored in `SystemClasses`
|
||||||
fn class<'gc>(
|
fn class<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
class_def: GcCell<'gc, Class<'gc>>,
|
class_def: GcCell<'gc, Class<'gc>>,
|
||||||
script: Script<'gc>,
|
script: Script<'gc>,
|
||||||
) -> Result<(ClassObject<'gc>, Object<'gc>), Error> {
|
) -> Result<ClassObject<'gc>, Error> {
|
||||||
let (_, mut global, mut domain) = script.init();
|
let (_, mut global, mut domain) = script.init();
|
||||||
|
|
||||||
let class_read = class_def.read();
|
let class_read = class_def.read();
|
||||||
|
@ -364,7 +246,7 @@ fn class<'gc>(
|
||||||
);
|
);
|
||||||
domain.export_definition(class_name, script, activation.context.gc_context)?;
|
domain.export_definition(class_name, script, activation.context.gc_context)?;
|
||||||
|
|
||||||
Ok((class_object, class_object.prototype()))
|
Ok(class_object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a builtin constant to the global scope.
|
/// Add a builtin constant to the global scope.
|
||||||
|
@ -402,13 +284,10 @@ fn namespace<'gc>(
|
||||||
|
|
||||||
macro_rules! avm2_system_class {
|
macro_rules! avm2_system_class {
|
||||||
($field:ident, $activation:ident, $class:expr, $script:expr) => {
|
($field:ident, $activation:ident, $class:expr, $script:expr) => {
|
||||||
let (class_object, proto) = class($activation, $class, $script)?;
|
let class_object = class($activation, $class, $script)?;
|
||||||
|
|
||||||
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
||||||
sc.$field = class_object;
|
sc.$field = class_object;
|
||||||
|
|
||||||
let sp = $activation.avm2().system_prototypes.as_mut().unwrap();
|
|
||||||
sp.$field = proto;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,16 +357,9 @@ pub fn load_player_globals<'gc>(
|
||||||
global_class.link_prototype(activation, global_proto)?;
|
global_class.link_prototype(activation, global_proto)?;
|
||||||
global_class.link_type(activation, class_proto, class_class);
|
global_class.link_type(activation, class_proto, class_class);
|
||||||
|
|
||||||
// At this point, we need at least a partial set of system prototypes in
|
// At this point, we need at least a partial set of system classes in
|
||||||
// order to continue initializing the player. The rest of the prototypes
|
// order to continue initializing the player. The rest of the classes
|
||||||
// are set to a bare object until we have a chance to initialize them.
|
// are set to a temporary class until we have a chance to initialize them.
|
||||||
activation.context.avm2.system_prototypes = Some(SystemPrototypes::new(
|
|
||||||
object_proto,
|
|
||||||
fn_proto,
|
|
||||||
class_proto,
|
|
||||||
global_proto,
|
|
||||||
ScriptObject::bare_object(mc),
|
|
||||||
));
|
|
||||||
|
|
||||||
activation.context.avm2.system_classes = Some(SystemClasses::new(
|
activation.context.avm2.system_classes = Some(SystemClasses::new(
|
||||||
object_class,
|
object_class,
|
||||||
|
@ -505,8 +377,8 @@ pub fn load_player_globals<'gc>(
|
||||||
let object_class = object_class.into_finished_class(activation)?;
|
let object_class = object_class.into_finished_class(activation)?;
|
||||||
let _global_class = global_class.into_finished_class(activation)?;
|
let _global_class = global_class.into_finished_class(activation)?;
|
||||||
|
|
||||||
globals.set_proto(mc, activation.avm2().prototypes().global);
|
globals.set_proto(mc, global_proto);
|
||||||
globals.set_instance_of(mc, activation.avm2().classes().global);
|
globals.set_instance_of(mc, global_class);
|
||||||
globals.fork_vtable(activation.context.gc_context);
|
globals.fork_vtable(activation.context.gc_context);
|
||||||
|
|
||||||
// From this point, `globals` is safe to be modified
|
// From this point, `globals` is safe to be modified
|
||||||
|
@ -951,16 +823,13 @@ fn load_playerglobal<'gc>(
|
||||||
let class_object = activation.resolve_class(&qname.into())?;
|
let class_object = activation.resolve_class(&qname.into())?;
|
||||||
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
||||||
sc.$field = class_object;
|
sc.$field = class_object;
|
||||||
|
|
||||||
let sp = $activation.avm2().system_prototypes.as_mut().unwrap();
|
|
||||||
sp.$field = class_object.prototype();
|
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This acts the same way as 'avm2_system_class', but for classes
|
// This acts the same way as 'avm2_system_class', but for classes
|
||||||
// declared in 'playerglobal'. Classes are declared as ("package", "class", field_name),
|
// declared in 'playerglobal'. Classes are declared as ("package", "class", field_name),
|
||||||
// and are stored in 'avm2().system_classes' and 'avm2().system_prototypes'
|
// and are stored in 'avm2().system_classes'
|
||||||
avm2_system_classes_playerglobal!(activation, script, [("flash.display", "Scene", scene)]);
|
avm2_system_classes_playerglobal!(activation, script, [("flash.display", "Scene", scene)]);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -235,7 +235,7 @@ pub fn to_string<'gc>(
|
||||||
this: Option<Object<'gc>>,
|
this: Option<Object<'gc>>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
let object_proto = activation.avm2().prototypes().object;
|
let object_proto = activation.avm2().classes().object.prototype();
|
||||||
let name = QName::dynamic_name("toString").into();
|
let name = QName::dynamic_name("toString").into();
|
||||||
object_proto
|
object_proto
|
||||||
.get_property(&name, activation)?
|
.get_property(&name, activation)?
|
||||||
|
|
|
@ -58,8 +58,7 @@ impl<'gc> ArrayObject<'gc> {
|
||||||
array: ArrayStorage<'gc>,
|
array: ArrayStorage<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().array;
|
let class = activation.avm2().classes().array;
|
||||||
let proto = activation.avm2().prototypes().array;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut instance: Object<'gc> = ArrayObject(GcCell::allocate(
|
let mut instance: Object<'gc> = ArrayObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -45,8 +45,7 @@ impl<'gc> ByteArrayObject<'gc> {
|
||||||
bytes: ByteArrayStorage,
|
bytes: ByteArrayStorage,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().bytearray;
|
let class = activation.avm2().classes().bytearray;
|
||||||
let proto = activation.avm2().prototypes().bytearray;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut instance: Object<'gc> = ByteArrayObject(GcCell::allocate(
|
let mut instance: Object<'gc> = ByteArrayObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -134,7 +134,7 @@ impl<'gc> ClassObject<'gc> {
|
||||||
class_object.link_prototype(activation, class_proto)?;
|
class_object.link_prototype(activation, class_proto)?;
|
||||||
|
|
||||||
let class_class = activation.avm2().classes().class;
|
let class_class = activation.avm2().classes().class;
|
||||||
let class_class_proto = activation.avm2().prototypes().class;
|
let class_class_proto = class_class.prototype();
|
||||||
|
|
||||||
class_object.link_type(activation, class_class_proto, class_class);
|
class_object.link_type(activation, class_class_proto, class_class);
|
||||||
class_object.into_finished_class(activation)
|
class_object.into_finished_class(activation)
|
||||||
|
@ -877,7 +877,6 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> {
|
||||||
let class_proto = self.allocate_prototype(activation, superclass_object)?;
|
let class_proto = self.allocate_prototype(activation, superclass_object)?;
|
||||||
|
|
||||||
let class_class = activation.avm2().classes().class;
|
let class_class = activation.avm2().classes().class;
|
||||||
let class_class_proto = activation.avm2().prototypes().class;
|
|
||||||
|
|
||||||
let constructor = self.0.read().constructor.clone();
|
let constructor = self.0.read().constructor.clone();
|
||||||
let native_constructor = self.0.read().native_constructor.clone();
|
let native_constructor = self.0.read().native_constructor.clone();
|
||||||
|
@ -886,7 +885,7 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> {
|
||||||
let mut class_object = ClassObject(GcCell::allocate(
|
let mut class_object = ClassObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
ClassObjectData {
|
ClassObjectData {
|
||||||
base: ScriptObjectData::base_new(Some(class_class_proto), Some(class_class)),
|
base: ScriptObjectData::new(class_class),
|
||||||
class: parameterized_class,
|
class: parameterized_class,
|
||||||
prototype: None,
|
prototype: None,
|
||||||
class_scope,
|
class_scope,
|
||||||
|
|
|
@ -49,8 +49,7 @@ impl<'gc> DomainObject<'gc> {
|
||||||
domain: Domain<'gc>,
|
domain: Domain<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().application_domain;
|
let class = activation.avm2().classes().application_domain;
|
||||||
let proto = activation.avm2().prototypes().application_domain;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
let mut this: Object<'gc> = DomainObject(GcCell::allocate(
|
let mut this: Object<'gc> = DomainObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
DomainObjectData { base, domain },
|
DomainObjectData { base, domain },
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'gc> FunctionObject<'gc> {
|
||||||
let this = Self::from_method(activation, method, scope, None, None);
|
let this = Self::from_method(activation, method, scope, None, None);
|
||||||
let es3_proto = ScriptObject::object(
|
let es3_proto = ScriptObject::object(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
activation.avm2().prototypes().object,
|
activation.avm2().classes().object.prototype(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.0.write(activation.context.gc_context).prototype = Some(es3_proto);
|
this.0.write(activation.context.gc_context).prototype = Some(es3_proto);
|
||||||
|
@ -61,14 +61,13 @@ impl<'gc> FunctionObject<'gc> {
|
||||||
receiver: Option<Object<'gc>>,
|
receiver: Option<Object<'gc>>,
|
||||||
subclass_object: Option<ClassObject<'gc>>,
|
subclass_object: Option<ClassObject<'gc>>,
|
||||||
) -> FunctionObject<'gc> {
|
) -> FunctionObject<'gc> {
|
||||||
let fn_proto = activation.avm2().prototypes().function;
|
|
||||||
let fn_class = activation.avm2().classes().function;
|
let fn_class = activation.avm2().classes().function;
|
||||||
let exec = Executable::from_method(method, scope, receiver, subclass_object);
|
let exec = Executable::from_method(method, scope, receiver, subclass_object);
|
||||||
|
|
||||||
FunctionObject(GcCell::allocate(
|
FunctionObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
FunctionObjectData {
|
FunctionObjectData {
|
||||||
base: ScriptObjectData::base_new(Some(fn_proto), Some(fn_class)),
|
base: ScriptObjectData::new(fn_class),
|
||||||
exec,
|
exec,
|
||||||
prototype: None,
|
prototype: None,
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,8 +71,7 @@ impl<'gc> LoaderInfoObject<'gc> {
|
||||||
root: DisplayObject<'gc>,
|
root: DisplayObject<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().loaderinfo;
|
let class = activation.avm2().classes().loaderinfo;
|
||||||
let proto = activation.avm2().prototypes().loaderinfo;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
let loaded_stream = Some(LoaderStream::Swf(movie, root));
|
let loaded_stream = Some(LoaderStream::Swf(movie, root));
|
||||||
|
|
||||||
let mut this: Object<'gc> = LoaderInfoObject(GcCell::allocate(
|
let mut this: Object<'gc> = LoaderInfoObject(GcCell::allocate(
|
||||||
|
@ -93,8 +92,7 @@ impl<'gc> LoaderInfoObject<'gc> {
|
||||||
/// Create a loader info object for the stage.
|
/// Create a loader info object for the stage.
|
||||||
pub fn from_stage(activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
pub fn from_stage(activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().loaderinfo;
|
let class = activation.avm2().classes().loaderinfo;
|
||||||
let proto = activation.avm2().prototypes().loaderinfo;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut this: Object<'gc> = LoaderInfoObject(GcCell::allocate(
|
let mut this: Object<'gc> = LoaderInfoObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -49,8 +49,7 @@ impl<'gc> NamespaceObject<'gc> {
|
||||||
namespace: Namespace<'gc>,
|
namespace: Namespace<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().namespace;
|
let class = activation.avm2().classes().namespace;
|
||||||
let proto = activation.avm2().prototypes().namespace;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut this: Object<'gc> = NamespaceObject(GcCell::allocate(
|
let mut this: Object<'gc> = NamespaceObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -65,14 +65,6 @@ impl<'gc> PrimitiveObject<'gc> {
|
||||||
return Err("Cannot box a null value".into());
|
return Err("Cannot box a null value".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let proto = match primitive {
|
|
||||||
Value::Bool(_) => activation.avm2().prototypes().boolean,
|
|
||||||
Value::Number(_) => activation.avm2().prototypes().number,
|
|
||||||
Value::Unsigned(_) => activation.avm2().prototypes().uint,
|
|
||||||
Value::Integer(_) => activation.avm2().prototypes().int,
|
|
||||||
Value::String(_) => activation.avm2().prototypes().string,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
let class = match primitive {
|
let class = match primitive {
|
||||||
Value::Bool(_) => activation.avm2().classes().boolean,
|
Value::Bool(_) => activation.avm2().classes().boolean,
|
||||||
Value::Number(_) => activation.avm2().classes().number,
|
Value::Number(_) => activation.avm2().classes().number,
|
||||||
|
@ -82,7 +74,7 @@ impl<'gc> PrimitiveObject<'gc> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
let base = ScriptObjectData::new(class);
|
||||||
let mut this: Object<'gc> = PrimitiveObject(GcCell::allocate(
|
let mut this: Object<'gc> = PrimitiveObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
PrimitiveObjectData { base, primitive },
|
PrimitiveObjectData { base, primitive },
|
||||||
|
|
|
@ -46,8 +46,7 @@ impl<'gc> QNameObject<'gc> {
|
||||||
qname: QName<'gc>,
|
qname: QName<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().qname;
|
let class = activation.avm2().classes().qname;
|
||||||
let proto = activation.avm2().prototypes().qname;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut this: Object<'gc> = QNameObject(GcCell::allocate(
|
let mut this: Object<'gc> = QNameObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -47,8 +47,7 @@ impl<'gc> RegExpObject<'gc> {
|
||||||
regexp: RegExp<'gc>,
|
regexp: RegExp<'gc>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().regexp;
|
let class = activation.avm2().classes().regexp;
|
||||||
let proto = activation.avm2().prototypes().regexp;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut this: Object<'gc> = RegExpObject(GcCell::allocate(
|
let mut this: Object<'gc> = RegExpObject(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
|
@ -132,6 +132,18 @@ impl<'gc> ScriptObjectData<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(instance_of: ClassObject<'gc>) -> Self {
|
||||||
|
ScriptObjectData {
|
||||||
|
values: Default::default(),
|
||||||
|
slots: Vec::new(),
|
||||||
|
bound_methods: Vec::new(),
|
||||||
|
proto: Some(instance_of.prototype()),
|
||||||
|
instance_of: Some(instance_of),
|
||||||
|
vtable: Some(instance_of.instance_vtable()),
|
||||||
|
enumerants: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_property_local(
|
pub fn get_property_local(
|
||||||
&self,
|
&self,
|
||||||
multiname: &Multiname<'gc>,
|
multiname: &Multiname<'gc>,
|
||||||
|
|
|
@ -94,11 +94,10 @@ impl<'gc> StageObject<'gc> {
|
||||||
display_object: DisplayObject<'gc>,
|
display_object: DisplayObject<'gc>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let class = activation.avm2().classes().graphics;
|
let class = activation.avm2().classes().graphics;
|
||||||
let proto = activation.avm2().prototypes().graphics;
|
|
||||||
let mut this = Self(GcCell::allocate(
|
let mut this = Self(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
StageObjectData {
|
StageObjectData {
|
||||||
base: ScriptObjectData::base_new(Some(proto), Some(class)),
|
base: ScriptObjectData::new(class),
|
||||||
display_object: Some(display_object),
|
display_object: Some(display_object),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
|
@ -46,8 +46,7 @@ impl<'gc> TextFormatObject<'gc> {
|
||||||
text_format: TextFormat,
|
text_format: TextFormat,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let class = activation.avm2().classes().textformat;
|
let class = activation.avm2().classes().textformat;
|
||||||
let proto = activation.avm2().prototypes().textformat;
|
let base = ScriptObjectData::new(class);
|
||||||
let base = ScriptObjectData::base_new(Some(proto), Some(class));
|
|
||||||
|
|
||||||
let mut this: Object<'gc> = Self(GcCell::allocate(
|
let mut this: Object<'gc> = Self(GcCell::allocate(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
|
|
Loading…
Reference in New Issue