From 3072f9fd82c17049a5b54336cefc659724f5d661 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 18 Apr 2020 13:56:13 +0200 Subject: [PATCH] LibJS: Move the empty object shape from Interpreter to GlobalObject The big remaining hurdle before a GlobalObject-agnostic Interpreter is the fact that Interpreter owns and vends the GlobalObject :^) --- Libraries/LibJS/Interpreter.cpp | 2 -- Libraries/LibJS/Interpreter.h | 3 --- Libraries/LibJS/Runtime/GlobalObject.cpp | 3 +++ Libraries/LibJS/Runtime/GlobalObject.h | 4 ++++ Libraries/LibJS/Runtime/Object.cpp | 8 ++++++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index b34d507884..24fdb5f49d 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -40,7 +40,6 @@ namespace JS { Interpreter::Interpreter() : m_heap(*this) { - m_empty_object_shape = heap().allocate(); } Interpreter::~Interpreter() @@ -161,7 +160,6 @@ Optional Interpreter::get_variable(const FlyString& name) void Interpreter::gather_roots(Badge, HashTable& roots) { - roots.set(m_empty_object_shape); roots.set(m_global_object); roots.set(m_exception); diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index de9cbb3717..a6f54d97aa 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -139,8 +139,6 @@ public: return m_call_stack.last().this_value; } - Shape* empty_object_shape() { return m_empty_object_shape; } - Exception* exception() { return m_exception; @@ -171,7 +169,6 @@ private: Vector m_scope_stack; Vector m_call_stack; - Shape* m_empty_object_shape { nullptr }; Object* m_global_object { nullptr }; Exception* m_exception { nullptr }; diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index 0ff1d13fef..317fd32eed 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -72,6 +72,7 @@ GlobalObject::GlobalObject() void GlobalObject::initialize() { // These are done first since other prototypes depend on their presence. + m_empty_object_shape = heap().allocate(); m_object_prototype = heap().allocate(); m_function_prototype = heap().allocate(); @@ -119,6 +120,8 @@ void GlobalObject::visit_children(Visitor& visitor) { Object::visit_children(visitor); + visitor.visit(m_empty_object_shape); + #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ visitor.visit(m_##snake_name##_constructor); JS_ENUMERATE_ERROR_SUBCLASSES diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h index 2f349dd86e..52ca09a3a0 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Libraries/LibJS/Runtime/GlobalObject.h @@ -37,6 +37,8 @@ public: virtual ~GlobalObject() override; + Shape* empty_object_shape() { return m_empty_object_shape; } + #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } \ Object* snake_name##_prototype() { return m_##snake_name##_prototype; } @@ -55,6 +57,8 @@ private: template void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype); + Shape* m_empty_object_shape { nullptr }; + #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ ConstructorName* m_##snake_name##_constructor { nullptr }; \ Object* m_##snake_name##_prototype { nullptr }; diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index f35205dffc..bc9affce08 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -45,8 +45,12 @@ Object* Object::create_empty(Interpreter&, GlobalObject& global_object) Object::Object(Object* prototype) { - m_shape = interpreter().empty_object_shape(); - set_prototype(prototype); + if (prototype) { + m_shape = interpreter().global_object().empty_object_shape(); + set_prototype(prototype); + } else { + m_shape = interpreter().heap().allocate(); + } } Object::~Object()