diff --git a/core/src/avm1/function.rs b/core/src/avm1/function.rs index afac8833d..5cc6be7f1 100644 --- a/core/src/avm1/function.rs +++ b/core/src/avm1/function.rs @@ -240,6 +240,7 @@ impl<'gc> Executable<'gc> { base_proto: Option>, args: &[Value<'gc>], reason: ExecutionReason, + callee: Object<'gc>, ) -> Result, Error<'gc>> { match self { Executable::Native(nf) => nf(activation, ac, this, args), @@ -250,7 +251,7 @@ impl<'gc> Executable<'gc> { ); let arguments = ScriptObject::array(ac.gc_context, Some(activation.avm.prototypes().array)); - arguments.define_value(ac.gc_context, "callee", this.into(), DontEnum.into()); + arguments.define_value(ac.gc_context, "callee", callee.into(), DontEnum.into()); if !af.suppress_arguments { for i in 0..args.len() { @@ -494,6 +495,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { ) -> Result<(), Error<'gc>> { self.base.set(name, value, activation, context) } + fn call( &self, name: &str, @@ -512,6 +514,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { base_proto, args, ExecutionReason::FunctionCall, + (*self).into(), ) } else { Ok(Value::Undefined) diff --git a/core/src/avm1/globals/function.rs b/core/src/avm1/globals/function.rs index 949a24e4e..af53c7df1 100644 --- a/core/src/avm1/globals/function.rs +++ b/core/src/avm1/globals/function.rs @@ -44,6 +44,7 @@ pub fn call<'gc>( None, args, ExecutionReason::FunctionCall, + func, ), _ => Ok(Value::Undefined), } @@ -85,6 +86,7 @@ pub fn apply<'gc>( None, &child_args, ExecutionReason::FunctionCall, + func, ), _ => Ok(Value::Undefined), } diff --git a/core/src/avm1/object/script_object.rs b/core/src/avm1/object/script_object.rs index d65b257bd..837abd616 100644 --- a/core/src/avm1/object/script_object.rs +++ b/core/src/avm1/object/script_object.rs @@ -59,6 +59,7 @@ impl<'gc> Watcher<'gc> { base_proto, &args, ExecutionReason::Special, + self.callback, ) } else { Ok(Value::Undefined) @@ -292,19 +293,21 @@ impl<'gc> ScriptObject<'gc> { if let Some(this_proto) = proto { worked = true; - if let Some(rval) = this_proto - .call_setter(name, value.clone(), activation, context) - .and_then(|o| o.as_executable()) + if let Some(rval) = + this_proto.call_setter(name, value.clone(), activation, context) { - let _ = rval.exec( - "[Setter]", - activation, - context, - this, - Some(this_proto), - &[value.clone()], - ExecutionReason::Special, - ); + if let Some(exec) = rval.as_executable() { + let _ = exec.exec( + "[Setter]", + activation, + context, + this, + Some(this_proto), + &[value.clone()], + ExecutionReason::Special, + rval, + ); + } } } } @@ -357,16 +360,19 @@ impl<'gc> ScriptObject<'gc> { } }; - if let Some(rval) = rval.and_then(|o| o.as_executable()) { - let _ = rval.exec( - "[Setter]", - activation, - context, - this, - base_proto, - &[value], - ExecutionReason::Special, - ); + if let Some(rval) = rval { + if let Some(exec) = rval.as_executable() { + let _ = exec.exec( + "[Setter]", + activation, + context, + this, + base_proto, + &[value], + ExecutionReason::Special, + rval, + ); + } } return return_value; @@ -397,7 +403,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { return Ok(self.proto().map_or(Value::Undefined, Value::Object)); } - let mut exec = None; + let mut getter = None; if let Some(value) = self .0 @@ -406,24 +412,29 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { .get(name, activation.is_case_sensitive()) { match value { - Property::Virtual { get, .. } => exec = Some(get.to_owned()), + Property::Virtual { get, .. } => getter = Some(get.to_owned()), Property::Stored { value, .. } => return Ok(value.to_owned()), } } - if let Some(get) = exec.and_then(|o| o.as_executable()) { - // Errors, even fatal ones, are completely and silently ignored here. - match get.exec( - "[Getter]", - activation, - context, - this, - Some((*self).into()), - &[], - ExecutionReason::Special, - ) { - Ok(value) => Ok(value), - Err(_) => Ok(Value::Undefined), + if let Some(getter) = getter { + if let Some(exec) = getter.as_executable() { + // Errors, even fatal ones, are completely and silently ignored here. + match exec.exec( + "[Getter]", + activation, + context, + this, + Some((*self).into()), + &[], + ExecutionReason::Special, + getter, + ) { + Ok(value) => Ok(value), + Err(_) => Ok(Value::Undefined), + } + } else { + Ok(Value::Undefined) } } else { Ok(Value::Undefined) diff --git a/core/tests/swfs/avm1/arguments/output.txt b/core/tests/swfs/avm1/arguments/output.txt index ad774a615..6b7fcd8c5 100644 --- a/core/tests/swfs/avm1/arguments/output.txt +++ b/core/tests/swfs/avm1/arguments/output.txt @@ -11,6 +11,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // dump("a") @@ -26,6 +32,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[0] a @@ -44,6 +56,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[1] b @@ -66,6 +84,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[3] d diff --git a/core/tests/swfs/avm1/arguments/test.fla b/core/tests/swfs/avm1/arguments/test.fla index b5221ea78..dea004340 100644 Binary files a/core/tests/swfs/avm1/arguments/test.fla and b/core/tests/swfs/avm1/arguments/test.fla differ diff --git a/core/tests/swfs/avm1/arguments/test.swf b/core/tests/swfs/avm1/arguments/test.swf index cb1492cc1..ee457bbe1 100644 Binary files a/core/tests/swfs/avm1/arguments/test.swf and b/core/tests/swfs/avm1/arguments/test.swf differ