summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/Runtime
diff options
context:
space:
mode:
authormattco98 <matthewcolsson@gmail.com>2020-04-28 19:19:31 -0700
committerAndreas Kling <kling@serenityos.org>2020-04-29 18:47:03 +0200
commit95abcc3722af0ec0115d519504e19d05c9cb79a5 (patch)
tree7bfd09133c9c56d680e3a81fc3016142cd1b534d /Libraries/LibJS/Runtime
parent58f6f50de48965a6bf0113c7e9ba79889dba09ac (diff)
downloadserenity-95abcc3722af0ec0115d519504e19d05c9cb79a5.zip
LibJS: Implement correct object property ordering
This commit introduces a way to get an object's own properties in the correct order. The "correct order" for JS object properties is first all array-like index properties (numeric keys) sorted by insertion order, followed by all string properties sorted by insertion order. Objects also now print correctly in the repl! Before this commit: courage ~/js-tests $ js > ({ foo: 1, bar: 2, baz: 3 }) { bar: 2, foo: 1, baz: 3 } After: courage ~/js-tests $ js > ({ foo: 1, bar: 2, baz: 3 }) { foo: 1, bar: 2, baz: 3 }
Diffstat (limited to 'Libraries/LibJS/Runtime')
-rw-r--r--Libraries/LibJS/Runtime/Cell.cpp5
-rw-r--r--Libraries/LibJS/Runtime/Cell.h1
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp1
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Shape.cpp12
-rw-r--r--Libraries/LibJS/Runtime/Shape.h7
6 files changed, 27 insertions, 1 deletions
diff --git a/Libraries/LibJS/Runtime/Cell.cpp b/Libraries/LibJS/Runtime/Cell.cpp
index c80b59e824..4c8cb69511 100644
--- a/Libraries/LibJS/Runtime/Cell.cpp
+++ b/Libraries/LibJS/Runtime/Cell.cpp
@@ -56,6 +56,11 @@ Interpreter& Cell::interpreter()
return heap().interpreter();
}
+Interpreter& Cell::interpreter() const
+{
+ return heap().interpreter();
+}
+
const LogStream& operator<<(const LogStream& stream, const Cell* cell)
{
if (!cell)
diff --git a/Libraries/LibJS/Runtime/Cell.h b/Libraries/LibJS/Runtime/Cell.h
index 9989618ed4..e08a31ac62 100644
--- a/Libraries/LibJS/Runtime/Cell.h
+++ b/Libraries/LibJS/Runtime/Cell.h
@@ -60,6 +60,7 @@ public:
Heap& heap() const;
Interpreter& interpreter();
+ Interpreter& interpreter() const;
protected:
Cell() {}
diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp
index 5144e75444..403c99f066 100644
--- a/Libraries/LibJS/Runtime/Object.cpp
+++ b/Libraries/LibJS/Runtime/Object.cpp
@@ -34,6 +34,7 @@
#include <LibJS/Runtime/NativeProperty.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/Shape.h>
+#include <LibJS/Runtime/StringObject.h>
#include <LibJS/Runtime/Value.h>
namespace JS {
diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp
index e7738ecfeb..475bbd56f4 100644
--- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp
@@ -76,7 +76,7 @@ Value ObjectConstructor::get_own_property_names(Interpreter& interpreter)
result->elements().append(js_string(interpreter, String::number(i)));
}
- for (auto& it : object->shape().property_table()) {
+ for (auto& it : object->shape().property_table_ordered()) {
result->elements().append(js_string(interpreter, it.key));
}
return result;
diff --git a/Libraries/LibJS/Runtime/Shape.cpp b/Libraries/LibJS/Runtime/Shape.cpp
index d03ad74a36..ef10ea8c51 100644
--- a/Libraries/LibJS/Runtime/Shape.cpp
+++ b/Libraries/LibJS/Runtime/Shape.cpp
@@ -117,6 +117,18 @@ size_t Shape::property_count() const
return property_table().size();
}
+Vector<Shape::Property> Shape::property_table_ordered() const
+{
+ auto vec = Vector<Shape::Property>();
+ vec.resize(property_table().size());
+
+ for (auto& it : property_table()) {
+ vec[it.value.offset] = { it.key, it.value };
+ }
+
+ return vec;
+}
+
void Shape::ensure_property_table() const
{
if (m_property_table)
diff --git a/Libraries/LibJS/Runtime/Shape.h b/Libraries/LibJS/Runtime/Shape.h
index 26c8eb574b..44cf3bdb43 100644
--- a/Libraries/LibJS/Runtime/Shape.h
+++ b/Libraries/LibJS/Runtime/Shape.h
@@ -88,6 +88,13 @@ public:
const HashMap<FlyString, PropertyMetadata>& property_table() const;
size_t property_count() const;
+ struct Property {
+ FlyString key;
+ PropertyMetadata value;
+ };
+
+ Vector<Property> property_table_ordered() const;
+
void set_prototype_without_transition(Object* new_prototype) { m_prototype = new_prototype; }
void remove_property_from_unique_shape(const FlyString&, size_t offset);