From c7a65727897931b0bbe7b6fc9079763bf09be8df Mon Sep 17 00:00:00 2001 From: davidot Date: Tue, 12 Oct 2021 21:48:50 +0200 Subject: LibJS: Add private references --- Userland/Libraries/LibJS/Runtime/Reference.cpp | 19 ++++++++++++++++- Userland/Libraries/LibJS/Runtime/Reference.h | 29 ++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Reference.cpp b/Userland/Libraries/LibJS/Runtime/Reference.cpp index 6c0f81e271..5468feec1a 100644 --- a/Userland/Libraries/LibJS/Runtime/Reference.cpp +++ b/Userland/Libraries/LibJS/Runtime/Reference.cpp @@ -37,6 +37,11 @@ void Reference::put_value(GlobalObject& global_object, Value value) return; auto* base_obj = base_obj_or_error.release_value(); + if (is_private_reference()) { + base_obj->private_set(m_private_name, value); + return; + } + auto succeeded_or_error = base_obj->internal_set(m_name, value, get_this_value()); if (succeeded_or_error.is_error()) return; @@ -76,6 +81,10 @@ Value Reference::get_value(GlobalObject& global_object) const if (is_property_reference()) { auto* base_obj = TRY_OR_DISCARD(m_base_value.to_object(global_object)); + + if (is_private_reference()) + return TRY_OR_DISCARD(base_obj->private_get(m_private_name)); + return TRY_OR_DISCARD(base_obj->get(m_name)); } @@ -111,7 +120,7 @@ bool Reference::delete_(GlobalObject& global_object) // 5. If IsPropertyReference(ref) is true, then if (is_property_reference()) { // a. Assert: ! IsPrivateReference(ref) is false. - // FIXME: We don't have private references yet. + VERIFY(!is_private_reference()); // b. If IsSuperReference(ref) is true, throw a ReferenceError exception. if (is_super_reference()) { @@ -181,4 +190,12 @@ String Reference::to_string() const return builder.to_string(); } +// 6.2.4.9 MakePrivateReference ( baseValue, privateIdentifier ), https://tc39.es/ecma262/#sec-makeprivatereference +Reference make_private_reference(VM& vm, Value base_value, FlyString const& private_identifier) +{ + auto* private_environment = vm.running_execution_context().private_environment; + VERIFY(private_environment); + return Reference { base_value, private_environment->resolve_private_identifier(private_identifier) }; +} + } diff --git a/Userland/Libraries/LibJS/Runtime/Reference.h b/Userland/Libraries/LibJS/Runtime/Reference.h index 3999b025ca..39793af82b 100644 --- a/Userland/Libraries/LibJS/Runtime/Reference.h +++ b/Userland/Libraries/LibJS/Runtime/Reference.h @@ -15,6 +15,8 @@ namespace JS { +Reference make_private_reference(VM&, Value base_value, FlyString const& private_identifier); + class Reference { public: enum class BaseType : u8 { @@ -55,6 +57,16 @@ public: { } + Reference(Value base, PrivateName name) + : m_base_type(BaseType::Value) + , m_base_value(base) + , m_this_value(Value {}) + , m_strict(true) + , m_is_private(true) + , m_private_name(move(name)) + { + } + Value base() const { VERIFY(m_base_type == BaseType::Value); @@ -80,9 +92,7 @@ public: return false; if (m_base_type == BaseType::Environment) return false; - if (m_base_value.is_boolean() || m_base_value.is_string() || m_base_value.is_symbol() || m_base_value.is_bigint() || m_base_value.is_number() || m_base_value.is_object()) - return true; - return false; + return true; } // 6.2.4.7 GetThisValue ( V ), https://tc39.es/ecma262/#sec-getthisvalue @@ -100,6 +110,12 @@ public: return !m_this_value.is_empty(); } + // 6.2.4.4 IsPrivateReference ( V ), https://tc39.es/ecma262/#sec-isprivatereference + bool is_private_reference() const + { + return m_is_private; + } + // Note: Non-standard helper. bool is_environment_reference() const { @@ -119,7 +135,7 @@ public: String to_string() const; - bool is_valid_reference() const { return m_name.is_valid(); } + bool is_valid_reference() const { return m_name.is_valid() || m_is_private; } Optional environment_coordinate() const { return m_environment_coordinate; } @@ -134,6 +150,11 @@ private: PropertyName m_name; Value m_this_value; bool m_strict { false }; + + bool m_is_private { false }; + // FIXME: This can (probably) be an union with m_name. + PrivateName m_private_name { 0, "" }; + Optional m_environment_coordinate; }; -- cgit v1.2.3