瀏覽代碼

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 :^)
Andreas Kling 5 年之前
父節點
當前提交
3072f9fd82

+ 0 - 2
Libraries/LibJS/Interpreter.cpp

@@ -40,7 +40,6 @@ namespace JS {
 Interpreter::Interpreter()
     : m_heap(*this)
 {
-    m_empty_object_shape = heap().allocate<Shape>();
 }
 
 Interpreter::~Interpreter()
@@ -161,7 +160,6 @@ Optional<Value> Interpreter::get_variable(const FlyString& name)
 
 void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
 {
-    roots.set(m_empty_object_shape);
     roots.set(m_global_object);
     roots.set(m_exception);
 

+ 0 - 3
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<ScopeFrame> m_scope_stack;
     Vector<CallFrame> m_call_stack;
 
-    Shape* m_empty_object_shape { nullptr };
     Object* m_global_object { nullptr };
 
     Exception* m_exception { nullptr };

+ 3 - 0
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<Shape>();
     m_object_prototype = heap().allocate<ObjectPrototype>();
     m_function_prototype = heap().allocate<FunctionPrototype>();
 
@@ -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

+ 4 - 0
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<typename ConstructorType>
     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 };

+ 6 - 2
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<Shape>();
+    }
 }
 
 Object::~Object()