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, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let method_name = self.pop();
|
let method_name = self.pop();
|
||||||
let object =
|
let object_val = self.pop();
|
||||||
value_object::ValueObject::boxed(context.gc_context, self.pop(), &self.prototypes);
|
let object = value_object::ValueObject::boxed(self, context, object_val);
|
||||||
let num_args = self.pop().as_i64()?; // TODO(Herschel): max arg count?
|
let num_args = self.pop().as_i64()?; // TODO(Herschel): max arg count?
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
for _ in 0..num_args {
|
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> {
|
fn action_get_member(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
||||||
let name_val = self.pop();
|
let name_val = self.pop();
|
||||||
let name = name_val.coerce_to_string(self, context)?;
|
let name = name_val.coerce_to_string(self, context)?;
|
||||||
let object =
|
let object_val = self.pop();
|
||||||
value_object::ValueObject::boxed(context.gc_context, self.pop(), &self.prototypes);
|
let object = value_object::ValueObject::boxed(self, context, object_val);
|
||||||
|
|
||||||
object.get(&name, self, context)?.push(self);
|
object.get(&name, self, context)?.push(self);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) mod movie_clip;
|
||||||
mod object;
|
mod object;
|
||||||
mod sound;
|
mod sound;
|
||||||
mod stage;
|
mod stage;
|
||||||
mod string;
|
pub(crate) mod string;
|
||||||
pub(crate) mod text_field;
|
pub(crate) mod text_field;
|
||||||
mod xml;
|
mod xml;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! Object impl for boxed values
|
//! Object impl for boxed values
|
||||||
|
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::globals::SystemPrototypes;
|
|
||||||
use crate::avm1::object::{ObjectPtr, TObject};
|
use crate::avm1::object::{ObjectPtr, TObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
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
|
/// If a class exists for a given value type, this function automatically
|
||||||
/// selects the correct prototype for it from the system prototypes list.
|
/// selects the correct prototype for it from the system prototypes list.
|
||||||
pub fn boxed(
|
pub fn boxed(
|
||||||
gc_context: MutationContext<'gc, '_>,
|
avm: &mut Avm1<'gc>,
|
||||||
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
value: Value<'gc>,
|
value: Value<'gc>,
|
||||||
system_prototypes: &SystemPrototypes<'gc>,
|
|
||||||
) -> Object<'gc> {
|
) -> Object<'gc> {
|
||||||
if let Value::Object(ob) = value {
|
if let Value::Object(ob) = value {
|
||||||
ob
|
ob
|
||||||
} else {
|
} else {
|
||||||
let proto = match value {
|
let (constructor, proto) = match &value {
|
||||||
Value::String(_) => Some(system_prototypes.string),
|
Value::String(_) => (
|
||||||
_ => None,
|
Some(crate::avm1::globals::string::string),
|
||||||
|
Some(avm.prototypes.string),
|
||||||
|
),
|
||||||
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
ValueObject(GcCell::allocate(
|
let obj = ValueObject(GcCell::allocate(
|
||||||
gc_context,
|
context.gc_context,
|
||||||
ValueObjectData {
|
ValueObjectData {
|
||||||
base: ScriptObject::object(gc_context, proto),
|
base: ScriptObject::object(context.gc_context, proto),
|
||||||
value,
|
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