summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-06-24 13:24:44 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-24 13:26:00 +0200
commit0cd65b55bdd91d5553f5299a7ac5514f86040c15 (patch)
tree8745268fcd56424c76165f735807888c82a741b3 /Userland/Libraries
parent3f8857cd21692488a638ce46a6e28bcfc940c817 (diff)
downloadserenity-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')
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp5
-rw-r--r--Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalEnvironmentRecord.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp3
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h17
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 };
};
}