diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index 581cf69405..3a3a50885a 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -84,6 +84,13 @@ void GlobalObject::initialize() m_object_prototype = heap().allocate_without_global_object(*this); m_function_prototype = heap().allocate_without_global_object(*this); + m_new_object_shape = vm.heap().allocate(*this, *this); + m_new_object_shape->set_prototype_without_transition(m_object_prototype); + + m_new_script_function_prototype_object_shape = vm.heap().allocate(*this, *this); + m_new_script_function_prototype_object_shape->set_prototype_without_transition(m_object_prototype); + m_new_script_function_prototype_object_shape->add_property_without_transition(vm.names.constructor, Attribute::Writable | Attribute::Configurable); + static_cast(m_function_prototype)->initialize(*this); static_cast(m_object_prototype)->initialize(*this); @@ -143,6 +150,8 @@ void GlobalObject::visit_children(Visitor& visitor) Object::visit_children(visitor); visitor.visit(m_empty_object_shape); + visitor.visit(m_new_object_shape); + visitor.visit(m_new_script_function_prototype_object_shape); #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ visitor.visit(m_##snake_name##_constructor); diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h index d45c1f74f5..d3aa83855d 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Libraries/LibJS/Runtime/GlobalObject.h @@ -45,6 +45,9 @@ public: Shape* empty_object_shape() { return m_empty_object_shape; } + Shape* new_object_shape() { return m_new_object_shape; } + Shape* new_script_function_prototype_object_shape() { return m_new_script_function_prototype_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; } @@ -71,6 +74,8 @@ private: NonnullOwnPtr m_console; Shape* m_empty_object_shape { nullptr }; + Shape* m_new_object_shape { nullptr }; + Shape* m_new_script_function_prototype_object_shape { nullptr }; #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ ConstructorName* m_##snake_name##_constructor { nullptr }; \ diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index 66bff30be0..9fd86bf43a 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -84,7 +84,7 @@ PropertyDescriptor PropertyDescriptor::from_dictionary(VM& vm, const Object& obj Object* Object::create_empty(GlobalObject& global_object) { - return global_object.heap().allocate(global_object, *global_object.object_prototype()); + return global_object.heap().allocate(global_object, *global_object.new_object_shape()); } Object::Object(GlobalObjectTag) @@ -99,12 +99,17 @@ Object::Object(ConstructWithoutPrototypeTag, GlobalObject& global_object) } Object::Object(Object& prototype) - : Cell() { m_shape = prototype.global_object().empty_object_shape(); set_prototype(&prototype); } +Object::Object(Shape& shape) + : m_shape(&shape) +{ + m_storage.resize(shape.property_count()); +} + void Object::initialize(GlobalObject&) { } diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h index 001255db42..a1d76957a3 100644 --- a/Libraries/LibJS/Runtime/Object.h +++ b/Libraries/LibJS/Runtime/Object.h @@ -63,6 +63,7 @@ public: static Object* create_empty(GlobalObject&); explicit Object(Object& prototype); + explicit Object(Shape&); virtual void initialize(GlobalObject&) override; virtual ~Object(); diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 4218045dd0..c3575b8c48 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -69,8 +69,8 @@ void ScriptFunction::initialize(GlobalObject& global_object) auto& vm = this->vm(); Function::initialize(global_object); if (!m_is_arrow_function) { - Object* prototype = Object::create_empty(global_object); - prototype->define_property_without_transition(vm.names.constructor, this, Attribute::Writable | Attribute::Configurable); + Object* prototype = vm.heap().allocate(global_object, *global_object.new_script_function_prototype_object_shape()); + prototype->define_property(vm.names.constructor, this, Attribute::Writable | Attribute::Configurable); define_property(vm.names.prototype, prototype, 0); } define_native_property(vm.names.length, length_getter, nullptr, Attribute::Configurable);