avm1: Replace manual constructor calling with Function::construct, to ensure we set __constructor__

This commit is contained in:
Nathan Adams 2020-07-27 23:02:35 +02:00 committed by Mike Welsh
parent 2faf35d43e
commit 69a4d10338
8 changed files with 60 additions and 31 deletions

View File

@ -207,24 +207,31 @@ pub fn update_after_event<'a, 'gc>(
pub struct SystemPrototypes<'gc> { pub struct SystemPrototypes<'gc> {
pub button: Object<'gc>, pub button: Object<'gc>,
pub object: Object<'gc>, pub object: Object<'gc>,
pub object_constructor: Object<'gc>,
pub function: Object<'gc>, pub function: Object<'gc>,
pub movie_clip: Object<'gc>, pub movie_clip: Object<'gc>,
pub sound: Object<'gc>, pub sound: Object<'gc>,
pub text_field: Object<'gc>, pub text_field: Object<'gc>,
pub text_format: Object<'gc>, pub text_format: Object<'gc>,
pub array: Object<'gc>, pub array: Object<'gc>,
pub array_constructor: Object<'gc>,
pub xml_node: Object<'gc>, pub xml_node: Object<'gc>,
pub string: Object<'gc>, pub string: Object<'gc>,
pub number: Object<'gc>, pub number: Object<'gc>,
pub boolean: Object<'gc>, pub boolean: Object<'gc>,
pub matrix: Object<'gc>, pub matrix: Object<'gc>,
pub matrix_constructor: Object<'gc>,
pub point: Object<'gc>, pub point: Object<'gc>,
pub point_constructor: Object<'gc>,
pub rectangle: Object<'gc>, pub rectangle: Object<'gc>,
pub rectangle_constructor: Object<'gc>, pub rectangle_constructor: Object<'gc>,
pub shared_object: Object<'gc>, pub shared_object: Object<'gc>,
pub shared_object_constructor: Object<'gc>,
pub color_transform: Object<'gc>, pub color_transform: Object<'gc>,
pub context_menu: Object<'gc>, pub context_menu: Object<'gc>,
pub context_menu_constructor: Object<'gc>,
pub context_menu_item: Object<'gc>, pub context_menu_item: Object<'gc>,
pub context_menu_item_constructor: Object<'gc>,
} }
/// Initialize default global scope and builtins for an AVM1 instance. /// Initialize default global scope and builtins for an AVM1 instance.
@ -442,29 +449,29 @@ pub fn create_globals<'gc>(
DontEnum.into(), DontEnum.into(),
); );
let context_menu = FunctionObject::constructor(
gc_context,
Executable::Native(context_menu::constructor),
Some(function_proto),
Some(context_menu_proto),
);
globals.define_value( globals.define_value(
gc_context, gc_context,
"ContextMenu", "ContextMenu",
FunctionObject::constructor( context_menu.into(),
gc_context,
Executable::Native(context_menu::constructor),
Some(function_proto),
Some(context_menu_proto),
)
.into(),
DontEnum.into(), DontEnum.into(),
); );
let context_menu_item = FunctionObject::constructor(
gc_context,
Executable::Native(context_menu_item::constructor),
Some(function_proto),
Some(context_menu_item_proto),
);
globals.define_value( globals.define_value(
gc_context, gc_context,
"ContextMenuItem", "ContextMenuItem",
FunctionObject::constructor( context_menu_item.into(),
gc_context,
Executable::Native(context_menu_item::constructor),
Some(function_proto),
Some(context_menu_item_proto),
)
.into(),
DontEnum.into(), DontEnum.into(),
); );
@ -610,24 +617,31 @@ pub fn create_globals<'gc>(
SystemPrototypes { SystemPrototypes {
button: button_proto, button: button_proto,
object: object_proto, object: object_proto,
object_constructor: object,
function: function_proto, function: function_proto,
movie_clip: movie_clip_proto, movie_clip: movie_clip_proto,
sound: sound_proto, sound: sound_proto,
text_field: text_field_proto, text_field: text_field_proto,
text_format: text_format_proto, text_format: text_format_proto,
array: array_proto, array: array_proto,
array_constructor: array,
xml_node: xmlnode_proto, xml_node: xmlnode_proto,
string: string_proto, string: string_proto,
number: number_proto, number: number_proto,
boolean: boolean_proto, boolean: boolean_proto,
matrix: matrix_proto, matrix: matrix_proto,
matrix_constructor: matrix,
point: point_proto, point: point_proto,
point_constructor: point,
rectangle: rectangle_proto, rectangle: rectangle_proto,
rectangle_constructor: rectangle, rectangle_constructor: rectangle,
shared_object: shared_object_proto, shared_object: shared_object_proto,
shared_object_constructor: shared_obj,
color_transform: color_transform_proto, color_transform: color_transform_proto,
context_menu: context_menu_proto, context_menu: context_menu_proto,
context_menu_constructor: context_menu,
context_menu_item: context_menu_item_proto, context_menu_item: context_menu_item_proto,
context_menu_item_constructor: context_menu_item,
}, },
globals.into(), globals.into(),
broadcaster_functions, broadcaster_functions,

