avm2: Intern strings in constant pools
Strings belonging to multinames are interned too, but the multinames themselves aren't.
This commit is contained in:
parent
09c729074c
commit
889a9bd009
|
@ -20,7 +20,7 @@ use crate::avm2::Multiname;
|
||||||
use crate::avm2::Namespace;
|
use crate::avm2::Namespace;
|
||||||
use crate::avm2::QName;
|
use crate::avm2::QName;
|
||||||
use crate::avm2::{value, Avm2, Error};
|
use crate::avm2::{value, Avm2, Error};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::{GcContext, UpdateContext};
|
||||||
use crate::string::AvmString;
|
use crate::string::AvmString;
|
||||||
use crate::swf::extensions::ReadSwfExt;
|
use crate::swf::extensions::ReadSwfExt;
|
||||||
use gc_arena::{Gc, GcCell};
|
use gc_arena::{Gc, GcCell};
|
||||||
|
@ -701,6 +701,11 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
self.context.avm2
|
self.context.avm2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn borrow_gc(&mut self) -> GcContext<'_, 'gc> {
|
||||||
|
self.context.borrow_gc()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the class that defined the currently-executing method, if it
|
/// Get the class that defined the currently-executing method, if it
|
||||||
/// exists.
|
/// exists.
|
||||||
///
|
///
|
||||||
|
@ -815,24 +820,24 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
|
|
||||||
/// Retrieve a string from the current constant pool.
|
/// Retrieve a string from the current constant pool.
|
||||||
fn pool_string<'b>(
|
fn pool_string<'b>(
|
||||||
&self,
|
&mut self,
|
||||||
method: &'b BytecodeMethod<'gc>,
|
method: &'b BytecodeMethod<'gc>,
|
||||||
index: Index<String>,
|
index: Index<String>,
|
||||||
) -> Result<AvmString<'gc>, Error<'gc>> {
|
) -> Result<AvmString<'gc>, Error<'gc>> {
|
||||||
method
|
method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_string(index.0, self.context.gc_context)
|
.pool_string(index.0, &mut self.borrow_gc())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a namespace from the current constant pool.
|
/// Retrieve a namespace from the current constant pool.
|
||||||
fn pool_namespace(
|
fn pool_namespace(
|
||||||
&self,
|
&mut self,
|
||||||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||||
index: Index<AbcNamespace>,
|
index: Index<AbcNamespace>,
|
||||||
) -> Result<Namespace<'gc>, Error<'gc>> {
|
) -> Result<Namespace<'gc>, Error<'gc>> {
|
||||||
method
|
method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_namespace(index, self.context.gc_context)
|
.pool_namespace(index, &mut self.borrow_gc())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a multiname from the current constant pool.
|
/// Retrieve a multiname from the current constant pool.
|
||||||
|
@ -843,7 +848,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
method
|
method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_maybe_uninitialized_multiname(index, self.context.gc_context)
|
.pool_maybe_uninitialized_multiname(index, &mut self.borrow_gc())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a multiname from the current constant pool.
|
/// Retrieve a multiname from the current constant pool.
|
||||||
|
@ -855,7 +860,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
let name = method
|
let name = method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_maybe_uninitialized_multiname(index, self.context.gc_context)?;
|
.pool_maybe_uninitialized_multiname(index, &mut self.borrow_gc())?;
|
||||||
if name.has_lazy_component() {
|
if name.has_lazy_component() {
|
||||||
let name = name.fill_with_runtime_params(self)?;
|
let name = name.fill_with_runtime_params(self)?;
|
||||||
Ok(Gc::allocate(self.context.gc_context, name))
|
Ok(Gc::allocate(self.context.gc_context, name))
|
||||||
|
@ -875,7 +880,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
method
|
method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_multiname_static(index, self.context.gc_context)
|
.pool_multiname_static(index, &mut self.borrow_gc())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a static, or non-runtime, multiname from the current constant
|
/// Retrieve a static, or non-runtime, multiname from the current constant
|
||||||
|
@ -889,7 +894,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
method
|
method
|
||||||
.translation_unit()
|
.translation_unit()
|
||||||
.pool_multiname_static_any(index, self.context.gc_context)
|
.pool_multiname_static_any(index, &mut self.borrow_gc())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a method entry from the current ABC file's method table.
|
/// Retrieve a method entry from the current ABC file's method table.
|
||||||
|
@ -1275,7 +1280,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||||
value: Index<String>,
|
value: Index<String>,
|
||||||
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||||
self.push_stack(self.pool_string(&method, value)?);
|
let s = self.pool_string(&method, value)?;
|
||||||
|
self.push_stack(s);
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1739,7 +1745,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
let qname = QName::from_abc_multiname(
|
let qname = QName::from_abc_multiname(
|
||||||
method.translation_unit(),
|
method.translation_unit(),
|
||||||
vname,
|
vname,
|
||||||
self.context.gc_context,
|
&mut self.borrow_gc(),
|
||||||
)?;
|
)?;
|
||||||
ScriptObject::catch_scope(self.context.gc_context, &qname)
|
ScriptObject::catch_scope(self.context.gc_context, &qname)
|
||||||
};
|
};
|
||||||
|
|
|
@ -272,20 +272,20 @@ impl<'gc> Class<'gc> {
|
||||||
.ok_or_else(|| "LoadError: Instance index not valid".into());
|
.ok_or_else(|| "LoadError: Instance index not valid".into());
|
||||||
let abc_instance = abc_instance?;
|
let abc_instance = abc_instance?;
|
||||||
|
|
||||||
let name =
|
let mut context = activation.borrow_gc();
|
||||||
QName::from_abc_multiname(unit, abc_instance.name, activation.context.gc_context)?;
|
let name = QName::from_abc_multiname(unit, abc_instance.name, &mut context)?;
|
||||||
let super_class = if abc_instance.super_name.0 == 0 {
|
let super_class = if abc_instance.super_name.0 == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Some(
|
||||||
unit.pool_multiname_static(abc_instance.super_name, activation.context.gc_context)?
|
unit.pool_multiname_static(abc_instance.super_name, &mut context)?
|
||||||
.deref()
|
.deref()
|
||||||
.clone(),
|
.clone(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let protected_namespace = if let Some(ns) = &abc_instance.protected_namespace {
|
let protected_namespace = if let Some(ns) = &abc_instance.protected_namespace {
|
||||||
Some(unit.pool_namespace(*ns, activation.context.gc_context)?)
|
Some(unit.pool_namespace(*ns, &mut context)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -293,7 +293,7 @@ impl<'gc> Class<'gc> {
|
||||||
let mut interfaces = Vec::with_capacity(abc_instance.interfaces.len());
|
let mut interfaces = Vec::with_capacity(abc_instance.interfaces.len());
|
||||||
for interface_name in &abc_instance.interfaces {
|
for interface_name in &abc_instance.interfaces {
|
||||||
interfaces.push(
|
interfaces.push(
|
||||||
unit.pool_multiname_static(*interface_name, activation.context.gc_context)?
|
unit.pool_multiname_static(*interface_name, &mut context)?
|
||||||
.deref()
|
.deref()
|
||||||
.clone(),
|
.clone(),
|
||||||
);
|
);
|
||||||
|
@ -495,7 +495,7 @@ impl<'gc> Class<'gc> {
|
||||||
body: &AbcMethodBody,
|
body: &AbcMethodBody,
|
||||||
) -> Result<GcCell<'gc, Self>, Error<'gc>> {
|
) -> Result<GcCell<'gc, Self>, Error<'gc>> {
|
||||||
let name =
|
let name =
|
||||||
translation_unit.pool_string(method.name.as_u30(), activation.context.gc_context)?;
|
translation_unit.pool_string(method.name.as_u30(), &mut activation.borrow_gc())?;
|
||||||
let mut traits = Vec::with_capacity(body.traits.len());
|
let mut traits = Vec::with_capacity(body.traits.len());
|
||||||
|
|
||||||
for trait_entry in body.traits.iter() {
|
for trait_entry in body.traits.iter() {
|
||||||
|
|
|
@ -57,12 +57,12 @@ impl<'gc> ParamConfig<'gc> {
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
) -> Result<Self, Error<'gc>> {
|
) -> Result<Self, Error<'gc>> {
|
||||||
let param_name = if let Some(name) = &config.name {
|
let param_name = if let Some(name) = &config.name {
|
||||||
txunit.pool_string(name.0, activation.context.gc_context)?
|
txunit.pool_string(name.0, &mut activation.borrow_gc())?
|
||||||
} else {
|
} else {
|
||||||
"<Unnamed Parameter>".into()
|
"<Unnamed Parameter>".into()
|
||||||
};
|
};
|
||||||
let param_type_name = txunit
|
let param_type_name = txunit
|
||||||
.pool_multiname_static_any(config.kind, activation.context.gc_context)?
|
.pool_multiname_static_any(config.kind, &mut activation.borrow_gc())?
|
||||||
.deref()
|
.deref()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ impl<'gc> BytecodeMethod<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let return_type = txunit
|
let return_type = txunit
|
||||||
.pool_multiname_static_any(method.return_type, activation.context.gc_context)?
|
.pool_multiname_static_any(method.return_type, &mut activation.borrow_gc())?
|
||||||
.deref()
|
.deref()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::avm2::Error;
|
||||||
use crate::avm2::Namespace;
|
use crate::avm2::Namespace;
|
||||||
use crate::avm2::QName;
|
use crate::avm2::QName;
|
||||||
use crate::avm2::{Object, Value};
|
use crate::avm2::{Object, Value};
|
||||||
|
use crate::context::GcContext;
|
||||||
use crate::string::{AvmString, WStr, WString};
|
use crate::string::{AvmString, WStr, WString};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use gc_arena::Gc;
|
use gc_arena::Gc;
|
||||||
|
@ -113,7 +114,7 @@ impl<'gc> Multiname<'gc> {
|
||||||
fn abc_namespace_set(
|
fn abc_namespace_set(
|
||||||
translation_unit: TranslationUnit<'gc>,
|
translation_unit: TranslationUnit<'gc>,
|
||||||
namespace_set_index: Index<AbcNamespaceSet>,
|
namespace_set_index: Index<AbcNamespaceSet>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<NamespaceSet<'gc>, Error<'gc>> {
|
) -> Result<NamespaceSet<'gc>, Error<'gc>> {
|
||||||
if namespace_set_index.0 == 0 {
|
if namespace_set_index.0 == 0 {
|
||||||
return Err(Error::RustError(
|
return Err(Error::RustError(
|
||||||
|
@ -134,37 +135,38 @@ impl<'gc> Multiname<'gc> {
|
||||||
|
|
||||||
if ns_set.len() == 1 {
|
if ns_set.len() == 1 {
|
||||||
Ok(NamespaceSet::single(
|
Ok(NamespaceSet::single(
|
||||||
translation_unit.pool_namespace(ns_set[0], mc)?,
|
translation_unit.pool_namespace(ns_set[0], context)?,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let mut result = Vec::with_capacity(ns_set.len());
|
let mut result = Vec::with_capacity(ns_set.len());
|
||||||
for ns in ns_set {
|
for ns in ns_set {
|
||||||
result.push(translation_unit.pool_namespace(*ns, mc)?)
|
result.push(translation_unit.pool_namespace(*ns, context)?)
|
||||||
}
|
}
|
||||||
Ok(NamespaceSet::multiple(result, mc))
|
Ok(NamespaceSet::multiple(result, context.gc_context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_abc_index(
|
pub fn from_abc_index(
|
||||||
translation_unit: TranslationUnit<'gc>,
|
translation_unit: TranslationUnit<'gc>,
|
||||||
multiname_index: Index<AbcMultiname>,
|
multiname_index: Index<AbcMultiname>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Self, Error<'gc>> {
|
) -> Result<Self, Error<'gc>> {
|
||||||
|
let mc = context.gc_context;
|
||||||
let abc = translation_unit.abc();
|
let abc = translation_unit.abc();
|
||||||
let abc_multiname = Self::resolve_multiname_index(&abc, multiname_index)?;
|
let abc_multiname = Self::resolve_multiname_index(&abc, multiname_index)?;
|
||||||
|
|
||||||
let mut multiname = match abc_multiname {
|
let mut multiname = match abc_multiname {
|
||||||
AbcMultiname::QName { namespace, name } | AbcMultiname::QNameA { namespace, name } => {
|
AbcMultiname::QName { namespace, name } | AbcMultiname::QNameA { namespace, name } => {
|
||||||
Self {
|
Self {
|
||||||
ns: NamespaceSet::single(translation_unit.pool_namespace(*namespace, mc)?),
|
ns: NamespaceSet::single(translation_unit.pool_namespace(*namespace, context)?),
|
||||||
name: translation_unit.pool_string_option(name.0, mc)?,
|
name: translation_unit.pool_string_option(name.0, context)?,
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AbcMultiname::RTQName { name } | AbcMultiname::RTQNameA { name } => Self {
|
AbcMultiname::RTQName { name } | AbcMultiname::RTQNameA { name } => Self {
|
||||||
ns: NamespaceSet::multiple(vec![], mc),
|
ns: NamespaceSet::multiple(vec![], mc),
|
||||||
name: translation_unit.pool_string_option(name.0, mc)?,
|
name: translation_unit.pool_string_option(name.0, context)?,
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
flags: MultinameFlags::HAS_LAZY_NS,
|
flags: MultinameFlags::HAS_LAZY_NS,
|
||||||
},
|
},
|
||||||
|
@ -182,14 +184,14 @@ impl<'gc> Multiname<'gc> {
|
||||||
namespace_set,
|
namespace_set,
|
||||||
name,
|
name,
|
||||||
} => Self {
|
} => Self {
|
||||||
ns: Self::abc_namespace_set(translation_unit, *namespace_set, mc)?,
|
ns: Self::abc_namespace_set(translation_unit, *namespace_set, context)?,
|
||||||
name: translation_unit.pool_string_option(name.0, mc)?,
|
name: translation_unit.pool_string_option(name.0, context)?,
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
},
|
},
|
||||||
AbcMultiname::MultinameL { namespace_set }
|
AbcMultiname::MultinameL { namespace_set }
|
||||||
| AbcMultiname::MultinameLA { namespace_set } => Self {
|
| AbcMultiname::MultinameLA { namespace_set } => Self {
|
||||||
ns: Self::abc_namespace_set(translation_unit, *namespace_set, mc)?,
|
ns: Self::abc_namespace_set(translation_unit, *namespace_set, context)?,
|
||||||
name: None,
|
name: None,
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
flags: MultinameFlags::HAS_LAZY_NAME,
|
flags: MultinameFlags::HAS_LAZY_NAME,
|
||||||
|
@ -199,7 +201,7 @@ impl<'gc> Multiname<'gc> {
|
||||||
parameters,
|
parameters,
|
||||||
} => {
|
} => {
|
||||||
let mut base = translation_unit
|
let mut base = translation_unit
|
||||||
.pool_multiname_static(*base_type, mc)?
|
.pool_multiname_static(*base_type, context)?
|
||||||
.deref()
|
.deref()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
@ -213,7 +215,7 @@ impl<'gc> Multiname<'gc> {
|
||||||
|
|
||||||
for param_type in parameters {
|
for param_type in parameters {
|
||||||
let param_multiname =
|
let param_multiname =
|
||||||
translation_unit.pool_multiname_static_any(*param_type, mc)?;
|
translation_unit.pool_multiname_static_any(*param_type, context)?;
|
||||||
|
|
||||||
base.params.push(param_multiname);
|
base.params.push(param_multiname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::avm2::script::TranslationUnit;
|
|
||||||
use crate::avm2::Error;
|
use crate::avm2::Error;
|
||||||
use crate::string::AvmString;
|
use crate::string::AvmString;
|
||||||
|
use crate::{avm2::script::TranslationUnit, context::GcContext};
|
||||||
use gc_arena::{Collect, Gc, MutationContext};
|
use gc_arena::{Collect, Gc, MutationContext};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use swf::avm2::types::{Index, Namespace as AbcNamespace};
|
use swf::avm2::types::{Index, Namespace as AbcNamespace};
|
||||||
|
@ -46,10 +46,10 @@ impl<'gc> Namespace<'gc> {
|
||||||
pub fn from_abc_namespace(
|
pub fn from_abc_namespace(
|
||||||
translation_unit: TranslationUnit<'gc>,
|
translation_unit: TranslationUnit<'gc>,
|
||||||
namespace_index: Index<AbcNamespace>,
|
namespace_index: Index<AbcNamespace>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Self, Error<'gc>> {
|
) -> Result<Self, Error<'gc>> {
|
||||||
if namespace_index.0 == 0 {
|
if namespace_index.0 == 0 {
|
||||||
return Ok(Self::any(mc));
|
return Ok(Self::any(context.gc_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
let actual_index = namespace_index.0 as usize - 1;
|
let actual_index = namespace_index.0 as usize - 1;
|
||||||
|
@ -62,28 +62,28 @@ impl<'gc> Namespace<'gc> {
|
||||||
|
|
||||||
let ns = match abc_namespace? {
|
let ns = match abc_namespace? {
|
||||||
AbcNamespace::Namespace(idx) => {
|
AbcNamespace::Namespace(idx) => {
|
||||||
NamespaceData::Namespace(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::Namespace(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::Package(idx) => {
|
AbcNamespace::Package(idx) => {
|
||||||
NamespaceData::Namespace(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::Namespace(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::PackageInternal(idx) => {
|
AbcNamespace::PackageInternal(idx) => {
|
||||||
NamespaceData::PackageInternal(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::PackageInternal(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::Protected(idx) => {
|
AbcNamespace::Protected(idx) => {
|
||||||
NamespaceData::Protected(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::Protected(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::Explicit(idx) => {
|
AbcNamespace::Explicit(idx) => {
|
||||||
NamespaceData::Explicit(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::Explicit(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::StaticProtected(idx) => {
|
AbcNamespace::StaticProtected(idx) => {
|
||||||
NamespaceData::StaticProtected(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::StaticProtected(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
AbcNamespace::Private(idx) => {
|
AbcNamespace::Private(idx) => {
|
||||||
NamespaceData::Private(translation_unit.pool_string(idx.0, mc)?)
|
NamespaceData::Private(translation_unit.pool_string(idx.0, context)?)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Self(Gc::allocate(mc, ns)))
|
Ok(Self(Gc::allocate(context.gc_context, ns)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any(mc: MutationContext<'gc, '_>) -> Self {
|
pub fn any(mc: MutationContext<'gc, '_>) -> Self {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::avm2::script::TranslationUnit;
|
||||||
use crate::avm2::Activation;
|
use crate::avm2::Activation;
|
||||||
use crate::avm2::Error;
|
use crate::avm2::Error;
|
||||||
use crate::avm2::{Namespace, NamespaceData};
|
use crate::avm2::{Namespace, NamespaceData};
|
||||||
|
use crate::context::GcContext;
|
||||||
use crate::either::Either;
|
use crate::either::Either;
|
||||||
use crate::string::{AvmString, WStr, WString};
|
use crate::string::{AvmString, WStr, WString};
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
|
@ -48,7 +49,7 @@ impl<'gc> QName<'gc> {
|
||||||
pub fn from_abc_multiname(
|
pub fn from_abc_multiname(
|
||||||
translation_unit: TranslationUnit<'gc>,
|
translation_unit: TranslationUnit<'gc>,
|
||||||
multiname_index: Index<AbcMultiname>,
|
multiname_index: Index<AbcMultiname>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Self, Error<'gc>> {
|
) -> Result<Self, Error<'gc>> {
|
||||||
if multiname_index.0 == 0 {
|
if multiname_index.0 == 0 {
|
||||||
return Err("Attempted to load a trait name of index zero".into());
|
return Err("Attempted to load a trait name of index zero".into());
|
||||||
|
@ -64,8 +65,8 @@ impl<'gc> QName<'gc> {
|
||||||
|
|
||||||
Ok(match abc_multiname? {
|
Ok(match abc_multiname? {
|
||||||
AbcMultiname::QName { namespace, name } => Self {
|
AbcMultiname::QName { namespace, name } => Self {
|
||||||
ns: translation_unit.pool_namespace(*namespace, mc)?,
|
ns: translation_unit.pool_namespace(*namespace, context)?,
|
||||||
name: translation_unit.pool_string(name.0, mc)?,
|
name: translation_unit.pool_string(name.0, context)?,
|
||||||
},
|
},
|
||||||
_ => return Err("Attempted to pull QName from non-QName multiname".into()),
|
_ => return Err("Attempted to pull QName from non-QName multiname".into()),
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::value::Value;
|
||||||
use crate::avm2::Multiname;
|
use crate::avm2::Multiname;
|
||||||
use crate::avm2::Namespace;
|
use crate::avm2::Namespace;
|
||||||
use crate::avm2::{Avm2, Error};
|
use crate::avm2::{Avm2, Error};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::{GcContext, UpdateContext};
|
||||||
use crate::string::AvmString;
|
use crate::string::AvmString;
|
||||||
use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
|
@ -231,9 +231,9 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_string_option(
|
pub fn pool_string_option(
|
||||||
self,
|
self,
|
||||||
string_index: u32,
|
string_index: u32,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Option<AvmString<'gc>>, Error<'gc>> {
|
) -> Result<Option<AvmString<'gc>>, Error<'gc>> {
|
||||||
let mut write = self.0.write(mc);
|
let mut write = self.0.write(context.gc_context);
|
||||||
if let Some(Some(string)) = write.strings.get(string_index as usize) {
|
if let Some(Some(string)) = write.strings.get(string_index as usize) {
|
||||||
return Ok(Some(*string));
|
return Ok(Some(*string));
|
||||||
}
|
}
|
||||||
|
@ -242,17 +242,18 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let avm_string = AvmString::new_utf8(
|
let raw = write
|
||||||
mc,
|
.abc
|
||||||
write
|
.constant_pool
|
||||||
.abc
|
.strings
|
||||||
.constant_pool
|
.get(string_index as usize - 1)
|
||||||
.strings
|
.ok_or_else(|| format!("Unknown string constant {string_index}"))?;
|
||||||
.get(string_index as usize - 1)
|
|
||||||
.ok_or_else(|| format!("Unknown string constant {string_index}"))?,
|
|
||||||
);
|
|
||||||
write.strings[string_index as usize] = Some(avm_string);
|
|
||||||
|
|
||||||
|
let avm_string = context
|
||||||
|
.interner
|
||||||
|
.intern_wstr(context.gc_context, ruffle_wstr::from_utf8(raw));
|
||||||
|
|
||||||
|
write.strings[string_index as usize] = Some(avm_string);
|
||||||
Ok(Some(avm_string))
|
Ok(Some(avm_string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,11 +266,11 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_string(
|
pub fn pool_string(
|
||||||
self,
|
self,
|
||||||
string_index: u32,
|
string_index: u32,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<AvmString<'gc>, Error<'gc>> {
|
) -> Result<AvmString<'gc>, Error<'gc>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.pool_string_option(string_index, mc)?
|
.pool_string_option(string_index, context)?
|
||||||
.unwrap_or_default())
|
.unwrap_or_else(AvmString::default))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a static, or non-runtime, multiname from the current constant
|
/// Retrieve a static, or non-runtime, multiname from the current constant
|
||||||
|
@ -279,7 +280,7 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_namespace(
|
pub fn pool_namespace(
|
||||||
self,
|
self,
|
||||||
ns_index: Index<AbcNamespace>,
|
ns_index: Index<AbcNamespace>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Namespace<'gc>, Error<'gc>> {
|
) -> Result<Namespace<'gc>, Error<'gc>> {
|
||||||
let read = self.0.read();
|
let read = self.0.read();
|
||||||
if let Some(Some(namespace)) = read.namespaces.get(ns_index.0 as usize) {
|
if let Some(Some(namespace)) = read.namespaces.get(ns_index.0 as usize) {
|
||||||
|
@ -288,8 +289,8 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
|
|
||||||
drop(read);
|
drop(read);
|
||||||
|
|
||||||
let namespace = Namespace::from_abc_namespace(self, ns_index, mc)?;
|
let namespace = Namespace::from_abc_namespace(self, ns_index, context)?;
|
||||||
self.0.write(mc).namespaces[ns_index.0 as usize] = Some(namespace);
|
self.0.write(context.gc_context).namespaces[ns_index.0 as usize] = Some(namespace);
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
|
@ -299,8 +300,9 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_maybe_uninitialized_multiname(
|
pub fn pool_maybe_uninitialized_multiname(
|
||||||
self,
|
self,
|
||||||
multiname_index: Index<AbcMultiname>,
|
multiname_index: Index<AbcMultiname>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
|
let mc = context.gc_context;
|
||||||
let read = self.0.read();
|
let read = self.0.read();
|
||||||
if let Some(Some(multiname)) = read.multinames.get(multiname_index.0 as usize) {
|
if let Some(Some(multiname)) = read.multinames.get(multiname_index.0 as usize) {
|
||||||
return Ok(*multiname);
|
return Ok(*multiname);
|
||||||
|
@ -308,7 +310,7 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
|
|
||||||
drop(read);
|
drop(read);
|
||||||
|
|
||||||
let multiname = Multiname::from_abc_index(self, multiname_index, mc)?;
|
let multiname = Multiname::from_abc_index(self, multiname_index, context)?;
|
||||||
let multiname = Gc::allocate(mc, multiname);
|
let multiname = Gc::allocate(mc, multiname);
|
||||||
self.0.write(mc).multinames[multiname_index.0 as usize] = Some(multiname);
|
self.0.write(mc).multinames[multiname_index.0 as usize] = Some(multiname);
|
||||||
|
|
||||||
|
@ -322,9 +324,9 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_multiname_static(
|
pub fn pool_multiname_static(
|
||||||
self,
|
self,
|
||||||
multiname_index: Index<AbcMultiname>,
|
multiname_index: Index<AbcMultiname>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
let multiname = self.pool_maybe_uninitialized_multiname(multiname_index, mc)?;
|
let multiname = self.pool_maybe_uninitialized_multiname(multiname_index, context)?;
|
||||||
if multiname.has_lazy_component() {
|
if multiname.has_lazy_component() {
|
||||||
return Err(format!("Multiname {} is not static", multiname_index.0).into());
|
return Err(format!("Multiname {} is not static", multiname_index.0).into());
|
||||||
}
|
}
|
||||||
|
@ -339,12 +341,13 @@ impl<'gc> TranslationUnit<'gc> {
|
||||||
pub fn pool_multiname_static_any(
|
pub fn pool_multiname_static_any(
|
||||||
self,
|
self,
|
||||||
multiname_index: Index<AbcMultiname>,
|
multiname_index: Index<AbcMultiname>,
|
||||||
mc: MutationContext<'gc, '_>,
|
context: &mut GcContext<'_, 'gc>,
|
||||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||||
if multiname_index.0 == 0 {
|
if multiname_index.0 == 0 {
|
||||||
|
let mc = context.gc_context;
|
||||||
Ok(Gc::allocate(mc, Multiname::any(mc)))
|
Ok(Gc::allocate(mc, Multiname::any(mc)))
|
||||||
} else {
|
} else {
|
||||||
self.pool_multiname_static(multiname_index, mc)
|
self.pool_multiname_static(multiname_index, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,8 +191,7 @@ impl<'gc> Trait<'gc> {
|
||||||
abc_trait: &AbcTrait,
|
abc_trait: &AbcTrait,
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
) -> Result<Self, Error<'gc>> {
|
) -> Result<Self, Error<'gc>> {
|
||||||
let mc = activation.context.gc_context;
|
let name = QName::from_abc_multiname(unit, abc_trait.name, &mut activation.borrow_gc())?;
|
||||||
let name = QName::from_abc_multiname(unit, abc_trait.name, mc)?;
|
|
||||||
|
|
||||||
Ok(match &abc_trait.kind {
|
Ok(match &abc_trait.kind {
|
||||||
AbcTraitKind::Slot {
|
AbcTraitKind::Slot {
|
||||||
|
@ -201,7 +200,7 @@ impl<'gc> Trait<'gc> {
|
||||||
value,
|
value,
|
||||||
} => {
|
} => {
|
||||||
let type_name = unit
|
let type_name = unit
|
||||||
.pool_multiname_static_any(*type_name, mc)?
|
.pool_multiname_static_any(*type_name, &mut activation.borrow_gc())?
|
||||||
.deref()
|
.deref()
|
||||||
.clone();
|
.clone();
|
||||||
let default_value = slot_default_value(unit, value, &type_name, activation)?;
|
let default_value = slot_default_value(unit, value, &type_name, activation)?;
|
||||||
|
@ -262,7 +261,7 @@ impl<'gc> Trait<'gc> {
|
||||||
value,
|
value,
|
||||||
} => {
|
} => {
|
||||||
let type_name = unit
|
let type_name = unit
|
||||||
.pool_multiname_static_any(*type_name, mc)?
|
.pool_multiname_static_any(*type_name, &mut activation.borrow_gc())?
|
||||||
.deref()
|
.deref()
|
||||||
.clone();
|
.clone();
|
||||||
let default_value = slot_default_value(unit, value, &type_name, activation)?;
|
let default_value = slot_default_value(unit, value, &type_name, activation)?;
|
||||||
|
|
|
@ -516,8 +516,8 @@ pub fn abc_default_value<'gc>(
|
||||||
AbcDefaultValue::Uint(u) => abc_uint(translation_unit, *u).map(|v| v.into()),
|
AbcDefaultValue::Uint(u) => abc_uint(translation_unit, *u).map(|v| v.into()),
|
||||||
AbcDefaultValue::Double(d) => abc_double(translation_unit, *d).map(|v| v.into()),
|
AbcDefaultValue::Double(d) => abc_double(translation_unit, *d).map(|v| v.into()),
|
||||||
AbcDefaultValue::String(s) => translation_unit
|
AbcDefaultValue::String(s) => translation_unit
|
||||||
.pool_string(s.0, activation.context.gc_context)
|
.pool_string(s.0, &mut activation.borrow_gc())
|
||||||
.map(|v| v.into()),
|
.map(Into::into),
|
||||||
AbcDefaultValue::True => Ok(true.into()),
|
AbcDefaultValue::True => Ok(true.into()),
|
||||||
AbcDefaultValue::False => Ok(false.into()),
|
AbcDefaultValue::False => Ok(false.into()),
|
||||||
AbcDefaultValue::Null => Ok(Value::Null),
|
AbcDefaultValue::Null => Ok(Value::Null),
|
||||||
|
@ -528,11 +528,10 @@ pub fn abc_default_value<'gc>(
|
||||||
| AbcDefaultValue::Protected(ns)
|
| AbcDefaultValue::Protected(ns)
|
||||||
| AbcDefaultValue::Explicit(ns)
|
| AbcDefaultValue::Explicit(ns)
|
||||||
| AbcDefaultValue::StaticProtected(ns)
|
| AbcDefaultValue::StaticProtected(ns)
|
||||||
| AbcDefaultValue::Private(ns) => Ok(NamespaceObject::from_namespace(
|
| AbcDefaultValue::Private(ns) => {
|
||||||
activation,
|
let ns = translation_unit.pool_namespace(*ns, &mut activation.borrow_gc())?;
|
||||||
translation_unit.pool_namespace(*ns, activation.context.gc_context)?,
|
NamespaceObject::from_namespace(activation, ns).map(Into::into)
|
||||||
)?
|
}
|
||||||
.into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue