diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 2f09b61289a2..4d396b5e41b5 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -326,15 +326,6 @@ impl<'a, 'gc> Activation<'a, 'gc> { } } - pub fn lookup_class_in_domain( - &mut self, - name: &Multiname<'gc>, - ) -> Result>, Error<'gc>> { - self.domain() - .get_class(name, self.context.gc_context) - .ok_or_else(|| format!("Attempted to resolve nonexistent type {name:?}").into()) - } - /// Resolve a single parameter value. /// /// Given an individual parameter value and the associated parameter's diff --git a/core/src/avm2/class.rs b/core/src/avm2/class.rs index 39153c877816..a824d5aad77f 100644 --- a/core/src/avm2/class.rs +++ b/core/src/avm2/class.rs @@ -1,6 +1,7 @@ //! AVM2 classes use crate::avm2::activation::Activation; +use crate::avm2::error::make_error_1014; use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{ClassObject, Object}; use crate::avm2::script::TranslationUnit; @@ -10,6 +11,7 @@ use crate::avm2::Error; use crate::avm2::Multiname; use crate::avm2::Namespace; use crate::avm2::QName; +use crate::context::UpdateContext; use bitflags::bitflags; use fnv::FnvHashMap; use gc_arena::{Collect, GcCell, Mutation}; @@ -80,8 +82,8 @@ pub struct Class<'gc> { /// The type parameter for this class (only supported for Vector) param: Option>>>, - /// The name of this class's superclass. - super_class: Option>, + /// This class's superclass, or None if it has no superclass + super_class: Option>>, /// Attributes of the given class. #[collect(require_static)] @@ -203,7 +205,7 @@ impl<'gc> Class<'gc> { /// using `load_traits`. pub fn new( name: QName<'gc>, - super_class: Option>, + super_class: Option>>, instance_init: Method<'gc>, class_init: Method<'gc>, mc: &Mutation<'gc>, @@ -249,10 +251,12 @@ impl<'gc> Class<'gc> { /// This is used to parameterize a generic type. The returned class will no /// longer be generic. pub fn with_type_param( + context: &mut UpdateContext<'_, 'gc>, this: GcCell<'gc, Class<'gc>>, param: Option>>, - mc: &Mutation<'gc>, ) -> GcCell<'gc, Class<'gc>> { + let mc = context.gc_context; + let read = this.read(); let key = param.map(ClassKey); @@ -275,7 +279,13 @@ impl<'gc> Class<'gc> { // FIXME - we should store a `Multiname` instead of a `QName`, and use the // `params` field. For now, this is good enough to get tests passing QName::new(read.name.namespace(), AvmString::new_utf8(mc, name)), - Some(Multiname::new(read.name.namespace(), "Vector.<*>")), + Some( + context + .avm2 + .classes() + .object_vector + .inner_class_definition(), + ), object_vector_cls.read().instance_init(), object_vector_cls.read().class_init(), mc, @@ -336,10 +346,19 @@ impl<'gc> Class<'gc> { let super_class = if abc_instance.super_name.0 == 0 { None } else { + let multiname = + unit.pool_multiname_static(abc_instance.super_name, &mut activation.context)?; + Some( - unit.pool_multiname_static(abc_instance.super_name, &mut activation.context)? - .deref() - .clone(), + activation + .domain() + .get_class(&mut activation.context, &multiname) + .ok_or_else(|| { + make_error_1014( + activation, + multiname.to_qualified_name(activation.context.gc_context), + ) + })?, ) }; @@ -616,8 +635,12 @@ impl<'gc> Class<'gc> { self.param = param; } - pub fn super_class_name(&self) -> &Option> { - &self.super_class + pub fn super_class(&self) -> Option>> { + self.super_class + } + + pub fn super_class_name(&self) -> Option> { + self.super_class.map(|c| c.read().name().into()) } pub fn protected_namespace(&self) -> Option> { diff --git a/core/src/avm2/domain.rs b/core/src/avm2/domain.rs index 8126fdb89512..3740ebf7196d 100644 --- a/core/src/avm2/domain.rs +++ b/core/src/avm2/domain.rs @@ -10,6 +10,7 @@ use crate::avm2::value::Value; use crate::avm2::Error; use crate::avm2::Multiname; use crate::avm2::QName; +use crate::context::UpdateContext; use gc_arena::{Collect, GcCell, GcWeakCell, Mutation}; use ruffle_wstr::WStr; @@ -213,20 +214,20 @@ impl<'gc> Domain<'gc> { pub fn get_class( self, + context: &mut UpdateContext<'_, 'gc>, multiname: &Multiname<'gc>, - mc: &Mutation<'gc>, ) -> Option>> { let class = self.get_class_inner(multiname); if let Some(class) = class { if let Some(param) = multiname.param() { if !param.is_any_name() { - if let Some(resolved_param) = self.get_class(¶m, mc) { - return Some(Class::with_type_param(class, Some(resolved_param), mc)); + if let Some(resolved_param) = self.get_class(context, ¶m) { + return Some(Class::with_type_param(context, class, Some(resolved_param))); } return None; } else { - return Some(Class::with_type_param(class, None, mc)); + return Some(Class::with_type_param(context, class, None)); } } } diff --git a/core/src/avm2/globals.rs b/core/src/avm2/globals.rs index bf2c2a080a5e..58e054a7c27c 100644 --- a/core/src/avm2/globals.rs +++ b/core/src/avm2/globals.rs @@ -2,7 +2,7 @@ use crate::avm2::activation::Activation; use crate::avm2::api_version::ApiVersion; use crate::avm2::class::Class; use crate::avm2::domain::Domain; -use crate::avm2::object::{ClassObject, Object, ScriptObject, TObject}; +use crate::avm2::object::{ClassObject, ScriptObject, TObject}; use crate::avm2::scope::{Scope, ScopeChain}; use crate::avm2::script::Script; use crate::avm2::Avm2; @@ -376,23 +376,11 @@ fn class<'gc>( let (_, global, mut domain) = script.init(); let class_read = class_def.read(); - let super_class = if let Some(sc_name) = class_read.super_class_name() { - let super_class: Result, Error<'gc>> = activation - .resolve_definition(sc_name) - .ok() - .and_then(|v| v) - .and_then(|v| v.as_object()) - .ok_or_else(|| { - format!( - "Could not resolve superclass {} when defining global class {}", - sc_name.to_qualified_name(mc), - class_read.name().to_qualified_name(mc) - ) - .into() - }); - let super_class = super_class? - .as_class_object() - .ok_or_else(|| Error::from("Base class of a global class is not a class"))?; + let super_class = if let Some(super_class) = class_read.super_class() { + let super_class = super_class + .read() + .class_object() + .ok_or_else(|| Error::from("Base class should have been initialized"))?; Some(super_class) } else { @@ -498,18 +486,18 @@ pub fn load_player_globals<'gc>( let object_proto = ScriptObject::custom_object(mc, Some(object_class), None); domain.export_class(object_classdef.read().name(), object_classdef, mc); - let fn_classdef = function::create_class(activation); + let fn_classdef = function::create_class(activation, object_classdef); let fn_class = ClassObject::from_class_partial(activation, fn_classdef, Some(object_class))?; let fn_proto = ScriptObject::custom_object(mc, Some(fn_class), Some(object_proto)); domain.export_class(fn_classdef.read().name(), fn_classdef, mc); - let class_classdef = class::create_class(activation); + let class_classdef = class::create_class(activation, object_classdef); let class_class = ClassObject::from_class_partial(activation, class_classdef, Some(object_class))?; let class_proto = ScriptObject::custom_object(mc, Some(object_class), Some(object_proto)); domain.export_class(class_classdef.read().name(), class_classdef, mc); - let global_classdef = global_scope::create_class(activation); + let global_classdef = global_scope::create_class(activation, object_classdef); let global_class = ClassObject::from_class_partial(activation, global_classdef, Some(object_class))?; let global_proto = ScriptObject::custom_object(mc, Some(object_class), Some(object_proto)); diff --git a/core/src/avm2/globals/array.rs b/core/src/avm2/globals/array.rs index e89323ae1d83..8039512355e3 100644 --- a/core/src/avm2/globals/array.rs +++ b/core/src/avm2/globals/array.rs @@ -8,7 +8,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{array_allocator, ArrayObject, FunctionObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use crate::string::AvmString; use bitflags::bitflags; @@ -1247,10 +1246,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Array"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/boolean.rs b/core/src/avm2/globals/boolean.rs index 80d34da9063e..5fdb6a7d1e62 100644 --- a/core/src/avm2/globals/boolean.rs +++ b/core/src/avm2/globals/boolean.rs @@ -7,7 +7,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{primitive_allocator, FunctionObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use gc_arena::GcCell; @@ -136,10 +135,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Boolean"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/class.rs b/core/src/avm2/globals/class.rs index d31859b7e3ef..3f5ddd26f2c2 100644 --- a/core/src/avm2/globals/class.rs +++ b/core/src/avm2/globals/class.rs @@ -6,7 +6,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use gc_arena::GcCell; @@ -44,14 +43,14 @@ fn prototype<'gc>( } /// Construct `Class`'s class. -pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> { +pub fn create_class<'gc>( + activation: &mut Activation<'_, 'gc>, + object_class: GcCell<'gc, Class<'gc>>, +) -> GcCell<'gc, Class<'gc>> { let gc_context = activation.context.gc_context; let class_class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Class"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(object_class), Method::from_builtin(instance_init, "", gc_context), Method::from_builtin(class_init, "", gc_context), gc_context, diff --git a/core/src/avm2/globals/date.rs b/core/src/avm2/globals/date.rs index eea53a9ce174..c9547c5e46ef 100644 --- a/core/src/avm2/globals/date.rs +++ b/core/src/avm2/globals/date.rs @@ -6,7 +6,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{date_allocator, DateObject, FunctionObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use crate::locale::{get_current_date_time, get_timezone}; use crate::string::{utils as string_utils, AvmString, WStr}; @@ -1327,10 +1326,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Date"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/function.rs b/core/src/avm2/globals/function.rs index e91e9616b076..55599dd8c378 100644 --- a/core/src/avm2/globals/function.rs +++ b/core/src/avm2/globals/function.rs @@ -8,7 +8,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{function_allocator, FunctionObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use gc_arena::GcCell; @@ -222,14 +221,14 @@ fn set_prototype<'gc>( } /// Construct `Function`'s class. -pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> { +pub fn create_class<'gc>( + activation: &mut Activation<'_, 'gc>, + object_classdef: GcCell<'gc, Class<'gc>>, +) -> GcCell<'gc, Class<'gc>> { let gc_context = activation.context.gc_context; let function_class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Function"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(object_classdef), Method::from_builtin(instance_init, "", gc_context), Method::from_builtin(class_init, "", gc_context), gc_context, diff --git a/core/src/avm2/globals/global_scope.rs b/core/src/avm2/globals/global_scope.rs index 853986f724c5..f0b99cb4fbc0 100644 --- a/core/src/avm2/globals/global_scope.rs +++ b/core/src/avm2/globals/global_scope.rs @@ -10,7 +10,6 @@ use crate::avm2::method::Method; use crate::avm2::object::Object; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use gc_arena::GcCell; @@ -33,14 +32,14 @@ pub fn class_init<'gc>( } /// Construct `global`'s class. -pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> { +pub fn create_class<'gc>( + activation: &mut Activation<'_, 'gc>, + object_class: GcCell<'gc, Class<'gc>>, +) -> GcCell<'gc, Class<'gc>> { let mc = activation.context.gc_context; Class::new( QName::new(activation.avm2().public_namespace_base_version, "global"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(object_class), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/int.rs b/core/src/avm2/globals/int.rs index 786480a08407..22aa6c034c0b 100644 --- a/core/src/avm2/globals/int.rs +++ b/core/src/avm2/globals/int.rs @@ -216,10 +216,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "int"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin_and_params( instance_init, "", diff --git a/core/src/avm2/globals/namespace.rs b/core/src/avm2/globals/namespace.rs index 358c8752c635..4c534709a9b0 100644 --- a/core/src/avm2/globals/namespace.rs +++ b/core/src/avm2/globals/namespace.rs @@ -6,7 +6,6 @@ use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{namespace_allocator, FunctionObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::Namespace; use crate::avm2::QName; use crate::{avm2_stub_constructor, avm2_stub_getter}; @@ -133,10 +132,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Namespace"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/number.rs b/core/src/avm2/globals/number.rs index 6d11a1aca393..512715426362 100644 --- a/core/src/avm2/globals/number.rs +++ b/core/src/avm2/globals/number.rs @@ -6,7 +6,6 @@ use crate::avm2::error::{make_error_1002, make_error_1003, make_error_1004}; use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::object::{primitive_allocator, FunctionObject, Object, TObject}; use crate::avm2::value::Value; -use crate::avm2::Multiname; use crate::avm2::QName; use crate::avm2::{AvmString, Error}; use gc_arena::GcCell; @@ -372,10 +371,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "Number"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/string.rs b/core/src/avm2/globals/string.rs index 46605c3183f1..56f644a36244 100644 --- a/core/src/avm2/globals/string.rs +++ b/core/src/avm2/globals/string.rs @@ -8,7 +8,6 @@ use crate::avm2::object::{primitive_allocator, FunctionObject, Object, TObject}; use crate::avm2::regexp::RegExpFlags; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use crate::avm2::{ArrayObject, ArrayStorage}; use crate::string::{AvmString, WString}; @@ -672,10 +671,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "String"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, "", mc), Method::from_builtin(class_init, "", mc), mc, diff --git a/core/src/avm2/globals/uint.rs b/core/src/avm2/globals/uint.rs index 481080dfac7e..dd4250629614 100644 --- a/core/src/avm2/globals/uint.rs +++ b/core/src/avm2/globals/uint.rs @@ -217,10 +217,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().public_namespace_base_version, "uint"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin_and_params( instance_init, "", diff --git a/core/src/avm2/globals/vector.rs b/core/src/avm2/globals/vector.rs index 3dab1ae4ef1a..5515c7159340 100644 --- a/core/src/avm2/globals/vector.rs +++ b/core/src/avm2/globals/vector.rs @@ -14,7 +14,6 @@ use crate::avm2::object::{ use crate::avm2::value::Value; use crate::avm2::vector::VectorStorage; use crate::avm2::Error; -use crate::avm2::Multiname; use crate::avm2::QName; use crate::string::AvmString; use gc_arena::GcCell; @@ -917,10 +916,7 @@ pub fn create_generic_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell let mc = activation.context.gc_context; let class = Class::new( QName::new(activation.avm2().vector_public_namespace, "Vector"), - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(generic_init, "", mc), Method::from_builtin(generic_init, "", mc), mc, @@ -953,10 +949,7 @@ pub fn create_builtin_class<'gc>( let class = Class::new( name, - Some(Multiname::new( - activation.avm2().public_namespace_base_version, - "Object", - )), + Some(activation.avm2().classes().object.inner_class_definition()), Method::from_builtin(instance_init, " instance initializer>", mc), Method::from_builtin(class_init, " class initializer>", mc), mc, diff --git a/core/src/avm2/object/class_object.rs b/core/src/avm2/object/class_object.rs index d421d6390eee..40dbc9e86d06 100644 --- a/core/src/avm2/object/class_object.rs +++ b/core/src/avm2/object/class_object.rs @@ -12,10 +12,10 @@ use crate::avm2::property::Property; use crate::avm2::scope::{Scope, ScopeChain}; use crate::avm2::value::Value; use crate::avm2::vtable::{ClassBoundMethod, VTable}; +use crate::avm2::Error; use crate::avm2::Multiname; use crate::avm2::QName; use crate::avm2::TranslationUnit; -use crate::avm2::{Domain, Error}; use crate::string::AvmString; use fnv::FnvHashMap; use gc_arena::{Collect, GcCell, GcWeakCell, Mutation}; @@ -339,11 +339,12 @@ impl<'gc> ClassObject<'gc> { let mut queue = vec![class]; while let Some(cls) = queue.pop() { for interface_name in cls.read().direct_interfaces() { - let interface = self.early_resolve_class( - scope.domain(), - interface_name, - activation.context.gc_context, - )?; + let interface = scope + .domain() + .get_class(&mut activation.context, interface_name) + .ok_or_else(|| { + Error::from(format!("Could not resolve interface {interface_name:?}")) + })?; if !interface.read().is_interface() { return Err(format!( @@ -359,12 +360,8 @@ impl<'gc> ClassObject<'gc> { } } - if let Some(superclass_name) = cls.read().super_class_name() { - queue.push(self.early_resolve_class( - scope.domain(), - superclass_name, - activation.context.gc_context, - )?); + if let Some(super_class) = cls.read().super_class() { + queue.push(super_class); } } write.interfaces = interfaces; @@ -396,20 +393,6 @@ impl<'gc> ClassObject<'gc> { Ok(()) } - // Looks up a class by name, without using `ScopeChain.resolve` - // This lets us look up an class before its `ClassObject` has been constructed, - // which is needed to resolve classes when constructing a (different) `ClassObject`. - fn early_resolve_class( - &self, - domain: Domain<'gc>, - class_name: &Multiname<'gc>, - mc: &Mutation<'gc>, - ) -> Result>, Error<'gc>> { - domain - .get_class(class_name, mc) - .ok_or_else(|| format!("Could not resolve class {class_name:?}").into()) - } - /// Manually set the type of this `Class`. /// /// This is intended to support initialization of early types such as @@ -983,7 +966,7 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> { let class_param = object_param.map(|c| c.inner_class_definition()); let parameterized_class: GcCell<'_, Class<'_>> = - Class::with_type_param(self_class, class_param, activation.context.gc_context); + Class::with_type_param(&mut activation.context, self_class, class_param); // NOTE: this isn't fully accurate, but much simpler. // FP's Vector is more of special case that literally copies some parent class's properties diff --git a/core/src/avm2/property.rs b/core/src/avm2/property.rs index 374994fed514..68dd114e61dc 100644 --- a/core/src/avm2/property.rs +++ b/core/src/avm2/property.rs @@ -77,7 +77,7 @@ impl<'gc> PropertyClass<'gc> { // so use that domain if we don't have a translation unit. let domain = unit.map_or(activation.avm2().playerglobals_domain, |u| u.domain()); - if let Some(class) = domain.get_class(name, activation.context.gc_context) { + if let Some(class) = domain.get_class(&mut activation.context, name) { *self = PropertyClass::Class(class); (Some(class), true) } else { @@ -114,7 +114,7 @@ impl<'gc> PropertyClass<'gc> { } else { let domain = unit.map_or(activation.avm2().playerglobals_domain, |u| u.domain()); - if let Some(class) = domain.get_class(name, activation.context.gc_context) { + if let Some(class) = domain.get_class(&mut activation.context, name) { *self = PropertyClass::Class(class); Ok(Some(class)) } else { diff --git a/core/src/avm2/script.rs b/core/src/avm2/script.rs index febaecfd8d97..8e0cae10f5c4 100644 --- a/core/src/avm2/script.rs +++ b/core/src/avm2/script.rs @@ -232,6 +232,10 @@ impl<'gc> TranslationUnit<'gc> { drop(read); let mut activation = Activation::from_domain(uc.reborrow(), domain); + // Make sure we have the correct domain for code that tries to access it + // using `activation.domain()` + activation.set_outer(ScopeChain::new(domain)); + let global_class = activation.avm2().classes().global; let global_obj = global_class.construct(&mut activation, &[])?; global_obj.fork_vtable(activation.context.gc_context); diff --git a/core/src/avm2/verify.rs b/core/src/avm2/verify.rs index 9656af75f31e..bec15cbcefb7 100644 --- a/core/src/avm2/verify.rs +++ b/core/src/avm2/verify.rs @@ -330,7 +330,7 @@ pub fn verify_method<'gc>( activation .domain() - .get_class(&multiname, activation.context.gc_context) + .get_class(&mut activation.context, &multiname) .ok_or_else(|| { make_error_1014( activation, @@ -448,7 +448,7 @@ pub fn verify_method<'gc>( let resolved_type = activation .domain() - .get_class(&pooled_type_name, activation.context.gc_context) + .get_class(&mut activation.context, &pooled_type_name) .ok_or_else(|| { make_error_1014( activation, @@ -610,7 +610,7 @@ pub fn resolve_param_config<'gc>( } else { let lookedup_class = activation .domain() - .get_class(¶m.param_type_name, activation.context.gc_context) + .get_class(&mut activation.context, ¶m.param_type_name) .ok_or_else(|| { make_error_1014( activation, @@ -648,7 +648,7 @@ fn resolve_return_type<'gc>( Ok(Some( activation .domain() - .get_class(return_type, activation.context.gc_context) + .get_class(&mut activation.context, return_type) .ok_or_else(|| { make_error_1014( activation, @@ -1028,7 +1028,7 @@ fn resolve_op<'gc>( let class = activation .domain() - .get_class(&multiname, activation.context.gc_context) + .get_class(&mut activation.context, &multiname) .unwrap(); // Verifier guarantees that class exists @@ -1041,7 +1041,7 @@ fn resolve_op<'gc>( let class = activation .domain() - .get_class(&multiname, activation.context.gc_context) + .get_class(&mut activation.context, &multiname) .unwrap(); // Verifier guarantees that class exists @@ -1088,7 +1088,7 @@ fn resolve_op<'gc>( let class = activation .domain() - .get_class(&multiname, activation.context.gc_context) + .get_class(&mut activation.context, &multiname) .unwrap(); // Verifier guarantees that class exists