View File

@ -138,7 +138,8 @@ pub fn array_function<'gc>(
let p = activation.avm.prototypes.array; let p = activation.avm.prototypes.array;
let array_obj = p.new(activation, context, p, &[])?; let array_obj = p.new(activation, context, p, &[])?;
let _ = constructor(activation, context, array_obj, args)?; let constructor = activation.avm.prototypes.array_constructor;
constructor.construct(activation, context, array_obj, args)?;
if args.len() == 1 { if args.len() == 1 {
let arg = args.get(0).unwrap(); let arg = args.get(0).unwrap();

View File

@ -22,7 +22,9 @@ pub fn constructor<'gc>(
let obj_proto = activation.avm.prototypes.object; let obj_proto = activation.avm.prototypes.object;
let built_in_items = obj_proto.new(activation, context, obj_proto, &[])?; let built_in_items = obj_proto.new(activation, context, obj_proto, &[])?;
let _ = crate::avm1::globals::object::constructor(activation, context, built_in_items, &[]); let constructor = activation.avm.prototypes.object_constructor;
constructor.construct(activation, context, built_in_items, &[])?;
built_in_items.set("print", true.into(), activation, context)?; built_in_items.set("print", true.into(), activation, context)?;
built_in_items.set("forward_back", true.into(), activation, context)?; built_in_items.set("forward_back", true.into(), activation, context)?;
built_in_items.set("rewind", true.into(), activation, context)?; built_in_items.set("rewind", true.into(), activation, context)?;
@ -36,7 +38,8 @@ pub fn constructor<'gc>(
let array_proto = activation.avm.prototypes.array; let array_proto = activation.avm.prototypes.array;
let custom_items = array_proto.new(activation, context, array_proto, &[])?; let custom_items = array_proto.new(activation, context, array_proto, &[])?;
let _ = crate::avm1::globals::array::constructor(activation, context, custom_items, &[]); let constructor = activation.avm.prototypes.array_constructor;
constructor.construct(activation, context, custom_items, &[])?;
this.set("customItems", custom_items.into(), activation, context)?; this.set("customItems", custom_items.into(), activation, context)?;
@ -55,7 +58,8 @@ pub fn copy<'gc>(
let context_menu_proto = activation.avm.prototypes.context_menu; let context_menu_proto = activation.avm.prototypes.context_menu;
let copy = context_menu_proto.new(activation, context, context_menu_proto, &[])?; let copy = context_menu_proto.new(activation, context, context_menu_proto, &[])?;
let _ = constructor(activation, context, copy, &[callback.into()]); let constructor = activation.avm.prototypes.context_menu_constructor;
constructor.construct(activation, context, copy, &[callback.into()])?;
let built_in = this let built_in = this
.get("builtInItems", activation, context)? .get("builtInItems", activation, context)?

View File

@ -87,7 +87,8 @@ pub fn copy<'gc>(
let context_menu_item_proto = activation.avm.prototypes.context_menu_item; let context_menu_item_proto = activation.avm.prototypes.context_menu_item;
let copy = context_menu_item_proto.new(activation, context, context_menu_item_proto, &[])?; let copy = context_menu_item_proto.new(activation, context, context_menu_item_proto, &[])?;
let _ = constructor( let constructor = activation.avm.prototypes.context_menu_item_constructor;
constructor.construct(
activation, activation,
context, context,
copy, copy,
@ -98,7 +99,7 @@ pub fn copy<'gc>(
enabled.into(), enabled.into(),
visible.into(), visible.into(),
], ],
); )?;
Ok(copy.into()) Ok(copy.into())
} }

View File

@ -132,7 +132,8 @@ pub fn matrix_to_object<'gc>(
matrix.ty.to_pixels().into(), matrix.ty.to_pixels().into(),
]; ];
let object = proto.new(activation, context, proto, &args)?; let object = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, object, &args)?; let constructor = activation.avm.prototypes.matrix_constructor;
constructor.construct(activation, context, object, &args)?;
Ok(object) Ok(object)
} }
@ -209,7 +210,8 @@ fn clone<'gc>(
this.get("ty", activation, context)?, this.get("ty", activation, context)?,
]; ];
let cloned = proto.new(activation, context, proto, &args)?; let cloned = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, cloned, &args)?; let constructor = activation.avm.prototypes.matrix_constructor;
constructor.construct(activation, context, cloned, &args)?;
Ok(cloned.into()) Ok(cloned.into())
} }

