summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2020-05-08 16:23:56 +0100
committerAndreas Kling <kling@serenityos.org>2020-05-08 20:06:49 +0200
commit01fd6ce04582e9714d592a3bcb9825792cca81dc (patch)
tree303f96743cfd6914548054334106ee89b2d54e13
parent8137f40b734920c9ffaf96d9747cdbb1c388545c (diff)
downloadserenity-01fd6ce04582e9714d592a3bcb9825792cca81dc.zip
LibJS: Support multiple arguments in Array constructor
-rw-r--r--Libraries/LibJS/Runtime/ArrayConstructor.cpp17
-rw-r--r--Libraries/LibJS/Tests/Array.js29
2 files changed, 41 insertions, 5 deletions
diff --git a/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Libraries/LibJS/Runtime/ArrayConstructor.cpp
index 65da8387c6..cab2a3f755 100644
--- a/Libraries/LibJS/Runtime/ArrayConstructor.cpp
+++ b/Libraries/LibJS/Runtime/ArrayConstructor.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,7 @@
#include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/ArrayConstructor.h>
+#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Shape.h>
@@ -50,14 +52,21 @@ Value ArrayConstructor::call(Interpreter& interpreter)
if (interpreter.argument_count() <= 0)
return Array::create(interpreter.global_object());
- if (interpreter.argument_count() == 1) {
+ if (interpreter.argument_count() == 1 && interpreter.argument(0).is_number()) {
+ auto array_length_value = interpreter.argument(0);
+ if (!array_length_value.is_integer() || array_length_value.to_i32() < 0) {
+ interpreter.throw_exception<TypeError>("Invalid array length");
+ return {};
+ }
auto* array = Array::create(interpreter.global_object());
- array->elements().resize(interpreter.argument(0).to_i32());
+ array->elements().resize(array_length_value.to_i32());
return array;
}
- // FIXME: Handle "new Array(element0, element1, ...)"
- ASSERT_NOT_REACHED();
+ auto* array = Array::create(interpreter.global_object());
+ for (size_t i = 0; i < interpreter.argument_count(); ++i)
+ array->elements().append(interpreter.argument(i));
+ return array;
}
Value ArrayConstructor::construct(Interpreter& interpreter)
diff --git a/Libraries/LibJS/Tests/Array.js b/Libraries/LibJS/Tests/Array.js
index a6ecb398c8..c103025bb0 100644
--- a/Libraries/LibJS/Tests/Array.js
+++ b/Libraries/LibJS/Tests/Array.js
@@ -8,9 +8,36 @@ try {
assert(typeof Array() === "object");
assert(typeof new Array() === "object");
- var a = new Array(5);
+ var a;
+
+ a = new Array(5);
assert(a.length === 5);
+ a = new Array("5");
+ assert(a.length === 1);
+ assert(a[0] === "5");
+
+ a = new Array(1, 2, 3);
+ assert(a.length === 3);
+ assert(a[0] === 1);
+ assert(a[1] === 2);
+ assert(a[2] === 3);
+
+ a = new Array([1, 2, 3]);
+ assert(a.length === 1);
+ assert(a[0][0] === 1);
+ assert(a[0][1] === 2);
+ assert(a[0][2] === 3);
+
+ [-1, -100, -0.1, 0.1, 1.23, Infinity, -Infinity, NaN].forEach(value => {
+ assertThrowsError(() => {
+ new Array(value);
+ }, {
+ error: TypeError,
+ message: "Invalid array length"
+ });
+ });
+
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);