LibJS: Support reading/writing elements in an Array via Object get/put

I'm not completely thrilled about Object::get() and Object::put() doing
special-case stuff for arrays, and we should probably come up with a
better abstraction for it.

But at least it works for now, which is really nice. :^)
This commit is contained in:
Andreas Kling 2020-03-20 20:51:59 +01:00
parent a3d2e07446
commit 8f7d4f67a4
Notes: sideshowbarker 2024-07-19 08:12:40 +09:00
3 changed files with 23 additions and 3 deletions

View file

@ -1,8 +1,7 @@
var a = [1, 2, 3];
console.log(a);
/*
a[1] = 5;
for (var i = 0; i < 3; ++i) {
console.log(a[i]);
}
*/

View file

@ -37,6 +37,7 @@ public:
i32 length() const { return static_cast<i32>(m_elements.size()); }
const Vector<Value>& elements() const { return m_elements; }
Vector<Value>& elements() { return m_elements; }
void append(Value);

View file

@ -27,6 +27,7 @@
#include <AK/String.h>
#include <LibJS/Heap/Heap.h>
#include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/NativeProperty.h>
#include <LibJS/Runtime/Object.h>
@ -47,6 +48,15 @@ Value Object::get(String property_name) const
{
const Object* object = this;
while (object) {
if (object->is_array()) {
auto* array = static_cast<const Array*>(object);
bool ok;
i32 index = property_name.to_int(ok);
if (ok) {
if (index >= 0 && index < array->length())
return array->elements()[index];
}
}
auto value = object->m_properties.get(property_name);
if (value.has_value()) {
if (value.value().is_object() && value.value().as_object()->is_native_property())
@ -62,6 +72,16 @@ void Object::put(String property_name, Value value)
{
Object* object = this;
while (object) {
if (object->is_array()) {
auto* array = static_cast<Array*>(object);
bool ok;
i32 index = property_name.to_int(ok);
if (ok && index >= 0) {
if (index >= array->length())
array->elements().resize(index + 1);
array->elements()[index] = value;
}
}
auto value_here = object->m_properties.get(property_name);
if (value_here.has_value()) {
if (value_here.value().is_object() && value_here.value().as_object()->is_native_property()) {