Explicitly allow `_global` and `_root` to be overwritten.

This commit is contained in:
David Wendt 2019-10-09 23:15:48 -04:00
parent 4709d2d0b4
commit 17b1e0429c
1 changed files with 36 additions and 4 deletions

View File

@ -1,8 +1,8 @@
use crate::avm1::object::{Attribute::*, Object}; use crate::avm1::object::{Attribute::*, Object};
use crate::avm1::Value; use crate::avm1::{ActionContext, Avm1, Value};
use crate::movie_clip::MovieClip; use crate::movie_clip::MovieClip;
use enumset::EnumSet; use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::{GcCell, MutationContext};
macro_rules! with_movie_clip { macro_rules! with_movie_clip {
( $gc_context: ident, $object:ident, $($name:expr => $fn:expr),* ) => {{ ( $gc_context: ident, $object:ident, $($name:expr => $fn:expr),* ) => {{
@ -44,6 +44,38 @@ macro_rules! with_movie_clip_mut {
}}; }};
} }
pub fn overwrite_root<'gc>(
_avm: &mut Avm1<'gc>,
ac: &mut ActionContext<'_, 'gc, '_>,
this: GcCell<'gc, Object<'gc>>,
args: &[Value<'gc>],
) -> Value<'gc> {
let new_val = args
.get(0)
.map(|v| v.to_owned())
.unwrap_or(Value::Undefined);
this.write(ac.gc_context)
.force_set("_root", new_val, EnumSet::new());
Value::Undefined
}
pub fn overwrite_global<'gc>(
_avm: &mut Avm1<'gc>,
ac: &mut ActionContext<'_, 'gc, '_>,
this: GcCell<'gc, Object<'gc>>,
args: &[Value<'gc>],
) -> Value<'gc> {
let new_val = args
.get(0)
.map(|v| v.to_owned())
.unwrap_or(Value::Undefined);
this.write(ac.gc_context)
.force_set("_global", new_val, EnumSet::new());
Value::Undefined
}
pub fn create_movie_object<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> { pub fn create_movie_object<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> {
let mut object = Object::object(gc_context); let mut object = Object::object(gc_context);
@ -84,14 +116,14 @@ pub fn create_movie_object<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<
object.force_set_virtual( object.force_set_virtual(
"_global", "_global",
|avm, context, _this, _args| avm.global_object(context), |avm, context, _this, _args| avm.global_object(context),
None, Some(overwrite_global),
EnumSet::new(), EnumSet::new(),
); );
object.force_set_virtual( object.force_set_virtual(
"_root", "_root",
|avm, context, _this, _args| avm.root_object(context), |avm, context, _this, _args| avm.root_object(context),
None, Some(overwrite_root),
EnumSet::new(), EnumSet::new(),
); );