diff --git a/crates/dash_middle/src/interner.rs b/crates/dash_middle/src/interner.rs index cfd22883..ed9920ff 100644 --- a/crates/dash_middle/src/interner.rs +++ b/crates/dash_middle/src/interner.rs @@ -254,6 +254,8 @@ pub mod sym { isConcatSpreadable, zero: "0", one: "1", + getPrototypeOf, + isPrototypeOf } ] } diff --git a/crates/dash_vm/src/js_std/object.rs b/crates/dash_vm/src/js_std/object.rs index f6d69d95..1464bd6c 100644 --- a/crates/dash_vm/src/js_std/object.rs +++ b/crates/dash_vm/src/js_std/object.rs @@ -7,7 +7,7 @@ use crate::value::function::native::CallContext; use crate::value::object::{NamedObject, Object, PropertyKey, PropertyValue}; use crate::value::ops::conversions::ValueConversion; use crate::value::root_ext::RootErrExt; -use crate::value::{Root, Value, ValueContext}; +use crate::value::{Root, Typeof, Value, ValueContext}; pub fn constructor(cx: CallContext) -> Result { match cx.args.first() { @@ -190,3 +190,28 @@ pub fn entries(cx: CallContext) -> Result { let entries = Array::from_vec(cx.scope, entries); Ok(Value::Object(cx.scope.register(entries))) } + +pub fn get_prototype_of(cx: CallContext) -> Result { + let obj = cx.args.first().unwrap_or_undefined().to_object(cx.scope)?; + obj.get_prototype(cx.scope) +} + +pub fn is_prototype_of(cx: CallContext) -> Result { + let target_proto = Value::Object(cx.this.to_object(cx.scope)?); + let mut this_proto = cx.args.first().unwrap_or_undefined(); + if this_proto.type_of() != Typeof::Object { + return Ok(Value::Boolean(false)); + } + + loop { + if this_proto == target_proto { + return Ok(Value::Boolean(true)); + } + + this_proto = match this_proto { + Value::Object(obj) => obj.get_prototype(cx.scope)?, + Value::External(obj) => obj.inner.get_prototype(cx.scope)?, + _ => return Ok(Value::Boolean(false)), + }; + } +} diff --git a/crates/dash_vm/src/lib.rs b/crates/dash_vm/src/lib.rs index 028450cb..ee11de19 100644 --- a/crates/dash_vm/src/lib.rs +++ b/crates/dash_vm/src/lib.rs @@ -235,6 +235,7 @@ impl Vm { (sym::defineProperty, scope.statics.object_define_property.clone()), (sym::entries, scope.statics.object_entries.clone()), (sym::assign, scope.statics.object_assign.clone()), + (sym::getPrototypeOf, scope.statics.object_get_prototype_of.clone()), ], [], [], @@ -249,6 +250,7 @@ impl Vm { [ (sym::toString, scope.statics.object_to_string.clone()), (sym::hasOwnProperty, scope.statics.object_has_own_property.clone()), + (sym::isPrototypeOf, scope.statics.object_is_prototype_of.clone()), ], [], [], diff --git a/crates/dash_vm/src/statics.rs b/crates/dash_vm/src/statics.rs index 038f24ee..6d68b16f 100644 --- a/crates/dash_vm/src/statics.rs +++ b/crates/dash_vm/src/statics.rs @@ -77,6 +77,8 @@ pub struct Statics { pub object_define_property: Handle, pub object_assign: Handle, pub object_entries: Handle, + pub object_get_prototype_of: Handle, + pub object_is_prototype_of: Handle, pub number_ctor: Handle, pub number_prototype: Handle, pub number_tostring: Handle, @@ -288,6 +290,8 @@ impl Statics { object_define_property: function(gc, sym::defineProperty, js_std::object::define_property), object_assign: function(gc, sym::assign, js_std::object::assign), object_entries: function(gc, sym::entries, js_std::object::entries), + object_get_prototype_of: function(gc, sym::getPrototypeOf, js_std::object::get_prototype_of), + object_is_prototype_of: function(gc, sym::isPrototypeOf, js_std::object::is_prototype_of), number_ctor: function(gc, sym::Number, js_std::number::constructor), number_prototype: builtin_object(gc, BoxedNumber::with_obj(0.0, NamedObject::null())), number_tostring: function(gc, sym::toString, js_std::number::to_string), diff --git a/crates/dash_vm/src/test/mod.rs b/crates/dash_vm/src/test/mod.rs index f9c38ff3..72846250 100644 --- a/crates/dash_vm/src/test/mod.rs +++ b/crates/dash_vm/src/test/mod.rs @@ -1,5 +1,4 @@ use std::ptr; -use std::rc::Rc; use dash_middle::interner::sym; use dash_optimizer::OptLevel; diff --git a/crates/dash_vm/src/value/mod.rs b/crates/dash_vm/src/value/mod.rs index 777ae364..65be4767 100755 --- a/crates/dash_vm/src/value/mod.rs +++ b/crates/dash_vm/src/value/mod.rs @@ -565,7 +565,7 @@ impl Value { } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Typeof { Undefined, Object,