avm2: Remove custom_object macros
This commit is contained in:
parent
54d417c539
commit
3f81910bb6
|
@ -28,7 +28,6 @@ mod array_object;
|
|||
mod bitmapdata_object;
|
||||
mod bytearray_object;
|
||||
mod class_object;
|
||||
mod custom_object;
|
||||
mod date_object;
|
||||
mod dispatch_object;
|
||||
mod domain_object;
|
||||
|
@ -60,7 +59,7 @@ pub use crate::avm2::object::loaderinfo_object::{
|
|||
pub use crate::avm2::object::namespace_object::{namespace_allocator, NamespaceObject};
|
||||
pub use crate::avm2::object::primitive_object::{primitive_allocator, PrimitiveObject};
|
||||
pub use crate::avm2::object::regexp_object::{regexp_allocator, RegExpObject};
|
||||
pub use crate::avm2::object::script_object::ScriptObject;
|
||||
pub use crate::avm2::object::script_object::{ScriptObject, ScriptObjectData};
|
||||
pub use crate::avm2::object::sound_object::{sound_allocator, SoundObject};
|
||||
pub use crate::avm2::object::soundchannel_object::{soundchannel_allocator, SoundChannelObject};
|
||||
pub use crate::avm2::object::stage_object::{stage_allocator, StageObject};
|
||||
|
@ -96,6 +95,11 @@ pub use crate::avm2::object::xml_object::{xml_allocator, XmlObject};
|
|||
}
|
||||
)]
|
||||
pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy {
|
||||
/// Get the base of this object.
|
||||
/// Any trait method implementations that were not overrided will foward the call to this instead.
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>>;
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>>;
|
||||
|
||||
/// Retrieve a property by QName, after multiname resolution, prototype
|
||||
/// lookups, and all other considerations have been taken.
|
||||
///
|
||||
|
@ -106,7 +110,14 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error>;
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let base = self.base();
|
||||
let rv = base.get_property_local(receiver, name, activation)?;
|
||||
|
||||
drop(base);
|
||||
|
||||
rv.resolve(activation)
|
||||
}
|
||||
|
||||
/// Retrieve a property by Multiname lookup.
|
||||
///
|
||||
|
@ -189,7 +200,17 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(activation.context.gc_context);
|
||||
|
||||
let rv = base.set_property_local(receiver, name, value, activation)?;
|
||||
|
||||
drop(base);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set a property by Multiname lookup.
|
||||
///
|
||||
|
@ -237,7 +258,16 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(activation.context.gc_context);
|
||||
let rv = base.init_property_local(receiver, name, value, activation)?;
|
||||
|
||||
drop(base);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialize a property by Multiname lookup.
|
||||
///
|
||||
|
@ -316,7 +346,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
|
||||
/// Retrieve a slot by its index.
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error>;
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_slot(id)
|
||||
}
|
||||
|
||||
/// Set a slot by its index.
|
||||
fn set_slot(
|
||||
|
@ -324,7 +358,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.set_slot(id, value, mc)
|
||||
}
|
||||
|
||||
/// Initialize a slot by its index.
|
||||
fn init_slot(
|
||||
|
@ -332,10 +370,18 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.init_slot(id, value, mc)
|
||||
}
|
||||
|
||||
/// Retrieve a method by its index.
|
||||
fn get_method(self, id: u32) -> Option<Object<'gc>>;
|
||||
fn get_method(self, id: u32) -> Option<Object<'gc>> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_method(id)
|
||||
}
|
||||
|
||||
/// Retrieves the scope chain of the object at time of its creation.
|
||||
///
|
||||
|
@ -343,7 +389,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
/// object is called, as well as any class methods on the object.
|
||||
/// Non-method functions and prototype functions (ES3 methods) do not use
|
||||
/// this scope chain.
|
||||
fn get_scope(self) -> Option<GcCell<'gc, Scope<'gc>>>;
|
||||
fn get_scope(self) -> Option<GcCell<'gc, Scope<'gc>>> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_scope()
|
||||
}
|
||||
|
||||
/// Resolve a multiname into a single QName, if any of the namespaces
|
||||
/// match.
|
||||
|
@ -381,15 +431,25 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
/// Trait names will be resolve on class objects and object instances, but
|
||||
/// not prototypes. If you want to search a prototype's provided traits you
|
||||
/// must walk the prototype chain using `resolve_any_trait`.
|
||||
fn resolve_any(self, local_name: AvmString<'gc>) -> Result<Option<Namespace<'gc>>, Error>;
|
||||
fn resolve_any(self, local_name: AvmString<'gc>) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
let base = self.base();
|
||||
|
||||
base.resolve_any(local_name)
|
||||
}
|
||||
|
||||
/// Given a local name of a trait, find the namespace it resides in, if any.
|
||||
///
|
||||
/// This function only works for names which are trait properties, not
|
||||
/// dynamic or prototype properties. Furthermore, instance prototypes *will*
|
||||
/// resolve trait names here, contrary to their behavior in `resolve_any.`
|
||||
fn resolve_any_trait(self, local_name: AvmString<'gc>)
|
||||
-> Result<Option<Namespace<'gc>>, Error>;
|
||||
fn resolve_any_trait(
|
||||
self,
|
||||
local_name: AvmString<'gc>,
|
||||
) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
let base = self.base();
|
||||
|
||||
base.resolve_any_trait(local_name)
|
||||
}
|
||||
|
||||
/// Indicates whether or not a property exists on an object.
|
||||
fn has_property(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
|
@ -404,47 +464,83 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
|
||||
/// Indicates whether or not a property or trait exists on an object and is
|
||||
/// not part of the prototype chain.
|
||||
fn has_own_property(self, name: &QName<'gc>) -> Result<bool, Error>;
|
||||
fn has_own_property(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
let base = self.base();
|
||||
|
||||
base.has_own_property(name)
|
||||
}
|
||||
|
||||
/// Returns true if an object has one or more traits of a given name.
|
||||
fn has_trait(self, name: &QName<'gc>) -> Result<bool, Error>;
|
||||
fn has_trait(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
let base = self.base();
|
||||
|
||||
base.has_trait(name)
|
||||
}
|
||||
|
||||
/// Check if a particular object contains a virtual getter by the given
|
||||
/// name.
|
||||
fn has_own_virtual_getter(self, name: &QName<'gc>) -> bool;
|
||||
fn has_own_virtual_getter(self, name: &QName<'gc>) -> bool {
|
||||
let base = self.base();
|
||||
|
||||
base.has_own_virtual_getter(name)
|
||||
}
|
||||
|
||||
/// Check if a particular object contains a virtual setter by the given
|
||||
/// name.
|
||||
fn has_own_virtual_setter(self, name: &QName<'gc>) -> bool;
|
||||
fn has_own_virtual_setter(self, name: &QName<'gc>) -> bool {
|
||||
let base = self.base();
|
||||
|
||||
base.has_own_virtual_setter(name)
|
||||
}
|
||||
|
||||
/// Indicates whether or not a property is overwritable.
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
_name: &QName<'gc>,
|
||||
) -> bool;
|
||||
_gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
let base = self.base();
|
||||
|
||||
base.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
/// Indicates whether or not a property is final.
|
||||
fn is_property_final(self, _name: &QName<'gc>) -> bool;
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
let base = self.base();
|
||||
|
||||
base.is_property_final(name)
|
||||
}
|
||||
|
||||
/// Delete a named property from the object.
|
||||
///
|
||||
/// Returns false if the property cannot be deleted.
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool;
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool {
|
||||
let mut base = self.base_mut(gc_context);
|
||||
|
||||
base.delete_property(name)
|
||||
}
|
||||
|
||||
/// Retrieve the `__proto__` of a given object.
|
||||
///
|
||||
/// The proto is another object used to resolve methods across a class of
|
||||
/// multiple objects. It should also be accessible as `__proto__` from
|
||||
/// `get`.
|
||||
fn proto(&self) -> Option<Object<'gc>>;
|
||||
fn proto(&self) -> Option<Object<'gc>> {
|
||||
let base = self.base();
|
||||
|
||||
base.proto()
|
||||
}
|
||||
|
||||
/// Change the `__proto__` on this object.
|
||||
///
|
||||
/// This method primarily exists so that the global scope that player
|
||||
/// globals loads into can be created before its superclasses are. It
|
||||
/// should be used sparingly, if at all.
|
||||
fn set_proto(self, mc: MutationContext<'gc, '_>, proto: Object<'gc>);
|
||||
fn set_proto(self, mc: MutationContext<'gc, '_>, proto: Object<'gc>) {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.set_proto(proto)
|
||||
}
|
||||
|
||||
/// Retrieve a given enumerable name by index.
|
||||
///
|
||||
|
@ -455,12 +551,20 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
/// Objects are responsible for maintaining a consistently ordered and
|
||||
/// indexed list of enumerable names which can be queried by this
|
||||
/// mechanism.
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<QName<'gc>>;
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<QName<'gc>> {
|
||||
let base = self.base();
|
||||
|
||||
base.get_enumerant_name(index)
|
||||
}
|
||||
|
||||
/// Determine if a property is currently enumerable.
|
||||
///
|
||||
/// Properties that do not exist are also not enumerable.
|
||||
fn property_is_enumerable(&self, name: &QName<'gc>) -> bool;
|
||||
fn property_is_enumerable(&self, name: &QName<'gc>) -> bool {
|
||||
let base = self.base();
|
||||
|
||||
base.property_is_enumerable(name)
|
||||
}
|
||||
|
||||
/// Mark a dynamic property on this object as enumerable.
|
||||
fn set_local_property_is_enumerable(
|
||||
|
@ -468,7 +572,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
mc: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
is_enumerable: bool,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.set_local_property_is_enumerable(name, is_enumerable)
|
||||
}
|
||||
|
||||
/// Install a method (or any other non-slot value) on an object.
|
||||
fn install_method(
|
||||
|
@ -478,7 +586,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
);
|
||||
) {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_method(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
/// Install a getter method on an object property.
|
||||
fn install_getter(
|
||||
|
@ -488,7 +600,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_getter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
/// Install a setter method on an object property.
|
||||
fn install_setter(
|
||||
|
@ -498,7 +614,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_setter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
/// Install a dynamic or built-in value property on an object.
|
||||
fn install_dynamic_property(
|
||||
|
@ -506,7 +626,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
) -> Result<(), Error>;
|
||||
) -> Result<(), Error> {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_dynamic_property(name, value)
|
||||
}
|
||||
|
||||
/// Install a slot on an object property.
|
||||
fn install_slot(
|
||||
|
@ -516,7 +640,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
);
|
||||
) {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_slot(name, id, value, is_final)
|
||||
}
|
||||
|
||||
/// Install a const on an object property.
|
||||
fn install_const(
|
||||
|
@ -526,7 +654,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
);
|
||||
) {
|
||||
let mut base = self.base_mut(mc);
|
||||
|
||||
base.install_const(name, id, value, is_final)
|
||||
}
|
||||
|
||||
/// Install all instance traits provided by a class.
|
||||
///
|
||||
|
@ -1244,7 +1376,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
fn as_ptr(&self) -> *const ObjectPtr;
|
||||
|
||||
/// Get this object's class, if it has one.
|
||||
fn instance_of(&self) -> Option<Object<'gc>>;
|
||||
fn instance_of(&self) -> Option<Object<'gc>> {
|
||||
let base = self.base();
|
||||
|
||||
base.instance_of()
|
||||
}
|
||||
|
||||
/// Get this object's class's `Class`, if it has one.
|
||||
fn instance_of_class_definition(&self) -> Option<GcCell<'gc, Class<'gc>>> {
|
||||
|
|
|
@ -5,11 +5,9 @@ use crate::avm2::array::ArrayStorage;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{impl_avm2_custom_object, impl_avm2_custom_object_instance};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -77,8 +75,17 @@ impl<'gc> ArrayObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for ArrayObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn get_property_local(
|
||||
self,
|
||||
|
@ -157,18 +164,6 @@ impl<'gc> TObject<'gc> for ArrayObject<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).base.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool {
|
||||
if name.namespace().is_public() {
|
||||
if let Ok(index) = name.local_name().parse::<usize>() {
|
||||
|
|
|
@ -4,15 +4,11 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::bitmap::bitmap_data::BitmapData;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates BitmapData objects.
|
||||
pub fn bitmapdata_allocator<'gc>(
|
||||
|
@ -78,9 +74,17 @@ impl<'gc> BitmapDataObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for BitmapDataObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let base = ScriptObjectData::base_new(Some((*self).into()), None);
|
||||
|
|
|
@ -3,11 +3,9 @@ use crate::avm2::bytearray::ByteArrayStorage;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{impl_avm2_custom_object, impl_avm2_custom_object_instance};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -43,8 +41,17 @@ pub struct ByteArrayObjectData<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for ByteArrayObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn get_property_local(
|
||||
self,
|
||||
|
@ -131,18 +138,6 @@ impl<'gc> TObject<'gc> for ByteArrayObject<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).base.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool {
|
||||
if name.namespace().is_public() {
|
||||
if let Ok(index) = name.local_name().parse::<usize>() {
|
||||
|
|
|
@ -11,8 +11,8 @@ use crate::avm2::scope::Scope;
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{impl_avm2_custom_object, impl_avm2_custom_object_properties};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// An Object which can be called to execute its function code.
|
||||
|
@ -356,8 +356,17 @@ impl<'gc> ClassObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for ClassObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn to_string(&self, mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(AvmString::new(
|
||||
|
@ -488,10 +497,6 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> {
|
|||
Some(*self)
|
||||
}
|
||||
|
||||
fn instance_of(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().base.instance_of()
|
||||
}
|
||||
|
||||
fn set_local_property_is_enumerable(
|
||||
&self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
|
|
|
@ -1,272 +0,0 @@
|
|||
//! Custom object macro
|
||||
|
||||
/// Implement defaults for `TObject` methods that deal with property retrieval,
|
||||
/// storage, and deletion.
|
||||
#[macro_export]
|
||||
macro_rules! impl_avm2_custom_object_properties {
|
||||
($field:ident) => {
|
||||
fn get_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let read = self.0.read();
|
||||
let rv = read.$field.get_property_local(receiver, name, activation)?;
|
||||
|
||||
drop(read);
|
||||
|
||||
rv.resolve(activation)
|
||||
}
|
||||
|
||||
fn set_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(activation.context.gc_context);
|
||||
let rv = write
|
||||
.$field
|
||||
.set_property_local(receiver, name, value, activation)?;
|
||||
|
||||
drop(write);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(activation.context.gc_context);
|
||||
let rv = write
|
||||
.$field
|
||||
.init_property_local(receiver, name, value, activation)?;
|
||||
|
||||
drop(write);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0
|
||||
.write(gc_context)
|
||||
.$field
|
||||
.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().$field.is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(
|
||||
&self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
multiname: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).$field.delete_property(multiname)
|
||||
}
|
||||
|
||||
fn has_own_property(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().$field.has_own_property(name)
|
||||
}
|
||||
|
||||
fn resolve_any(self, local_name: AvmString<'gc>) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().$field.resolve_any(local_name)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Implement defaults for `TObject` methods that mark this object as an
|
||||
/// instance of a class.
|
||||
#[macro_export]
|
||||
macro_rules! impl_avm2_custom_object_instance {
|
||||
($field:ident) => {
|
||||
fn has_trait(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().$field.has_trait(name)
|
||||
}
|
||||
|
||||
fn get_scope(self) -> Option<GcCell<'gc, Scope<'gc>>> {
|
||||
self.0.read().$field.get_scope()
|
||||
}
|
||||
|
||||
fn resolve_any_trait(
|
||||
self,
|
||||
local_name: AvmString<'gc>,
|
||||
) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().$field.resolve_any_trait(local_name)
|
||||
}
|
||||
|
||||
fn instance_of(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().$field.instance_of()
|
||||
}
|
||||
|
||||
fn set_local_property_is_enumerable(
|
||||
&self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
is_enumerable: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.set_local_property_is_enumerable(name, is_enumerable)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Implement defaults for `TObject` methods not separated out into a separate
|
||||
/// macro.
|
||||
#[macro_export]
|
||||
macro_rules! impl_avm2_custom_object {
|
||||
($field:ident) => {
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error> {
|
||||
self.0.read().$field.get_slot(id)
|
||||
}
|
||||
|
||||
fn set_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).$field.set_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn init_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).$field.init_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn get_method(self, id: u32) -> Option<Object<'gc>> {
|
||||
self.0.read().$field.get_method(id)
|
||||
}
|
||||
|
||||
fn has_own_virtual_getter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().$field.has_own_virtual_getter(name)
|
||||
}
|
||||
|
||||
fn has_own_virtual_setter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().$field.has_own_virtual_setter(name)
|
||||
}
|
||||
|
||||
fn proto(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().$field.proto()
|
||||
}
|
||||
|
||||
fn set_proto(self, mc: MutationContext<'gc, '_>, proto: Object<'gc>) {
|
||||
self.0.write(mc).$field.set_proto(proto)
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<QName<'gc>> {
|
||||
self.0.read().$field.get_enumerant_name(index)
|
||||
}
|
||||
|
||||
fn property_is_enumerable(&self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().$field.property_is_enumerable(name)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn install_method(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_method(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_getter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_getter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_setter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_setter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_dynamic_property(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_dynamic_property(name, value)
|
||||
}
|
||||
|
||||
fn install_slot(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_slot(name, id, value, is_final)
|
||||
}
|
||||
|
||||
fn install_const(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.$field
|
||||
.install_const(name, id, value, is_final)
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,16 +1,11 @@
|
|||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::{Hint, Value};
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates Date objects.
|
||||
pub fn date_allocator<'gc>(
|
||||
|
@ -58,9 +53,17 @@ pub struct DateObjectData<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for DateObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let this: Object<'gc> = Object::DateObject(*self);
|
||||
|
|
|
@ -2,16 +2,10 @@
|
|||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::events::DispatchList;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -71,9 +65,17 @@ impl<'gc> DispatchObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for DispatchObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn construct(
|
||||
self,
|
||||
|
|
|
@ -5,14 +5,10 @@ use crate::avm2::domain::Domain;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates AppDomain objects.
|
||||
pub fn appdomain_allocator<'gc>(
|
||||
|
@ -114,9 +110,17 @@ impl<'gc> DomainObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for DomainObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn as_application_domain(&self) -> Option<Domain<'gc>> {
|
||||
Some(self.0.read().domain)
|
||||
|
|
|
@ -5,13 +5,9 @@ use crate::avm2::events::Event;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -81,9 +77,17 @@ impl<'gc> EventObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for EventObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let base = ScriptObjectData::base_new(Some((*self).into()), None);
|
||||
|
|
|
@ -9,11 +9,8 @@ use crate::avm2::object::{Object, ObjectPtr, TObject};
|
|||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// An Object which can be called to execute its function code.
|
||||
#[derive(Collect, Debug, Clone, Copy)]
|
||||
|
@ -87,9 +84,17 @@ impl<'gc> FunctionObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for FunctionObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn to_string(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok("function Function() {}".into())
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
//! Loader-info object
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::display_object::DisplayObject;
|
||||
use crate::string::AvmString;
|
||||
use crate::tag_utils::SwfMovie;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::Ref;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A class instance allocator that allocates LoaderInfo objects.
|
||||
|
@ -118,9 +113,17 @@ impl<'gc> LoaderInfoObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for LoaderInfoObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn value_of(&self, mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
if let Some(class) = self.instance_of_class_definition() {
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
//! Boxed namespaces
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::names::Namespace;
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::Ref;
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates namespace objects.
|
||||
pub fn namespace_allocator<'gc>(
|
||||
|
@ -71,9 +66,17 @@ impl<'gc> NamespaceObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for NamespaceObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn to_string(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(self.0.read().namespace.as_uri().into())
|
||||
|
|
|
@ -3,16 +3,11 @@
|
|||
use std::cell::{Ref, RefMut};
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
|
||||
/// A class instance allocator that allocates primitive objects.
|
||||
|
@ -105,9 +100,17 @@ impl<'gc> PrimitiveObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for PrimitiveObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn to_string(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(self.0.read().primitive.clone())
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
//! Object representation for regexp
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::regexp::RegExp;
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -69,9 +64,17 @@ impl<'gc> RegExpObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for RegExpObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let base = ScriptObjectData::base_new(Some((*self).into()), None);
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::avm2::value::Value;
|
|||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -60,152 +61,12 @@ pub struct ScriptObjectData<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
||||
fn get_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let rv = self
|
||||
.0
|
||||
.read()
|
||||
.get_property_local(receiver, name, activation)?;
|
||||
|
||||
rv.resolve(activation)
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
self.0.read()
|
||||
}
|
||||
|
||||
fn set_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let rv = self
|
||||
.0
|
||||
.write(activation.context.gc_context)
|
||||
.set_property_local(receiver, name, value, activation)?;
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_property_local(
|
||||
self,
|
||||
receiver: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let rv = self
|
||||
.0
|
||||
.write(activation.context.gc_context)
|
||||
.init_property_local(receiver, name, value, activation)?;
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool {
|
||||
self.0.write(gc_context).delete_property(name)
|
||||
}
|
||||
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error> {
|
||||
self.0.read().get_slot(id)
|
||||
}
|
||||
|
||||
fn set_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).set_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn init_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).init_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn get_method(self, id: u32) -> Option<Object<'gc>> {
|
||||
self.0.read().get_method(id)
|
||||
}
|
||||
|
||||
fn get_scope(self) -> Option<GcCell<'gc, Scope<'gc>>> {
|
||||
self.0.read().get_scope()
|
||||
}
|
||||
|
||||
fn resolve_any(self, local_name: AvmString<'gc>) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().resolve_any(local_name)
|
||||
}
|
||||
|
||||
fn resolve_any_trait(
|
||||
self,
|
||||
local_name: AvmString<'gc>,
|
||||
) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().resolve_any_trait(local_name)
|
||||
}
|
||||
|
||||
fn has_own_property(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().has_own_property(name)
|
||||
}
|
||||
|
||||
fn has_trait(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().has_trait(name)
|
||||
}
|
||||
|
||||
fn has_own_virtual_getter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().has_own_virtual_getter(name)
|
||||
}
|
||||
|
||||
fn has_own_virtual_setter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().has_own_virtual_setter(name)
|
||||
}
|
||||
|
||||
fn proto(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().proto
|
||||
}
|
||||
|
||||
fn set_proto(self, mc: MutationContext<'gc, '_>, proto: Object<'gc>) {
|
||||
self.0.write(mc).set_proto(proto)
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<QName<'gc>> {
|
||||
self.0.read().get_enumerant_name(index)
|
||||
}
|
||||
|
||||
fn property_is_enumerable(&self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().property_is_enumerable(name)
|
||||
}
|
||||
|
||||
fn set_local_property_is_enumerable(
|
||||
&self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
is_enumerable: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.set_local_property_is_enumerable(name, is_enumerable)
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
self.0.write(mc)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
|
@ -217,91 +78,9 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
Ok(ScriptObject::object(activation.context.gc_context, this))
|
||||
}
|
||||
|
||||
fn to_string(&self, mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
if let Some(class) = self.instance_of_class_definition() {
|
||||
Ok(AvmString::new(mc, format!("[object {}]", class.read().name().local_name())).into())
|
||||
} else {
|
||||
Ok("[object Object]".into())
|
||||
}
|
||||
}
|
||||
|
||||
fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Object(Object::from(*self)))
|
||||
}
|
||||
|
||||
fn install_method(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.install_method(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_getter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.install_getter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_setter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.install_setter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_dynamic_property(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).install_dynamic_property(name, value)
|
||||
}
|
||||
|
||||
fn install_slot(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0.write(mc).install_slot(name, id, value, is_final)
|
||||
}
|
||||
|
||||
fn install_const(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0.write(mc).install_const(name, id, value, is_final)
|
||||
}
|
||||
|
||||
fn instance_of(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().instance_of()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> ScriptObject<'gc> {
|
||||
|
|
|
@ -4,15 +4,11 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::backend::audio::SoundHandle;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates Sound objects.
|
||||
pub fn sound_allocator<'gc>(
|
||||
|
@ -81,9 +77,17 @@ impl<'gc> SoundObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for SoundObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(Object::from(*self).into())
|
||||
|
|
|
@ -4,15 +4,11 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::backend::audio::SoundInstanceHandle;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates SoundChannel objects.
|
||||
pub fn soundchannel_allocator<'gc>(
|
||||
|
@ -77,14 +73,22 @@ impl<'gc> SoundChannelObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for SoundChannelObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(Object::from(*self).into())
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let base = ScriptObjectData::base_new(Some((*self).into()), None);
|
||||
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
//! AVM2 object impl for the display hierarchy.
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::function::Executable;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::display_object::DisplayObject;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates Stage objects.
|
||||
pub fn stage_allocator<'gc>(
|
||||
|
@ -120,175 +118,18 @@ impl<'gc> StageObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for StageObject<'gc> {
|
||||
fn get_property_local(
|
||||
self,
|
||||
reciever: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let read = self.0.read();
|
||||
let rv = read.base.get_property_local(reciever, name, activation)?;
|
||||
|
||||
drop(read);
|
||||
|
||||
rv.resolve(activation)
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn set_property_local(
|
||||
self,
|
||||
reciever: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(activation.context.gc_context);
|
||||
let rv = write
|
||||
.base
|
||||
.set_property_local(reciever, name, value, activation)?;
|
||||
|
||||
drop(write);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_property_local(
|
||||
self,
|
||||
reciever: Object<'gc>,
|
||||
name: &QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(activation.context.gc_context);
|
||||
let rv = write
|
||||
.base
|
||||
.init_property_local(reciever, name, value, activation)?;
|
||||
|
||||
drop(write);
|
||||
|
||||
rv.resolve(activation)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).base.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(
|
||||
&self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
multiname: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).base.delete_property(multiname)
|
||||
}
|
||||
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error> {
|
||||
self.0.read().base.get_slot(id)
|
||||
}
|
||||
|
||||
fn set_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).base.set_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn init_slot(
|
||||
self,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).base.init_slot(id, value, mc)
|
||||
}
|
||||
|
||||
fn get_method(self, id: u32) -> Option<Object<'gc>> {
|
||||
self.0.read().base.get_method(id)
|
||||
}
|
||||
|
||||
fn get_scope(self) -> Option<GcCell<'gc, Scope<'gc>>> {
|
||||
self.0.read().base.get_scope()
|
||||
}
|
||||
|
||||
fn resolve_any(self, local_name: AvmString<'gc>) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().base.resolve_any(local_name)
|
||||
}
|
||||
|
||||
fn resolve_any_trait(
|
||||
self,
|
||||
local_name: AvmString<'gc>,
|
||||
) -> Result<Option<Namespace<'gc>>, Error> {
|
||||
self.0.read().base.resolve_any_trait(local_name)
|
||||
}
|
||||
|
||||
fn has_own_property(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().base.has_own_property(name)
|
||||
}
|
||||
|
||||
fn has_trait(self, name: &QName<'gc>) -> Result<bool, Error> {
|
||||
self.0.read().base.has_trait(name)
|
||||
}
|
||||
|
||||
fn has_own_virtual_getter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.has_own_virtual_getter(name)
|
||||
}
|
||||
|
||||
fn has_own_virtual_setter(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.has_own_virtual_setter(name)
|
||||
}
|
||||
|
||||
fn proto(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().base.proto()
|
||||
}
|
||||
|
||||
fn set_proto(self, mc: MutationContext<'gc, '_>, proto: Object<'gc>) {
|
||||
self.0.write(mc).base.set_proto(proto)
|
||||
}
|
||||
|
||||
fn get_enumerant_name(&self, index: u32) -> Option<QName<'gc>> {
|
||||
self.0.read().base.get_enumerant_name(index)
|
||||
}
|
||||
|
||||
fn property_is_enumerable(&self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.property_is_enumerable(name)
|
||||
}
|
||||
|
||||
fn set_local_property_is_enumerable(
|
||||
&self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
is_enumerable: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.set_local_property_is_enumerable(name, is_enumerable)
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn as_executable(&self) -> Option<Executable<'gc>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn instance_of(&self) -> Option<Object<'gc>> {
|
||||
self.0.read().base.instance_of()
|
||||
}
|
||||
|
||||
fn as_display_object(&self) -> Option<DisplayObject<'gc>> {
|
||||
self.0.read().display_object
|
||||
}
|
||||
|
@ -297,16 +138,6 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
|||
self.0.write(mc).display_object = Some(obj);
|
||||
}
|
||||
|
||||
fn call(
|
||||
self,
|
||||
_reciever: Option<Object<'gc>>,
|
||||
_arguments: &[Value<'gc>],
|
||||
_activation: &mut Activation<'_, 'gc, '_>,
|
||||
_base_proto: Option<Object<'gc>>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
Err("Not a callable function!".into())
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let this: Object<'gc> = Object::StageObject(*self);
|
||||
let base = ScriptObjectData::base_new(Some(this), None);
|
||||
|
@ -324,83 +155,4 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
|||
fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result<Value<'gc>, Error> {
|
||||
Ok(Value::Object(Object::from(*self)))
|
||||
}
|
||||
|
||||
fn install_method(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.install_method(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_getter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.install_getter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_setter(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
disp_id: u32,
|
||||
function: Object<'gc>,
|
||||
is_final: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.install_setter(name, disp_id, function, is_final)
|
||||
}
|
||||
|
||||
fn install_dynamic_property(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
value: Value<'gc>,
|
||||
) -> Result<(), Error> {
|
||||
self.0.write(mc).base.install_dynamic_property(name, value)
|
||||
}
|
||||
|
||||
fn install_slot(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.install_slot(name, id, value, is_final)
|
||||
}
|
||||
|
||||
fn install_const(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
name: QName<'gc>,
|
||||
id: u32,
|
||||
value: Value<'gc>,
|
||||
is_final: bool,
|
||||
) {
|
||||
self.0
|
||||
.write(mc)
|
||||
.base
|
||||
.install_const(name, id, value, is_final)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,10 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::vector::VectorStorage;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{impl_avm2_custom_object, impl_avm2_custom_object_instance};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
|
@ -90,8 +88,17 @@ impl<'gc> VectorObject<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for VectorObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn get_property_local(
|
||||
self,
|
||||
|
@ -190,18 +197,6 @@ impl<'gc> TObject<'gc> for VectorObject<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_property_overwritable(
|
||||
self,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: &QName<'gc>,
|
||||
) -> bool {
|
||||
self.0.write(gc_context).base.is_property_overwritable(name)
|
||||
}
|
||||
|
||||
fn is_property_final(self, name: &QName<'gc>) -> bool {
|
||||
self.0.read().base.is_property_final(name)
|
||||
}
|
||||
|
||||
fn delete_property(&self, gc_context: MutationContext<'gc, '_>, name: &QName<'gc>) -> bool {
|
||||
if name.namespace().is_package("") && name.local_name().parse::<usize>().is_ok() {
|
||||
return true;
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
//! Object representation for XML objects
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{Object, ObjectPtr, TObject};
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use crate::{
|
||||
impl_avm2_custom_object, impl_avm2_custom_object_instance, impl_avm2_custom_object_properties,
|
||||
};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::cell::{Ref, RefMut};
|
||||
|
||||
/// A class instance allocator that allocates XML objects.
|
||||
pub fn xml_allocator<'gc>(
|
||||
|
@ -40,9 +35,17 @@ pub struct XmlObjectData<'gc> {
|
|||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for XmlObject<'gc> {
|
||||
impl_avm2_custom_object!(base);
|
||||
impl_avm2_custom_object_properties!(base);
|
||||
impl_avm2_custom_object_instance!(base);
|
||||
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
|
||||
Ref::map(self.0.read(), |read| &read.base)
|
||||
}
|
||||
|
||||
fn base_mut(&self, mc: MutationContext<'gc, '_>) -> RefMut<ScriptObjectData<'gc>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr {
|
||||
self.0.as_ptr() as *const ObjectPtr
|
||||
}
|
||||
|
||||
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
|
||||
let this: Object<'gc> = Object::XmlObject(*self);
|
||||
|
|
Loading…
Reference in New Issue