avm2: Make all domain object construction (save for the global domain) pull the constructor and call it in `from_domain`.
This also adds `DomainObject::script_global`, which does the same thing but picks the `global` class instead of `ApplicationDomain`.
This commit is contained in:
parent
6fe44c3862
commit
22fedf4dca
|
@ -79,31 +79,21 @@ pub fn application_domain<'gc>(
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
if let Some(this) = this {
|
if let Some(this) = this {
|
||||||
if let Some(loader_stream) = this.as_loader_stream() {
|
if let Some(loader_stream) = this.as_loader_stream() {
|
||||||
let appdomain_proto = activation.avm2().prototypes().application_domain;
|
|
||||||
let appdomain_constr = activation.avm2().constructors().application_domain;
|
|
||||||
|
|
||||||
match &*loader_stream {
|
match &*loader_stream {
|
||||||
LoaderStream::Stage => {
|
LoaderStream::Stage => {
|
||||||
return Ok(DomainObject::from_domain(
|
return Ok(DomainObject::from_domain(
|
||||||
activation.context.gc_context,
|
activation,
|
||||||
appdomain_constr,
|
|
||||||
Some(appdomain_proto),
|
|
||||||
activation.context.avm2.global_domain(),
|
activation.context.avm2.global_domain(),
|
||||||
)
|
)?
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
LoaderStream::Swf(movie, _) => {
|
LoaderStream::Swf(movie, _) => {
|
||||||
let library = activation
|
let domain = activation
|
||||||
.context
|
.context
|
||||||
.library
|
.library
|
||||||
.library_for_movie_mut(movie.clone());
|
.library_for_movie_mut(movie.clone())
|
||||||
return Ok(DomainObject::from_domain(
|
.avm2_domain();
|
||||||
activation.context.gc_context,
|
return Ok(DomainObject::from_domain(activation, domain)?.into());
|
||||||
appdomain_constr,
|
|
||||||
Some(appdomain_proto),
|
|
||||||
library.avm2_domain(),
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,9 @@ pub fn current_domain<'gc>(
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
let globals = activation.scope().map(|s| s.read().globals());
|
let globals = activation.scope().map(|s| s.read().globals());
|
||||||
let appdomain = globals.and_then(|g| g.as_application_domain());
|
let appdomain = globals.and_then(|g| g.as_application_domain());
|
||||||
let appdomain_proto = activation.avm2().prototypes().application_domain;
|
|
||||||
let appdomain_constr = activation.avm2().constructors().application_domain;
|
|
||||||
|
|
||||||
if let Some(appdomain) = appdomain {
|
if let Some(appdomain) = appdomain {
|
||||||
return Ok(DomainObject::from_domain(
|
return Ok(DomainObject::from_domain(activation, appdomain)?.into());
|
||||||
activation.context.gc_context,
|
|
||||||
appdomain_constr,
|
|
||||||
Some(appdomain_proto),
|
|
||||||
appdomain,
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
|
@ -63,16 +55,7 @@ pub fn parent_domain<'gc>(
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
if let Some(appdomain) = this.and_then(|this| this.as_application_domain()) {
|
if let Some(appdomain) = this.and_then(|this| this.as_application_domain()) {
|
||||||
if let Some(parent_domain) = appdomain.parent_domain() {
|
if let Some(parent_domain) = appdomain.parent_domain() {
|
||||||
let appdomain_proto = activation.avm2().prototypes().application_domain;
|
return Ok(DomainObject::from_domain(activation, parent_domain)?.into());
|
||||||
let appdomain_constr = activation.avm2().constructors().application_domain;
|
|
||||||
|
|
||||||
return Ok(DomainObject::from_domain(
|
|
||||||
activation.context.gc_context,
|
|
||||||
appdomain_constr,
|
|
||||||
Some(appdomain_proto),
|
|
||||||
parent_domain,
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,13 @@ pub fn appdomain_deriver<'gc>(
|
||||||
.globals()
|
.globals()
|
||||||
.as_application_domain()
|
.as_application_domain()
|
||||||
.ok_or("Constructor scope must have an appdomain at the bottom of it's scope stack")?;
|
.ok_or("Constructor scope must have an appdomain at the bottom of it's scope stack")?;
|
||||||
|
let base = ScriptObjectData::base_new(Some(proto), ScriptObjectClass::ClassInstance(constr));
|
||||||
|
|
||||||
DomainObject::derive(constr, proto, domain, activation.context.gc_context)
|
Ok(DomainObject(GcCell::allocate(
|
||||||
|
activation.context.gc_context,
|
||||||
|
DomainObjectData { base, domain },
|
||||||
|
))
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Collect, Debug, Copy)]
|
#[derive(Clone, Collect, Debug, Copy)]
|
||||||
|
@ -58,28 +63,53 @@ impl<'gc> DomainObject<'gc> {
|
||||||
DomainObject(GcCell::allocate(mc, DomainObjectData { base, domain })).into()
|
DomainObject(GcCell::allocate(mc, DomainObjectData { base, domain })).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new object for a given domain.
|
||||||
|
///
|
||||||
|
/// This function will call instance initializers. You do not need to do so
|
||||||
|
/// yourself.
|
||||||
pub fn from_domain(
|
pub fn from_domain(
|
||||||
mc: MutationContext<'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
constr: Object<'gc>,
|
|
||||||
base_proto: Option<Object<'gc>>,
|
|
||||||
domain: Domain<'gc>,
|
domain: Domain<'gc>,
|
||||||
) -> Object<'gc> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
let base = ScriptObjectData::base_new(base_proto, ScriptObjectClass::ClassInstance(constr));
|
let constr = activation.avm2().constructors().application_domain;
|
||||||
|
let proto = activation.avm2().prototypes().application_domain;
|
||||||
|
let base =
|
||||||
|
ScriptObjectData::base_new(Some(proto), ScriptObjectClass::ClassInstance(constr));
|
||||||
|
let this = DomainObject(GcCell::allocate(
|
||||||
|
activation.context.gc_context,
|
||||||
|
DomainObjectData { base, domain },
|
||||||
|
))
|
||||||
|
.into();
|
||||||
|
|
||||||
DomainObject(GcCell::allocate(mc, DomainObjectData { base, domain })).into()
|
constr.call_initializer(Some(this), &[], activation, Some(constr))?;
|
||||||
|
|
||||||
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a primitive subclass.
|
/// Create a new object for a given script's global scope.
|
||||||
pub fn derive(
|
///
|
||||||
constr: Object<'gc>,
|
/// The `domain` object will serve as the scope of last resort should the
|
||||||
base_proto: Object<'gc>,
|
/// global scope not have a particular name defined.
|
||||||
|
///
|
||||||
|
/// This function will call instance initializers. You do not need to do so
|
||||||
|
/// yourself.
|
||||||
|
pub fn script_global(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
domain: Domain<'gc>,
|
domain: Domain<'gc>,
|
||||||
mc: MutationContext<'gc, '_>,
|
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
|
let constr = activation.avm2().constructors().global;
|
||||||
|
let proto = activation.avm2().prototypes().global;
|
||||||
let base =
|
let base =
|
||||||
ScriptObjectData::base_new(Some(base_proto), ScriptObjectClass::ClassInstance(constr));
|
ScriptObjectData::base_new(Some(proto), ScriptObjectClass::ClassInstance(constr));
|
||||||
|
let this = DomainObject(GcCell::allocate(
|
||||||
|
activation.context.gc_context,
|
||||||
|
DomainObjectData { base, domain },
|
||||||
|
))
|
||||||
|
.into();
|
||||||
|
|
||||||
Ok(DomainObject(GcCell::allocate(mc, DomainObjectData { base, domain })).into())
|
constr.call_initializer(Some(this), &[], activation, Some(constr))?;
|
||||||
|
|
||||||
|
Ok(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +137,6 @@ impl<'gc> TObject<'gc> for DomainObject<'gc> {
|
||||||
)?
|
)?
|
||||||
.coerce_to_object(activation)?;
|
.coerce_to_object(activation)?;
|
||||||
|
|
||||||
Ok(DomainObject::from_domain(
|
appdomain_deriver(constr, this, activation)
|
||||||
activation.context.gc_context,
|
|
||||||
constr,
|
|
||||||
Some(this),
|
|
||||||
activation.context.avm2.global_domain(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,11 +146,9 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
|
|
||||||
drop(read);
|
drop(read);
|
||||||
|
|
||||||
let global_proto = uc.avm2.prototypes().global;
|
let mut activation = Activation::from_nothing(uc.reborrow());
|
||||||
let global_constr = uc.avm2.constructors().global;
|
let global = DomainObject::script_global(&mut activation, domain)?;
|
||||||
|
drop(activation);
|
||||||
let global =
|
|
||||||
DomainObject::from_domain(uc.gc_context, global_constr, Some(global_proto), domain);
|
|
||||||
|
|
||||||
let mut script = Script::from_abc_index(self, script_index, global, uc.gc_context)?;
|
let mut script = Script::from_abc_index(self, script_index, global, uc.gc_context)?;
|
||||||
self.0
|
self.0
|
||||||
|
|
Loading…
Reference in New Issue