avm1: Implement arguments.callee
This commit is contained in:
parent
4a56cb1062
commit
f0980301da
|
@ -240,6 +240,7 @@ impl<'gc> Executable<'gc> {
|
|||
base_proto: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
reason: ExecutionReason,
|
||||
callee: Object<'gc>,
|
||||
) -> Result<Value<'gc>, 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)
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ impl<'gc> Watcher<'gc> {
|
|||
base_proto,
|
||||
&args,
|
||||
ExecutionReason::Special,
|
||||
self.callback,
|
||||
)
|
||||
} else {
|
||||
Ok(Value::Undefined)
|
||||
|
@ -292,11 +293,11 @@ 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(
|
||||
if let Some(exec) = rval.as_executable() {
|
||||
let _ = exec.exec(
|
||||
"[Setter]",
|
||||
activation,
|
||||
context,
|
||||
|
@ -304,10 +305,12 @@ impl<'gc> ScriptObject<'gc> {
|
|||
Some(this_proto),
|
||||
&[value.clone()],
|
||||
ExecutionReason::Special,
|
||||
rval,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This signals we didn't call a virtual setter above. Normally,
|
||||
//we'd resolve and return up there, but we have borrows that need
|
||||
|
@ -357,8 +360,9 @@ impl<'gc> ScriptObject<'gc> {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(rval) = rval.and_then(|o| o.as_executable()) {
|
||||
let _ = rval.exec(
|
||||
if let Some(rval) = rval {
|
||||
if let Some(exec) = rval.as_executable() {
|
||||
let _ = exec.exec(
|
||||
"[Setter]",
|
||||
activation,
|
||||
context,
|
||||
|
@ -366,8 +370,10 @@ impl<'gc> ScriptObject<'gc> {
|
|||
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,14 +412,15 @@ 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()) {
|
||||
if let Some(getter) = getter {
|
||||
if let Some(exec) = getter.as_executable() {
|
||||
// Errors, even fatal ones, are completely and silently ignored here.
|
||||
match get.exec(
|
||||
match exec.exec(
|
||||
"[Getter]",
|
||||
activation,
|
||||
context,
|
||||
|
@ -421,6 +428,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
Some((*self).into()),
|
||||
&[],
|
||||
ExecutionReason::Special,
|
||||
getter,
|
||||
) {
|
||||
Ok(value) => Ok(value),
|
||||
Err(_) => Ok(Value::Undefined),
|
||||
|
@ -428,6 +436,9 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
} else {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
} else {
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a named property on the object.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue