summaryrefslogtreecommitdiff
path: root/Libraries/LibJS
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-06-08 12:15:58 +0200
committerAndreas Kling <kling@serenityos.org>2020-06-08 12:15:58 +0200
commitff8bb962b620874668b797a1ee1c25de3f5c1074 (patch)
tree7267c17fdfa4fd6b1bb51daafe980cfc96937e96 /Libraries/LibJS
parent10aebabf0bd21c2b0599525a708c95dca502fa7a (diff)
downloadserenity-ff8bb962b620874668b797a1ee1c25de3f5c1074.zip
LibJS: Always keep a reference to the global object in Shape
We need to move towards supporting multiple global objects, which will be a large refactoring. To keep it manageable, let's do it in steps, starting with giving Object a way to find the GlobalObject it lives inside by asking its Shape for it.
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Object.h2
-rw-r--r--Libraries/LibJS/Runtime/Shape.cpp25
-rw-r--r--Libraries/LibJS/Runtime/Shape.h10
5 files changed, 26 insertions, 15 deletions
diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp
index f5b621e9a5..5da7a1dbd6 100644
--- a/Libraries/LibJS/Runtime/GlobalObject.cpp
+++ b/Libraries/LibJS/Runtime/GlobalObject.cpp
@@ -70,7 +70,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_empty_object_shape = heap().allocate<Shape>(*this);
m_object_prototype = heap().allocate<ObjectPrototype>();
m_function_prototype = heap().allocate<FunctionPrototype>();
diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp
index 01c57a17d2..866f86b65a 100644
--- a/Libraries/LibJS/Runtime/Object.cpp
+++ b/Libraries/LibJS/Runtime/Object.cpp
@@ -91,7 +91,7 @@ Object::Object(Object* prototype)
m_shape = interpreter().global_object().empty_object_shape();
set_prototype(prototype);
} else {
- m_shape = interpreter().heap().allocate<Shape>();
+ m_shape = interpreter().heap().allocate<Shape>(interpreter().global_object());
}
}
diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h
index bd127d2e74..9e7dff8959 100644
--- a/Libraries/LibJS/Runtime/Object.h
+++ b/Libraries/LibJS/Runtime/Object.h
@@ -73,6 +73,8 @@ public:
Shape& shape() { return *m_shape; }
const Shape& shape() const { return *m_shape; }
+ GlobalObject& global_object() const { return shape().global_object(); }
+
virtual Value get(PropertyName) const;
virtual bool has_property(PropertyName) const;
diff --git a/Libraries/LibJS/Runtime/Shape.cpp b/Libraries/LibJS/Runtime/Shape.cpp
index 549ec600e7..cf6821e04d 100644
--- a/Libraries/LibJS/Runtime/Shape.cpp
+++ b/Libraries/LibJS/Runtime/Shape.cpp
@@ -25,13 +25,14 @@
*/
#include <LibJS/Interpreter.h>
+#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Shape.h>
namespace JS {
Shape* Shape::create_unique_clone() const
{
- auto* new_shape = heap().allocate<Shape>();
+ auto* new_shape = heap().allocate<Shape>(m_global_object);
new_shape->m_unique = true;
new_shape->m_prototype = m_prototype;
ensure_property_table();
@@ -45,7 +46,7 @@ Shape* Shape::create_put_transition(const FlyString& property_name, PropertyAttr
TransitionKey key { property_name, attributes };
if (auto* existing_shape = m_forward_transitions.get(key).value_or(nullptr))
return existing_shape;
- auto* new_shape = heap().allocate<Shape>(this, property_name, attributes, TransitionType::Put);
+ auto* new_shape = heap().allocate<Shape>(*this, property_name, attributes, TransitionType::Put);
m_forward_transitions.set(key, new_shape);
return new_shape;
}
@@ -55,31 +56,34 @@ Shape* Shape::create_configure_transition(const FlyString& property_name, Proper
TransitionKey key { property_name, attributes };
if (auto* existing_shape = m_forward_transitions.get(key).value_or(nullptr))
return existing_shape;
- auto* new_shape = heap().allocate<Shape>(this, property_name, attributes, TransitionType::Configure);
+ auto* new_shape = heap().allocate<Shape>(*this, property_name, attributes, TransitionType::Configure);
m_forward_transitions.set(key, new_shape);
return new_shape;
}
Shape* Shape::create_prototype_transition(Object* new_prototype)
{
- return heap().allocate<Shape>(this, new_prototype);
+ return heap().allocate<Shape>(*this, new_prototype);
}
-Shape::Shape()
+Shape::Shape(GlobalObject& global_object)
+ : m_global_object(global_object)
{
}
-Shape::Shape(Shape* previous_shape, const FlyString& property_name, PropertyAttributes attributes, TransitionType transition_type)
- : m_previous(previous_shape)
+Shape::Shape(Shape& previous_shape, const FlyString& property_name, PropertyAttributes attributes, TransitionType transition_type)
+ : m_global_object(previous_shape.m_global_object)
+ , m_previous(&previous_shape)
, m_property_name(property_name)
, m_attributes(attributes)
- , m_prototype(previous_shape->m_prototype)
+ , m_prototype(previous_shape.m_prototype)
, m_transition_type(transition_type)
{
}
-Shape::Shape(Shape* previous_shape, Object* new_prototype)
- : m_previous(previous_shape)
+Shape::Shape(Shape& previous_shape, Object* new_prototype)
+ : m_global_object(previous_shape.m_global_object)
+ , m_previous(&previous_shape)
, m_prototype(new_prototype)
, m_transition_type(TransitionType::Prototype)
{
@@ -92,6 +96,7 @@ Shape::~Shape()
void Shape::visit_children(Cell::Visitor& visitor)
{
Cell::visit_children(visitor);
+ visitor.visit(&m_global_object);
visitor.visit(m_prototype);
visitor.visit(m_previous);
for (auto& it : m_forward_transitions)
diff --git a/Libraries/LibJS/Runtime/Shape.h b/Libraries/LibJS/Runtime/Shape.h
index 60f59f09e4..17fd34a057 100644
--- a/Libraries/LibJS/Runtime/Shape.h
+++ b/Libraries/LibJS/Runtime/Shape.h
@@ -62,9 +62,9 @@ public:
Prototype,
};
- Shape();
- Shape(Shape* previous_shape, const FlyString& property_name, PropertyAttributes attributes, TransitionType);
- Shape(Shape* previous_shape, Object* new_prototype);
+ explicit Shape(GlobalObject&);
+ Shape(Shape& previous_shape, const FlyString& property_name, PropertyAttributes attributes, TransitionType);
+ Shape(Shape& previous_shape, Object* new_prototype);
Shape* create_put_transition(const FlyString& name, PropertyAttributes attributes);
Shape* create_configure_transition(const FlyString& name, PropertyAttributes attributes);
@@ -73,6 +73,8 @@ public:
bool is_unique() const { return m_unique; }
Shape* create_unique_clone() const;
+ GlobalObject& global_object() const { return m_global_object; }
+
Object* prototype() { return m_prototype; }
const Object* prototype() const { return m_prototype; }
@@ -99,6 +101,8 @@ private:
void ensure_property_table() const;
+ GlobalObject& m_global_object;
+
mutable OwnPtr<HashMap<FlyString, PropertyMetadata>> m_property_table;
HashMap<TransitionKey, Shape*> m_forward_transitions;