summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAngel <angel@ttm.sh>2020-05-26 20:31:22 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-26 20:34:44 +0200
commit199a6b40b3e7ae997d6ecfde6276c86cc2a1dd30 (patch)
tree036ceeb78c37490f1aa6c269393019e60f3a2bdc /Libraries
parentd1bc1f5783f31a9339c192e889a24ccd82813b4f (diff)
downloadserenity-199a6b40b3e7ae997d6ecfde6276c86cc2a1dd30.zip
LibJS: Add Array.prototype.fill
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibJS/Runtime/ArrayPrototype.cpp48
-rw-r--r--Libraries/LibJS/Runtime/ArrayPrototype.h1
-rw-r--r--Libraries/LibJS/Tests/Array.prototype.fill.js24
-rw-r--r--Libraries/LibJS/Tests/test-common.js15
4 files changed, 88 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp
index 297f791afc..b6c372ccab 100644
--- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp
+++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp
@@ -68,6 +68,7 @@ ArrayPrototype::ArrayPrototype()
put_native_function("some", some, 1, attr);
put_native_function("every", every, 1, attr);
put_native_function("splice", splice, 2, attr);
+ put_native_function("fill", fill, 1, attr);
put("length", Value(0), Attribute::Configurable);
}
@@ -743,4 +744,51 @@ Value ArrayPrototype::splice(Interpreter& interpreter)
return removed_elements;
}
+Value ArrayPrototype::fill(Interpreter& interpreter)
+{
+ auto *this_object = interpreter.this_value().to_object(interpreter);
+ if (!this_object)
+ return {};
+
+ ssize_t length = get_length(interpreter, *this_object);
+ if (interpreter.exception())
+ return {};
+
+ ssize_t relative_start = 0;
+ ssize_t relative_end = length;
+
+ if (interpreter.argument_count() >= 2) {
+ relative_start = interpreter.argument(1).to_i32(interpreter);
+ if (interpreter.exception())
+ return {};
+ }
+
+ if (interpreter.argument_count() >= 3) {
+ relative_end = interpreter.argument(2).to_i32(interpreter);
+ if (interpreter.exception())
+ return {};
+ }
+
+ size_t from, to;
+
+ if (relative_start < 0)
+ from = max(length + relative_start, 0L);
+ else
+ from = min(relative_start, length);
+
+ if (relative_end < 0)
+ to = max(length + relative_end, 0L);
+ else
+ to = min(relative_end, length);
+
+ for (size_t i = from; i < to; i++) {
+ this_object->put_by_index(i, interpreter.argument(0));
+ if (interpreter.exception())
+ return {};
+ }
+
+ return this_object;
}
+
+}
+
diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.h b/Libraries/LibJS/Runtime/ArrayPrototype.h
index 854788ed54..81750751da 100644
--- a/Libraries/LibJS/Runtime/ArrayPrototype.h
+++ b/Libraries/LibJS/Runtime/ArrayPrototype.h
@@ -61,6 +61,7 @@ private:
static Value some(Interpreter&);
static Value every(Interpreter&);
static Value splice(Interpreter&);
+ static Value fill(Interpreter&);
};
}
diff --git a/Libraries/LibJS/Tests/Array.prototype.fill.js b/Libraries/LibJS/Tests/Array.prototype.fill.js
new file mode 100644
index 0000000000..c70960b802
--- /dev/null
+++ b/Libraries/LibJS/Tests/Array.prototype.fill.js
@@ -0,0 +1,24 @@
+load("test-common.js");
+
+try {
+ assert(Array.prototype.fill.length === 1);
+
+ var array = [1, 2, 3, 4];
+ assertArrayEquals(array.fill(0, 2, 4), [1, 2, 0, 0]);
+ assertArrayEquals(array.fill(5, 1), [1, 5, 5, 5]);
+ assertArrayEquals(array.fill(6), [6, 6, 6, 6]);
+
+ assertArrayEquals([1, 2, 3].fill(4), [4, 4, 4]);
+ assertArrayEquals([1, 2, 3].fill(4, 1), [1, 4, 4]);
+ assertArrayEquals([1, 2, 3].fill(4, 1, 2), [1, 4, 3]);
+ assertArrayEquals([1, 2, 3].fill(4, 3, 3), [1, 2, 3]);
+ assertArrayEquals([1, 2, 3].fill(4, -3, -2), [4, 2, 3]);
+ assertArrayEquals([1, 2, 3].fill(4, NaN, NaN), [1, 2, 3]);
+ assertArrayEquals([1, 2, 3].fill(4, 3, 5), [1, 2, 3]);
+ assertArrayEquals(Array(3).fill(4), [4, 4, 4]);
+
+ console.log("PASS");
+} catch (e) {
+ console.log("FAIL: " + e);
+}
+
diff --git a/Libraries/LibJS/Tests/test-common.js b/Libraries/LibJS/Tests/test-common.js
index 7be49e77bb..0a14352b97 100644
--- a/Libraries/LibJS/Tests/test-common.js
+++ b/Libraries/LibJS/Tests/test-common.js
@@ -50,6 +50,21 @@ function assertThrowsError(testFunction, options) {
}
}
+/**
+ * Ensures the provided arrays contain exactly the same items.
+ * @param {Array} a First array
+ * @param {Array} b Second array
+ */
+function assertArrayEquals(a, b) {
+ if (a.length != b.length)
+ throw new AssertionError("Array lengths do not match");
+
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] !== b[i])
+ throw new AssertionError("Elements do not match");
+ }
+}
+
const assertVisitsAll = (testFunction, expectedOutput) => {
const visited = [];
testFunction(value => visited.push(value));