Impl `Object.isPrototypeOf` w/ test

This commit is contained in:
David Wendt 2020-03-06 15:02:19 -05:00
parent d29f3dc1d0
commit 0e89cb2175
5 changed files with 72 additions and 2 deletions

View File

@ -12,7 +12,7 @@ use gc_arena::MutationContext;
/// Implements `Object`
pub fn constructor<'gc>(
_avm: &mut Avm2<'gc>,
_action_context: &mut UpdateContext<'_, 'gc, '_>,
_context: &mut UpdateContext<'_, 'gc, '_>,
_this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<ReturnValue<'gc>, Error> {
@ -22,7 +22,7 @@ pub fn constructor<'gc>(
/// `Object.prototype.hasOwnProperty`
pub fn has_own_property<'gc>(
_avm: &mut Avm2<'gc>,
_action_context: &mut UpdateContext<'_, 'gc, '_>,
_context: &mut UpdateContext<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<ReturnValue<'gc>, Error> {
@ -39,6 +39,29 @@ pub fn has_own_property<'gc>(
Ok(false.into())
}
/// `Object.prototype.isPrototypeOf`
pub fn is_prototype_of<'gc>(
_avm: &mut Avm2<'gc>,
_context: &mut UpdateContext<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<ReturnValue<'gc>, Error> {
let search_proto: Result<Object<'gc>, Error> =
this.ok_or_else(|| "No valid this parameter".into());
let search_proto = search_proto?;
let mut target_proto = args.get(0).cloned().unwrap_or(Value::Undefined);
while let Value::Object(proto) = target_proto {
if Object::ptr_eq(search_proto, proto) {
return Ok(true.into());
}
target_proto = proto.proto().map(|o| o.into()).unwrap_or(Value::Undefined);
}
Ok(false.into())
}
/// Partially construct `Object.prototype`.
///
/// `__proto__` and other cross-linked properties of this object will *not*
@ -59,4 +82,10 @@ pub fn fill_proto<'gc>(
0,
FunctionObject::from_builtin(gc_context, has_own_property, fn_proto),
);
object_proto.install_method(
gc_context,
QName::new(Namespace::public_namespace(), "isPrototypeOf"),
0,
FunctionObject::from_builtin(gc_context, is_prototype_of, fn_proto),
);
}

View File

@ -0,0 +1,28 @@
package {
public class Test {}
}
class ES4Class extends Object {
}
function ES3Class() {
}
var es4inst = new ES4Class();
var es3inst = new ES3Class();
trace("//ES4Class.prototype.isPrototypeOf(es4inst);");
trace(ES4Class.prototype.isPrototypeOf(es4inst));
trace("//Object.prototype.isPrototypeOf(es4inst);");
trace(Object.prototype.isPrototypeOf(es4inst));
trace("//ES3Class.prototype.isPrototypeOf(es4inst);");
trace(ES3Class.prototype.isPrototypeOf(es4inst));
trace("//ES4Class.prototype.isPrototypeOf(es3inst);");
trace(ES4Class.prototype.isPrototypeOf(es3inst));
trace("//Object.prototype.isPrototypeOf(es3inst);");
trace(Object.prototype.isPrototypeOf(es3inst));
trace("//ES3Class.prototype.isPrototypeOf(es3inst);");
trace(ES3Class.prototype.isPrototypeOf(es3inst));

View File

@ -0,0 +1,13 @@
//ES4Class.prototype.isPrototypeOf(es4inst);
true
//Object.prototype.isPrototypeOf(es4inst);
true
//ES3Class.prototype.isPrototypeOf(es4inst);
false
//ES4Class.prototype.isPrototypeOf(es3inst);
false
//Object.prototype.isPrototypeOf(es3inst);
true
//ES3Class.prototype.isPrototypeOf(es3inst);
true

Binary file not shown.

Binary file not shown.