diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index 844b53628..f0ca786c6 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -8,7 +8,7 @@ use crate::avm2::property::Attribute; use crate::avm2::return_value::ReturnValue; use crate::avm2::scope::Scope; use crate::avm2::script_object::ScriptObject; -use crate::avm2::value::Value; +use crate::avm2::value::{abc_default_value, Value}; use crate::avm2::{Avm2, Error}; use crate::context::UpdateContext; use enumset::EnumSet; @@ -173,6 +173,14 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy ); match &trait_entry.kind { + AbcTraitKind::Slot { slot_id, value, .. } => { + let value = if let Some(value) = value { + abc_default_value(&abc, value)? + } else { + Value::Undefined + }; + self.install_slot(context.gc_context, trait_name, *slot_id, value); + } AbcTraitKind::Method { method, .. } => { let method = Avm2MethodEntry::from_method_index(abc, method.clone()).unwrap(); let function = diff --git a/core/src/avm2/value.rs b/core/src/avm2/value.rs index e7bf8dc76..477ae9eaa 100644 --- a/core/src/avm2/value.rs +++ b/core/src/avm2/value.rs @@ -5,7 +5,7 @@ use crate::avm2::object::Object; use crate::avm2::Error; use gc_arena::Collect; use std::f64::NAN; -use swf::avm2::types::{AbcFile, Index}; +use swf::avm2::types::{AbcFile, DefaultValue as AbcDefaultValue, Index}; /// An AVM2 value. /// @@ -210,6 +210,32 @@ pub fn abc_string_option(file: &AbcFile, index: Index) -> Result( + file: &AbcFile, + default: &AbcDefaultValue, +) -> Result, Error> { + match default { + AbcDefaultValue::Int(i) => abc_int(file, *i).map(|v| v.into()), + AbcDefaultValue::Uint(u) => abc_uint(file, *u).map(|v| v.into()), + AbcDefaultValue::Double(d) => abc_double(file, *d).map(|v| v.into()), + AbcDefaultValue::String(s) => abc_string(file, s.clone()).map(|v| v.into()), + AbcDefaultValue::True => Ok(true.into()), + AbcDefaultValue::False => Ok(false.into()), + AbcDefaultValue::Null => Ok(Value::Null), + AbcDefaultValue::Undefined => Ok(Value::Undefined), + AbcDefaultValue::Namespace(ns) + | AbcDefaultValue::Package(ns) + | AbcDefaultValue::PackageInternal(ns) + | AbcDefaultValue::Protected(ns) + | AbcDefaultValue::Explicit(ns) + | AbcDefaultValue::StaticProtected(ns) + | AbcDefaultValue::Private(ns) => { + Namespace::from_abc_namespace(file, ns.clone()).map(|v| v.into()) + } + } +} + impl<'gc> Value<'gc> { pub fn as_object(&self) -> Result, Error> { if let Value::Object(object) = self {