diff options
author | Andreas Kling <kling@serenityos.org> | 2021-06-24 13:24:44 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-24 13:26:00 +0200 |
commit | 0cd65b55bdd91d5553f5299a7ac5514f86040c15 (patch) | |
tree | 8745268fcd56424c76165f735807888c82a741b3 /Userland/Libraries | |
parent | 3f8857cd21692488a638ce46a6e28bcfc940c817 (diff) | |
download | serenity-0cd65b55bdd91d5553f5299a7ac5514f86040c15.zip |
LibJS: Add ObjectEnvironmentRecord.[[IsWithEnvironment]] field
This is true for environments created by `with` statements, and false
for other (global) object environments.
Also add the WithBaseObject abstract operation while we're here.
Diffstat (limited to 'Userland/Libraries')
5 files changed, 22 insertions, 7 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 1865212e0a..082a35e2ea 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -175,10 +175,7 @@ DeclarativeEnvironmentRecord* new_declarative_environment(EnvironmentRecord& env ObjectEnvironmentRecord* new_object_environment(Object& object, bool is_with_environment, EnvironmentRecord* environment_record) { auto& global_object = object.global_object(); - if (!is_with_environment) { - TODO(); - } - return global_object.heap().allocate<ObjectEnvironmentRecord>(global_object, object, environment_record); + return global_object.heap().allocate<ObjectEnvironmentRecord>(global_object, object, is_with_environment ? ObjectEnvironmentRecord::IsWithEnvironment::Yes : ObjectEnvironmentRecord::IsWithEnvironment::No, environment_record); } // 9.4.3 GetThisEnvironment ( ), https://tc39.es/ecma262/#sec-getthisenvironment diff --git a/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h index f4a13278b8..443165818a 100644 --- a/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h +++ b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h @@ -34,6 +34,8 @@ public: virtual bool has_this_binding() const { return false; } virtual Value get_this_binding(GlobalObject&) const { return {}; } + virtual Object* with_base_object() const { return nullptr; } + virtual bool has_binding([[maybe_unused]] FlyString const& name) const { return false; } virtual void create_mutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool can_be_deleted) { } virtual void create_immutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) { } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironmentRecord.cpp b/Userland/Libraries/LibJS/Runtime/GlobalEnvironmentRecord.cpp index ee866636e1..d233052aaf 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironmentRecord.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironmentRecord.cpp @@ -16,7 +16,7 @@ GlobalEnvironmentRecord::GlobalEnvironmentRecord(GlobalObject& global_object) : EnvironmentRecord(nullptr) , m_global_object(global_object) { - m_object_record = global_object.heap().allocate<ObjectEnvironmentRecord>(global_object, global_object, nullptr); + m_object_record = global_object.heap().allocate<ObjectEnvironmentRecord>(global_object, global_object, ObjectEnvironmentRecord::IsWithEnvironment::No, nullptr); m_declarative_record = global_object.heap().allocate<DeclarativeEnvironmentRecord>(global_object); } diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp index 2be830ea7b..b961d97c0a 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp @@ -10,9 +10,10 @@ namespace JS { -ObjectEnvironmentRecord::ObjectEnvironmentRecord(Object& object, EnvironmentRecord* parent_scope) +ObjectEnvironmentRecord::ObjectEnvironmentRecord(Object& object, IsWithEnvironment is_with_environment, EnvironmentRecord* parent_scope) : EnvironmentRecord(parent_scope) , m_object(object) + , m_with_environment(is_with_environment == IsWithEnvironment::Yes) { } diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h index f9780f0fb5..707a9ee64b 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h @@ -14,7 +14,11 @@ class ObjectEnvironmentRecord : public EnvironmentRecord { JS_ENVIRONMENT_RECORD(ObjectEnvironmentRecord, EnvironmentRecord); public: - ObjectEnvironmentRecord(Object&, EnvironmentRecord* parent_scope); + enum class IsWithEnvironment { + No, + Yes, + }; + ObjectEnvironmentRecord(Object&, IsWithEnvironment, EnvironmentRecord* parent_scope); virtual Optional<Variable> get_from_environment_record(FlyString const&) const override; virtual void put_into_environment_record(FlyString const&, Variable) override; @@ -28,12 +32,23 @@ public: virtual Value get_binding_value(GlobalObject&, FlyString const& name, bool strict) override; virtual bool delete_binding(GlobalObject&, FlyString const& name) override; + // 9.1.1.2.10 WithBaseObject ( ), https://tc39.es/ecma262/#sec-object-environment-records-withbaseobject + virtual Object* with_base_object() const override + { + if (is_with_environment()) + return &m_object; + return nullptr; + } + + bool is_with_environment() const { return m_with_environment; } + Object& object() { return m_object; } private: virtual void visit_edges(Visitor&) override; Object& m_object; + bool m_with_environment { false }; }; } |