From db550b035c16625023237a9c5c52f1d33ad8444e Mon Sep 17 00:00:00 2001 From: EmperorBale Date: Tue, 27 Jul 2021 16:58:13 -0700 Subject: [PATCH] avm2: Add Date stub --- core/src/avm2/globals.rs | 7 ++++ core/src/avm2/globals/date.rs | 48 ++++++++++++++++++++++++ core/src/avm2/object.rs | 3 ++ core/src/avm2/object/date_object.rs | 58 +++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 core/src/avm2/globals/date.rs create mode 100644 core/src/avm2/object/date_object.rs diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index a413cfd1a..ec578d882 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -18,6 +18,7 @@ use gc_arena::{Collect, GcCell, MutationContext}; mod array; mod boolean; mod class; +mod date; mod flash; mod function; mod global_scope; @@ -120,6 +121,7 @@ pub struct SystemPrototypes<'gc> { pub soundchannel: Object<'gc>, pub bitmap: Object<'gc>, pub bitmapdata: Object<'gc>, + pub date: Object<'gc>, } impl<'gc> SystemPrototypes<'gc> { @@ -174,6 +176,7 @@ impl<'gc> SystemPrototypes<'gc> { soundchannel: empty, bitmap: empty, bitmapdata: empty, + date: empty, } } } @@ -219,6 +222,7 @@ pub struct SystemClasses<'gc> { pub soundchannel: Object<'gc>, pub bitmap: Object<'gc>, pub bitmapdata: Object<'gc>, + pub date: Object<'gc>, } impl<'gc> SystemClasses<'gc> { @@ -273,6 +277,7 @@ impl<'gc> SystemClasses<'gc> { soundchannel: empty, bitmap: empty, bitmapdata: empty, + date: empty, } } } @@ -555,6 +560,8 @@ pub fn load_player_globals<'gc>( script ); + avm2_system_class!(date, activation, date::create_class(mc), domain, script); + // package `flash.system` avm2_system_class!( application_domain, diff --git a/core/src/avm2/globals/date.rs b/core/src/avm2/globals/date.rs new file mode 100644 index 000000000..b73342214 --- /dev/null +++ b/core/src/avm2/globals/date.rs @@ -0,0 +1,48 @@ +//! `Date` class + +use crate::avm2::activation::Activation; +use crate::avm2::class::Class; +use crate::avm2::method::Method; +use crate::avm2::names::{Namespace, QName}; +use crate::avm2::object::{date_allocator, Object}; +use crate::avm2::value::Value; +use crate::avm2::Error; +use gc_arena::{GcCell, MutationContext}; + +/// Implements `Date`'s instance constructor. +pub fn instance_init<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(this) = this { + activation.super_init(this, &[])?; + } + + Ok(Value::Undefined) +} + +/// Implements `Date`'s class constructor. +pub fn class_init<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + _this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + Ok(Value::Undefined) +} + +/// Construct `Date`'s class. +pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { + let class = Class::new( + QName::new(Namespace::public(), "Date"), + Some(QName::new(Namespace::public(), "Object").into()), + Method::from_builtin(instance_init, "", mc), + Method::from_builtin(class_init, "", mc), + mc, + ); + + let mut write = class.write(mc); + write.set_instance_allocator(date_allocator); + + class +} diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index e366bd9d7..b82f26ef5 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -29,6 +29,7 @@ mod bitmapdata_object; mod bytearray_object; mod class_object; mod custom_object; +mod date_object; mod dispatch_object; mod domain_object; mod event_object; @@ -48,6 +49,7 @@ pub use crate::avm2::object::array_object::{array_allocator, ArrayObject}; pub use crate::avm2::object::bitmapdata_object::{bitmapdata_allocator, BitmapDataObject}; pub use crate::avm2::object::bytearray_object::{bytearray_allocator, ByteArrayObject}; pub use crate::avm2::object::class_object::ClassObject; +pub use crate::avm2::object::date_object::{date_allocator, DateObject}; pub use crate::avm2::object::dispatch_object::DispatchObject; pub use crate::avm2::object::domain_object::{appdomain_allocator, DomainObject}; pub use crate::avm2::object::event_object::{event_allocator, EventObject}; @@ -90,6 +92,7 @@ pub use crate::avm2::object::xml_object::{xml_allocator, XmlObject}; SoundObject(SoundObject<'gc>), SoundChannelObject(SoundChannelObject<'gc>), BitmapDataObject(BitmapDataObject<'gc>), + DateObject(DateObject<'gc>), } )] pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy { diff --git a/core/src/avm2/object/date_object.rs b/core/src/avm2/object/date_object.rs new file mode 100644 index 000000000..ef4710ad3 --- /dev/null +++ b/core/src/avm2/object/date_object.rs @@ -0,0 +1,58 @@ +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 Date objects. +pub fn date_allocator<'gc>( + class: Object<'gc>, + proto: Object<'gc>, + activation: &mut Activation<'_, 'gc, '_>, +) -> Result, Error> { + let base = ScriptObjectData::base_new(Some(proto), Some(class)); + + Ok(DateObject(GcCell::allocate( + activation.context.gc_context, + DateObjectData { base }, + )) + .into()) +} +#[derive(Clone, Collect, Debug, Copy)] +#[collect(no_drop)] +pub struct DateObject<'gc>(GcCell<'gc, DateObjectData<'gc>>); + +#[derive(Clone, Collect, Debug)] +#[collect(no_drop)] +pub struct DateObjectData<'gc> { + /// Base script object + base: ScriptObjectData<'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 derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result, Error> { + let this: Object<'gc> = Object::DateObject(*self); + let base = ScriptObjectData::base_new(Some(this), None); + + Ok(DateObject(GcCell::allocate( + activation.context.gc_context, + DateObjectData { base }, + )) + .into()) + } + + fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result, Error> { + Ok(Value::Object(Object::from(*self))) + } +}