View File

@ -26,7 +26,8 @@ pub fn construct_new_point<'gc>(
) -> Result<Object<'gc>, Error<'gc>> { ) -> Result<Object<'gc>, Error<'gc>> {
let proto = context.system_prototypes.point; let proto = context.system_prototypes.point;
let object = proto.new(activation, context, proto, &args)?; let object = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, object, &args)?; let constructor = activation.avm.prototypes.point_constructor;
constructor.construct(activation, context, object, &args)?;
Ok(object) Ok(object)
} }
@ -99,7 +100,8 @@ fn clone<'gc>(
this.get("y", activation, context)?, this.get("y", activation, context)?,
]; ];
let cloned = proto.new(activation, context, proto, &args)?; let cloned = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, cloned, &args)?; let constructor = activation.avm.prototypes.point_constructor;
constructor.construct(activation, context, proto, &args)?;
Ok(cloned.into()) Ok(cloned.into())
} }

View File

@ -131,7 +131,8 @@ fn clone<'gc>(
this.get("height", activation, context)?, this.get("height", activation, context)?,
]; ];
let cloned = proto.new(activation, context, proto, &args)?; let cloned = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, cloned, &args)?; let constructor = activation.avm.prototypes.rectangle_constructor;
constructor.construct(activation, context, cloned, &args)?;
Ok(cloned.into()) Ok(cloned.into())
} }
@ -390,7 +391,8 @@ fn union<'gc>(
Value::Number(height), Value::Number(height),
]; ];
let result = proto.new(activation, context, proto, &args)?; let result = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, result, &args)?; let constructor = activation.avm.prototypes.rectangle_constructor;
constructor.construct(activation, context, result, &args)?;
Ok(result.into()) Ok(result.into())
} }
@ -613,7 +615,8 @@ fn intersection<'gc>(
Value::Number(bottom - top), Value::Number(bottom - top),
]; ];
let result = proto.new(activation, context, proto, &args)?; let result = proto.new(activation, context, proto, &args)?;
let _ = constructor(activation, context, result, &args)?; let constructor = activation.avm.prototypes.rectangle_constructor;
constructor.construct(activation, context, result, &args)?;
Ok(result.into()) Ok(result.into())
} }

View File

@ -116,8 +116,8 @@ fn recursive_deserialize<'gc>(
JsonValue::Object(o) => { JsonValue::Object(o) => {
let so = activation.avm.prototypes.object; let so = activation.avm.prototypes.object;
let obj = so.new(activation, context, so, &[]).unwrap(); let obj = so.new(activation, context, so, &[]).unwrap();
let _ = crate::avm1::globals::object::constructor(activation, context, obj, &[]) let constructor = activation.avm.prototypes.object_constructor;
.unwrap(); let _ = constructor.construct(activation, context, obj, &[]);
recursive_deserialize(JsonValue::Object(o.clone()), activation, obj, context); recursive_deserialize(JsonValue::Object(o.clone()), activation, obj, context);
object.define_value( object.define_value(
@ -160,7 +160,8 @@ pub fn get_local<'gc>(
// Data property only should exist when created with getLocal/Remote // Data property only should exist when created with getLocal/Remote
let so = activation.avm.prototypes.shared_object; let so = activation.avm.prototypes.shared_object;
let this = so.new(activation, action_context, so, &[])?; let this = so.new(activation, action_context, so, &[])?;
let _ = constructor(activation, action_context, this, &[])?; let constructor = activation.avm.prototypes.shared_object_constructor;
constructor.construct(activation, action_context, this, &[])?;
// Set the internal name // Set the internal name
let obj_so = this.as_shared_object().unwrap(); let obj_so = this.as_shared_object().unwrap();
@ -169,7 +170,8 @@ pub fn get_local<'gc>(
// Create the data object // Create the data object
let data_proto = activation.avm.prototypes.object; let data_proto = activation.avm.prototypes.object;
let data = data_proto.new(activation, action_context, so, &[])?; let data = data_proto.new(activation, action_context, so, &[])?;
let _ = crate::avm1::globals::object::constructor(activation, action_context, data, &[])?; let constructor = activation.avm.prototypes.object_constructor;
constructor.construct(activation, action_context, data, &[])?;
// Load the data object from storage if it existed prior // Load the data object from storage if it existed prior
if let Some(saved) = action_context.storage.get_string(&name) { if let Some(saved) = action_context.storage.get_string(&name) {