avm1: Boxing a value calls the object constructor
This commit is contained in:
parent
ccf62979a1
commit
b49357e46f
|
@ -937,8 +937,8 @@ impl<'gc> Avm1<'gc> {
|
|||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
) -> Result<(), Error> {
|
||||
let method_name = self.pop();
|
||||
let object =
|
||||
value_object::ValueObject::boxed(context.gc_context, self.pop(), &self.prototypes);
|
||||
let object_val = self.pop();
|
||||
let object = value_object::ValueObject::boxed(self, context, object_val);
|
||||
let num_args = self.pop().as_i64()?; // TODO(Herschel): max arg count?
|
||||
let mut args = Vec::new();
|
||||
for _ in 0..num_args {
|
||||
|
@ -1276,8 +1276,8 @@ impl<'gc> Avm1<'gc> {
|
|||
fn action_get_member(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
||||
let name_val = self.pop();
|
||||
let name = name_val.coerce_to_string(self, context)?;
|
||||
let object =
|
||||
value_object::ValueObject::boxed(context.gc_context, self.pop(), &self.prototypes);
|
||||
let object_val = self.pop();
|
||||
let object = value_object::ValueObject::boxed(self, context, object_val);
|
||||
|
||||
object.get(&name, self, context)?.push(self);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) mod movie_clip;
|
|||
mod object;
|
||||
mod sound;
|
||||
mod stage;
|
||||
mod string;
|
||||
pub(crate) mod string;
|
||||
pub(crate) mod text_field;
|
||||
mod xml;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! Object impl for boxed values
|
||||
|
||||
use crate::avm1::function::Executable;
|
||||
use crate::avm1::globals::SystemPrototypes;
|
||||
use crate::avm1::object::{ObjectPtr, TObject};
|
||||
use crate::avm1::property::Attribute;
|
||||
use crate::avm1::return_value::ReturnValue;
|
||||
|
@ -40,26 +39,35 @@ impl<'gc> ValueObject<'gc> {
|
|||
/// If a class exists for a given value type, this function automatically
|
||||
/// selects the correct prototype for it from the system prototypes list.
|
||||
pub fn boxed(
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
avm: &mut Avm1<'gc>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
value: Value<'gc>,
|
||||
system_prototypes: &SystemPrototypes<'gc>,
|
||||
) -> Object<'gc> {
|
||||
if let Value::Object(ob) = value {
|
||||
ob
|
||||
} else {
|
||||
let proto = match value {
|
||||
Value::String(_) => Some(system_prototypes.string),
|
||||
_ => None,
|
||||
let (constructor, proto) = match &value {
|
||||
Value::String(_) => (
|
||||
Some(crate::avm1::globals::string::string),
|
||||
Some(avm.prototypes.string),
|
||||
),
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
ValueObject(GcCell::allocate(
|
||||
gc_context,
|
||||
let obj = ValueObject(GcCell::allocate(
|
||||
context.gc_context,
|
||||
ValueObjectData {
|
||||
base: ScriptObject::object(gc_context, proto),
|
||||
value,
|
||||
base: ScriptObject::object(context.gc_context, proto),
|
||||
value: Value::Undefined,
|
||||
},
|
||||
))
|
||||
.into()
|
||||
));
|
||||
|
||||
// Constructor populates the boxed object with the value.
|
||||
if let Some(constructor) = constructor {
|
||||
let _ = constructor(avm, context, obj.into(), &[value]);
|
||||
}
|
||||
|
||||
obj.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue