mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17:42 +00:00
LibJS: Implement Array length setter
This commit is contained in:
parent
d5d3e0b4ed
commit
418092a71a
4 changed files with 74 additions and 19 deletions
|
@ -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());
|
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
if (!this_object->is_array())
|
if (!this_object->is_array()) {
|
||||||
return interpreter.throw_exception<TypeError>("Not an array");
|
interpreter.throw_exception<TypeError>("Not an Array");
|
||||||
return Value(static_cast<const Array*>(this_object)->length());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
|
Array* array_from(Interpreter&);
|
||||||
|
|
||||||
class Array final : public Object {
|
class Array final : public Object {
|
||||||
public:
|
public:
|
||||||
static Array* create(GlobalObject&);
|
static Array* create(GlobalObject&);
|
||||||
|
@ -47,5 +49,4 @@ private:
|
||||||
static void length_setter(Interpreter&, Value);
|
static void length_setter(Interpreter&, Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
static Function* callback_from_args(Interpreter& interpreter, const String& name)
|
||||||
{
|
{
|
||||||
if (interpreter.argument_count() < 1) {
|
if (interpreter.argument_count() < 1) {
|
||||||
|
|
48
Libraries/LibJS/Tests/array-length-setter.js
Normal file
48
Libraries/LibJS/Tests/array-length-setter.js
Normal 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);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue