avm2: make Namespace a GC type
This commit is contained in:
parent
4e0dce2efa
commit
e0e653e463
|
@ -56,7 +56,7 @@ pub use crate::avm2::domain::Domain;
|
|||
pub use crate::avm2::error::Error;
|
||||
pub use crate::avm2::globals::flash::ui::context_menu::make_context_menu_state;
|
||||
pub use crate::avm2::multiname::Multiname;
|
||||
pub use crate::avm2::namespace::Namespace;
|
||||
pub use crate::avm2::namespace::{Namespace, NamespaceData};
|
||||
pub use crate::avm2::object::{
|
||||
ArrayObject, ClassObject, EventObject, Object, ScriptObject, SoundChannelObject, StageObject,
|
||||
TObject,
|
||||
|
@ -87,6 +87,13 @@ pub struct Avm2<'gc> {
|
|||
/// System classes.
|
||||
system_classes: Option<SystemClasses<'gc>>,
|
||||
|
||||
pub public_namespace: Namespace<'gc>,
|
||||
pub as3_namespace: Namespace<'gc>,
|
||||
pub vector_public_namespace: Namespace<'gc>,
|
||||
pub vector_internal_namespace: Namespace<'gc>,
|
||||
pub proxy_namespace: Namespace<'gc>,
|
||||
pub ruffle_private_namespace: Namespace<'gc>,
|
||||
|
||||
#[collect(require_static)]
|
||||
native_method_table: &'static [Option<(&'static str, NativeMethodImpl)>],
|
||||
|
||||
|
@ -121,6 +128,17 @@ impl<'gc> Avm2<'gc> {
|
|||
call_stack: GcCell::allocate(mc, CallStack::new()),
|
||||
globals,
|
||||
system_classes: None,
|
||||
|
||||
public_namespace: Namespace::package("", mc),
|
||||
as3_namespace: Namespace::package("http://adobe.com/AS3/2006/builtin", mc),
|
||||
vector_public_namespace: Namespace::package("__AS3__.vec", mc),
|
||||
vector_internal_namespace: Namespace::internal("__AS3__.vec", mc),
|
||||
proxy_namespace: Namespace::package(
|
||||
"http://www.adobe.com/2006/actionscript/flash/proxy",
|
||||
mc,
|
||||
),
|
||||
ruffle_private_namespace: Namespace::private("", mc),
|
||||
|
||||
native_method_table: Default::default(),
|
||||
native_instance_allocator_table: Default::default(),
|
||||
native_instance_init_table: Default::default(),
|
||||
|
|
|
@ -492,18 +492,14 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
unreachable!();
|
||||
};
|
||||
|
||||
let mut args_object = ArrayObject::from_storage(&mut activation, args_array)?;
|
||||
let args_object = ArrayObject::from_storage(&mut activation, args_array)?;
|
||||
|
||||
if method
|
||||
.method()
|
||||
.flags
|
||||
.contains(AbcMethodFlags::NEED_ARGUMENTS)
|
||||
{
|
||||
args_object.set_property(
|
||||
&Multiname::public("callee"),
|
||||
callee.into(),
|
||||
&mut activation,
|
||||
)?;
|
||||
args_object.set_string_property_local("callee", callee.into(), &mut activation)?;
|
||||
}
|
||||
|
||||
*activation
|
||||
|
@ -647,11 +643,6 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
self.context.avm2
|
||||
}
|
||||
|
||||
/// Set the return value.
|
||||
pub fn set_return_value(&mut self, value: Value<'gc>) {
|
||||
self.return_value = Some(value);
|
||||
}
|
||||
|
||||
/// Get the class that defined the currently-executing method, if it
|
||||
/// exists.
|
||||
///
|
||||
|
@ -781,7 +772,9 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||
index: Index<AbcNamespace>,
|
||||
) -> Result<Namespace<'gc>, Error<'gc>> {
|
||||
Namespace::from_abc_namespace(method.translation_unit(), index, self.context.gc_context)
|
||||
method
|
||||
.translation_unit()
|
||||
.pool_namespace(index, self.context.gc_context)
|
||||
}
|
||||
|
||||
/// Retrieve a multiname from the current constant pool.
|
||||
|
@ -1667,7 +1660,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
}
|
||||
|
||||
let name = name_value.coerce_to_string(self)?;
|
||||
let multiname = Multiname::public(name);
|
||||
let multiname = Multiname::new(self.avm2().public_namespace, name);
|
||||
let has_prop = obj.has_property_via_in(self, &multiname)?;
|
||||
|
||||
self.push_stack(has_prop);
|
||||
|
@ -1897,11 +1890,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
let value = self.pop_stack();
|
||||
let name = self.pop_stack();
|
||||
|
||||
object.set_property(
|
||||
&Multiname::public(name.coerce_to_string(self)?),
|
||||
value,
|
||||
self,
|
||||
)?;
|
||||
object.set_public_property(name.coerce_to_string(self)?, value, self)?;
|
||||
}
|
||||
|
||||
self.push_stack(object);
|
||||
|
|
|
@ -2,7 +2,6 @@ use crate::avm2::bytearray::ByteArrayStorage;
|
|||
use crate::avm2::object::{ByteArrayObject, TObject};
|
||||
use crate::avm2::ArrayObject;
|
||||
use crate::avm2::ArrayStorage;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::{Activation, Error, Object, Value};
|
||||
use crate::string::AvmString;
|
||||
use enumset::EnumSet;
|
||||
|
@ -101,7 +100,7 @@ pub fn recursive_serialize<'gc>(
|
|||
let name = obj
|
||||
.get_enumerant_name(index, activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
let value = obj.get_property(&Multiname::public(name), activation)?;
|
||||
let value = obj.get_public_property(name, activation)?;
|
||||
|
||||
if let Some(value) = serialize_value(activation, value, amf_version) {
|
||||
elements.push(Element::new(name.to_utf8_lossy(), value));
|
||||
|
@ -138,11 +137,8 @@ pub fn deserialize_value<'gc>(
|
|||
let mut array = ArrayObject::from_storage(activation, storage)?;
|
||||
// Now let's add each element as a property
|
||||
for element in elements {
|
||||
array.set_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
element.name(),
|
||||
)),
|
||||
array.set_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, element.name()),
|
||||
deserialize_value(activation, element.value())?,
|
||||
activation,
|
||||
)?;
|
||||
|
@ -172,11 +168,8 @@ pub fn deserialize_value<'gc>(
|
|||
.construct(activation, &[])?;
|
||||
for entry in elements {
|
||||
let value = deserialize_value(activation, entry.value())?;
|
||||
obj.set_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
entry.name(),
|
||||
)),
|
||||
obj.set_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, entry.name()),
|
||||
value,
|
||||
activation,
|
||||
)?;
|
||||
|
@ -227,11 +220,8 @@ pub fn deserialize_lso<'gc>(
|
|||
.construct(activation, &[])?;
|
||||
|
||||
for child in &lso.body {
|
||||
obj.set_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
&child.name,
|
||||
)),
|
||||
obj.set_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, &child.name),
|
||||
deserialize_value(activation, child.value())?,
|
||||
activation,
|
||||
)?;
|
||||
|
|
|
@ -260,11 +260,7 @@ impl<'gc> Class<'gc> {
|
|||
};
|
||||
|
||||
let protected_namespace = if let Some(ns) = &abc_instance.protected_namespace {
|
||||
Some(Namespace::from_abc_namespace(
|
||||
unit,
|
||||
*ns,
|
||||
activation.context.gc_context,
|
||||
)?)
|
||||
Some(unit.pool_namespace(*ns, activation.context.gc_context)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -472,7 +468,7 @@ impl<'gc> Class<'gc> {
|
|||
Ok(GcCell::allocate(
|
||||
activation.context.gc_context,
|
||||
Self {
|
||||
name: QName::dynamic_name(name),
|
||||
name: QName::new(activation.avm2().public_namespace, name),
|
||||
params: Vec::new(),
|
||||
super_class: None,
|
||||
attributes: ClassAttributes::empty(),
|
||||
|
@ -526,52 +522,55 @@ impl<'gc> Class<'gc> {
|
|||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn define_public_constant_string_class_traits(
|
||||
pub fn define_constant_number_class_traits(
|
||||
&mut self,
|
||||
items: &[(&'static str, &'static str)],
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, f64)],
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_const(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::public("String"),
|
||||
QName::new(namespace, name),
|
||||
Multiname::new(activation.avm2().public_namespace, "Number"),
|
||||
Some(value.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_constant_number_class_traits(&mut self, items: &[(&'static str, f64)]) {
|
||||
pub fn define_constant_uint_class_traits(
|
||||
&mut self,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, u32)],
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_const(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::public("Number"),
|
||||
QName::new(namespace, name),
|
||||
Multiname::new(activation.avm2().public_namespace, "uint"),
|
||||
Some(value.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_constant_uint_class_traits(&mut self, items: &[(&'static str, u32)]) {
|
||||
pub fn define_constant_int_class_traits(
|
||||
&mut self,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, i32)],
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_const(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::public("uint"),
|
||||
QName::new(namespace, name),
|
||||
Multiname::new(activation.avm2().public_namespace, "int"),
|
||||
Some(value.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_constant_int_class_traits(&mut self, items: &[(&'static str, i32)]) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_const(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::public("int"),
|
||||
Some(value.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_builtin_class_properties(
|
||||
pub fn define_builtin_class_properties(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(
|
||||
&'static str,
|
||||
Option<NativeMethodImpl>,
|
||||
|
@ -581,88 +580,51 @@ impl<'gc> Class<'gc> {
|
|||
for &(name, getter, setter) in items {
|
||||
if let Some(getter) = getter {
|
||||
self.define_class_trait(Trait::from_getter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(getter, name, mc),
|
||||
));
|
||||
}
|
||||
if let Some(setter) = setter {
|
||||
self.define_class_trait(Trait::from_setter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(setter, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_builtin_instance_methods(
|
||||
pub fn define_builtin_instance_methods(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, NativeMethodImpl)],
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_instance_trait(Trait::from_method(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(value, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_as3_builtin_class_methods(
|
||||
pub fn define_builtin_class_methods(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, NativeMethodImpl)],
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_method(
|
||||
QName::new(Namespace::as3_namespace(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(value, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_as3_builtin_instance_methods(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
items: &[(&'static str, NativeMethodImpl)],
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_instance_trait(Trait::from_method(
|
||||
QName::new(Namespace::as3_namespace(), name),
|
||||
Method::from_builtin(value, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_ns_builtin_instance_methods(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
ns: &'static str,
|
||||
items: &[(&'static str, NativeMethodImpl)],
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_instance_trait(Trait::from_method(
|
||||
QName::new(Namespace::Namespace(ns.into()), name),
|
||||
Method::from_builtin(value, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_builtin_class_methods(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
items: &[(&'static str, NativeMethodImpl)],
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_class_trait(Trait::from_method(
|
||||
QName::new(Namespace::public(), name),
|
||||
Method::from_builtin(value, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_builtin_instance_properties(
|
||||
pub fn define_builtin_instance_properties(
|
||||
&mut self,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(
|
||||
&'static str,
|
||||
Option<NativeMethodImpl>,
|
||||
|
@ -672,74 +634,34 @@ impl<'gc> Class<'gc> {
|
|||
for &(name, getter, setter) in items {
|
||||
if let Some(getter) = getter {
|
||||
self.define_instance_trait(Trait::from_getter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(getter, name, mc),
|
||||
));
|
||||
}
|
||||
if let Some(setter) = setter {
|
||||
self.define_instance_trait(Trait::from_setter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(namespace, name),
|
||||
Method::from_builtin(setter, name, mc),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[inline(never)]
|
||||
pub fn define_public_slot_number_instance_traits(
|
||||
pub fn define_slot_number_instance_traits(
|
||||
&mut self,
|
||||
namespace: Namespace<'gc>,
|
||||
items: &[(&'static str, Option<f64>)],
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
for &(name, value) in items {
|
||||
self.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::public("Number"),
|
||||
QName::new(namespace, name),
|
||||
Multiname::new(activation.avm2().public_namespace, "Number"),
|
||||
value.map(|v| v.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn define_public_slot_instance_traits(
|
||||
&mut self,
|
||||
items: &[(&'static str, &'static str, &'static str)],
|
||||
) {
|
||||
for &(name, type_ns, type_name) in items {
|
||||
self.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::public(), name),
|
||||
Multiname::new(Namespace::Namespace(type_ns.into()), type_name),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn define_public_slot_instance_traits_type_multiname(
|
||||
&mut self,
|
||||
items: &[(&'static str, Multiname<'gc>)],
|
||||
) {
|
||||
for (name, type_name) in items {
|
||||
self.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::public(), *name),
|
||||
type_name.clone(),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn define_private_slot_instance_traits(
|
||||
&mut self,
|
||||
items: &[(&'static str, &'static str, &'static str, &'static str)],
|
||||
) {
|
||||
for &(ns, name, type_ns, type_name) in items {
|
||||
self.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::Private(ns.into()), name),
|
||||
Multiname::new(Namespace::Namespace(type_ns.into()), type_name),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a trait on the class.
|
||||
///
|
||||
/// Class traits will be accessible as properties on the class object.
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::avm2::object::{Object, TObject};
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::display_object::TDisplayObject;
|
||||
use crate::string::AvmString;
|
||||
use fnv::FnvHashMap;
|
||||
|
@ -342,8 +341,6 @@ impl<'gc> Hash for EventHandler<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub const NS_EVENT_DISPATCHER: &str = "https://ruffle.rs/AS3/impl/EventDispatcher/";
|
||||
|
||||
/// Retrieve the parent of a given `EventDispatcher`.
|
||||
///
|
||||
/// `EventDispatcher` does not provide a generic way for it's subclasses to
|
||||
|
@ -381,7 +378,7 @@ pub fn dispatch_event_to_target<'gc>(
|
|||
);
|
||||
let dispatch_list = dispatcher
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "dispatch_list"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "dispatch_list"),
|
||||
activation,
|
||||
)?
|
||||
.as_object();
|
||||
|
@ -438,7 +435,7 @@ pub fn dispatch_event<'gc>(
|
|||
) -> Result<bool, Error<'gc>> {
|
||||
let target = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "target"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "target"),
|
||||
activation,
|
||||
)?
|
||||
.as_object()
|
||||
|
|
|
@ -39,11 +39,6 @@ mod vector;
|
|||
mod xml;
|
||||
mod xml_list;
|
||||
|
||||
pub(crate) const NS_RUFFLE_INTERNAL: &str = "https://ruffle.rs/AS3/impl/";
|
||||
pub(crate) const NS_VECTOR: &str = "__AS3__.vec";
|
||||
|
||||
pub use flash::utils::NS_FLASH_PROXY;
|
||||
|
||||
/// This structure represents all system builtin classes.
|
||||
#[derive(Clone, Collect)]
|
||||
#[collect(no_drop)]
|
||||
|
@ -217,7 +212,10 @@ fn function<'gc>(
|
|||
let (_, mut global, mut domain) = script.init();
|
||||
let mc = activation.context.gc_context;
|
||||
let scope = activation.create_scopechain();
|
||||
let qname = QName::new(Namespace::package(package), name);
|
||||
let qname = QName::new(
|
||||
Namespace::package(package, activation.context.gc_context),
|
||||
name,
|
||||
);
|
||||
let method = Method::from_builtin(nf, name, mc);
|
||||
let as3fn = FunctionObject::from_method(activation, method, scope, None, None).into();
|
||||
domain.export_definition(qname, script, mc)?;
|
||||
|
@ -250,9 +248,9 @@ fn dynamic_class<'gc>(
|
|||
/// This function returns the class object and class prototype as a class, which
|
||||
/// may be stored in `SystemClasses`
|
||||
fn class<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
class_def: GcCell<'gc, Class<'gc>>,
|
||||
script: Script<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<ClassObject<'gc>, Error<'gc>> {
|
||||
let (_, mut global, mut domain) = script.init();
|
||||
|
||||
|
@ -299,7 +297,7 @@ fn class<'gc>(
|
|||
|
||||
macro_rules! avm2_system_class {
|
||||
($field:ident, $activation:ident, $class:expr, $script:expr) => {
|
||||
let class_object = class($activation, $class, $script)?;
|
||||
let class_object = class($class, $script, $activation)?;
|
||||
|
||||
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
||||
sc.$field = class_object;
|
||||
|
@ -341,20 +339,20 @@ pub fn load_player_globals<'gc>(
|
|||
//
|
||||
// Hence, this ridiculously complicated dance of classdef, type allocation,
|
||||
// and partial initialization.
|
||||
let object_classdef = object::create_class(mc);
|
||||
let object_classdef = object::create_class(activation);
|
||||
let object_class = ClassObject::from_class_partial(activation, object_classdef, None)?;
|
||||
let object_proto = ScriptObject::custom_object(mc, Some(object_class), None);
|
||||
|
||||
let fn_classdef = function::create_class(mc);
|
||||
let fn_classdef = function::create_class(activation);
|
||||
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));
|
||||
|
||||
let class_classdef = class::create_class(mc);
|
||||
let class_classdef = class::create_class(activation);
|
||||
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));
|
||||
|
||||
let global_classdef = global_scope::create_class(mc);
|
||||
let global_classdef = global_scope::create_class(activation);
|
||||
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));
|
||||
|
@ -405,14 +403,24 @@ pub fn load_player_globals<'gc>(
|
|||
// After this point, it is safe to initialize any other classes.
|
||||
// Make sure to initialize superclasses *before* their subclasses!
|
||||
|
||||
avm2_system_class!(string, activation, string::create_class(mc), script);
|
||||
avm2_system_class!(boolean, activation, boolean::create_class(mc), script);
|
||||
avm2_system_class!(number, activation, number::create_class(mc), script);
|
||||
avm2_system_class!(int, activation, int::create_class(mc), script);
|
||||
avm2_system_class!(uint, activation, uint::create_class(mc), script);
|
||||
avm2_system_class!(namespace, activation, namespace::create_class(mc), script);
|
||||
avm2_system_class!(qname, activation, qname::create_class(mc), script);
|
||||
avm2_system_class!(array, activation, array::create_class(mc), script);
|
||||
avm2_system_class!(string, activation, string::create_class(activation), script);
|
||||
avm2_system_class!(
|
||||
boolean,
|
||||
activation,
|
||||
boolean::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(number, activation, number::create_class(activation), script);
|
||||
avm2_system_class!(int, activation, int::create_class(activation), script);
|
||||
avm2_system_class!(uint, activation, uint::create_class(activation), script);
|
||||
avm2_system_class!(
|
||||
namespace,
|
||||
activation,
|
||||
namespace::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(qname, activation, qname::create_class(activation), script);
|
||||
avm2_system_class!(array, activation, array::create_class(activation), script);
|
||||
|
||||
function(activation, "", "trace", toplevel::trace, script)?;
|
||||
function(
|
||||
|
@ -456,105 +464,105 @@ pub fn load_player_globals<'gc>(
|
|||
function(activation, "", "parseFloat", toplevel::parse_float, script)?;
|
||||
function(activation, "", "escape", toplevel::escape, script)?;
|
||||
|
||||
avm2_system_class!(regexp, activation, regexp::create_class(mc), script);
|
||||
avm2_system_class!(vector, activation, vector::create_class(mc), script);
|
||||
avm2_system_class!(regexp, activation, regexp::create_class(activation), script);
|
||||
avm2_system_class!(vector, activation, vector::create_class(activation), script);
|
||||
|
||||
avm2_system_class!(date, activation, date::create_class(mc), script);
|
||||
avm2_system_class!(date, activation, date::create_class(activation), script);
|
||||
|
||||
// package `flash.system`
|
||||
avm2_system_class!(
|
||||
application_domain,
|
||||
activation,
|
||||
flash::system::application_domain::create_class(mc),
|
||||
flash::system::application_domain::create_class(activation),
|
||||
script
|
||||
);
|
||||
|
||||
class(
|
||||
activation,
|
||||
flash::events::ieventdispatcher::create_interface(mc),
|
||||
flash::events::ieventdispatcher::create_interface(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
eventdispatcher,
|
||||
activation,
|
||||
flash::events::eventdispatcher::create_class(mc),
|
||||
flash::events::eventdispatcher::create_class(activation),
|
||||
script
|
||||
);
|
||||
|
||||
// package `flash.display`
|
||||
class(
|
||||
activation,
|
||||
flash::display::ibitmapdrawable::create_interface(mc),
|
||||
flash::display::ibitmapdrawable::create_interface(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
display_object,
|
||||
activation,
|
||||
flash::display::displayobject::create_class(mc),
|
||||
flash::display::displayobject::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
shape,
|
||||
activation,
|
||||
flash::display::shape::create_class(mc),
|
||||
flash::display::shape::create_class(activation),
|
||||
script
|
||||
);
|
||||
class(
|
||||
activation,
|
||||
flash::display::interactiveobject::create_class(mc),
|
||||
flash::display::interactiveobject::create_class(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
simplebutton,
|
||||
activation,
|
||||
flash::display::simplebutton::create_class(mc),
|
||||
flash::display::simplebutton::create_class(activation),
|
||||
script
|
||||
);
|
||||
class(
|
||||
activation,
|
||||
flash::display::displayobjectcontainer::create_class(mc),
|
||||
flash::display::displayobjectcontainer::create_class(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
sprite,
|
||||
activation,
|
||||
flash::display::sprite::create_class(mc),
|
||||
flash::display::sprite::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
movieclip,
|
||||
activation,
|
||||
flash::display::movieclip::create_class(mc),
|
||||
flash::display::movieclip::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
graphics,
|
||||
activation,
|
||||
flash::display::graphics::create_class(mc),
|
||||
flash::display::graphics::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
loaderinfo,
|
||||
activation,
|
||||
flash::display::loaderinfo::create_class(mc),
|
||||
flash::display::loaderinfo::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
stage,
|
||||
activation,
|
||||
flash::display::stage::create_class(mc),
|
||||
flash::display::stage::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
bitmap,
|
||||
activation,
|
||||
flash::display::bitmap::create_class(mc),
|
||||
flash::display::bitmap::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
bitmapdata,
|
||||
activation,
|
||||
flash::display::bitmapdata::create_class(mc),
|
||||
flash::display::bitmapdata::create_class(activation),
|
||||
script
|
||||
);
|
||||
|
||||
|
@ -564,25 +572,29 @@ pub fn load_player_globals<'gc>(
|
|||
avm2_system_class!(
|
||||
video,
|
||||
activation,
|
||||
flash::media::video::create_class(mc),
|
||||
script
|
||||
);
|
||||
class(activation, flash::media::sound::create_class(mc), script)?;
|
||||
avm2_system_class!(
|
||||
soundtransform,
|
||||
activation,
|
||||
flash::media::soundtransform::create_class(mc),
|
||||
flash::media::video::create_class(activation),
|
||||
script
|
||||
);
|
||||
class(
|
||||
activation,
|
||||
flash::media::soundmixer::create_class(mc),
|
||||
flash::media::sound::create_class(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
soundtransform,
|
||||
activation,
|
||||
flash::media::soundtransform::create_class(activation),
|
||||
script
|
||||
);
|
||||
class(
|
||||
flash::media::soundmixer::create_class(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
avm2_system_class!(
|
||||
soundchannel,
|
||||
activation,
|
||||
flash::media::soundchannel::create_class(mc),
|
||||
flash::media::soundchannel::create_class(activation),
|
||||
script
|
||||
);
|
||||
|
||||
|
@ -590,16 +602,20 @@ pub fn load_player_globals<'gc>(
|
|||
avm2_system_class!(
|
||||
textfield,
|
||||
activation,
|
||||
flash::text::textfield::create_class(mc),
|
||||
flash::text::textfield::create_class(activation),
|
||||
script
|
||||
);
|
||||
avm2_system_class!(
|
||||
textformat,
|
||||
activation,
|
||||
flash::text::textformat::create_class(mc),
|
||||
flash::text::textformat::create_class(activation),
|
||||
script
|
||||
);
|
||||
class(activation, flash::text::font::create_class(mc), script)?;
|
||||
class(
|
||||
flash::text::font::create_class(activation),
|
||||
script,
|
||||
activation,
|
||||
)?;
|
||||
|
||||
// Inside this call, the macro `avm2_system_classes_playerglobal`
|
||||
// triggers classloading. Therefore, we run `load_playerglobal`
|
||||
|
@ -652,7 +668,7 @@ fn load_playerglobal<'gc>(
|
|||
macro_rules! avm2_system_classes_playerglobal {
|
||||
($activation:expr, $script:expr, [$(($package:expr, $class_name:expr, $field:ident)),* $(,)?]) => {
|
||||
$(
|
||||
let name = Multiname::new(Namespace::package($package), $class_name);
|
||||
let name = Multiname::new(Namespace::package($package, activation.context.gc_context), $class_name);
|
||||
let class_object = activation.resolve_class(&name)?;
|
||||
let sc = $activation.avm2().system_classes.as_mut().unwrap();
|
||||
sc.$field = class_object;
|
||||
|
|
|
@ -8,11 +8,10 @@ use crate::avm2::object::{array_allocator, ArrayObject, 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::string::AvmString;
|
||||
use bitflags::bitflags;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::cmp::{min, Ordering};
|
||||
use std::mem::swap;
|
||||
|
||||
|
@ -135,11 +134,8 @@ pub fn resolve_array_hole<'gc>(
|
|||
}
|
||||
|
||||
if let Some(proto) = this.proto() {
|
||||
proto.get_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
i.to_string(),
|
||||
)),
|
||||
proto.get_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, i.to_string()),
|
||||
activation,
|
||||
)
|
||||
} else {
|
||||
|
@ -213,7 +209,7 @@ pub fn to_locale_string<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
join_inner(act, this, &[",".into()], |v, activation| {
|
||||
if let Ok(o) = v.coerce_to_object(activation) {
|
||||
o.call_property(&Multiname::public("toLocaleString"), &[], activation)
|
||||
o.call_public_property("toLocaleString", &[], activation)
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -270,7 +266,7 @@ impl<'gc> ArrayIter<'gc> {
|
|||
end_index: u32,
|
||||
) -> Result<Self, Error<'gc>> {
|
||||
let length = array_object
|
||||
.get_property(&Multiname::public("length"), activation)?
|
||||
.get_public_property("length", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
|
||||
Ok(Self {
|
||||
|
@ -295,11 +291,8 @@ impl<'gc> ArrayIter<'gc> {
|
|||
|
||||
Some(
|
||||
self.array_object
|
||||
.get_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
i.to_string(),
|
||||
)),
|
||||
.get_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, i.to_string()),
|
||||
activation,
|
||||
)
|
||||
.map(|val| (i, val)),
|
||||
|
@ -324,11 +317,8 @@ impl<'gc> ArrayIter<'gc> {
|
|||
|
||||
Some(
|
||||
self.array_object
|
||||
.get_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
i.to_string(),
|
||||
)),
|
||||
.get_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, i.to_string()),
|
||||
activation,
|
||||
)
|
||||
.map(|val| (i, val)),
|
||||
|
@ -1145,12 +1135,10 @@ pub fn sort_on<'gc>(
|
|||
// it's treated as if the field's value was undefined.
|
||||
// TODO: verify this and fix it
|
||||
let a_object = a.coerce_to_object(activation)?;
|
||||
let a_field =
|
||||
a_object.get_property(&Multiname::public(*field_name), activation)?;
|
||||
let a_field = a_object.get_public_property(*field_name, activation)?;
|
||||
|
||||
let b_object = b.coerce_to_object(activation)?;
|
||||
let b_field =
|
||||
b_object.get_property(&Multiname::public(*field_name), activation)?;
|
||||
let b_field = b_object.get_public_property(*field_name, activation)?;
|
||||
|
||||
let ord = if options.contains(SortOptions::NUMERIC) {
|
||||
compare_numeric(activation, a_field, b_field)?
|
||||
|
@ -1183,10 +1171,11 @@ pub fn sort_on<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Array`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "Array"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Array"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Array instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Array class initializer>", mc),
|
||||
mc,
|
||||
|
@ -1202,14 +1191,22 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("toLocaleString", to_locale_string),
|
||||
("valueOf", value_of),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_PROPERTIES: &[(
|
||||
&str,
|
||||
Option<NativeMethodImpl>,
|
||||
Option<NativeMethodImpl>,
|
||||
)] = &[("length", Some(length), Some(set_length))];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("concat", concat),
|
||||
|
@ -1231,7 +1228,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("sort", sort),
|
||||
("sortOn", sort_on),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const CONSTANTS: &[(&str, u32)] = &[
|
||||
(
|
||||
|
@ -1246,7 +1247,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("UNIQUESORT", SortOptions::UNIQUE_SORT.bits() as u32),
|
||||
];
|
||||
write.define_public_constant_uint_class_traits(CONSTANTS);
|
||||
write.define_constant_uint_class_traits(
|
||||
activation.avm2().public_namespace,
|
||||
CONSTANTS,
|
||||
activation,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ 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::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Boolean`'s instance initializer.
|
||||
fn instance_init<'gc>(
|
||||
|
@ -58,8 +57,8 @@ fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let boolean_proto = this_class.prototype();
|
||||
|
||||
boolean_proto.set_property_local(
|
||||
&Multiname::public("toString"),
|
||||
boolean_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", gc_context),
|
||||
|
@ -70,8 +69,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
boolean_proto.set_property_local(
|
||||
&Multiname::public("valueOf"),
|
||||
boolean_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", gc_context),
|
||||
|
@ -124,10 +123,11 @@ fn value_of<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Boolean`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "Boolean"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Boolean"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Boolean instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Boolean class initializer>", mc),
|
||||
mc,
|
||||
|
@ -144,7 +144,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] =
|
||||
&[("toString", to_string), ("valueOf", value_of)];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ use crate::avm2::object::{Object, TObject};
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Class`'s instance initializer.
|
||||
///
|
||||
|
@ -46,10 +45,11 @@ fn prototype<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Class`'s class.
|
||||
pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let gc_context = activation.context.gc_context;
|
||||
let class_class = Class::new(
|
||||
QName::new(Namespace::public(), "Class"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Class"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Class instance initializer>", gc_context),
|
||||
Method::from_builtin(class_init, "<Class class initializer>", gc_context),
|
||||
gc_context,
|
||||
|
@ -62,7 +62,11 @@ pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Cl
|
|||
Option<NativeMethodImpl>,
|
||||
Option<NativeMethodImpl>,
|
||||
)] = &[("prototype", Some(prototype), None)];
|
||||
write.define_public_builtin_instance_properties(gc_context, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
gc_context,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class_class
|
||||
}
|
||||
|
|
|
@ -7,12 +7,11 @@ use crate::avm2::object::{date_allocator, DateObject, FunctionObject, Object, TO
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::locale::{get_current_date_time, get_timezone};
|
||||
use crate::string::{utils as string_utils, AvmString, WStr};
|
||||
use chrono::{DateTime, Datelike, Duration, FixedOffset, LocalResult, TimeZone, Timelike, Utc};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
// All of these methods will be defined as both
|
||||
|
@ -302,8 +301,8 @@ pub fn class_init<'gc>(
|
|||
let date_proto = this_class.prototype();
|
||||
|
||||
for (name, method) in PUBLIC_INSTANCE_AND_PROTO_METHODS {
|
||||
date_proto.set_property_local(
|
||||
&Multiname::public(*name),
|
||||
date_proto.set_string_property_local(
|
||||
*name,
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(*method, name, gc_context),
|
||||
|
@ -1326,10 +1325,11 @@ pub fn parse<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Date`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "Date"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Date"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Date instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Date class initializer>", mc),
|
||||
mc,
|
||||
|
@ -1366,13 +1366,24 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("dayUTC", Some(day_utc), None),
|
||||
("timezoneOffset", Some(timezone_offset), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
|
||||
write.define_as3_builtin_instance_methods(mc, PUBLIC_INSTANCE_AND_PROTO_METHODS);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
PUBLIC_INSTANCE_AND_PROTO_METHODS,
|
||||
);
|
||||
|
||||
const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[("UTC", utc), ("parse", parse)];
|
||||
|
||||
write.define_as3_builtin_class_methods(mc, PUBLIC_CLASS_METHODS);
|
||||
write.define_builtin_class_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::bitmap::bitmap_data::BitmapData;
|
|||
use crate::character::Character;
|
||||
use crate::display_object::{Bitmap, TDisplayObject};
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.display.Bitmap`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -94,11 +94,7 @@ pub fn instance_init<'gc>(
|
|||
);
|
||||
};
|
||||
|
||||
this.set_property(
|
||||
&Multiname::public("bitmapData"),
|
||||
bd_object.into(),
|
||||
activation,
|
||||
)?;
|
||||
this.set_public_property("bitmapData", bd_object.into(), activation)?;
|
||||
|
||||
bitmap.set_smoothing(activation.context.gc_context, smoothing);
|
||||
} else {
|
||||
|
@ -229,11 +225,12 @@ pub fn set_smoothing<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Bitmap`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Bitmap"),
|
||||
QName::new(Namespace::package("flash.display", mc), "Bitmap"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObject",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Bitmap instance initializer>", mc),
|
||||
|
@ -258,7 +255,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("smoothing", Some(smoothing), Some(set_smoothing)),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::bitmap::is_size_valid;
|
|||
use crate::character::Character;
|
||||
use crate::display_object::Bitmap;
|
||||
use crate::swf::BlendMode;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use ruffle_render::filters::{BlurFilter, ColorMatrixFilter, Filter};
|
||||
use ruffle_render::transform::Transform;
|
||||
use std::str::FromStr;
|
||||
|
@ -219,16 +219,16 @@ pub fn copy_pixels<'gc>(
|
|||
.coerce_to_object(activation)?;
|
||||
|
||||
let src_min_x = source_rect
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let src_min_y = source_rect
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let src_width = source_rect
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let src_height = source_rect
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
|
||||
let dest_point = args
|
||||
|
@ -237,10 +237,10 @@ pub fn copy_pixels<'gc>(
|
|||
.coerce_to_object(activation)?;
|
||||
|
||||
let dest_x = dest_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let dest_y = dest_point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
|
||||
if let Some(src_bitmap) = source_bitmap.as_bitmap_data() {
|
||||
|
@ -277,10 +277,10 @@ pub fn copy_pixels<'gc>(
|
|||
.coerce_to_object(activation)
|
||||
{
|
||||
x = alpha_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
y = alpha_point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
}
|
||||
|
||||
|
@ -333,16 +333,16 @@ pub fn get_pixels<'gc>(
|
|||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation)?;
|
||||
let x = rectangle
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let y = rectangle
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let width = rectangle
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let height = rectangle
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let bytearray = ByteArrayObject::from_storage(
|
||||
activation,
|
||||
|
@ -469,16 +469,16 @@ pub fn set_pixels<'gc>(
|
|||
.coerce_to_object(activation)?;
|
||||
if let Some(bitmap_data) = this.and_then(|t| t.as_bitmap_data()) {
|
||||
let x = rectangle
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let y = rectangle
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let width = rectangle
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let height = rectangle
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
|
||||
let ba_read = bytearray
|
||||
|
@ -532,10 +532,10 @@ pub fn copy_channel<'gc>(
|
|||
.coerce_to_object(activation)?;
|
||||
|
||||
let dest_x = dest_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let dest_y = dest_point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
|
||||
let source_channel = args
|
||||
|
@ -551,16 +551,16 @@ pub fn copy_channel<'gc>(
|
|||
if let Some(source_bitmap) = source_bitmap.as_bitmap_data() {
|
||||
//TODO: what if source is disposed
|
||||
let src_min_x = source_rect
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let src_min_y = source_rect
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let src_width = source_rect
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let src_height = source_rect
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let src_max_x = src_min_x + src_width;
|
||||
let src_max_y = src_min_y + src_height;
|
||||
|
@ -660,16 +660,16 @@ pub fn color_transform<'gc>(
|
|||
// TODO: Re-use `object_to_rectangle` in `movie_clip.rs`.
|
||||
let rectangle = rectangle.coerce_to_object(activation)?;
|
||||
let x = rectangle
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let y = rectangle
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let width = rectangle
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
let height = rectangle
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
|
||||
let x_min = x.max(0) as u32;
|
||||
|
@ -828,16 +828,16 @@ pub fn fill_rect<'gc>(
|
|||
|
||||
if let Some(bitmap_data) = this.and_then(|this| this.as_bitmap_data()) {
|
||||
let x = rectangle
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let y = rectangle
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let width = rectangle
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let height = rectangle
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
|
||||
bitmap_data.write(activation.context.gc_context).fill_rect(
|
||||
|
@ -942,10 +942,10 @@ pub fn apply_filter<'gc>(
|
|||
})?;
|
||||
let dest_point = (
|
||||
dest_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?,
|
||||
dest_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?,
|
||||
);
|
||||
let filter = args[3]
|
||||
|
@ -954,46 +954,27 @@ pub fn apply_filter<'gc>(
|
|||
Error::from(format!("TypeError: Error #1034: Type Coercion failed: cannot convert {} to flash.filters.BitmapFilter.", args[1].coerce_to_string(activation).unwrap_or_default()))
|
||||
})?;
|
||||
|
||||
let bevel_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"BevelFilter",
|
||||
))?;
|
||||
let bitmap_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"BitmapFilter",
|
||||
))?;
|
||||
let blur_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"BlurFilter",
|
||||
))?;
|
||||
let color_matrix_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"ColorMatrixFilter",
|
||||
))?;
|
||||
let convolution_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"ConvolutionFilter",
|
||||
))?;
|
||||
let displacement_map_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"DisplacementMapFilter",
|
||||
))?;
|
||||
let drop_shadow_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"DropShadowFilter",
|
||||
))?;
|
||||
let glow_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"GlowFilter",
|
||||
))?;
|
||||
let gradient_bevel_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"GradientBevelFilter",
|
||||
))?;
|
||||
let gradient_glow_filter = activation.resolve_class(&Multiname::new(
|
||||
Namespace::package("flash.filters"),
|
||||
"GradientGlowFilter",
|
||||
))?;
|
||||
let filters_namespace = Namespace::package("flash.filters", activation.context.gc_context);
|
||||
let bevel_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "BevelFilter"))?;
|
||||
let bitmap_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "BitmapFilter"))?;
|
||||
let blur_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "BlurFilter"))?;
|
||||
let color_matrix_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "ColorMatrixFilter"))?;
|
||||
let convolution_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "ConvolutionFilter"))?;
|
||||
let displacement_map_filter = activation
|
||||
.resolve_class(&Multiname::new(filters_namespace, "DisplacementMapFilter"))?;
|
||||
let drop_shadow_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "DropShadowFilter"))?;
|
||||
let glow_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "GlowFilter"))?;
|
||||
let gradient_bevel_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "GradientBevelFilter"))?;
|
||||
let gradient_glow_filter =
|
||||
activation.resolve_class(&Multiname::new(filters_namespace, "GradientGlowFilter"))?;
|
||||
// let shader_filter = activation.resolve_class(&Multiname::new(
|
||||
// Namespace::package("flash.filters"),
|
||||
// "ShaderFilter",
|
||||
|
@ -1001,7 +982,7 @@ pub fn apply_filter<'gc>(
|
|||
let filter = if filter.is_of_type(color_matrix_filter, activation) {
|
||||
let mut matrix = [0.0; 20];
|
||||
if let Some(object) = filter
|
||||
.get_property(&Multiname::public("matrix"), activation)?
|
||||
.get_public_property("matrix", activation)?
|
||||
.as_object()
|
||||
{
|
||||
if let Some(array) = object.as_array_storage() {
|
||||
|
@ -1017,13 +998,13 @@ pub fn apply_filter<'gc>(
|
|||
Filter::ColorMatrixFilter(ColorMatrixFilter { matrix })
|
||||
} else if filter.is_of_type(blur_filter, activation) {
|
||||
let blur_x = filter
|
||||
.get_property(&Multiname::public("blurX"), activation)?
|
||||
.get_public_property("blurX", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let blur_y = filter
|
||||
.get_property(&Multiname::public("blurY"), activation)?
|
||||
.get_public_property("blurY", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let quality = filter
|
||||
.get_property(&Multiname::public("quality"), activation)?
|
||||
.get_public_property("quality", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
Filter::BlurFilter(BlurFilter {
|
||||
blur_x: blur_x as f32,
|
||||
|
@ -1207,10 +1188,10 @@ pub fn perlin_noise<'gc>(
|
|||
if let Some(offsets) = offsets.as_array_storage() {
|
||||
if let Some(Value::Object(e)) = offsets.get(i) {
|
||||
let x = e
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let y = e
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
Ok((x, y))
|
||||
} else {
|
||||
|
@ -1245,10 +1226,11 @@ pub fn perlin_noise<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `BitmapData`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "BitmapData"),
|
||||
Some(Multiname::new(Namespace::package(""), "Object")),
|
||||
QName::new(Namespace::package("flash.display", mc), "BitmapData"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<BitmapData instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<BitmapData class initializer>", mc),
|
||||
mc,
|
||||
|
@ -1260,7 +1242,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
write.set_instance_allocator(bitmapdata_allocator);
|
||||
|
||||
write.implements(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"IBitmapDrawable",
|
||||
));
|
||||
|
||||
|
@ -1274,7 +1256,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("rect", Some(rect), None),
|
||||
("transparent", Some(transparent), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("getPixels", get_pixels),
|
||||
|
@ -1299,7 +1285,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("clone", clone),
|
||||
("perlinNoise", perlin_noise),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::string::AvmString;
|
|||
use crate::types::{Degrees, Percent};
|
||||
use crate::vminterface::Instantiator;
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::str::FromStr;
|
||||
use swf::Twips;
|
||||
use swf::{BlendMode, Rectangle};
|
||||
|
@ -285,8 +285,9 @@ pub fn set_filters<'gc>(
|
|||
|
||||
if let Some(filters_array) = new_filters.as_array_object() {
|
||||
if let Some(filters_storage) = filters_array.as_array_storage() {
|
||||
let filter_class =
|
||||
Multiname::new(Namespace::package("flash.filters"), "BitmapFilter");
|
||||
let filters_namespace =
|
||||
Namespace::package("flash.filters", activation.context.gc_context);
|
||||
let filter_class = Multiname::new(filters_namespace, "BitmapFilter");
|
||||
|
||||
let filter_class_object = activation.resolve_class(&filter_class)?;
|
||||
|
||||
|
@ -769,10 +770,10 @@ pub fn set_transform<'gc>(
|
|||
|
||||
// FIXME - consider 3D matrix and pixel bounds
|
||||
let matrix = transform
|
||||
.get_property(&Multiname::public("matrix"), activation)?
|
||||
.get_public_property("matrix", activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
let color_transform = transform
|
||||
.get_property(&Multiname::public("colorTransform"), activation)?
|
||||
.get_public_property("colorTransform", activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
|
||||
let matrix =
|
||||
|
@ -867,7 +868,7 @@ pub fn object_to_rectangle<'gc>(
|
|||
let mut values = [0.0; 4];
|
||||
for (&name, value) in NAMES.iter().zip(&mut values) {
|
||||
*value = object
|
||||
.get_property(&Multiname::public(name), activation)?
|
||||
.get_public_property(name, activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
}
|
||||
let [x, y, width, height] = values;
|
||||
|
@ -921,10 +922,10 @@ fn local_to_global<'gc>(
|
|||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation)?;
|
||||
let x = point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let y = point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
let (out_x, out_y) = dobj.local_to_global((Twips::from_pixels(x), Twips::from_pixels(y)));
|
||||
|
@ -953,10 +954,10 @@ fn global_to_local<'gc>(
|
|||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation)?;
|
||||
let x = point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let y = point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
let (out_x, out_y) = dobj.global_to_local((Twips::from_pixels(x), Twips::from_pixels(y)));
|
||||
|
@ -1106,11 +1107,12 @@ pub fn set_opaque_background<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `DisplayObject`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "DisplayObject"),
|
||||
QName::new(Namespace::package("flash.display", mc), "DisplayObject"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.events"),
|
||||
Namespace::package("flash.events", mc),
|
||||
"EventDispatcher",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<DisplayObject instance initializer>", mc),
|
||||
|
@ -1128,7 +1130,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
));
|
||||
|
||||
write.implements(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"IBitmapDrawable",
|
||||
));
|
||||
|
||||
|
@ -1174,7 +1176,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Some(set_cache_as_bitmap),
|
||||
),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("hitTestPoint", hit_test_point),
|
||||
|
@ -1184,7 +1190,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("getBounds", get_bounds),
|
||||
("getRect", get_rect),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::{ArrayObject, ArrayStorage, Error};
|
|||
use crate::context::UpdateContext;
|
||||
use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer};
|
||||
use crate::{avm2_stub_getter, avm2_stub_method, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::cmp::min;
|
||||
|
||||
/// Implements `flash.display.DisplayObjectContainer`'s instance constructor.
|
||||
|
@ -640,14 +640,15 @@ pub fn set_tab_children<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `DisplayObjectContainer`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObjectContainer",
|
||||
),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"InteractiveObject",
|
||||
)),
|
||||
Method::from_builtin(
|
||||
|
@ -680,7 +681,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("tabChildren", Some(tab_children), Some(set_tab_children)),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("getChildAt", get_child_at),
|
||||
|
@ -702,7 +707,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
are_inaccessible_objects_under_point,
|
||||
),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::avm2_stub_method;
|
|||
use crate::display_object::TDisplayObject;
|
||||
use crate::drawing::Drawing;
|
||||
use crate::string::WStr;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use ruffle_render::shape_utils::DrawCommand;
|
||||
use std::f64::consts::FRAC_1_SQRT_2;
|
||||
use swf::{Color, FillStyle, Fixed8, LineCapStyle, LineJoinStyle, LineStyle, Twips};
|
||||
|
@ -788,10 +788,11 @@ fn draw_ellipse<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Graphics`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Graphics"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.display", mc), "Graphics"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Graphics instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Graphics class initializer>", mc),
|
||||
mc,
|
||||
|
@ -822,7 +823,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("drawCircle", draw_circle),
|
||||
("drawEllipse", draw_ellipse),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::avm2::value::Value;
|
|||
use crate::avm2::Error;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Emulates attempts to execute bodiless methods.
|
||||
pub fn bodiless_method<'gc>(
|
||||
|
@ -29,9 +29,10 @@ pub fn class_init<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `IBitmapDrawable`'s class.
|
||||
pub fn create_interface<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_interface<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "IBitmapDrawable"),
|
||||
QName::new(Namespace::package("flash.display", mc), "IBitmapDrawable"),
|
||||
None,
|
||||
Method::from_builtin(
|
||||
bodiless_method,
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::avm2::Namespace;
|
|||
use crate::avm2::QName;
|
||||
use crate::display_object::{TDisplayObject, TInteractiveObject};
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.display.InteractiveObject`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -144,7 +144,10 @@ fn set_context_menu<'gc>(
|
|||
.and_then(|t| t.as_display_object())
|
||||
.and_then(|dobj| dobj.as_interactive())
|
||||
{
|
||||
let cls_name = Multiname::new(Namespace::package("flash.display"), "NativeMenu");
|
||||
let cls_name = Multiname::new(
|
||||
Namespace::package("flash.display", activation.context.gc_context),
|
||||
"NativeMenu",
|
||||
);
|
||||
let cls = activation.resolve_class(&cls_name)?;
|
||||
let value = args
|
||||
.get(0)
|
||||
|
@ -222,11 +225,12 @@ pub fn set_focus_rect<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `InteractiveObject`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "InteractiveObject"),
|
||||
QName::new(Namespace::package("flash.display", mc), "InteractiveObject"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObject",
|
||||
)),
|
||||
Method::from_builtin(
|
||||
|
@ -262,7 +266,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("tabIndex", Some(tab_index), Some(set_tab_index)),
|
||||
("focusRect", Some(focus_rect), Some(set_focus_rect)),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::avm2::object::LoaderInfoObject;
|
|||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::{Error, Object};
|
||||
use crate::backend::navigator::Request;
|
||||
use crate::display_object::LoaderDisplay;
|
||||
|
@ -40,7 +39,10 @@ pub fn init<'gc>(
|
|||
false,
|
||||
)?;
|
||||
this.set_property(
|
||||
&Multiname::new(Namespace::private(""), "_contentLoaderInfo"),
|
||||
&Multiname::new(
|
||||
activation.avm2().ruffle_private_namespace,
|
||||
"_contentLoaderInfo",
|
||||
),
|
||||
loader_info.into(),
|
||||
activation,
|
||||
)?;
|
||||
|
@ -61,7 +63,7 @@ pub fn load<'gc>(
|
|||
.and_then(|v| v.coerce_to_object(activation).ok());
|
||||
|
||||
let url = url_request
|
||||
.get_property(&Multiname::public("url"), activation)?
|
||||
.get_public_property("url", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
// This is a dummy MovieClip, which will get overwritten in `Loader`
|
||||
|
@ -72,7 +74,10 @@ pub fn load<'gc>(
|
|||
|
||||
let loader_info = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::private(""), "_contentLoaderInfo"),
|
||||
&Multiname::new(
|
||||
activation.avm2().ruffle_private_namespace,
|
||||
"_contentLoaderInfo",
|
||||
),
|
||||
activation,
|
||||
)?
|
||||
.as_object()
|
||||
|
@ -112,7 +117,10 @@ pub fn load_bytes<'gc>(
|
|||
|
||||
let loader_info = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::private(""), "_contentLoaderInfo"),
|
||||
&Multiname::new(
|
||||
activation.avm2().ruffle_private_namespace,
|
||||
"_contentLoaderInfo",
|
||||
),
|
||||
activation,
|
||||
)?
|
||||
.as_object()
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::QName;
|
|||
use crate::avm2::{AvmString, Error};
|
||||
use crate::avm2_stub_getter;
|
||||
use crate::display_object::TDisplayObject;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use swf::{write_swf, Compression};
|
||||
|
||||
// FIXME - Throw an actual 'Error' with the proper code
|
||||
|
@ -470,7 +470,7 @@ pub fn parameters<'gc>(
|
|||
for (k, v) in parameters.iter() {
|
||||
let avm_k = AvmString::new_utf8(activation.context.gc_context, k);
|
||||
let avm_v = AvmString::new_utf8(activation.context.gc_context, v);
|
||||
params_obj.set_property(&Multiname::public(avm_k), avm_v.into(), activation)?;
|
||||
params_obj.set_public_property(avm_k, avm_v.into(), activation)?;
|
||||
}
|
||||
|
||||
return Ok(params_obj.into());
|
||||
|
@ -505,11 +505,12 @@ pub fn uncaught_error_events<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `LoaderInfo`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "LoaderInfo"),
|
||||
QName::new(Namespace::package("flash.display", mc), "LoaderInfo"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.events"),
|
||||
Namespace::package("flash.events", mc),
|
||||
"EventDispatcher",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<LoaderInfo instance initializer>", mc),
|
||||
|
@ -552,7 +553,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("sharedEvents", Some(shared_events), None),
|
||||
("uncaughtErrorEvents", Some(uncaught_error_events), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::Namespace;
|
|||
use crate::avm2::QName;
|
||||
use crate::display_object::{MovieClip, Scene, TDisplayObject};
|
||||
use crate::string::{AvmString, WString};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.display.MovieClip`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -545,11 +545,12 @@ pub fn next_scene<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `MovieClip`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "MovieClip"),
|
||||
QName::new(Namespace::package("flash.display", mc), "MovieClip"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"Sprite",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<MovieClip instance initializer>", mc),
|
||||
|
@ -575,7 +576,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("isPlaying", Some(is_playing), None),
|
||||
("totalFrames", Some(total_frames), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("addFrameScript", add_frame_script),
|
||||
|
@ -588,7 +593,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("prevScene", prev_scene),
|
||||
("nextScene", next_scene),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::globals::NS_RUFFLE_INTERNAL;
|
||||
use crate::avm2::method::{Method, NativeMethodImpl};
|
||||
use crate::avm2::object::{Object, StageObject, TObject};
|
||||
use crate::avm2::traits::Trait;
|
||||
|
@ -12,7 +11,7 @@ use crate::avm2::Multiname;
|
|||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::display_object::Graphic;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.display.Shape`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -52,13 +51,13 @@ pub fn graphics<'gc>(
|
|||
if let Some(dobj) = this.as_display_object() {
|
||||
// Lazily initialize the `Graphics` object in a hidden property.
|
||||
let graphics = match this.get_property(
|
||||
&Multiname::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
activation,
|
||||
)? {
|
||||
Value::Undefined | Value::Null => {
|
||||
let graphics = Value::from(StageObject::graphics(activation, dobj)?);
|
||||
this.set_property(
|
||||
&Multiname::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
graphics,
|
||||
activation,
|
||||
)?;
|
||||
|
@ -74,11 +73,12 @@ pub fn graphics<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Shape`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Shape"),
|
||||
QName::new(Namespace::package("flash.display", mc), "Shape"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObject",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Shape instance initializer>", mc),
|
||||
|
@ -93,12 +93,16 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Option<NativeMethodImpl>,
|
||||
Option<NativeMethodImpl>,
|
||||
)] = &[("graphics", Some(graphics), None)];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
// Slot for lazy-initialized Graphics object.
|
||||
write.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
Multiname::new(Namespace::package("flash.display"), "Graphics"),
|
||||
QName::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
Multiname::new(Namespace::package("flash.display", mc), "Graphics"),
|
||||
None,
|
||||
));
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::Namespace;
|
|||
use crate::avm2::QName;
|
||||
use crate::display_object::{Avm2Button, ButtonTracking, TDisplayObject};
|
||||
use crate::vminterface::Instantiator;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use swf::ButtonState;
|
||||
|
||||
/// Implements `flash.display.SimpleButton`'s instance constructor.
|
||||
|
@ -362,11 +362,12 @@ pub fn set_use_hand_cursor<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `SimpleButton`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "SimpleButton"),
|
||||
QName::new(Namespace::package("flash.display", mc), "SimpleButton"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"InteractiveObject",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<SimpleButton instance initializer>", mc),
|
||||
|
@ -404,7 +405,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Some(set_sound_transform),
|
||||
),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::class::{Class, ClassAttributes};
|
||||
use crate::avm2::globals::NS_RUFFLE_INTERNAL;
|
||||
use crate::avm2::method::{Method, NativeMethodImpl};
|
||||
use crate::avm2::object::{Object, StageObject, TObject};
|
||||
use crate::avm2::traits::Trait;
|
||||
|
@ -13,7 +12,7 @@ use crate::avm2::Namespace;
|
|||
use crate::avm2::QName;
|
||||
use crate::display_object::{MovieClip, SoundTransform, TDisplayObject};
|
||||
use crate::tag_utils::SwfMovie;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use ruffle_render::bounding_box::BoundingBox;
|
||||
use std::sync::Arc;
|
||||
use swf::Twips;
|
||||
|
@ -78,13 +77,13 @@ pub fn graphics<'gc>(
|
|||
if let Some(dobj) = this.as_display_object() {
|
||||
// Lazily initialize the `Graphics` object in a hidden property.
|
||||
let graphics = match this.get_property(
|
||||
&Multiname::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
activation,
|
||||
)? {
|
||||
Value::Undefined | Value::Null => {
|
||||
let graphics = Value::from(StageObject::graphics(activation, dobj)?);
|
||||
this.set_property(
|
||||
&Multiname::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
graphics,
|
||||
activation,
|
||||
)?;
|
||||
|
@ -196,19 +195,19 @@ pub fn start_drag<'gc>(
|
|||
let constraint = if let Some(rect) = args.get(1) {
|
||||
let rect = rect.coerce_to_object(activation)?;
|
||||
let x = rect
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
let y = rect
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
let width = rect
|
||||
.get_property(&Multiname::public("width"), activation)?
|
||||
.get_public_property("width", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
let height = rect
|
||||
.get_property(&Multiname::public("height"), activation)?
|
||||
.get_public_property("height", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
// Normalize the bounds.
|
||||
|
@ -300,11 +299,12 @@ pub fn set_use_hand_cursor<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Sprite`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Sprite"),
|
||||
QName::new(Namespace::package("flash.display", mc), "Sprite"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObjectContainer",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Sprite instance initializer>", mc),
|
||||
|
@ -335,16 +335,27 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Some(set_use_hand_cursor),
|
||||
),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] =
|
||||
&[("startDrag", start_drag), ("stopDrag", stop_drag)];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
// Slot for lazy-initialized Graphics object.
|
||||
write.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::private(NS_RUFFLE_INTERNAL), "graphics"),
|
||||
Multiname::new(Namespace::package("flash.display"), "Graphics"),
|
||||
QName::new(activation.avm2().ruffle_private_namespace, "graphics"),
|
||||
Multiname::new(
|
||||
Namespace::package("flash.display", activation.context.gc_context),
|
||||
"Graphics",
|
||||
),
|
||||
None,
|
||||
));
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::avm2::{ArrayObject, ArrayStorage};
|
|||
use crate::display_object::{StageDisplayState, TDisplayObject};
|
||||
use crate::string::{AvmString, WString};
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use swf::Color;
|
||||
|
||||
/// Implements `flash.display.Stage`'s instance constructor.
|
||||
|
@ -762,11 +762,12 @@ pub fn set_full_screen_source_rect<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Stage`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.display"), "Stage"),
|
||||
QName::new(Namespace::package("flash.display", mc), "Stage"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObjectContainer",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Stage instance initializer>", mc),
|
||||
|
@ -820,7 +821,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
if let Some(getter) = getter {
|
||||
write.define_instance_trait(
|
||||
Trait::from_getter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(activation.avm2().public_namespace, name),
|
||||
Method::from_builtin(getter, name, mc),
|
||||
)
|
||||
.with_override(),
|
||||
|
@ -829,7 +830,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
if let Some(setter) = setter {
|
||||
write.define_instance_trait(
|
||||
Trait::from_setter(
|
||||
QName::new(Namespace::public(), name),
|
||||
QName::new(activation.avm2().public_namespace, name),
|
||||
Method::from_builtin(setter, name, mc),
|
||||
)
|
||||
.with_override(),
|
||||
|
@ -876,10 +877,18 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("quality", Some(quality), Some(set_quality)),
|
||||
("stage3Ds", Some(stage3ds), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("invalidate", invalidate)];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::avm2::object::Context3DObject;
|
||||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::Multiname;
|
||||
|
||||
use crate::avm2::{Activation, Error, Object, Value};
|
||||
|
||||
|
@ -26,11 +25,7 @@ pub fn request_context3d_internal<'gc>(
|
|||
|
||||
// FIXME - fire this at least one frame later,
|
||||
// since some seems to expect this (e.g. the adobe triangle example)
|
||||
this.call_property(
|
||||
&Multiname::public("dispatchEvent"),
|
||||
&[event.into()],
|
||||
activation,
|
||||
)?;
|
||||
this.call_public_property("dispatchEvent", &[event.into()], activation)?;
|
||||
}
|
||||
}
|
||||
Ok(Value::Undefined)
|
||||
|
|
|
@ -4,7 +4,6 @@ use ruffle_render::backend::Context3DVertexBufferFormat;
|
|||
use ruffle_render::backend::ProgramType;
|
||||
|
||||
use crate::avm2::Activation;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::TObject;
|
||||
use crate::avm2::Value;
|
||||
use crate::avm2::{Error, Object};
|
||||
|
@ -255,14 +254,14 @@ pub fn set_program_constants_from_matrix<'gc>(
|
|||
// See https://github.com/openfl/openfl/blob/971a4c9e43b5472fd84d73920a2b7c1b3d8d9257/src/openfl/display3D/Context3D.hx#L1532-L1550
|
||||
if user_transposedMatrix {
|
||||
matrix = matrix
|
||||
.call_property(&Multiname::public("clone"), &[], activation)?
|
||||
.call_public_property("clone", &[], activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
|
||||
matrix.call_property(&Multiname::public("transpose"), &[], activation)?;
|
||||
matrix.call_public_property("transpose", &[], activation)?;
|
||||
}
|
||||
|
||||
let matrix_raw_data = matrix
|
||||
.get_property(&Multiname::public("rawData"), activation)?
|
||||
.get_public_property("rawData", activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
let matrix_raw_data = matrix_raw_data
|
||||
.as_vector_storage()
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::class::{Class, ClassAttributes};
|
||||
use crate::avm2::events::{
|
||||
dispatch_event as dispatch_event_internal, parent_of, NS_EVENT_DISPATCHER,
|
||||
};
|
||||
use crate::avm2::events::{dispatch_event as dispatch_event_internal, parent_of};
|
||||
use crate::avm2::method::{Method, NativeMethodImpl};
|
||||
use crate::avm2::object::{DispatchObject, Object, TObject};
|
||||
use crate::avm2::traits::Trait;
|
||||
|
@ -13,7 +11,7 @@ use crate::avm2::Multiname;
|
|||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{Avm2, Error};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.events.EventDispatcher`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -27,7 +25,7 @@ pub fn instance_init<'gc>(
|
|||
let target = args.get(0).cloned().unwrap_or(Value::Null);
|
||||
|
||||
this.init_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "target"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "target"),
|
||||
target,
|
||||
activation,
|
||||
)?;
|
||||
|
@ -46,14 +44,14 @@ fn dispatch_list<'gc>(
|
|||
mut this: Object<'gc>,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
match this.get_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "dispatch_list"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "dispatch_list"),
|
||||
activation,
|
||||
)? {
|
||||
Value::Object(o) => Ok(o),
|
||||
_ => {
|
||||
let dispatch_list = DispatchObject::empty_list(activation.context.gc_context);
|
||||
this.init_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "dispatch_list"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "dispatch_list"),
|
||||
dispatch_list.into(),
|
||||
activation,
|
||||
)?;
|
||||
|
@ -185,7 +183,7 @@ pub fn will_trigger<'gc>(
|
|||
|
||||
let target = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "target"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "target"),
|
||||
activation,
|
||||
)?
|
||||
.as_object()
|
||||
|
@ -237,7 +235,7 @@ pub fn to_string<'gc>(
|
|||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let object_proto = activation.avm2().classes().object.prototype();
|
||||
let name = Multiname::public("toString");
|
||||
let name = Multiname::new(activation.avm2().public_namespace, "toString");
|
||||
object_proto
|
||||
.get_property(&name, activation)?
|
||||
.as_callable(activation, Some(&name), Some(object_proto))?
|
||||
|
@ -245,10 +243,11 @@ pub fn to_string<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `EventDispatcher`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.events"), "EventDispatcher"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.events", mc), "EventDispatcher"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<EventDispatcher instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<EventDispatcher class initializer>", mc),
|
||||
mc,
|
||||
|
@ -259,7 +258,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
write.set_attributes(ClassAttributes::SEALED);
|
||||
|
||||
write.implements(Multiname::new(
|
||||
Namespace::package("flash.events"),
|
||||
Namespace::package("flash.events", mc),
|
||||
"IEventDispatcher",
|
||||
));
|
||||
|
||||
|
@ -271,16 +270,20 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("dispatchEvent", dispatch_event),
|
||||
("toString", to_string),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
write.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::private(NS_EVENT_DISPATCHER), "target"),
|
||||
Multiname::public("Object"),
|
||||
QName::new(activation.avm2().ruffle_private_namespace, "target"),
|
||||
Multiname::new(activation.avm2().public_namespace, "Object"),
|
||||
None,
|
||||
));
|
||||
write.define_instance_trait(Trait::from_slot(
|
||||
QName::new(Namespace::private(NS_EVENT_DISPATCHER), "dispatch_list"),
|
||||
Multiname::public("Object"),
|
||||
QName::new(activation.avm2().ruffle_private_namespace, "dispatch_list"),
|
||||
Multiname::new(activation.avm2().public_namespace, "Object"),
|
||||
None,
|
||||
));
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::avm2::value::Value;
|
|||
use crate::avm2::Error;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Emulates attempts to execute bodiless methods.
|
||||
pub fn bodiless_method<'gc>(
|
||||
|
@ -29,9 +29,10 @@ pub fn class_init<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `IEventDispatcher`'s class.
|
||||
pub fn create_interface<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_interface<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.events"), "IEventDispatcher"),
|
||||
QName::new(Namespace::package("flash.events", mc), "IEventDispatcher"),
|
||||
None,
|
||||
Method::from_builtin(
|
||||
bodiless_method,
|
||||
|
@ -53,7 +54,11 @@ pub fn create_interface<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<
|
|||
("removeEventListener", bodiless_method),
|
||||
("willTrigger", bodiless_method),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::object::{Object, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::display_object::TDisplayObject;
|
||||
use swf::Twips;
|
||||
|
||||
|
@ -15,7 +14,7 @@ pub fn get_stage_x<'gc>(
|
|||
if let Some(this) = this {
|
||||
if let Some(evt) = this.as_event() {
|
||||
let local_x = this
|
||||
.get_property(&Multiname::public("localX"), activation)?
|
||||
.get_public_property("localX", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
if local_x.is_nan() {
|
||||
|
@ -43,7 +42,7 @@ pub fn get_stage_y<'gc>(
|
|||
if let Some(this) = this {
|
||||
if let Some(evt) = this.as_event() {
|
||||
let local_y = this
|
||||
.get_property(&Multiname::public("localY"), activation)?
|
||||
.get_public_property("localY", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
if local_y.is_nan() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::{Activation, Error, Namespace, Object, TObject, Value};
|
||||
use crate::avm2::{Activation, Error, Object, TObject, Value};
|
||||
use crate::avm2_stub_getter;
|
||||
use crate::display_object::TDisplayObject;
|
||||
use crate::prelude::{ColorTransform, DisplayObject, Matrix, Twips};
|
||||
|
@ -14,7 +14,7 @@ fn get_display_object<'gc>(
|
|||
) -> Result<DisplayObject<'gc>, Error<'gc>> {
|
||||
Ok(this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_displayObject"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_displayObject"),
|
||||
activation,
|
||||
)?
|
||||
.as_object()
|
||||
|
@ -29,7 +29,7 @@ pub fn init<'gc>(
|
|||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
this.unwrap().set_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_displayObject"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_displayObject"),
|
||||
args[0],
|
||||
activation,
|
||||
)?;
|
||||
|
@ -145,28 +145,28 @@ pub fn object_to_color_transform<'gc>(
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<ColorTransform, Error<'gc>> {
|
||||
let red_multiplier = object
|
||||
.get_property(&Multiname::public("redMultiplier"), activation)?
|
||||
.get_public_property("redMultiplier", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let green_multiplier = object
|
||||
.get_property(&Multiname::public("greenMultiplier"), activation)?
|
||||
.get_public_property("greenMultiplier", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let blue_multiplier = object
|
||||
.get_property(&Multiname::public("blueMultiplier"), activation)?
|
||||
.get_public_property("blueMultiplier", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let alpha_multiplier = object
|
||||
.get_property(&Multiname::public("alphaMultiplier"), activation)?
|
||||
.get_public_property("alphaMultiplier", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let red_offset = object
|
||||
.get_property(&Multiname::public("redOffset"), activation)?
|
||||
.get_public_property("redOffset", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let green_offset = object
|
||||
.get_property(&Multiname::public("greenOffset"), activation)?
|
||||
.get_public_property("greenOffset", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let blue_offset = object
|
||||
.get_property(&Multiname::public("blueOffset"), activation)?
|
||||
.get_public_property("blueOffset", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let alpha_offset = object
|
||||
.get_property(&Multiname::public("alphaOffset"), activation)?
|
||||
.get_public_property("alphaOffset", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
Ok(ColorTransform {
|
||||
r_mult: Fixed8::from_f64(red_multiplier),
|
||||
|
@ -224,25 +224,25 @@ pub fn object_to_matrix<'gc>(
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Matrix, Error<'gc>> {
|
||||
let a = object
|
||||
.get_property(&Multiname::public("a"), activation)?
|
||||
.get_public_property("a", activation)?
|
||||
.coerce_to_number(activation)? as f32;
|
||||
let b = object
|
||||
.get_property(&Multiname::public("b"), activation)?
|
||||
.get_public_property("b", activation)?
|
||||
.coerce_to_number(activation)? as f32;
|
||||
let c = object
|
||||
.get_property(&Multiname::public("c"), activation)?
|
||||
.get_public_property("c", activation)?
|
||||
.coerce_to_number(activation)? as f32;
|
||||
let d = object
|
||||
.get_property(&Multiname::public("d"), activation)?
|
||||
.get_public_property("d", activation)?
|
||||
.coerce_to_number(activation)? as f32;
|
||||
let tx = Twips::from_pixels(
|
||||
object
|
||||
.get_property(&Multiname::public("tx"), activation)?
|
||||
.get_public_property("tx", activation)?
|
||||
.coerce_to_number(activation)?,
|
||||
);
|
||||
let ty = Twips::from_pixels(
|
||||
object
|
||||
.get_property(&Multiname::public("ty"), activation)?
|
||||
.get_public_property("ty", activation)?
|
||||
.coerce_to_number(activation)?,
|
||||
);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::backend::navigator::Request;
|
|||
use crate::character::Character;
|
||||
use crate::display_object::SoundTransform;
|
||||
use crate::{avm2_stub_constructor, avm2_stub_getter, avm2_stub_method};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use swf::{SoundEvent, SoundInfo};
|
||||
|
||||
/// Implements `flash.media.Sound`'s instance constructor.
|
||||
|
@ -221,7 +221,7 @@ pub fn load<'gc>(
|
|||
};
|
||||
|
||||
let url = url_request
|
||||
.get_property(&Multiname::public("url"), activation)?
|
||||
.get_public_property("url", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
// TODO: context parameter currently unused.
|
||||
|
@ -266,11 +266,12 @@ pub fn load_pcm_from_byte_array<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Sound`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.media"), "Sound"),
|
||||
QName::new(Namespace::package("flash.media", mc), "Sound"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.events"),
|
||||
Namespace::package("flash.events", mc),
|
||||
"EventDispatcher",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Sound instance initializer>", mc),
|
||||
|
@ -295,7 +296,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("url", Some(url), None),
|
||||
("length", Some(length), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("play", play),
|
||||
|
@ -308,7 +313,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("loadPCMFromByteArray", load_pcm_from_byte_array),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::avm2::Multiname;
|
|||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::display_object::SoundTransform;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.media.SoundChannel`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -131,11 +131,12 @@ pub fn stop<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `SoundChannel`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.media"), "SoundChannel"),
|
||||
QName::new(Namespace::package("flash.media", mc), "SoundChannel"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.events"),
|
||||
Namespace::package("flash.events", mc),
|
||||
"EventDispatcher",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<SoundChannel instance initializer>", mc),
|
||||
|
@ -162,10 +163,18 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Some(set_sound_transform),
|
||||
),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("stop", stop)];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::avm2::Namespace;
|
|||
use crate::avm2::QName;
|
||||
use crate::avm2_stub_getter;
|
||||
use crate::display_object::SoundTransform;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.media.SoundMixer`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -218,10 +218,11 @@ pub fn compute_spectrum<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `SoundMixer`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.media"), "SoundMixer"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.media", mc), "SoundMixer"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<SoundMixer instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<SoundMixer class initializer>", mc),
|
||||
mc,
|
||||
|
@ -240,14 +241,22 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("bufferTime", Some(buffer_time), Some(set_buffer_time)),
|
||||
];
|
||||
write.define_public_builtin_class_properties(mc, PUBLIC_CLASS_PROPERTIES);
|
||||
write.define_builtin_class_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("stopAll", stop_all),
|
||||
("areSoundsInaccessible", are_sounds_inaccessible),
|
||||
("computeSpectrum", compute_spectrum),
|
||||
];
|
||||
write.define_public_builtin_class_methods(mc, PUBLIC_CLASS_METHODS);
|
||||
write.define_builtin_class_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm2::Error;
|
|||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.media.SoundTransform`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -31,8 +31,8 @@ pub fn instance_init<'gc>(
|
|||
.unwrap_or_else(|| 0.0.into())
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
this.set_property(&Multiname::public("volume"), volume.into(), activation)?;
|
||||
this.set_property(&Multiname::public("pan"), pan.into(), activation)?;
|
||||
this.set_public_property("volume", volume.into(), activation)?;
|
||||
this.set_public_property("pan", pan.into(), activation)?;
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
|
@ -55,10 +55,10 @@ pub fn pan<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(this) = this {
|
||||
let left_to_right = this
|
||||
.get_property(&Multiname::public("leftToRight"), activation)?
|
||||
.get_public_property("leftToRight", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let right_to_left = this
|
||||
.get_property(&Multiname::public("rightToLeft"), activation)?
|
||||
.get_public_property("rightToLeft", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
if left_to_right != 0.0 || right_to_left != 0.0 {
|
||||
|
@ -66,7 +66,7 @@ pub fn pan<'gc>(
|
|||
}
|
||||
|
||||
let left_to_left = this
|
||||
.get_property(&Multiname::public("leftToLeft"), activation)?
|
||||
.get_public_property("leftToLeft", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
return Ok((1.0 - left_to_left.powf(2.0).abs()).into());
|
||||
|
@ -88,28 +88,21 @@ pub fn set_pan<'gc>(
|
|||
.unwrap_or(Value::Undefined)
|
||||
.coerce_to_number(activation)?;
|
||||
|
||||
this.set_property(
|
||||
&Multiname::public("leftToLeft"),
|
||||
(1.0 - pan).sqrt().into(),
|
||||
activation,
|
||||
)?;
|
||||
this.set_property(
|
||||
&Multiname::public("rightToRight"),
|
||||
(1.0 + pan).sqrt().into(),
|
||||
activation,
|
||||
)?;
|
||||
this.set_property(&Multiname::public("leftToRight"), (0.0).into(), activation)?;
|
||||
this.set_property(&Multiname::public("rightToLeft"), (0.0).into(), activation)?;
|
||||
this.set_public_property("leftToLeft", (1.0 - pan).sqrt().into(), activation)?;
|
||||
this.set_public_property("rightToRight", (1.0 + pan).sqrt().into(), activation)?;
|
||||
this.set_public_property("leftToRight", (0.0).into(), activation)?;
|
||||
this.set_public_property("rightToLeft", (0.0).into(), activation)?;
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `SoundTransform`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.media"), "SoundTransform"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.media", mc), "SoundTransform"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<SoundTransform instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<SoundTransform class initializer>", mc),
|
||||
mc,
|
||||
|
@ -124,7 +117,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Option<NativeMethodImpl>,
|
||||
Option<NativeMethodImpl>,
|
||||
)] = &[("pan", Some(pan), Some(set_pan))];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_SLOTS: &[(&str, Option<f64>)] = &[
|
||||
("leftToLeft", None),
|
||||
|
@ -133,7 +130,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("rightToRight", None),
|
||||
("volume", None),
|
||||
];
|
||||
write.define_public_slot_number_instance_traits(PUBLIC_INSTANCE_SLOTS);
|
||||
write.define_slot_number_instance_traits(
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_SLOTS,
|
||||
activation,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm2::Error;
|
|||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.media.Video`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -34,11 +34,12 @@ pub fn class_init<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Video`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.media"), "Video"),
|
||||
QName::new(Namespace::package("flash.media", mc), "Video"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"DisplayObject",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<Video instance initializer>", mc),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! `flash.net` namespace
|
||||
|
||||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::{Activation, Error, Multiname, Object, Value};
|
||||
use crate::avm2::{Activation, Error, Object, Value};
|
||||
|
||||
pub mod object_encoding;
|
||||
pub mod shared_object;
|
||||
|
@ -24,7 +24,7 @@ pub fn navigate_to_url<'gc>(
|
|||
.coerce_to_string(activation)?;
|
||||
|
||||
let url = request
|
||||
.get_property(&Multiname::public("url"), activation)?
|
||||
.get_public_property("url", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
activation
|
||||
|
|
|
@ -141,7 +141,10 @@ pub fn get_local<'gc>(
|
|||
let mut this = sharedobject_cls.construct(activation, &[])?;
|
||||
|
||||
// Set the internal name
|
||||
let ruffle_name = Multiname::new(Namespace::Namespace("__ruffle__".into()), "_ruffleName");
|
||||
let ruffle_name = Multiname::new(
|
||||
Namespace::package("__ruffle__", activation.context.gc_context),
|
||||
"_ruffleName",
|
||||
);
|
||||
this.set_property(
|
||||
&ruffle_name,
|
||||
AvmString::new_utf8(activation.context.gc_context, &full_name).into(),
|
||||
|
@ -167,7 +170,7 @@ pub fn get_local<'gc>(
|
|||
.into();
|
||||
}
|
||||
|
||||
this.set_property(&Multiname::public("data"), data, activation)?;
|
||||
this.set_public_property("data", data, activation)?;
|
||||
activation
|
||||
.context
|
||||
.avm2_shared_objects
|
||||
|
@ -183,10 +186,13 @@ pub fn flush<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(this) = this {
|
||||
let data = this
|
||||
.get_property(&Multiname::public("data"), activation)?
|
||||
.get_public_property("data", activation)?
|
||||
.coerce_to_object(activation)?;
|
||||
|
||||
let ruffle_name = Multiname::new(Namespace::Namespace("__ruffle__".into()), "_ruffleName");
|
||||
let ruffle_name = Multiname::new(
|
||||
Namespace::package("__ruffle__", activation.context.gc_context),
|
||||
"_ruffleName",
|
||||
);
|
||||
let name = this
|
||||
.get_property(&ruffle_name, activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::{Error, Object};
|
||||
use crate::avm2_stub_method;
|
||||
use crate::backend::navigator::{NavigationMethod, Request};
|
||||
|
@ -23,7 +22,7 @@ pub fn load<'gc>(
|
|||
};
|
||||
|
||||
let data_format = this
|
||||
.get_property(&Multiname::public("dataFormat"), activation)?
|
||||
.get_public_property("dataFormat", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let data_format = if &data_format == b"binary" {
|
||||
|
@ -48,11 +47,11 @@ fn spawn_fetch<'gc>(
|
|||
data_format: DataFormat,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let url = url_request
|
||||
.get_property(&Multiname::public("url"), activation)?
|
||||
.get_public_property("url", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let method_str = url_request
|
||||
.get_property(&Multiname::public("method"), activation)?
|
||||
.get_public_property("method", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let method = NavigationMethod::from_method_str(&method_str).unwrap_or_else(|| {
|
||||
|
@ -61,10 +60,10 @@ fn spawn_fetch<'gc>(
|
|||
});
|
||||
|
||||
let content_type = url_request
|
||||
.get_property(&Multiname::public("contentType"), activation)?
|
||||
.get_public_property("contentType", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let data = url_request.get_property(&Multiname::public("data"), activation)?;
|
||||
let data = url_request.get_public_property("data", activation)?;
|
||||
|
||||
let data = if let Value::Null = data {
|
||||
None
|
||||
|
@ -80,7 +79,7 @@ fn spawn_fetch<'gc>(
|
|||
if data.is_of_type(activation.avm2().classes().urlvariables, activation) {
|
||||
if &*content_type == b"application/x-www-form-urlencoded" {
|
||||
let data = data
|
||||
.call_property(&Multiname::public("toString"), &[], activation)?
|
||||
.call_public_property("toString", &[], activation)?
|
||||
.coerce_to_string(activation)?
|
||||
.to_string()
|
||||
.into_bytes();
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm2::Error;
|
|||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.system.ApplicationDomain`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -71,7 +71,7 @@ pub fn get_definition<'gc>(
|
|||
.cloned()
|
||||
.unwrap_or_else(|| "".into())
|
||||
.coerce_to_string(activation)?;
|
||||
let name = QName::from_qualified_name(name, activation.context.gc_context);
|
||||
let name = QName::from_qualified_name(name, activation);
|
||||
let (qname, mut defined_script) = match appdomain.get_defining_script(&name.into())? {
|
||||
Some(data) => data,
|
||||
None => {
|
||||
|
@ -107,7 +107,7 @@ pub fn has_definition<'gc>(
|
|||
.unwrap_or_else(|| "".into())
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let qname = QName::from_qualified_name(name, activation.context.gc_context);
|
||||
let qname = QName::from_qualified_name(name, activation);
|
||||
|
||||
return Ok(appdomain.has_definition(qname).into());
|
||||
}
|
||||
|
@ -147,10 +147,11 @@ pub fn domain_memory<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `ApplicationDomain`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.system"), "ApplicationDomain"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.system", mc), "ApplicationDomain"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(
|
||||
instance_init,
|
||||
"<ApplicationDomain instance initializer>",
|
||||
|
@ -165,7 +166,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
|
||||
const PUBLIC_CLASS_PROPERTIES: &[(&str, Option<NativeMethodImpl>, Option<NativeMethodImpl>)] =
|
||||
&[("currentDomain", Some(current_domain), None)];
|
||||
write.define_public_builtin_class_properties(mc, PUBLIC_CLASS_PROPERTIES);
|
||||
write.define_builtin_class_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_PROPERTIES: &[(
|
||||
&str,
|
||||
|
@ -175,13 +180,21 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("domainMemory", Some(domain_memory), Some(set_domain_memory)),
|
||||
("parentDomain", Some(parent_domain), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("getDefinition", get_definition),
|
||||
("hasDefinition", has_definition),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::{ArrayObject, ArrayStorage, Error};
|
|||
use crate::avm2_stub_getter;
|
||||
use crate::character::Character;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.text.Font`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -177,10 +177,11 @@ pub fn register_font<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Font`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.text"), "Font"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.text", mc), "Font"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Font instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Font class initializer>", mc),
|
||||
mc,
|
||||
|
@ -199,16 +200,28 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("fontStyle", Some(font_style), None),
|
||||
("fontType", Some(font_type), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("hasGlyphs", has_glyphs)];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("enumerateFonts", enumerate_fonts),
|
||||
("registerFont", register_font),
|
||||
];
|
||||
write.define_public_builtin_class_methods(mc, PUBLIC_CLASS_METHODS);
|
||||
write.define_builtin_class_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::html::TextFormat;
|
|||
use crate::string::AvmString;
|
||||
use crate::tag_utils::SwfMovie;
|
||||
use crate::{avm2_stub_getter, avm2_stub_setter};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::sync::Arc;
|
||||
use swf::Color;
|
||||
|
||||
|
@ -1296,11 +1296,12 @@ pub fn set_restrict<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `TextField`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.text"), "TextField"),
|
||||
QName::new(Namespace::package("flash.text", mc), "TextField"),
|
||||
Some(Multiname::new(
|
||||
Namespace::package("flash.display"),
|
||||
Namespace::package("flash.display", mc),
|
||||
"InteractiveObject",
|
||||
)),
|
||||
Method::from_builtin(instance_init, "<TextField instance initializer>", mc),
|
||||
|
@ -1364,7 +1365,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("sharpness", Some(sharpness), Some(set_sharpness)),
|
||||
("numLines", Some(num_lines), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("appendText", append_text),
|
||||
|
@ -1375,7 +1380,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("setTextFormat", set_text_format),
|
||||
("getLineMetrics", get_line_metrics),
|
||||
];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::avm2::QName;
|
|||
use crate::ecma_conversions::round_to_even;
|
||||
use crate::html::TextFormat;
|
||||
use crate::string::{AvmString, WStr};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `flash.text.TextFormat`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -489,11 +489,8 @@ fn set_tab_stops<'gc>(
|
|||
|
||||
let tab_stops: Result<Vec<_>, Error<'gc>> = (0..length)
|
||||
.map(|i| {
|
||||
let element = object.get_property(
|
||||
&Multiname::public(AvmString::new_utf8(
|
||||
activation.context.gc_context,
|
||||
i.to_string(),
|
||||
)),
|
||||
let element = object.get_public_property(
|
||||
AvmString::new_utf8(activation.context.gc_context, i.to_string()),
|
||||
activation,
|
||||
)?;
|
||||
Ok(round_to_even(element.coerce_to_number(activation)?).into())
|
||||
|
@ -570,10 +567,11 @@ fn set_url<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `TextFormat`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package("flash.text"), "TextFormat"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(Namespace::package("flash.text", mc), "TextFormat"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<TextFormat instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<TextFormat class initializer>", mc),
|
||||
mc,
|
||||
|
@ -640,7 +638,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
),
|
||||
("url", Some(getter!(url)), Some(setter!(set_url))),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::multiname::Multiname;
|
||||
use crate::avm2::object::{Object, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
|
@ -11,26 +10,16 @@ pub fn hide_built_in_items<'gc>(
|
|||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(this) = this {
|
||||
if let Value::Object(mut items) =
|
||||
this.get_property(&Multiname::public("builtInItems"), activation)?
|
||||
{
|
||||
if let Value::Object(mut items) = this.get_public_property("builtInItems", activation)? {
|
||||
// items is a ContextMenuBuiltInItems
|
||||
items.set_property(
|
||||
&Multiname::public("forwardAndBack"),
|
||||
Value::Bool(false),
|
||||
activation,
|
||||
)?;
|
||||
items.set_property(&Multiname::public("loop"), Value::Bool(false), activation)?;
|
||||
items.set_property(&Multiname::public("play"), Value::Bool(false), activation)?;
|
||||
items.set_property(&Multiname::public("print"), Value::Bool(false), activation)?;
|
||||
items.set_property(
|
||||
&Multiname::public("quality"),
|
||||
Value::Bool(false),
|
||||
activation,
|
||||
)?;
|
||||
items.set_property(&Multiname::public("rewind"), Value::Bool(false), activation)?;
|
||||
items.set_property(&Multiname::public("save"), Value::Bool(false), activation)?;
|
||||
items.set_property(&Multiname::public("zoom"), Value::Bool(false), activation)?;
|
||||
items.set_public_property("forwardAndBack", Value::Bool(false), activation)?;
|
||||
items.set_public_property("loop", Value::Bool(false), activation)?;
|
||||
items.set_public_property("play", Value::Bool(false), activation)?;
|
||||
items.set_public_property("print", Value::Bool(false), activation)?;
|
||||
items.set_public_property("quality", Value::Bool(false), activation)?;
|
||||
items.set_public_property("rewind", Value::Bool(false), activation)?;
|
||||
items.set_public_property("save", Value::Bool(false), activation)?;
|
||||
items.set_public_property("zoom", Value::Bool(false), activation)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +35,7 @@ pub fn make_context_menu_state<'gc>(
|
|||
macro_rules! check_bool {
|
||||
( $obj:expr, $name:expr, $value:expr ) => {
|
||||
matches!(
|
||||
$obj.get_property(&Multiname::public($name), activation),
|
||||
$obj.get_public_property($name, activation),
|
||||
Ok(Value::Bool($value))
|
||||
)
|
||||
};
|
||||
|
@ -54,9 +43,7 @@ pub fn make_context_menu_state<'gc>(
|
|||
|
||||
let mut builtin_items = context_menu::BuiltInItemFlags::for_stage(activation.context.stage);
|
||||
if let Some(menu) = menu {
|
||||
if let Ok(Value::Object(builtins)) =
|
||||
menu.get_property(&Multiname::public("builtInItems"), activation)
|
||||
{
|
||||
if let Ok(Value::Object(builtins)) = menu.get_public_property("builtInItems", activation) {
|
||||
if check_bool!(builtins, "zoom", false) {
|
||||
builtin_items.zoom = false;
|
||||
}
|
||||
|
@ -84,8 +71,7 @@ pub fn make_context_menu_state<'gc>(
|
|||
result.build_builtin_items(builtin_items, activation.context.stage);
|
||||
|
||||
if let Some(menu) = menu {
|
||||
if let Ok(Value::Object(custom_items)) =
|
||||
menu.get_property(&Multiname::public("customItems"), activation)
|
||||
if let Ok(Value::Object(custom_items)) = menu.get_public_property("customItems", activation)
|
||||
{
|
||||
// note: this borrows the array, but it shouldn't be possible for
|
||||
// AS to get invoked here and cause BorrowMutError
|
||||
|
@ -94,7 +80,7 @@ pub fn make_context_menu_state<'gc>(
|
|||
// this is a CustomMenuItem
|
||||
if let Some(Value::Object(item)) = item {
|
||||
let caption = if let Ok(Value::String(s)) =
|
||||
item.get_property(&Multiname::public("caption"), activation)
|
||||
item.get_public_property("caption", activation)
|
||||
{
|
||||
s
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,6 @@ pub mod dictionary;
|
|||
pub mod proxy;
|
||||
pub mod timer;
|
||||
|
||||
/// `flash.utils.flash_proxy` namespace
|
||||
pub const NS_FLASH_PROXY: &str = "http://www.adobe.com/2006/actionscript/flash/proxy";
|
||||
|
||||
/// Implements `flash.utils.getTimer`
|
||||
pub fn get_timer<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
|
@ -260,6 +257,6 @@ pub fn get_definition_by_name<'gc>(
|
|||
.get(0)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_string(activation)?;
|
||||
let qname = QName::from_qualified_name(name, activation.context.gc_context);
|
||||
let qname = QName::from_qualified_name(name, activation);
|
||||
appdomain.get_defined_value(activation, qname)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::{Error, Object};
|
||||
use crate::timer::TimerCallback;
|
||||
|
||||
|
@ -17,7 +16,7 @@ pub fn stop<'gc>(
|
|||
let mut this = this.expect("`this` should be set in native method!");
|
||||
let id = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_timerId"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_timerId"),
|
||||
activation,
|
||||
)
|
||||
.unwrap()
|
||||
|
@ -26,7 +25,7 @@ pub fn stop<'gc>(
|
|||
if id != -1 {
|
||||
activation.context.timers.remove(id);
|
||||
this.set_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_timerId"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_timerId"),
|
||||
(-1).into(),
|
||||
activation,
|
||||
)?;
|
||||
|
@ -44,7 +43,7 @@ pub fn start<'gc>(
|
|||
let mut this = this.expect("`this` should be set in native method!");
|
||||
let id = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_timerId"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_timerId"),
|
||||
activation,
|
||||
)
|
||||
.unwrap()
|
||||
|
@ -52,7 +51,7 @@ pub fn start<'gc>(
|
|||
|
||||
let delay = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_delay"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_delay"),
|
||||
activation,
|
||||
)
|
||||
.unwrap()
|
||||
|
@ -61,7 +60,7 @@ pub fn start<'gc>(
|
|||
if id == -1 {
|
||||
let on_update = this
|
||||
.get_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "onUpdate"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "onUpdate"),
|
||||
activation,
|
||||
)?
|
||||
.coerce_to_object(activation)?;
|
||||
|
@ -74,7 +73,7 @@ pub fn start<'gc>(
|
|||
false,
|
||||
);
|
||||
this.set_property(
|
||||
&Multiname::new(Namespace::Private("".into()), "_timerId"),
|
||||
&Multiname::new(activation.avm2().ruffle_private_namespace, "_timerId"),
|
||||
id.into(),
|
||||
activation,
|
||||
)?;
|
||||
|
|
|
@ -8,9 +8,8 @@ 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::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Function`'s instance initializer.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -36,8 +35,8 @@ pub fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let function_proto = this_class.prototype();
|
||||
|
||||
function_proto.set_property_local(
|
||||
&Multiname::public("call"),
|
||||
function_proto.set_string_property_local(
|
||||
"call",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(call, "call", activation.context.gc_context),
|
||||
|
@ -48,8 +47,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
function_proto.set_property_local(
|
||||
&Multiname::public("apply"),
|
||||
function_proto.set_string_property_local(
|
||||
"apply",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(apply, "apply", activation.context.gc_context),
|
||||
|
@ -181,10 +180,11 @@ fn set_prototype<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Function`'s class.
|
||||
pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let gc_context = activation.context.gc_context;
|
||||
let function_class = Class::new(
|
||||
QName::new(Namespace::public(), "Function"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Function"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Function instance initializer>", gc_context),
|
||||
Method::from_builtin(class_init, "<Function class initializer>", gc_context),
|
||||
gc_context,
|
||||
|
@ -194,7 +194,11 @@ pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Cl
|
|||
|
||||
// Fixed traits (in AS3 namespace)
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("call", call), ("apply", apply)];
|
||||
write.define_as3_builtin_instance_methods(gc_context, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
gc_context,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_PROPERTIES: &[(
|
||||
&str,
|
||||
|
@ -204,7 +208,11 @@ pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Cl
|
|||
("prototype", Some(prototype), Some(set_prototype)),
|
||||
("length", Some(length), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(gc_context, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
gc_context,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
write.set_instance_allocator(function_allocator);
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@ use crate::avm2::object::Object;
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `global`'s instance constructor.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -34,10 +33,11 @@ pub fn class_init<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `global`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
Class::new(
|
||||
QName::new(Namespace::public(), "global"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "global"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<global instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<global class initializer>", mc),
|
||||
mc,
|
||||
|
|
|
@ -7,10 +7,9 @@ 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::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{AvmString, Error};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `int`'s instance initializer.
|
||||
fn instance_init<'gc>(
|
||||
|
@ -59,8 +58,8 @@ fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let int_proto = this_class.prototype();
|
||||
|
||||
int_proto.set_property_local(
|
||||
&Multiname::public("toExponential"),
|
||||
int_proto.set_string_property_local(
|
||||
"toExponential",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_exponential, "toExponential", gc_context),
|
||||
|
@ -71,8 +70,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
int_proto.set_property_local(
|
||||
&Multiname::public("toFixed"),
|
||||
int_proto.set_string_property_local(
|
||||
"toFixed",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_fixed, "toFixed", gc_context),
|
||||
|
@ -83,8 +82,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
int_proto.set_property_local(
|
||||
&Multiname::public("toPrecision"),
|
||||
int_proto.set_string_property_local(
|
||||
"toPrecision",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_precision, "toPrecision", gc_context),
|
||||
|
@ -95,8 +94,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
int_proto.set_property_local(
|
||||
&Multiname::public("toString"),
|
||||
int_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", gc_context),
|
||||
|
@ -107,8 +106,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
int_proto.set_property_local(
|
||||
&Multiname::public("valueOf"),
|
||||
int_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", gc_context),
|
||||
|
@ -265,10 +264,11 @@ fn value_of<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `int`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "int"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "int"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<int instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<int class initializer>", mc),
|
||||
mc,
|
||||
|
@ -284,7 +284,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
));
|
||||
|
||||
const CLASS_CONSTANTS: &[(&str, i32)] = &[("MAX_VALUE", i32::MAX), ("MIN_VALUE", i32::MIN)];
|
||||
write.define_public_constant_int_class_traits(CLASS_CONSTANTS);
|
||||
write.define_constant_int_class_traits(
|
||||
activation.avm2().public_namespace,
|
||||
CLASS_CONSTANTS,
|
||||
activation,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("toExponential", to_exponential),
|
||||
|
@ -293,7 +297,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("toString", to_string),
|
||||
("valueOf", value_of),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use crate::avm2::globals::array::ArrayIter;
|
|||
use crate::avm2::object::{ArrayObject, FunctionObject, Object, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::ecma_conversions::f64_to_wrapping_i32;
|
||||
use crate::string::{AvmString, Units};
|
||||
use serde::Serialize;
|
||||
|
@ -42,9 +41,9 @@ fn deserialize_json_inner<'gc>(
|
|||
Some(reviver) => reviver.call(None, &[key.into(), val], activation)?,
|
||||
};
|
||||
if matches!(mapped_val, Value::Undefined) {
|
||||
obj.delete_property(activation, &Multiname::public(key))?;
|
||||
obj.delete_public_property(activation, key)?;
|
||||
} else {
|
||||
obj.set_property(&Multiname::public(key), mapped_val, activation)?;
|
||||
obj.set_public_property(key, mapped_val, activation)?;
|
||||
}
|
||||
}
|
||||
obj.into()
|
||||
|
@ -119,7 +118,7 @@ impl<'gc> AvmSerializer<'gc> {
|
|||
} else {
|
||||
let obj = value.as_object().unwrap();
|
||||
let to_json = obj
|
||||
.get_property(&Multiname::public("toJSON"), activation)?
|
||||
.get_public_property("toJSON", activation)?
|
||||
.as_object()
|
||||
.and_then(|obj| obj.as_function_object());
|
||||
if let Some(to_json) = to_json {
|
||||
|
@ -152,7 +151,7 @@ impl<'gc> AvmSerializer<'gc> {
|
|||
while let Some(r) = iter.next(activation) {
|
||||
let item = r?.1;
|
||||
let key = item.coerce_to_string(activation)?;
|
||||
let value = obj.get_property(&Multiname::public(key), activation)?;
|
||||
let value = obj.get_public_property(key, activation)?;
|
||||
let mapped = self.map_value(activation, || key, value)?;
|
||||
if !matches!(mapped, Value::Undefined) {
|
||||
js_obj.insert(
|
||||
|
@ -168,7 +167,7 @@ impl<'gc> AvmSerializer<'gc> {
|
|||
Value::Undefined => break,
|
||||
name_val => {
|
||||
let name = name_val.coerce_to_string(activation)?;
|
||||
let value = obj.get_property(&Multiname::public(name), activation)?;
|
||||
let value = obj.get_public_property(name, activation)?;
|
||||
let mapped = self.map_value(activation, || name, value)?;
|
||||
if !matches!(mapped, Value::Undefined) {
|
||||
js_obj.insert(
|
||||
|
|
|
@ -7,10 +7,9 @@ use crate::avm2::object::{namespace_allocator, Object};
|
|||
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;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Namespace`'s instance initializer.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -54,10 +53,11 @@ pub fn class_init<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Namespace`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "Namespace"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Namespace"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Namespace instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Namespace class initializer>", mc),
|
||||
mc,
|
||||
|
|
|
@ -6,10 +6,9 @@ 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::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{AvmString, Error};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Number`'s instance initializer.
|
||||
fn instance_init<'gc>(
|
||||
|
@ -58,8 +57,8 @@ fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let number_proto = this_class.prototype();
|
||||
|
||||
number_proto.set_property_local(
|
||||
&Multiname::public("toExponential"),
|
||||
number_proto.set_string_property_local(
|
||||
"toExponential",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_exponential, "toExponential", gc_context),
|
||||
|
@ -70,8 +69,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
number_proto.set_property_local(
|
||||
&Multiname::public("toFixed"),
|
||||
number_proto.set_string_property_local(
|
||||
"toFixed",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_fixed, "toFixed", gc_context),
|
||||
|
@ -82,8 +81,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
number_proto.set_property_local(
|
||||
&Multiname::public("toPrecision"),
|
||||
number_proto.set_string_property_local(
|
||||
"toPrecision",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_precision, "toPrecision", gc_context),
|
||||
|
@ -94,8 +93,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
number_proto.set_property_local(
|
||||
&Multiname::public("toString"),
|
||||
number_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", gc_context),
|
||||
|
@ -106,8 +105,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
number_proto.set_property_local(
|
||||
&Multiname::public("valueOf"),
|
||||
number_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", gc_context),
|
||||
|
@ -351,10 +350,11 @@ fn value_of<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Number`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "Number"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "Number"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Number instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Number class initializer>", mc),
|
||||
mc,
|
||||
|
@ -376,11 +376,19 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("NEGATIVE_INFINITY", f64::NEG_INFINITY),
|
||||
("POSITIVE_INFINITY", f64::INFINITY),
|
||||
];
|
||||
write.define_public_constant_number_class_traits(CLASS_CONSTANTS);
|
||||
write.define_constant_number_class_traits(
|
||||
activation.avm2().public_namespace,
|
||||
CLASS_CONSTANTS,
|
||||
activation,
|
||||
);
|
||||
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] =
|
||||
&[("toLocaleString", to_locale_string)];
|
||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("toExponential", to_exponential),
|
||||
|
@ -389,7 +397,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("toString", to_string),
|
||||
("valueOf", value_of),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -8,9 +8,8 @@ use crate::avm2::traits::Trait;
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `Object`'s instance initializer.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -50,8 +49,8 @@ pub fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let object_proto = this_class.prototype();
|
||||
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("hasOwnProperty"),
|
||||
object_proto.set_string_property_local(
|
||||
"hasOwnProperty",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(has_own_property, "hasOwnProperty", gc_context),
|
||||
|
@ -62,8 +61,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("propertyIsEnumerable"),
|
||||
object_proto.set_string_property_local(
|
||||
"propertyIsEnumerable",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(property_is_enumerable, "propertyIsEnumerable", gc_context),
|
||||
|
@ -74,8 +73,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("setPropertyIsEnumerable"),
|
||||
object_proto.set_string_property_local(
|
||||
"setPropertyIsEnumerable",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(
|
||||
|
@ -90,8 +89,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("isPrototypeOf"),
|
||||
object_proto.set_string_property_local(
|
||||
"isPrototypeOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(is_prototype_of, "isPrototypeOf", gc_context),
|
||||
|
@ -102,8 +101,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("toString"),
|
||||
object_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", gc_context),
|
||||
|
@ -114,8 +113,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("toLocaleString"),
|
||||
object_proto.set_string_property_local(
|
||||
"toLocaleString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_locale_string, "toLocaleString", gc_context),
|
||||
|
@ -126,8 +125,8 @@ pub fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
object_proto.set_property_local(
|
||||
&Multiname::public("valueOf"),
|
||||
object_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", gc_context),
|
||||
|
@ -211,7 +210,7 @@ pub fn has_own_property<'gc>(
|
|||
args.get(0).ok_or_else(|| "No name specified".into());
|
||||
let name = name?.coerce_to_string(activation)?;
|
||||
|
||||
let multiname = Multiname::public(name);
|
||||
let multiname = Multiname::new(activation.avm2().public_namespace, name);
|
||||
Ok(this.has_own_property(&multiname).into())
|
||||
}
|
||||
|
||||
|
@ -274,9 +273,10 @@ pub fn set_property_is_enumerable<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Object`'s class.
|
||||
pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let gc_context = activation.context.gc_context;
|
||||
let object_class = Class::new(
|
||||
QName::new(Namespace::public(), "Object"),
|
||||
QName::new(activation.avm2().public_namespace, "Object"),
|
||||
None,
|
||||
Method::from_builtin(instance_init, "<Object instance initializer>", gc_context),
|
||||
Method::from_builtin(class_init, "<Object class initializer>", gc_context),
|
||||
|
@ -290,18 +290,22 @@ pub fn create_class<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Cl
|
|||
));
|
||||
|
||||
write.define_class_trait(Trait::from_const(
|
||||
QName::new(Namespace::public(), "length"),
|
||||
Multiname::public("int"),
|
||||
QName::new(activation.avm2().public_namespace, "length"),
|
||||
Multiname::new(activation.avm2().public_namespace, "int"),
|
||||
None,
|
||||
));
|
||||
|
||||
// Fixed traits (in AS3 namespace)
|
||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("hasOwnProperty", has_own_property),
|
||||
("isPrototypeOf", is_prototype_of),
|
||||
("propertyIsEnumerable", property_is_enumerable),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(gc_context, PUBLIC_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
gc_context,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
object_class
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::avm2::Error;
|
|||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `QName`'s instance initializer.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -25,8 +25,11 @@ pub fn instance_init<'gc>(
|
|||
|
||||
let namespace = match ns_arg {
|
||||
Value::Object(o) if o.as_namespace().is_some() => *o.as_namespace().unwrap(),
|
||||
Value::Undefined | Value::Null => Namespace::Any,
|
||||
v => Namespace::Namespace(v.coerce_to_string(activation)?),
|
||||
Value::Undefined | Value::Null => Namespace::any(activation.context.gc_context),
|
||||
v => Namespace::package(
|
||||
v.coerce_to_string(activation)?,
|
||||
activation.context.gc_context,
|
||||
),
|
||||
};
|
||||
|
||||
(namespace, local_arg)
|
||||
|
@ -36,7 +39,7 @@ pub fn instance_init<'gc>(
|
|||
Value::Object(o) if o.as_qname_object().is_some() => {
|
||||
o.as_qname_object().unwrap().qname().unwrap().namespace()
|
||||
}
|
||||
_ => Namespace::Namespace("".into()),
|
||||
_ => activation.avm2().public_namespace,
|
||||
};
|
||||
|
||||
(namespace, qname_arg)
|
||||
|
@ -68,10 +71,10 @@ pub fn class_init<'gc>(
|
|||
let this = this.unwrap();
|
||||
let scope = activation.create_scopechain();
|
||||
let this_class = this.as_class_object().unwrap();
|
||||
let mut qname_proto = this_class.prototype();
|
||||
let qname_proto = this_class.prototype();
|
||||
|
||||
qname_proto.set_property(
|
||||
&Multiname::public("toString"),
|
||||
qname_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", activation.context.gc_context),
|
||||
|
@ -83,8 +86,8 @@ pub fn class_init<'gc>(
|
|||
activation,
|
||||
)?;
|
||||
|
||||
qname_proto.set_property(
|
||||
&Multiname::public("valueOf"),
|
||||
qname_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", activation.context.gc_context),
|
||||
|
@ -134,7 +137,7 @@ pub fn uri<'gc>(
|
|||
if let Some(this) = this.and_then(|t| t.as_qname_object()) {
|
||||
if let Some(qname) = this.qname() {
|
||||
return Ok(match qname.namespace() {
|
||||
Namespace::Any => Value::Null,
|
||||
ns if ns.is_any() => Value::Null,
|
||||
ns => ns.as_uri().into(),
|
||||
});
|
||||
}
|
||||
|
@ -172,10 +175,11 @@ pub fn value_of<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `QName`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "QName"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "QName"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<QName instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<QName class initializer>", mc),
|
||||
mc,
|
||||
|
@ -193,11 +197,19 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("localName", Some(local_name), None),
|
||||
("uri", Some(uri), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] =
|
||||
&[("toString", to_string), ("valueOf", value_of)];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -7,11 +7,10 @@ use crate::avm2::regexp::RegExpFlags;
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{activation::Activation, array::ArrayStorage};
|
||||
use crate::string::{AvmString, WString};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `RegExp`'s instance initializer.
|
||||
pub fn instance_init<'gc>(
|
||||
|
@ -233,13 +232,9 @@ pub fn exec<'gc>(
|
|||
|
||||
let object = ArrayObject::from_storage(activation, storage)?;
|
||||
|
||||
object.set_property_local(
|
||||
&Multiname::public("index"),
|
||||
Value::Number(index as f64),
|
||||
activation,
|
||||
)?;
|
||||
object.set_string_property_local("index", Value::Number(index as f64), activation)?;
|
||||
|
||||
object.set_property_local(&Multiname::public("input"), text.into(), activation)?;
|
||||
object.set_string_property_local("input", text.into(), activation)?;
|
||||
|
||||
return Ok(object.into());
|
||||
}
|
||||
|
@ -268,16 +263,25 @@ pub fn test<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `RegExp`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "RegExp"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "RegExp"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin_and_params(
|
||||
instance_init,
|
||||
"<RegExp instance initializer>",
|
||||
vec![
|
||||
ParamConfig::optional("re", Multiname::public("String"), ""),
|
||||
ParamConfig::optional("flags", Multiname::public("String"), ""),
|
||||
ParamConfig::optional(
|
||||
"re",
|
||||
Multiname::new(activation.avm2().public_namespace, "String"),
|
||||
"",
|
||||
),
|
||||
ParamConfig::optional(
|
||||
"flags",
|
||||
Multiname::new(activation.avm2().public_namespace, "String"),
|
||||
"",
|
||||
),
|
||||
],
|
||||
false,
|
||||
mc,
|
||||
|
@ -307,10 +311,18 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("lastIndex", Some(last_index), Some(set_last_index)),
|
||||
("source", Some(source), None),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("exec", exec), ("test", test)];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -8,11 +8,10 @@ use crate::avm2::regexp::RegExpFlags;
|
|||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{ArrayObject, ArrayStorage};
|
||||
use crate::string::{AvmString, WString};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::iter;
|
||||
|
||||
/// Implements `String`'s instance initializer.
|
||||
|
@ -611,10 +610,11 @@ fn to_upper_case<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `String`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "String"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "String"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<String instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<String class initializer>", mc),
|
||||
mc,
|
||||
|
@ -629,7 +629,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
Option<NativeMethodImpl>,
|
||||
Option<NativeMethodImpl>,
|
||||
)] = &[("length", Some(length), None)];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("charAt", char_at),
|
||||
|
@ -650,12 +654,20 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("toLowerCase", to_lower_case),
|
||||
("toUpperCase", to_upper_case),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
const AS3_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[("fromCharCode", from_char_code)];
|
||||
const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[("fromCharCode", from_char_code)];
|
||||
write.define_as3_builtin_class_methods(mc, AS3_CLASS_METHODS);
|
||||
write.define_public_builtin_class_methods(mc, PUBLIC_CLASS_METHODS);
|
||||
write.define_builtin_class_methods(mc, activation.avm2().as3_namespace, AS3_CLASS_METHODS);
|
||||
write.define_builtin_class_methods(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_CLASS_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -7,10 +7,9 @@ use crate::avm2::method::{Method, NativeMethodImpl, ParamConfig};
|
|||
use crate::avm2::object::{primitive_allocator, FunctionObject, Object, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{AvmString, Error};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
|
||||
/// Implements `uint`'s instance initializer.
|
||||
fn instance_init<'gc>(
|
||||
|
@ -59,8 +58,8 @@ fn class_init<'gc>(
|
|||
let this_class = this.as_class_object().unwrap();
|
||||
let uint_proto = this_class.prototype();
|
||||
|
||||
uint_proto.set_property_local(
|
||||
&Multiname::public("toExponential"),
|
||||
uint_proto.set_string_property_local(
|
||||
"toExponential",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_exponential, "toExponential", gc_context),
|
||||
|
@ -71,8 +70,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
uint_proto.set_property_local(
|
||||
&Multiname::public("toFixed"),
|
||||
uint_proto.set_string_property_local(
|
||||
"toFixed",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_fixed, "toFixed", gc_context),
|
||||
|
@ -83,8 +82,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
uint_proto.set_property_local(
|
||||
&Multiname::public("toPrecision"),
|
||||
uint_proto.set_string_property_local(
|
||||
"toPrecision",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_precision, "toPrecision", gc_context),
|
||||
|
@ -95,8 +94,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
uint_proto.set_property_local(
|
||||
&Multiname::public("toString"),
|
||||
uint_proto.set_string_property_local(
|
||||
"toString",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(to_string, "toString", gc_context),
|
||||
|
@ -107,8 +106,8 @@ fn class_init<'gc>(
|
|||
.into(),
|
||||
activation,
|
||||
)?;
|
||||
uint_proto.set_property_local(
|
||||
&Multiname::public("valueOf"),
|
||||
uint_proto.set_string_property_local(
|
||||
"valueOf",
|
||||
FunctionObject::from_method(
|
||||
activation,
|
||||
Method::from_builtin(value_of, "valueOf", gc_context),
|
||||
|
@ -264,10 +263,11 @@ fn value_of<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `uint`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "uint"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().public_namespace, "uint"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<uint instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<uint class initializer>", mc),
|
||||
mc,
|
||||
|
@ -279,13 +279,20 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
write.set_native_instance_init(Method::from_builtin_and_params(
|
||||
native_instance_init,
|
||||
"<uint native instance initializer>",
|
||||
vec![ParamConfig::of_type("num", Multiname::public("Object"))],
|
||||
vec![ParamConfig::of_type(
|
||||
"num",
|
||||
Multiname::new(activation.avm2().public_namespace, "Object"),
|
||||
)],
|
||||
false,
|
||||
mc,
|
||||
));
|
||||
|
||||
const CLASS_CONSTANTS: &[(&str, u32)] = &[("MAX_VALUE", u32::MAX), ("MIN_VALUE", u32::MIN)];
|
||||
write.define_public_constant_uint_class_traits(CLASS_CONSTANTS);
|
||||
write.define_constant_uint_class_traits(
|
||||
activation.avm2().public_namespace,
|
||||
CLASS_CONSTANTS,
|
||||
activation,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("toExponential", to_exponential),
|
||||
|
@ -294,7 +301,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("toString", to_string),
|
||||
("valueOf", value_of),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -6,17 +6,15 @@ use crate::avm2::globals::array::{
|
|||
compare_numeric, compare_string_case_insensitive, compare_string_case_sensitive, ArrayIter,
|
||||
SortOptions,
|
||||
};
|
||||
use crate::avm2::globals::NS_VECTOR;
|
||||
use crate::avm2::method::{Method, NativeMethodImpl};
|
||||
use crate::avm2::object::{vector_allocator, FunctionObject, Object, TObject, VectorObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::vector::VectorStorage;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
use gc_arena::GcCell;
|
||||
use std::cmp::{max, min, Ordering};
|
||||
|
||||
/// Implements `Vector`'s instance constructor.
|
||||
|
@ -71,7 +69,7 @@ fn class_call<'gc>(
|
|||
}
|
||||
|
||||
let length = arg
|
||||
.get_property(&Multiname::public("length"), activation)?
|
||||
.get_public_property("length", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
|
||||
let mut new_storage = VectorStorage::new(0, false, value_type, activation);
|
||||
|
@ -98,17 +96,22 @@ pub fn class_init<'gc>(
|
|||
let mut globals = activation.global_scope().unwrap();
|
||||
let mut domain = activation.domain();
|
||||
|
||||
let vector_internal_namespace = activation.avm2().vector_internal_namespace;
|
||||
|
||||
//We have to grab Object's defining script instead of our own, because
|
||||
//at this point Vector hasn't actually been defined yet. It doesn't
|
||||
//matter because we only have one script for our globals.
|
||||
let (_, script) = domain
|
||||
.get_defining_script(&Multiname::public("Object"))?
|
||||
.get_defining_script(&Multiname::new(
|
||||
activation.avm2().public_namespace,
|
||||
"Object",
|
||||
))?
|
||||
.unwrap();
|
||||
|
||||
let class_class = activation.avm2().classes().class;
|
||||
let int_class = activation.avm2().classes().int;
|
||||
let int_vector_class = this.apply(activation, &[int_class.into()])?;
|
||||
let int_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$int");
|
||||
let int_vector_name = QName::new(vector_internal_namespace, "Vector$int");
|
||||
int_vector_class
|
||||
.inner_class_definition()
|
||||
.write(activation.context.gc_context)
|
||||
|
@ -124,7 +127,7 @@ pub fn class_init<'gc>(
|
|||
|
||||
let uint_class = activation.avm2().classes().uint;
|
||||
let uint_vector_class = this.apply(activation, &[uint_class.into()])?;
|
||||
let uint_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$uint");
|
||||
let uint_vector_name = QName::new(vector_internal_namespace, "Vector$uint");
|
||||
uint_vector_class
|
||||
.inner_class_definition()
|
||||
.write(activation.context.gc_context)
|
||||
|
@ -140,7 +143,7 @@ pub fn class_init<'gc>(
|
|||
|
||||
let number_class = activation.avm2().classes().number;
|
||||
let number_vector_class = this.apply(activation, &[number_class.into()])?;
|
||||
let number_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$double");
|
||||
let number_vector_name = QName::new(vector_internal_namespace, "Vector$double");
|
||||
number_vector_class
|
||||
.inner_class_definition()
|
||||
.write(activation.context.gc_context)
|
||||
|
@ -155,7 +158,7 @@ pub fn class_init<'gc>(
|
|||
domain.export_definition(number_vector_name, script, activation.context.gc_context)?;
|
||||
|
||||
let object_vector_class = this.apply(activation, &[Value::Null])?;
|
||||
let object_vector_name = QName::new(Namespace::internal(NS_VECTOR), "Vector$object");
|
||||
let object_vector_name = QName::new(vector_internal_namespace, "Vector$object");
|
||||
object_vector_class
|
||||
.inner_class_definition()
|
||||
.write(activation.context.gc_context)
|
||||
|
@ -180,8 +183,8 @@ pub fn specialized_class_init<'gc>(
|
|||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(this) = this {
|
||||
let mut proto = this
|
||||
.get_property(&Multiname::public("prototype"), activation)?
|
||||
let proto = this
|
||||
.get_public_property("prototype", activation)?
|
||||
.as_object()
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
|
@ -213,8 +216,8 @@ pub fn specialized_class_init<'gc>(
|
|||
("splice", splice),
|
||||
];
|
||||
for (pubname, func) in PUBLIC_PROTOTYPE_METHODS {
|
||||
proto.set_property(
|
||||
&Multiname::public(*pubname),
|
||||
proto.set_string_property_local(
|
||||
*pubname,
|
||||
FunctionObject::from_function(
|
||||
activation,
|
||||
Method::from_builtin(*func, pubname, activation.context.gc_context),
|
||||
|
@ -437,7 +440,7 @@ pub fn to_locale_string<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
join_inner(activation, this, &[",".into()], |v, act| {
|
||||
if let Ok(o) = v.coerce_to_object(act) {
|
||||
o.call_property(&Multiname::public("toLocaleString"), &[], act)
|
||||
o.call_public_property("toLocaleString", &[], act)
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -592,7 +595,7 @@ pub fn index_of<'gc>(
|
|||
|
||||
let from_index = if from_index < 0 {
|
||||
let length = this
|
||||
.get_property(&Multiname::public("length"), activation)?
|
||||
.get_public_property("length", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
max(length + from_index, 0) as u32
|
||||
} else {
|
||||
|
@ -629,7 +632,7 @@ pub fn last_index_of<'gc>(
|
|||
|
||||
let from_index = if from_index < 0 {
|
||||
let length = this
|
||||
.get_property(&Multiname::public("length"), activation)?
|
||||
.get_public_property("length", activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
max(length + from_index, 0) as u32
|
||||
} else {
|
||||
|
@ -1006,10 +1009,11 @@ pub fn splice<'gc>(
|
|||
}
|
||||
|
||||
/// Construct `Vector`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Class<'gc>> {
|
||||
let mc = activation.context.gc_context;
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::package(NS_VECTOR), "Vector"),
|
||||
Some(Multiname::public("Object")),
|
||||
QName::new(activation.avm2().vector_public_namespace, "Vector"),
|
||||
Some(Multiname::new(activation.avm2().public_namespace, "Object")),
|
||||
Method::from_builtin(instance_init, "<Vector instance initializer>", mc),
|
||||
Method::from_builtin(class_init, "<Vector class initializer>", mc),
|
||||
mc,
|
||||
|
@ -1038,7 +1042,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("length", Some(length), Some(set_length)),
|
||||
("fixed", Some(fixed), Some(set_fixed)),
|
||||
];
|
||||
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
|
||||
write.define_builtin_instance_properties(
|
||||
mc,
|
||||
activation.avm2().public_namespace,
|
||||
PUBLIC_INSTANCE_PROPERTIES,
|
||||
);
|
||||
|
||||
const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[
|
||||
("concat", concat),
|
||||
|
@ -1063,7 +1071,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
|||
("sort", sort),
|
||||
("splice", splice),
|
||||
];
|
||||
write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS);
|
||||
write.define_builtin_instance_methods(
|
||||
mc,
|
||||
activation.avm2().as3_namespace,
|
||||
AS3_INSTANCE_METHODS,
|
||||
);
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ impl<'gc> BytecodeMethod<'gc> {
|
|||
abc_method: abc_method.0,
|
||||
abc_method_body: None,
|
||||
signature,
|
||||
return_type: Multiname::any(),
|
||||
return_type: Multiname::any(activation.context.gc_context),
|
||||
is_function,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -126,15 +126,13 @@ impl<'gc> Multiname<'gc> {
|
|||
let ns_set = ns_set?;
|
||||
|
||||
if ns_set.len() == 1 {
|
||||
Ok(NamespaceSet::single(Namespace::from_abc_namespace(
|
||||
translation_unit,
|
||||
ns_set[0],
|
||||
mc,
|
||||
)?))
|
||||
Ok(NamespaceSet::single(
|
||||
translation_unit.pool_namespace(ns_set[0], mc)?,
|
||||
))
|
||||
} else {
|
||||
let mut result = Vec::with_capacity(ns_set.len());
|
||||
for ns in ns_set {
|
||||
result.push(Namespace::from_abc_namespace(translation_unit, *ns, mc)?)
|
||||
result.push(translation_unit.pool_namespace(*ns, mc)?)
|
||||
}
|
||||
Ok(NamespaceSet::multiple(result, mc))
|
||||
}
|
||||
|
@ -151,11 +149,7 @@ impl<'gc> Multiname<'gc> {
|
|||
Ok(match abc_multiname {
|
||||
AbcMultiname::QName { namespace, name } | AbcMultiname::QNameA { namespace, name } => {
|
||||
Self {
|
||||
ns: NamespaceSet::single(Namespace::from_abc_namespace(
|
||||
translation_unit,
|
||||
*namespace,
|
||||
mc,
|
||||
)?),
|
||||
ns: NamespaceSet::single(translation_unit.pool_namespace(*namespace, mc)?),
|
||||
name: translation_unit.pool_string_option(name.0, mc)?,
|
||||
params: Vec::new(),
|
||||
flags: Default::default(),
|
||||
|
@ -290,9 +284,9 @@ impl<'gc> Multiname<'gc> {
|
|||
}
|
||||
|
||||
/// Indicates the any type (any name in any namespace).
|
||||
pub fn any() -> Self {
|
||||
pub fn any(mc: MutationContext<'gc, '_>) -> Self {
|
||||
Self {
|
||||
ns: NamespaceSet::single(Namespace::Any),
|
||||
ns: NamespaceSet::single(Namespace::any(mc)),
|
||||
name: None,
|
||||
params: Vec::new(),
|
||||
flags: Default::default(),
|
||||
|
@ -308,15 +302,6 @@ impl<'gc> Multiname<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn public(name: impl Into<AvmString<'gc>>) -> Self {
|
||||
Self {
|
||||
ns: NamespaceSet::single(Namespace::public()),
|
||||
name: Some(name.into()),
|
||||
params: Vec::new(),
|
||||
flags: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn namespace_set(&self) -> &[Namespace<'gc>] {
|
||||
match &self.ns {
|
||||
NamespaceSet::Single(ns) => std::slice::from_ref(ns),
|
||||
|
@ -339,8 +324,8 @@ impl<'gc> Multiname<'gc> {
|
|||
pub fn is_any(&self) -> bool {
|
||||
self.name.is_none()
|
||||
&& match self.ns {
|
||||
NamespaceSet::Single(ns) => ns == Namespace::Any,
|
||||
NamespaceSet::Multiple(ns) => ns.contains(&Namespace::Any),
|
||||
NamespaceSet::Single(ns) => ns.is_any(),
|
||||
NamespaceSet::Multiple(ns) => ns.iter().any(|ns| ns.is_any()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,7 +334,7 @@ impl<'gc> Multiname<'gc> {
|
|||
let ns_match = self
|
||||
.namespace_set()
|
||||
.iter()
|
||||
.any(|ns| *ns == Namespace::Any || *ns == name.namespace());
|
||||
.any(|ns| ns.is_any() || *ns == name.namespace());
|
||||
let name_match = self.name.map(|n| n == name.local_name()).unwrap_or(true);
|
||||
|
||||
ns_match && name_match
|
||||
|
@ -363,7 +348,7 @@ impl<'gc> Multiname<'gc> {
|
|||
pub fn to_qualified_name(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
||||
let mut uri = WString::new();
|
||||
let ns = match self.ns.get(0).filter(|_| self.ns.len() == 1) {
|
||||
Some(Namespace::Any) => "*".into(),
|
||||
Some(ns) if ns.is_any() => "*".into(),
|
||||
Some(ns) => ns.as_uri(),
|
||||
None => "".into(),
|
||||
};
|
||||
|
@ -398,7 +383,7 @@ impl<'gc> Multiname<'gc> {
|
|||
pub fn to_error_qualified_name(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
||||
let mut uri = WString::new();
|
||||
let ns = match self.ns.get(0).filter(|_| self.ns.len() == 1) {
|
||||
Some(Namespace::Any) => "*".into(),
|
||||
Some(ns) if ns.is_any() => "*".into(),
|
||||
Some(ns) => ns.as_uri(),
|
||||
None => "".into(),
|
||||
};
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
use crate::avm2::script::TranslationUnit;
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::{Collect, MutationContext};
|
||||
use gc_arena::{Collect, Gc, MutationContext};
|
||||
use std::fmt::Debug;
|
||||
use swf::avm2::types::{Index, Namespace as AbcNamespace};
|
||||
|
||||
#[derive(Clone, Copy, Collect, Debug)]
|
||||
#[collect(no_drop)]
|
||||
pub struct Namespace<'gc>(pub Gc<'gc, NamespaceData<'gc>>);
|
||||
|
||||
impl<'gc> PartialEq for Namespace<'gc> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
*self.0 == *other.0
|
||||
}
|
||||
}
|
||||
impl<'gc> Eq for Namespace<'gc> {}
|
||||
|
||||
/// Represents the name of a namespace.
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Clone, Copy, Collect, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Clone, Collect, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[collect(no_drop)]
|
||||
pub enum Namespace<'gc> {
|
||||
pub enum NamespaceData<'gc> {
|
||||
// note: this is the default "public namespace", corresponding to both
|
||||
// ABC Namespace and PackageNamespace
|
||||
Namespace(AvmString<'gc>),
|
||||
|
@ -24,13 +35,15 @@ pub enum Namespace<'gc> {
|
|||
impl<'gc> Namespace<'gc> {
|
||||
/// Read a namespace declaration from the ABC constant pool and copy it to
|
||||
/// a namespace value.
|
||||
/// NOTE: you should use the TranslationUnit.pool_namespace instead of calling this.
|
||||
/// otherwise you run a risk of creating a duplicate of private ns singleton.
|
||||
pub fn from_abc_namespace(
|
||||
translation_unit: TranslationUnit<'gc>,
|
||||
namespace_index: Index<AbcNamespace>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<Self, Error<'gc>> {
|
||||
if namespace_index.0 == 0 {
|
||||
return Ok(Self::Any);
|
||||
return Ok(Self::any(mc));
|
||||
}
|
||||
|
||||
let actual_index = namespace_index.0 as usize - 1;
|
||||
|
@ -41,73 +54,84 @@ impl<'gc> Namespace<'gc> {
|
|||
.get(actual_index)
|
||||
.ok_or_else(|| format!("Unknown namespace constant {}", namespace_index.0).into());
|
||||
|
||||
Ok(match abc_namespace? {
|
||||
let ns = match abc_namespace? {
|
||||
AbcNamespace::Namespace(idx) => {
|
||||
Self::Namespace(translation_unit.pool_string(idx.0, mc)?)
|
||||
NamespaceData::Namespace(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Package(idx) => {
|
||||
NamespaceData::Namespace(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Package(idx) => Self::Namespace(translation_unit.pool_string(idx.0, mc)?),
|
||||
AbcNamespace::PackageInternal(idx) => {
|
||||
Self::PackageInternal(translation_unit.pool_string(idx.0, mc)?)
|
||||
NamespaceData::PackageInternal(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Protected(idx) => {
|
||||
Self::Protected(translation_unit.pool_string(idx.0, mc)?)
|
||||
NamespaceData::Protected(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Explicit(idx) => {
|
||||
NamespaceData::Explicit(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Explicit(idx) => Self::Explicit(translation_unit.pool_string(idx.0, mc)?),
|
||||
AbcNamespace::StaticProtected(idx) => {
|
||||
Self::StaticProtected(translation_unit.pool_string(idx.0, mc)?)
|
||||
NamespaceData::StaticProtected(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
AbcNamespace::Private(idx) => Self::Private(translation_unit.pool_string(idx.0, mc)?),
|
||||
})
|
||||
AbcNamespace::Private(idx) => {
|
||||
NamespaceData::Private(translation_unit.pool_string(idx.0, mc)?)
|
||||
}
|
||||
};
|
||||
Ok(Self(Gc::allocate(mc, ns)))
|
||||
}
|
||||
|
||||
pub fn public() -> Self {
|
||||
Self::Namespace("".into())
|
||||
pub fn any(mc: MutationContext<'gc, '_>) -> Self {
|
||||
Self(Gc::allocate(mc, NamespaceData::Any))
|
||||
}
|
||||
|
||||
pub fn as3_namespace() -> Self {
|
||||
Self::Namespace("http://adobe.com/AS3/2006/builtin".into())
|
||||
pub fn package(package_name: impl Into<AvmString<'gc>>, mc: MutationContext<'gc, '_>) -> Self {
|
||||
Self(Gc::allocate(
|
||||
mc,
|
||||
NamespaceData::Namespace(package_name.into()),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn package(package_name: impl Into<AvmString<'gc>>) -> Self {
|
||||
Self::Namespace(package_name.into())
|
||||
pub fn internal(package_name: impl Into<AvmString<'gc>>, mc: MutationContext<'gc, '_>) -> Self {
|
||||
Self(Gc::allocate(
|
||||
mc,
|
||||
NamespaceData::PackageInternal(package_name.into()),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn internal(package_name: impl Into<AvmString<'gc>>) -> Self {
|
||||
Self::PackageInternal(package_name.into())
|
||||
}
|
||||
|
||||
pub fn private(name: impl Into<AvmString<'gc>>) -> Self {
|
||||
Self::Private(name.into())
|
||||
// note: since private namespaces are compared by identity,
|
||||
// if you try using it to create temporary namespaces it will likely not work.
|
||||
pub fn private(name: impl Into<AvmString<'gc>>, mc: MutationContext<'gc, '_>) -> Self {
|
||||
Self(Gc::allocate(mc, NamespaceData::Private(name.into())))
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
matches!(self, Self::Namespace(name) if name.is_empty())
|
||||
matches!(*self.0, NamespaceData::Namespace(name) if name.is_empty())
|
||||
}
|
||||
|
||||
pub fn is_any(&self) -> bool {
|
||||
matches!(self, Self::Any)
|
||||
matches!(*self.0, NamespaceData::Any)
|
||||
}
|
||||
|
||||
pub fn is_private(&self) -> bool {
|
||||
matches!(self, Self::Private(_))
|
||||
matches!(*self.0, NamespaceData::Private(_))
|
||||
}
|
||||
|
||||
pub fn is_namespace(&self) -> bool {
|
||||
matches!(self, Self::Namespace(_))
|
||||
matches!(*self.0, NamespaceData::Namespace(_))
|
||||
}
|
||||
|
||||
/// Get the string value of this namespace, ignoring its type.
|
||||
///
|
||||
/// TODO: Is this *actually* the namespace URI?
|
||||
pub fn as_uri(&self) -> AvmString<'gc> {
|
||||
match self {
|
||||
Self::Namespace(s) => *s,
|
||||
Self::PackageInternal(s) => *s,
|
||||
Self::Protected(s) => *s,
|
||||
Self::Explicit(s) => *s,
|
||||
Self::StaticProtected(s) => *s,
|
||||
Self::Private(s) => *s,
|
||||
Self::Any => "".into(),
|
||||
match &*self.0 {
|
||||
NamespaceData::Namespace(s) => *s,
|
||||
NamespaceData::PackageInternal(s) => *s,
|
||||
NamespaceData::Protected(s) => *s,
|
||||
NamespaceData::Explicit(s) => *s,
|
||||
NamespaceData::StaticProtected(s) => *s,
|
||||
NamespaceData::Private(s) => *s,
|
||||
NamespaceData::Any => "".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,6 +193,18 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
}
|
||||
|
||||
/// Same as get_property, but constructs a public Multiname for you.
|
||||
fn get_public_property(
|
||||
self,
|
||||
name: impl Into<AvmString<'gc>>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
self.get_property(
|
||||
&Multiname::new(activation.avm2().public_namespace, name),
|
||||
activation,
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a local property of the object. The Multiname should always be public.
|
||||
///
|
||||
/// This skips class field lookups and looks at:
|
||||
|
@ -208,6 +220,20 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
base.set_property_local(name, value, activation)
|
||||
}
|
||||
|
||||
/// Same as get_property_local, but constructs a public Multiname for you.
|
||||
/// TODO: this feels upside down, as in: we shouldn't need multinames/namespaces
|
||||
/// by the time we reach dynamic properties.
|
||||
/// But for now, this function is a smaller change to the core than a full refactor.
|
||||
fn set_string_property_local(
|
||||
self,
|
||||
name: impl Into<AvmString<'gc>>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
let name = Multiname::new(activation.avm2().public_namespace, name);
|
||||
self.set_property_local(&name, value, activation)
|
||||
}
|
||||
|
||||
/// Set a property by Multiname lookup.
|
||||
///
|
||||
/// This method should not be overridden.
|
||||
|
@ -256,6 +282,20 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
}
|
||||
|
||||
/// Same as set_property, but constructs a public Multiname for you.
|
||||
fn set_public_property(
|
||||
&mut self,
|
||||
name: impl Into<AvmString<'gc>>,
|
||||
value: Value<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
self.set_property(
|
||||
&Multiname::new(activation.avm2().public_namespace, name),
|
||||
value,
|
||||
activation,
|
||||
)
|
||||
}
|
||||
|
||||
/// Init a local property of the object. The Multiname should always be public.
|
||||
///
|
||||
/// This skips class field lookups and looks at:
|
||||
|
@ -419,6 +459,20 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
}
|
||||
|
||||
/// Same as call_property, but constructs a public Multiname for you.
|
||||
fn call_public_property(
|
||||
self,
|
||||
name: impl Into<AvmString<'gc>>,
|
||||
arguments: &[Value<'gc>],
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
self.call_property(
|
||||
&Multiname::new(activation.avm2().public_namespace, name),
|
||||
arguments,
|
||||
activation,
|
||||
)
|
||||
}
|
||||
|
||||
/// Retrieve a slot by its index.
|
||||
fn get_slot(self, id: u32) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let base = self.base();
|
||||
|
@ -559,6 +613,16 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
}
|
||||
}
|
||||
|
||||
/// Same as delete_property, but constructs a public Multiname for you.
|
||||
fn delete_public_property(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
name: impl Into<AvmString<'gc>>,
|
||||
) -> Result<bool, Error<'gc>> {
|
||||
let name = Multiname::new(activation.avm2().public_namespace, name);
|
||||
self.delete_property(activation, &name)
|
||||
}
|
||||
|
||||
/// Retrieve the `__proto__` of a given object.
|
||||
///
|
||||
/// The proto is another object used to resolve methods across a class of
|
||||
|
@ -630,7 +694,8 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
let name = self
|
||||
.get_enumerant_name(index, activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
self.get_property(&Multiname::public(name), activation)
|
||||
// todo: this probably doesn't need non-public accesses
|
||||
self.get_public_property(name, activation)
|
||||
}
|
||||
|
||||
/// Determine if a property is currently enumerable.
|
||||
|
@ -840,7 +905,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
class: Object<'gc>,
|
||||
) -> Result<bool, Error<'gc>> {
|
||||
let type_proto = class
|
||||
.get_property(&Multiname::public("prototype"), activation)?
|
||||
.get_public_property("prototype", activation)?
|
||||
.as_object();
|
||||
|
||||
if let Some(type_proto) = type_proto {
|
||||
|
|
|
@ -284,11 +284,7 @@ impl<'gc> ClassObject<'gc> {
|
|||
class_proto: Object<'gc>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
self.0.write(activation.context.gc_context).prototype = Some(class_proto);
|
||||
class_proto.set_property_local(
|
||||
&Multiname::public("constructor"),
|
||||
self.into(),
|
||||
activation,
|
||||
)?;
|
||||
class_proto.set_string_property_local("constructor", self.into(), activation)?;
|
||||
class_proto.set_local_property_is_enumerable(
|
||||
activation.context.gc_context,
|
||||
"constructor".into(),
|
||||
|
@ -353,7 +349,10 @@ impl<'gc> ClassObject<'gc> {
|
|||
|
||||
for interface_trait in iface_read.instance_traits() {
|
||||
if !interface_trait.name().namespace().is_public() {
|
||||
let public_name = QName::dynamic_name(interface_trait.name().local_name());
|
||||
let public_name = QName::new(
|
||||
activation.context.avm2.public_namespace,
|
||||
interface_trait.name().local_name(),
|
||||
);
|
||||
self.instance_vtable().copy_property_for_interface(
|
||||
activation.context.gc_context,
|
||||
public_name,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::avm2::activation::Activation;
|
|||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::{Error, Multiname};
|
||||
use crate::avm2::Error;
|
||||
use crate::string::AvmString;
|
||||
use core::fmt;
|
||||
use fnv::FnvHashMap;
|
||||
|
@ -153,10 +153,7 @@ impl<'gc> TObject<'gc> for DictionaryObject<'gc> {
|
|||
if !name_value.is_primitive() {
|
||||
Ok(self.get_property_by_object(name_value.as_object().unwrap()))
|
||||
} else {
|
||||
self.get_property(
|
||||
&Multiname::public(name_value.coerce_to_string(activation)?),
|
||||
activation,
|
||||
)
|
||||
self.get_public_property(name_value.coerce_to_string(activation)?, activation)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject};
|
|||
use crate::avm2::string::AvmString;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::string::WString;
|
||||
use core::fmt;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
|
@ -62,10 +61,10 @@ impl<'gc> ErrorObject<'gc> {
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<AvmString<'gc>, Error<'gc>> {
|
||||
let name = self
|
||||
.get_property(&Multiname::public("name"), activation)?
|
||||
.get_public_property("name", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
let message = self
|
||||
.get_property(&Multiname::public("message"), activation)?
|
||||
.get_public_property("message", activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
if message.is_empty() {
|
||||
return Ok(name);
|
||||
|
|
|
@ -21,7 +21,7 @@ pub fn namespace_allocator<'gc>(
|
|||
activation.context.gc_context,
|
||||
NamespaceObjectData {
|
||||
base,
|
||||
namespace: Namespace::public(),
|
||||
namespace: activation.context.avm2.public_namespace,
|
||||
},
|
||||
))
|
||||
.into())
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
//! Object representation for `Proxy`.
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::globals::NS_FLASH_PROXY;
|
||||
use crate::avm2::object::script_object::ScriptObjectData;
|
||||
use crate::avm2::object::{ClassObject, Object, ObjectPtr, QNameObject, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::QName;
|
||||
use crate::avm2::{AvmString, Error};
|
||||
use core::fmt;
|
||||
|
@ -79,7 +77,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
QNameObject::from_qname(activation, QName::new(*namespace, local_name))?;
|
||||
|
||||
return self.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "getProperty"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "getProperty"),
|
||||
&[qname.into()],
|
||||
activation,
|
||||
);
|
||||
|
@ -115,7 +113,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
QNameObject::from_qname(activation, QName::new(*namespace, local_name))?;
|
||||
|
||||
self.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "setProperty"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "setProperty"),
|
||||
&[qname.into(), value],
|
||||
activation,
|
||||
)?;
|
||||
|
@ -160,10 +158,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
args.extend_from_slice(arguments);
|
||||
|
||||
return self.call_property(
|
||||
&Multiname::new(
|
||||
Namespace::Namespace(NS_FLASH_PROXY.into()),
|
||||
"callProperty",
|
||||
),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "callProperty"),
|
||||
&args[..],
|
||||
activation,
|
||||
);
|
||||
|
@ -195,10 +190,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
|
||||
return Ok(self
|
||||
.call_property(
|
||||
&Multiname::new(
|
||||
Namespace::Namespace(NS_FLASH_PROXY.into()),
|
||||
"deleteProperty",
|
||||
),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "deleteProperty"),
|
||||
&[qname.into()],
|
||||
activation,
|
||||
)?
|
||||
|
@ -221,7 +213,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
) -> Result<bool, Error<'gc>> {
|
||||
Ok(self
|
||||
.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "hasProperty"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "hasProperty"),
|
||||
// this should probably pass the multiname as-is? See above
|
||||
&[name.local_name().unwrap().into()],
|
||||
activation,
|
||||
|
@ -236,7 +228,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
) -> Result<Option<u32>, Error<'gc>> {
|
||||
Ok(Some(
|
||||
self.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "nextNameIndex"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "nextNameIndex"),
|
||||
&[last_index.into()],
|
||||
activation,
|
||||
)?
|
||||
|
@ -250,7 +242,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
self.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "nextName"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "nextName"),
|
||||
&[index.into()],
|
||||
activation,
|
||||
)
|
||||
|
@ -262,7 +254,7 @@ impl<'gc> TObject<'gc> for ProxyObject<'gc> {
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
self.call_property(
|
||||
&Multiname::new(Namespace::Namespace(NS_FLASH_PROXY.into()), "nextValue"),
|
||||
&Multiname::new(activation.avm2().proxy_namespace, "nextValue"),
|
||||
&[index.into()],
|
||||
activation,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::avm2::script::TranslationUnit;
|
||||
use crate::avm2::Activation;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::{Namespace, NamespaceData};
|
||||
use crate::either::Either;
|
||||
use crate::string::{AvmString, WStr, WString};
|
||||
use gc_arena::{Collect, MutationContext};
|
||||
|
@ -16,7 +17,7 @@ use swf::avm2::types::{Index, Multiname as AbcMultiname};
|
|||
/// `QName`. All other forms of names and multinames are either versions of
|
||||
/// `QName` with unspecified parameters, or multiple names to be checked in
|
||||
/// order.
|
||||
#[derive(Clone, Copy, Collect, Hash)]
|
||||
#[derive(Clone, Copy, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct QName<'gc> {
|
||||
ns: Namespace<'gc>,
|
||||
|
@ -40,13 +41,6 @@ impl<'gc> QName<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn dynamic_name(local_part: impl Into<AvmString<'gc>>) -> Self {
|
||||
Self {
|
||||
ns: Namespace::public(),
|
||||
name: local_part.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Pull a `QName` from the multiname pool.
|
||||
///
|
||||
/// This function returns an Err if the multiname does not exist or is not
|
||||
|
@ -70,7 +64,7 @@ impl<'gc> QName<'gc> {
|
|||
|
||||
Ok(match abc_multiname? {
|
||||
AbcMultiname::QName { namespace, name } => Self {
|
||||
ns: Namespace::from_abc_namespace(translation_unit, *namespace, mc)?,
|
||||
ns: translation_unit.pool_namespace(*namespace, mc)?,
|
||||
name: translation_unit.pool_string(name.0, mc)?,
|
||||
},
|
||||
_ => return Err("Attempted to pull QName from non-QName multiname".into()),
|
||||
|
@ -83,19 +77,20 @@ impl<'gc> QName<'gc> {
|
|||
/// NAMESPACE::LOCAL_NAME
|
||||
/// NAMESPACE.LOCAL_NAME (Where the LAST dot is used to split the namespace & local_name)
|
||||
/// LOCAL_NAME (Use the public namespace)
|
||||
pub fn from_qualified_name(name: AvmString<'gc>, mc: MutationContext<'gc, '_>) -> Self {
|
||||
pub fn from_qualified_name(name: AvmString<'gc>, activation: &mut Activation<'_, 'gc>) -> Self {
|
||||
let mc = activation.context.gc_context;
|
||||
let parts = name
|
||||
.rsplit_once(WStr::from_units(b"::"))
|
||||
.or_else(|| name.rsplit_once(WStr::from_units(b".")));
|
||||
|
||||
if let Some((package_name, local_name)) = parts {
|
||||
Self {
|
||||
ns: Namespace::Namespace(AvmString::new(mc, package_name)),
|
||||
ns: Namespace::package(AvmString::new(mc, package_name), mc),
|
||||
name: AvmString::new(mc, local_name),
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
ns: Namespace::public(),
|
||||
ns: activation.avm2().public_namespace,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
@ -155,14 +150,14 @@ impl<'gc> QName<'gc> {
|
|||
|
||||
/// Get the string value of this QName, including the namespace URI.
|
||||
pub fn as_uri(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
||||
let ns = match &self.ns {
|
||||
Namespace::Namespace(s) => s,
|
||||
Namespace::PackageInternal(s) => s,
|
||||
Namespace::Protected(s) => s,
|
||||
Namespace::Explicit(s) => s,
|
||||
Namespace::StaticProtected(s) => s,
|
||||
Namespace::Private(s) => s,
|
||||
Namespace::Any => WStr::from_units(b"*"),
|
||||
let ns = match &*self.ns.0 {
|
||||
NamespaceData::Namespace(s) => s,
|
||||
NamespaceData::PackageInternal(s) => s,
|
||||
NamespaceData::Protected(s) => s,
|
||||
NamespaceData::Explicit(s) => s,
|
||||
NamespaceData::StaticProtected(s) => s,
|
||||
NamespaceData::Private(s) => s,
|
||||
NamespaceData::Any => WStr::from_units(b"*"),
|
||||
};
|
||||
|
||||
if ns.is_empty() {
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::avm2::scope::ScopeChain;
|
|||
use crate::avm2::traits::Trait;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use crate::avm2::{Avm2, Error};
|
||||
use crate::context::UpdateContext;
|
||||
use crate::string::AvmString;
|
||||
|
@ -18,7 +19,8 @@ use std::cell::Ref;
|
|||
use std::mem::drop;
|
||||
use std::rc::Rc;
|
||||
use swf::avm2::types::{
|
||||
AbcFile, Index, Method as AbcMethod, Multiname as AbcMultiname, Script as AbcScript,
|
||||
AbcFile, Index, Method as AbcMethod, Multiname as AbcMultiname, Namespace as AbcNamespace,
|
||||
Script as AbcScript,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Collect)]
|
||||
|
@ -60,6 +62,9 @@ pub struct TranslationUnitData<'gc> {
|
|||
/// They're lazy loaded and offset by 1, with the 0th element being always None.
|
||||
strings: Vec<Option<AvmString<'gc>>>,
|
||||
|
||||
/// All namespaces loaded from the ABC's scripts list.
|
||||
namespaces: Vec<Option<Namespace<'gc>>>,
|
||||
|
||||
/// All multinames loaded from the ABC's multiname list
|
||||
/// Note that some of these may have a runtime (lazy) component.
|
||||
/// Make sure to check for that before using them.
|
||||
|
@ -91,6 +96,7 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
let methods = vec![None; abc.methods.len()];
|
||||
let scripts = vec![None; abc.scripts.len()];
|
||||
let strings = vec![None; abc.constant_pool.strings.len() + 1];
|
||||
let namespaces = vec![None; abc.constant_pool.namespaces.len() + 1];
|
||||
let multinames = vec![None; abc.constant_pool.multinames.len() + 1];
|
||||
let private_trait_scripts = PropertyMap::new();
|
||||
|
||||
|
@ -103,6 +109,7 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
methods,
|
||||
scripts,
|
||||
strings,
|
||||
namespaces,
|
||||
multinames,
|
||||
private_trait_scripts,
|
||||
},
|
||||
|
@ -278,6 +285,28 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
/// Retrieve a static, or non-runtime, multiname from the current constant
|
||||
/// pool.
|
||||
///
|
||||
/// This version of the function treats index 0 as an error condition.
|
||||
pub fn pool_namespace(
|
||||
self,
|
||||
ns_index: Index<AbcNamespace>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<Namespace<'gc>, Error<'gc>> {
|
||||
let read = self.0.read();
|
||||
if let Some(Some(namespace)) = read.namespaces.get(ns_index.0 as usize) {
|
||||
return Ok(*namespace);
|
||||
}
|
||||
|
||||
drop(read);
|
||||
|
||||
let namespace = Namespace::from_abc_namespace(self, ns_index, mc)?;
|
||||
self.0.write(mc).namespaces[ns_index.0 as usize] = Some(namespace);
|
||||
|
||||
Ok(namespace)
|
||||
}
|
||||
|
||||
/// Retrieve a multiname from the current constant pool.
|
||||
/// The name can have a lazy component, do not pass it anywhere.
|
||||
pub fn pool_maybe_uninitialized_multiname(
|
||||
|
@ -326,7 +355,7 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
mc: MutationContext<'gc, '_>,
|
||||
) -> Result<Gc<'gc, Multiname<'gc>>, Error<'gc>> {
|
||||
if multiname_index.0 == 0 {
|
||||
Ok(Gc::allocate(mc, Multiname::any()))
|
||||
Ok(Gc::allocate(mc, Multiname::any(mc)))
|
||||
} else {
|
||||
self.pool_multiname_static(multiname_index, mc)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::error;
|
||||
use crate::avm2::globals::NS_VECTOR;
|
||||
use crate::avm2::object::{ClassObject, NamespaceObject, Object, PrimitiveObject, TObject};
|
||||
use crate::avm2::script::TranslationUnit;
|
||||
use crate::avm2::Error;
|
||||
|
@ -532,7 +531,7 @@ pub fn abc_default_value<'gc>(
|
|||
| AbcDefaultValue::StaticProtected(ns)
|
||||
| AbcDefaultValue::Private(ns) => Ok(NamespaceObject::from_namespace(
|
||||
activation,
|
||||
Namespace::from_abc_namespace(translation_unit, *ns, activation.context.gc_context)?,
|
||||
translation_unit.pool_namespace(*ns, activation.context.gc_context)?,
|
||||
)?
|
||||
.into()),
|
||||
}
|
||||
|
@ -636,20 +635,16 @@ impl<'gc> Value<'gc> {
|
|||
let mut prim = *self;
|
||||
let object = *o;
|
||||
|
||||
if let Value::Object(_) =
|
||||
object.get_property(&Multiname::public("toString"), activation)?
|
||||
{
|
||||
prim = object.call_property(&Multiname::public("toString"), &[], activation)?;
|
||||
if let Value::Object(_) = object.get_public_property("toString", activation)? {
|
||||
prim = object.call_public_property("toString", &[], activation)?;
|
||||
}
|
||||
|
||||
if prim.is_primitive() {
|
||||
return Ok(prim);
|
||||
}
|
||||
|
||||
if let Value::Object(_) =
|
||||
object.get_property(&Multiname::public("valueOf"), activation)?
|
||||
{
|
||||
prim = object.call_property(&Multiname::public("valueOf"), &[], activation)?;
|
||||
if let Value::Object(_) = object.get_public_property("valueOf", activation)? {
|
||||
prim = object.call_public_property("valueOf", &[], activation)?;
|
||||
}
|
||||
|
||||
if prim.is_primitive() {
|
||||
|
@ -662,20 +657,16 @@ impl<'gc> Value<'gc> {
|
|||
let mut prim = *self;
|
||||
let object = *o;
|
||||
|
||||
if let Value::Object(_) =
|
||||
object.get_property(&Multiname::public("valueOf"), activation)?
|
||||
{
|
||||
prim = object.call_property(&Multiname::public("valueOf"), &[], activation)?;
|
||||
if let Value::Object(_) = object.get_public_property("valueOf", activation)? {
|
||||
prim = object.call_public_property("valueOf", &[], activation)?;
|
||||
}
|
||||
|
||||
if prim.is_primitive() {
|
||||
return Ok(prim);
|
||||
}
|
||||
|
||||
if let Value::Object(_) =
|
||||
object.get_property(&Multiname::public("toString"), activation)?
|
||||
{
|
||||
prim = object.call_property(&Multiname::public("toString"), &[], activation)?;
|
||||
if let Value::Object(_) = object.get_public_property("toString", activation)? {
|
||||
prim = object.call_public_property("toString", &[], activation)?;
|
||||
}
|
||||
|
||||
if prim.is_primitive() {
|
||||
|
@ -969,14 +960,16 @@ impl<'gc> Value<'gc> {
|
|||
|
||||
if let Some(vector) = object.as_vector_storage() {
|
||||
let name = class.inner_class_definition().read().name();
|
||||
if name == QName::new(Namespace::package(NS_VECTOR), "Vector")
|
||||
|| (name == QName::new(Namespace::internal(NS_VECTOR), "Vector$int")
|
||||
let vector_public_namespace = activation.avm2().vector_public_namespace;
|
||||
let vector_internal_namespace = activation.avm2().vector_internal_namespace;
|
||||
if name == QName::new(vector_public_namespace, "Vector")
|
||||
|| (name == QName::new(vector_internal_namespace, "Vector$int")
|
||||
&& vector.value_type() == activation.avm2().classes().int)
|
||||
|| (name == QName::new(Namespace::internal(NS_VECTOR), "Vector$uint")
|
||||
|| (name == QName::new(vector_internal_namespace, "Vector$uint")
|
||||
&& vector.value_type() == activation.avm2().classes().uint)
|
||||
|| (name == QName::new(Namespace::internal(NS_VECTOR), "Vector$number")
|
||||
|| (name == QName::new(vector_internal_namespace, "Vector$number")
|
||||
&& vector.value_type() == activation.avm2().classes().number)
|
||||
|| (name == QName::new(Namespace::internal(NS_VECTOR), "Vector$object")
|
||||
|| (name == QName::new(vector_internal_namespace, "Vector$object")
|
||||
&& vector.value_type() == activation.avm2().classes().object)
|
||||
{
|
||||
return Ok(*self);
|
||||
|
|
|
@ -1319,8 +1319,9 @@ pub trait TDisplayObject<'gc>:
|
|||
if self.has_explicit_name() {
|
||||
if let Some(Avm2Value::Object(mut p)) = self.parent().map(|p| p.object2()) {
|
||||
if let Avm2Value::Object(c) = self.object2() {
|
||||
let name = Avm2Multiname::public(self.name());
|
||||
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||
let name =
|
||||
Avm2Multiname::new(activation.avm2().public_namespace, self.name());
|
||||
if let Err(e) = p.init_property(&name, c.into(), &mut activation) {
|
||||
tracing::error!(
|
||||
"Got error when setting AVM2 child named \"{}\": {}",
|
||||
|
@ -1895,23 +1896,23 @@ impl SoundTransform {
|
|||
) -> Result<Self, Avm2Error<'gc>> {
|
||||
Ok(SoundTransform {
|
||||
left_to_left: (as3_st
|
||||
.get_property(&Avm2Multiname::public("leftToLeft"), activation)?
|
||||
.get_public_property("leftToLeft", activation)?
|
||||
.coerce_to_number(activation)?
|
||||
* 100.0) as i32,
|
||||
left_to_right: (as3_st
|
||||
.get_property(&Avm2Multiname::public("leftToRight"), activation)?
|
||||
.get_public_property("leftToRight", activation)?
|
||||
.coerce_to_number(activation)?
|
||||
* 100.0) as i32,
|
||||
right_to_left: (as3_st
|
||||
.get_property(&Avm2Multiname::public("rightToLeft"), activation)?
|
||||
.get_public_property("rightToLeft", activation)?
|
||||
.coerce_to_number(activation)?
|
||||
* 100.0) as i32,
|
||||
right_to_right: (as3_st
|
||||
.get_property(&Avm2Multiname::public("rightToRight"), activation)?
|
||||
.get_public_property("rightToRight", activation)?
|
||||
.coerce_to_number(activation)?
|
||||
* 100.0) as i32,
|
||||
volume: (as3_st
|
||||
.get_property(&Avm2Multiname::public("volume"), activation)?
|
||||
.get_public_property("volume", activation)?
|
||||
.coerce_to_number(activation)?
|
||||
* 100.0) as i32,
|
||||
})
|
||||
|
@ -1927,31 +1928,27 @@ impl SoundTransform {
|
|||
.soundtransform
|
||||
.construct(activation, &[])?;
|
||||
|
||||
as3_st.set_property(
|
||||
&Avm2Multiname::public("leftToLeft"),
|
||||
as3_st.set_public_property(
|
||||
"leftToLeft",
|
||||
(self.left_to_left as f64 / 100.0).into(),
|
||||
activation,
|
||||
)?;
|
||||
as3_st.set_property(
|
||||
&Avm2Multiname::public("leftToRight"),
|
||||
as3_st.set_public_property(
|
||||
"leftToRight",
|
||||
(self.left_to_right as f64 / 100.0).into(),
|
||||
activation,
|
||||
)?;
|
||||
as3_st.set_property(
|
||||
&Avm2Multiname::public("rightToLeft"),
|
||||
as3_st.set_public_property(
|
||||
"rightToLeft",
|
||||
(self.right_to_left as f64 / 100.0).into(),
|
||||
activation,
|
||||
)?;
|
||||
as3_st.set_property(
|
||||
&Avm2Multiname::public("rightToRight"),
|
||||
as3_st.set_public_property(
|
||||
"rightToRight",
|
||||
(self.right_to_right as f64 / 100.0).into(),
|
||||
activation,
|
||||
)?;
|
||||
as3_st.set_property(
|
||||
&Avm2Multiname::public("volume"),
|
||||
(self.volume as f64 / 100.0).into(),
|
||||
activation,
|
||||
)?;
|
||||
as3_st.set_public_property("volume", (self.volume as f64 / 100.0).into(), activation)?;
|
||||
|
||||
Ok(as3_st)
|
||||
}
|
||||
|
|
|
@ -737,7 +737,7 @@ impl<'gc> MovieClip<'gc> {
|
|||
let class_name = reader.read_str()?.to_str_lossy(reader.encoding());
|
||||
let class_name = AvmString::new_utf8(activation.context.gc_context, class_name);
|
||||
|
||||
let name = Avm2QName::from_qualified_name(class_name, activation.context.gc_context);
|
||||
let name = Avm2QName::from_qualified_name(class_name, &mut activation);
|
||||
let library = activation
|
||||
.context
|
||||
.library
|
||||
|
|
|
@ -10,8 +10,8 @@ use crate::avm2::object::EventObject as Avm2EventObject;
|
|||
use crate::avm2::object::LoaderStream;
|
||||
use crate::avm2::object::TObject as _;
|
||||
use crate::avm2::{
|
||||
Activation as Avm2Activation, Avm2, Domain as Avm2Domain, Multiname as Avm2Multiname,
|
||||
Object as Avm2Object, Value as Avm2Value,
|
||||
Activation as Avm2Activation, Avm2, Domain as Avm2Domain, Object as Avm2Object,
|
||||
Value as Avm2Value,
|
||||
};
|
||||
use crate::backend::navigator::{OwnedFuture, Request};
|
||||
use crate::context::{ActionQueue, ActionType, UpdateContext};
|
||||
|
@ -632,7 +632,7 @@ impl<'gc> Loader<'gc> {
|
|||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) = event_handler {
|
||||
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||
let mut loader = loader_info
|
||||
.get_property(&Avm2Multiname::public("loader"), &mut activation)
|
||||
.get_public_property("loader", &mut activation)
|
||||
.map_err(|e| Error::Avm2Error(e.to_string()))?
|
||||
.as_object()
|
||||
.unwrap()
|
||||
|
@ -1035,7 +1035,7 @@ impl<'gc> Loader<'gc> {
|
|||
};
|
||||
|
||||
target
|
||||
.set_property(&Avm2Multiname::public("data"), data_object, activation)
|
||||
.set_public_property("data", data_object, activation)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
@ -1386,11 +1386,8 @@ impl<'gc> Loader<'gc> {
|
|||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||
let domain = context
|
||||
.and_then(|o| {
|
||||
o.get_property(
|
||||
&Avm2Multiname::public("applicationDomain"),
|
||||
&mut activation,
|
||||
)
|
||||
.ok()
|
||||
o.get_public_property("applicationDomain", &mut activation)
|
||||
.ok()
|
||||
})
|
||||
.and_then(|v| v.coerce_to_object(&mut activation).ok())
|
||||
.and_then(|o| o.as_application_domain())
|
||||
|
|
Loading…
Reference in New Issue