From 8d94cc629ff83703e8c06419a87442e720f7cb33 Mon Sep 17 00:00:00 2001 From: cybai Date: Sat, 11 Jun 2022 20:20:23 +0900 Subject: [PATCH] Implement getter of `Object.p.__proto__` --- boa_engine/src/builtins/object/mod.rs | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/builtins/object/mod.rs b/boa_engine/src/builtins/object/mod.rs index da0274cd51d..74188ba3d54 100644 --- a/boa_engine/src/builtins/object/mod.rs +++ b/boa_engine/src/builtins/object/mod.rs @@ -21,7 +21,7 @@ use crate::{ internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder, IntegrityLevel, JsObject, ObjectData, ObjectKind, }, - property::{PropertyDescriptor, PropertyKey, PropertyNameKind}, + property::{Attribute, PropertyDescriptor, PropertyKey, PropertyNameKind}, symbol::WellKnownSymbols, value::JsValue, Context, JsResult, JsString, @@ -43,6 +43,10 @@ impl BuiltIn for Object { fn init(context: &mut Context) -> Option { let _timer = Profiler::global().start_event(Self::NAME, "init"); + let legacy_proto_getter = FunctionBuilder::native(context, Self::legacy_proto_getter) + .name("get __proto__") + .build(); + ConstructorBuilder::with_standard_constructor( context, Self::constructor, @@ -51,6 +55,12 @@ impl BuiltIn for Object { .name(Self::NAME) .length(Self::LENGTH) .inherit(None) + .accessor( + "__proto__", + Some(legacy_proto_getter), + None, + Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) .method(Self::has_own_property, "hasOwnProperty", 1) .method(Self::property_is_enumerable, "propertyIsEnumerable", 1) .method(Self::to_string, "toString", 0) @@ -117,6 +127,31 @@ impl Object { Ok(context.construct_object().into()) } + /// `get Object.prototype.__proto__` + /// + /// The `__proto__` getter function exposes the value of the + /// internal [[Prototype]] of an object. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-get-object.prototype.__proto__ + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto + pub fn legacy_proto_getter( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> JsResult { + // 1. Let O be ? ToObject(this value). + let obj = this.to_object(context)?; + + // 2. Return ? O.[[GetPrototypeOf]](). + let proto = obj.__get_prototype_of__(context)?; + + Ok(proto.map_or(JsValue::Null, JsValue::new)) + } + /// `Object.prototype.__defineGetter__(prop, func)` /// /// Binds an object's property to a function to be called when that property is looked up.