diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 09fc44889..45836c3ce 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -216,7 +216,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { .ok_or_else(|| format!("Could not resolve parameter type {:?}", type_name))? .coerce_to_object(self)?; - if class.get_own_class_definition().is_none() { + if class.as_class_object().is_none() { return Err(format!("Resolved parameter type {:?} is not a class", type_name).into()); } @@ -1279,7 +1279,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // dynamic properties not yet set if name.is_err() && !object - .get_own_class_definition() + .instance_of_class_definition() .map(|c| c.read().is_sealed()) .unwrap_or(false) { @@ -1357,7 +1357,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // Unknown properties on a dynamic class delete successfully. self.context.avm2.push( !object - .get_own_class_definition() + .instance_of_class_definition() .map(|c| c.read().is_sealed()) .unwrap_or(false), ) @@ -2559,7 +2559,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { }); let class = found?.coerce_to_object(self)?; - if class.get_own_class_definition().is_none() { + if class.as_class_object().is_none() { return Err("TypeError: The right-hand side of operator must be a class.".into()); } @@ -2576,7 +2576,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let class = self.context.avm2.pop().coerce_to_object(self)?; let value = self.context.avm2.pop().coerce_to_object(self)?; - if class.get_own_class_definition().is_none() { + if class.as_class_object().is_none() { return Err("TypeError: The right-hand side of operator must be a class.".into()); } diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index 5315a0324..df2a38f9f 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -311,7 +311,7 @@ fn dynamic_class<'gc>( script: Script<'gc>, ) -> Result<(), Error> { let class = class_object - .get_own_class_definition() + .as_class_definition() .ok_or("Attempted to create builtin dynamic class without class on it's constructor!")?; let name = class.read().name().clone(); @@ -464,7 +464,7 @@ pub fn load_player_globals<'gc>( object_class.install_traits( activation, object_class - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .class_traits(), @@ -472,7 +472,7 @@ pub fn load_player_globals<'gc>( function_class.install_traits( activation, function_class - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .class_traits(), @@ -480,7 +480,7 @@ pub fn load_player_globals<'gc>( class_class.install_traits( activation, class_class - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .class_traits(), diff --git a/core/src/avm2/globals/flash/display/bitmapdata.rs b/core/src/avm2/globals/flash/display/bitmapdata.rs index b8ba6bcb5..778abf37b 100644 --- a/core/src/avm2/globals/flash/display/bitmapdata.rs +++ b/core/src/avm2/globals/flash/display/bitmapdata.rs @@ -22,8 +22,7 @@ pub fn instance_init<'gc>( activation.super_init(this, &[])?; let name = this - .instance_of() - .and_then(|t| t.get_own_class_definition()) + .instance_of_class_definition() .map(|c| c.read().name().clone()); let character = this .instance_of() diff --git a/core/src/avm2/globals/flash/media/sound.rs b/core/src/avm2/globals/flash/media/sound.rs index 127e50558..5d77b8e80 100644 --- a/core/src/avm2/globals/flash/media/sound.rs +++ b/core/src/avm2/globals/flash/media/sound.rs @@ -40,7 +40,7 @@ pub fn instance_init<'gc>( { this.set_sound(activation.context.gc_context, *sound); } else { - log::warn!("Attempted to construct subclass of Sound, {}, which is associated with non-Sound character {}", class_object.get_own_class_definition().expect("Class object is also a class").read().name().local_name(), symbol); + log::warn!("Attempted to construct subclass of Sound, {}, which is associated with non-Sound character {}", class_object.as_class_definition().expect("Class object is also a class").read().name().local_name(), symbol); } } } diff --git a/core/src/avm2/globals/flash/utils.rs b/core/src/avm2/globals/flash/utils.rs index 2c23ac9f7..09294cf4f 100644 --- a/core/src/avm2/globals/flash/utils.rs +++ b/core/src/avm2/globals/flash/utils.rs @@ -40,7 +40,7 @@ pub fn get_qualified_class_name<'gc>( Ok(AvmString::new( activation.context.gc_context, class - .get_own_class_definition() + .as_class_definition() .ok_or("This object does not have a class")? .read() .name() @@ -72,7 +72,7 @@ pub fn get_qualified_super_class_name<'gc>( Ok(AvmString::new( activation.context.gc_context, super_class - .get_own_class_definition() + .as_class_definition() .ok_or("This object does not have a class")? .read() .name() diff --git a/core/src/avm2/globals/vector.rs b/core/src/avm2/globals/vector.rs index bf7ee8868..02bf66235 100644 --- a/core/src/avm2/globals/vector.rs +++ b/core/src/avm2/globals/vector.rs @@ -67,7 +67,7 @@ pub fn class_init<'gc>( let int_vector_class = this.apply(activation, &[int_class.into()])?; let int_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$int"); int_vector_class - .get_own_class_definition() + .as_class_definition() .unwrap() .write(activation.context.gc_context) .set_name(int_vector_name.clone()); @@ -85,7 +85,7 @@ pub fn class_init<'gc>( let uint_vector_class = this.apply(activation, &[uint_class.into()])?; let uint_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$uint"); uint_vector_class - .get_own_class_definition() + .as_class_definition() .unwrap() .write(activation.context.gc_context) .set_name(uint_vector_name.clone()); @@ -103,7 +103,7 @@ pub fn class_init<'gc>( let number_vector_class = this.apply(activation, &[number_class.into()])?; let number_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$double"); number_vector_class - .get_own_class_definition() + .as_class_definition() .unwrap() .write(activation.context.gc_context) .set_name(number_vector_name.clone()); @@ -120,7 +120,7 @@ pub fn class_init<'gc>( let object_vector_class = this.apply(activation, &[Value::Null])?; let object_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$object"); object_vector_class - .get_own_class_definition() + .as_class_definition() .unwrap() .write(activation.context.gc_context) .set_name(object_vector_name.clone()); @@ -282,14 +282,14 @@ pub fn concat<'gc>( for arg in args.iter().map(|a| a.clone()) { let arg_obj = arg.coerce_to_object(activation)?; let arg_class = arg_obj - .get_own_class_definition() + .instance_of_class_definition() .ok_or("TypeError: Tried to concat from a bare object")?; if !arg.is_of_type(activation, my_class)? { return Err(format!( "TypeError: Cannot coerce argument of type {:?} to argument of type {:?}", arg_class.read().name(), my_class - .get_own_class_definition() + .as_class_definition() .ok_or("TypeError: Tried to concat into a bare object")? .read() .name() @@ -308,13 +308,13 @@ pub fn concat<'gc>( if let Ok(val_obj) = val.coerce_to_object(activation) { if !val.is_of_type(activation, val_class)? { let other_val_class = val_obj - .get_own_class_definition() + .instance_of_class_definition() .ok_or("TypeError: Tried to concat a bare object into a Vector")?; return Err(format!( "TypeError: Cannot coerce Vector value of type {:?} to type {:?}", other_val_class.read().name(), val_class - .get_own_class_definition() + .as_class_definition() .ok_or("TypeError: Tried to concat into a bare object")? .read() .name() diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index 22e2bc74d..e366bd9d7 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -131,7 +131,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// defined prototype methods for ES3-style classes. fn find_class_for_trait(self, name: &QName<'gc>) -> Result>, Error> { let class = self - .get_own_class_definition() + .as_class_definition() .ok_or("Cannot get base traits on non-class object")?; if class.read().has_instance_trait(name) { @@ -436,7 +436,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy } } - if let Some(class) = from_class_object.get_own_class_definition() { + if let Some(class) = from_class_object.as_class_definition() { self.install_traits(activation, class.read().instance_traits())?; } @@ -701,7 +701,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy })?; let mut class_traits = Vec::new(); superclass_object - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .lookup_instance_traits(name, &mut class_traits)?; @@ -767,7 +767,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy })?; let mut class_traits = Vec::new(); superclass_object - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .lookup_instance_traits(name, &mut class_traits)?; @@ -827,7 +827,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy })?; let mut class_traits = Vec::new(); superclass_object - .get_own_class_definition() + .as_class_definition() .unwrap() .read() .lookup_instance_traits(name, &mut class_traits)?; @@ -926,7 +926,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// coercions. fn to_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { let class_name = self - .get_own_class_definition() + .instance_of_class_definition() .map(|c| c.read().name().local_name()) .unwrap_or_else(|| "Object".into()); @@ -943,7 +943,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// of the class that created this object). fn to_locale_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { let class_name = self - .get_own_class_definition() + .instance_of_class_definition() .map(|c| c.read().name().local_name()) .unwrap_or_else(|| "Object".into()); @@ -1085,22 +1085,25 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// Get a raw pointer value for this object. fn as_ptr(&self) -> *const ObjectPtr; - /// Get this object's `Class`, if it has one. - /// This this object is already a ClassObject, return its own Class. - /// Note: this probably shouldn't be used in most cases. - fn get_own_class_definition(&self) -> Option>> { - let class = self - .as_class_object() - .or_else(|| self.instance_of().and_then(|cls| cls.as_class_object())); - class.map(|cls| cls.inner_class_definition()) - } - + /// Get this object's class, if it has one. fn instance_of(&self) -> Option>; + /// Get this object's class's `Class`, if it has one. + fn instance_of_class_definition(&self) -> Option>> { + self.instance_of().and_then(|cls| cls.as_class_definition()) + } + + /// Try to corece this object into a `ClassObject`. fn as_class_object(&self) -> Option> { None } + /// Get this object's `Class`, if it's a `ClassObject`. + fn as_class_definition(&self) -> Option>> { + self.as_class_object() + .map(|cls| cls.inner_class_definition()) + } + /// Get this object's `Executable`, if it has one. fn as_executable(&self) -> Option> { None diff --git a/core/src/avm2/object/class_object.rs b/core/src/avm2/object/class_object.rs index 6d803e389..69a1b8604 100644 --- a/core/src/avm2/object/class_object.rs +++ b/core/src/avm2/object/class_object.rs @@ -85,7 +85,7 @@ impl<'gc> ClassObject<'gc> { superclass_object: Option>, scope: Option>>, ) -> Result, Error> { - if let Some(base_class) = superclass_object.and_then(|b| b.get_own_class_definition()) { + if let Some(base_class) = superclass_object.and_then(|b| b.as_class_definition()) { if base_class.read().is_final() { return Err(format!( "Base class {:?} is final and cannot be extended", @@ -294,7 +294,7 @@ impl<'gc> ClassObject<'gc> { } let interface = interface.unwrap().coerce_to_object(activation)?; - if let Some(class) = interface.get_own_class_definition() { + if let Some(class) = interface.as_class_definition() { if !class.read().is_interface() { return Err(format!( "Class {:?} is not an interface and cannot be implemented by classes", @@ -530,7 +530,7 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> { nullable_params: &[Value<'gc>], ) -> Result, Error> { let self_class = self - .get_own_class_definition() + .as_class_definition() .ok_or("Attempted to apply type arguments to non-class!")?; if !self_class.read().is_generic() { @@ -570,7 +570,7 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> { class_params.push( param .unwrap_or(activation.avm2().classes().object) - .get_own_class_definition() + .as_class_definition() .ok_or(format!( "Cannot apply class {:?} with non-class parameter", self_class.read().name() diff --git a/core/src/avm2/object/loaderinfo_object.rs b/core/src/avm2/object/loaderinfo_object.rs index 87c2fd5fd..06dc80ac0 100644 --- a/core/src/avm2/object/loaderinfo_object.rs +++ b/core/src/avm2/object/loaderinfo_object.rs @@ -123,7 +123,7 @@ impl<'gc> TObject<'gc> for LoaderInfoObject<'gc> { impl_avm2_custom_object_instance!(base); fn value_of(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { - if let Some(class) = self.get_own_class_definition() { + 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()) diff --git a/core/src/avm2/object/primitive_object.rs b/core/src/avm2/object/primitive_object.rs index 13de17876..1f16b92a6 100644 --- a/core/src/avm2/object/primitive_object.rs +++ b/core/src/avm2/object/primitive_object.rs @@ -118,7 +118,7 @@ impl<'gc> TObject<'gc> for PrimitiveObject<'gc> { val @ Value::Integer(_) | val @ Value::Unsigned(_) => Ok(val), _ => { let class_name = self - .get_own_class_definition() + .instance_of_class_definition() .map(|c| c.read().name().local_name()) .unwrap_or_else(|| "Object".into()); diff --git a/core/src/avm2/object/script_object.rs b/core/src/avm2/object/script_object.rs index 6a8e286fa..e3a43b637 100644 --- a/core/src/avm2/object/script_object.rs +++ b/core/src/avm2/object/script_object.rs @@ -218,7 +218,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { } fn to_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { - if let Some(class) = self.get_own_class_definition() { + 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()) @@ -512,7 +512,7 @@ impl<'gc> ScriptObjectData<'gc> { while let Some(class) = cur_class { let cur_static_class = class - .get_own_class_definition() + .as_class_definition() .ok_or("Object is not a class constructor")?; if cur_static_class.read().has_instance_trait(name) { return Ok(true); @@ -573,7 +573,7 @@ impl<'gc> ScriptObjectData<'gc> { while let Some(class) = cur_class { let cur_static_class = class - .get_own_class_definition() + .as_class_definition() .ok_or("Object is not a class constructor")?; if let Some(ns) = cur_static_class .read() @@ -761,7 +761,7 @@ impl<'gc> ScriptObjectData<'gc> { value: Value<'gc>, ) -> Result<(), Error> { if let Some(class) = self.instance_of() { - if let Some(class) = class.get_own_class_definition() { + if let Some(class) = class.as_class_definition() { if class.read().is_sealed() { return Err(format!( "Objects of type {:?} are not dynamic", diff --git a/core/src/avm2/value.rs b/core/src/avm2/value.rs index 60500e153..187f6b548 100644 --- a/core/src/avm2/value.rs +++ b/core/src/avm2/value.rs @@ -611,7 +611,7 @@ impl<'gc> Value<'gc> { } } - if let Some(static_class) = class.get_own_class_definition() { + if let Some(static_class) = class.as_class_definition() { return Err(format!( "Cannot coerce {:?} to an {:?}", self, @@ -671,7 +671,7 @@ impl<'gc> Value<'gc> { activation: &mut Activation<'_, 'gc, '_>, type_object: Object<'gc>, ) -> Result { - if let Some(type_class) = type_object.get_own_class_definition() { + if let Some(type_class) = type_object.as_class_definition() { if type_class.read().name() == &QName::new(Namespace::public(), "Number") { return Ok(self.is_number()); }