LibJS: Implement Array length setter

This commit is contained in:
Linus Groh 2020-04-23 00:33:13 +01:00 committed by Andreas Kling
parent d5d3e0b4ed
commit 418092a71a
Notes: sideshowbarker 2024-07-19 07:23:31 +09:00
4 changed files with 74 additions and 19 deletions

View File

@ -49,19 +49,37 @@ Array::~Array()
{
}
Value Array::length_getter(Interpreter& interpreter)
Array* array_from(Interpreter& interpreter)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
if (!this_object)
return {};
if (!this_object->is_array())
return interpreter.throw_exception<TypeError>("Not an array");
return Value(static_cast<const Array*>(this_object)->length());
if (!this_object->is_array()) {
interpreter.throw_exception<TypeError>("Not an Array");
return nullptr;
}
return static_cast<Array*>(this_object);
}
void Array::length_setter(Interpreter&, Value)
Value Array::length_getter(Interpreter& interpreter)
{
ASSERT_NOT_REACHED();
auto* array = array_from(interpreter);
if (!array)
return {};
return Value(array->length());
}
void Array::length_setter(Interpreter& interpreter, Value value)
{
auto* array = array_from(interpreter);
if (!array)
return;
auto length = value.to_number();
if (length.is_nan() || length.is_infinity() || length.as_double() < 0) {
interpreter.throw_exception<RangeError>("Invalid array length");
return;
}
array->elements().resize(length.as_double());
}
}

View File

@ -30,6 +30,8 @@
namespace JS {
Array* array_from(Interpreter&);
class Array final : public Object {
public:
static Array* create(GlobalObject&);
@ -47,5 +49,4 @@ private:
static void length_setter(Interpreter&, Value);
};
}

View File

@ -63,18 +63,6 @@ ArrayPrototype::~ArrayPrototype()
{
}
static Array* array_from(Interpreter& interpreter)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
if (!this_object)
return {};
if (!this_object->is_array()) {
interpreter.throw_exception<TypeError>("Not an Array");
return nullptr;
}
return static_cast<Array*>(this_object);
}
static Function* callback_from_args(Interpreter& interpreter, const String& name)
{
if (interpreter.argument_count() < 1) {

View File

@ -0,0 +1,48 @@
load("test-common.js");
try {
var a = [1, 2, 3];
assert(a.length === 3);
assert(a[0] === 1);
assert(a[1] === 2);
assert(a[2] === 3);
a.length = 5;
assert(a.length === 5);
assert(a[0] === 1);
assert(a[1] === 2);
assert(a[2] === 3);
assert(a[3] === undefined);
assert(a[4] === undefined);
a.length = 1;
assert(a.length === 1);
assert(a[0] === 1);
a.length = 0;
assert(a.length === 0);
a.length = "42";
assert(a.length === 42);
a.length = [];
assert(a.length === 0);
a.length = true;
assert(a.length === 1);
[undefined, "foo", -1, Infinity, -Infinity, NaN].forEach(value => {
assertThrowsError(() => {
a.length = value;
}, {
error: RangeError,
message: "Invalid array length"
});
assert(a.length === 1);
});
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}