From 983c0fb20098a3b7334cdcee11adb47b8e86a784 Mon Sep 17 00:00:00 2001 From: David Wendt Date: Fri, 25 Oct 2019 18:02:47 -0400 Subject: [PATCH] Add proto chain inspection to the object interface. --- core/src/avm1/globals/object.rs | 9 ++------- core/src/avm1/object.rs | 7 +++++++ core/src/avm1/script_object.rs | 8 ++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/core/src/avm1/globals/object.rs b/core/src/avm1/globals/object.rs index 2910a3724..b6942148c 100644 --- a/core/src/avm1/globals/object.rs +++ b/core/src/avm1/globals/object.rs @@ -105,19 +105,14 @@ fn is_prototype_of<'gc>( Ok(ob) => ob, Err(_) => return Ok(Value::Bool(false).into()), }; - let mut proto = ob.read().as_script_object().unwrap().prototype().cloned(); + let mut proto = ob.read().proto(); while let Some(proto_ob) = proto { if GcCell::ptr_eq(this, proto_ob) { return Ok(Value::Bool(true).into()); } - proto = proto_ob - .read() - .as_script_object() - .unwrap() - .prototype() - .cloned(); + proto = proto_ob.read().proto(); } Ok(Value::Bool(false).into()) diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index 10ec6feb2..8890e81a6 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -75,6 +75,13 @@ pub trait Object<'gc>: 'gc + Collect + Debug { /// Returns false if the property cannot be deleted. fn delete(&mut self, name: &str) -> bool; + /// Retrieve the `__proto__` of a given object. + /// + /// The proto is another object used to resolve methods across a class of + /// multiple objects. It should also be accessible as `__proto__` from + /// `get`. + fn proto(&self) -> Option>; + /// Checks if the object has a given named property. fn has_property(&self, name: &str) -> bool; diff --git a/core/src/avm1/script_object.rs b/core/src/avm1/script_object.rs index 660e29cde..825c9f4d2 100644 --- a/core/src/avm1/script_object.rs +++ b/core/src/avm1/script_object.rs @@ -204,10 +204,6 @@ impl<'gc> ScriptObject<'gc> { self.prototype = Some(prototype); } - pub fn prototype(&self) -> Option<&ObjectCell<'gc>> { - self.prototype.as_ref() - } - pub fn set_type_of(&mut self, type_of: &'static str) { self.type_of = type_of; } @@ -332,6 +328,10 @@ impl<'gc> Object<'gc> for ScriptObject<'gc> { false } + fn proto(&self) -> Option> { + self.prototype + } + /// Checks if the object has a given named property. fn has_property(&self, name: &str) -> bool { self.has_own_property(name)