From 856ab9c600d1aa2a8aae327e2b4172a6c6c77217 Mon Sep 17 00:00:00 2001 From: Kesse Jones Date: Sat, 18 Apr 2020 17:50:19 -0300 Subject: LibJS: Add Array.prototype.slice --- Libraries/LibJS/Runtime/ArrayPrototype.cpp | 41 ++++++++++++++++++++ Libraries/LibJS/Runtime/ArrayPrototype.h | 1 + Libraries/LibJS/Tests/Array.prototype.slice.js | 53 ++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 Libraries/LibJS/Tests/Array.prototype.slice.js (limited to 'Libraries') diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 8ec1765fcd..d59c939128 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -51,6 +51,7 @@ ArrayPrototype::ArrayPrototype() put_native_function("unshift", unshift, 1); put_native_function("join", join, 1); put_native_function("concat", concat, 1); + put_native_function("slice", slice, 2); put("length", Value(0)); } @@ -254,4 +255,44 @@ Value ArrayPrototype::concat(Interpreter& interpreter) return Value(new_array); } +Value ArrayPrototype::slice(Interpreter& interpreter) +{ + auto* array = array_from(interpreter); + if (!array) + return {}; + + auto* new_array = Array::create(interpreter.global_object()); + if (interpreter.argument_count() == 0) { + new_array->elements().append(array->elements()); + return new_array; + } + + ssize_t array_size = static_cast(array->elements().size()); + auto start_slice = interpreter.argument(0).to_i32(); + auto end_slice = array_size; + + if (start_slice > array_size) + return new_array; + + if (start_slice < 0) + start_slice = end_slice + start_slice; + + if (interpreter.argument_count() >= 2) { + end_slice = interpreter.argument(1).to_i32(); + + if (end_slice < 0) + end_slice = array_size + end_slice; + else if (end_slice > array_size) + end_slice = array_size; + } + + size_t array_capacity = start_slice + array_size - end_slice; + new_array->elements().ensure_capacity(array_capacity); + for (ssize_t i = start_slice; i < end_slice; ++i) { + new_array->elements().append(array->elements().at(i)); + } + + return new_array; +} + } diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.h b/Libraries/LibJS/Runtime/ArrayPrototype.h index 2b9cfb89d1..5c27d3c9c7 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -49,6 +49,7 @@ private: static Value unshift(Interpreter&); static Value join(Interpreter&); static Value concat(Interpreter&); + static Value slice(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Array.prototype.slice.js b/Libraries/LibJS/Tests/Array.prototype.slice.js new file mode 100644 index 0000000000..e34f2c1a1b --- /dev/null +++ b/Libraries/LibJS/Tests/Array.prototype.slice.js @@ -0,0 +1,53 @@ +load("test-common.js"); + +try { + assert(Array.prototype.slice.length === 2); + + var array = ["hello", "friends", "serenity", 1]; + + var array_slice = array.slice(); + assert(array_slice.length === array.length); + assert(array_slice.length === 4); + assert(array_slice[0] === "hello"); + assert(array_slice[1] === "friends"); + assert(array_slice[2] === "serenity"); + assert(array_slice[3] === 1); + + array_slice = array.slice(1) + assert(array_slice.length === 3); + assert(array_slice[0] === "friends"); + assert(array_slice[1] === "serenity"); + assert(array_slice[2] === 1); + + array_slice = array.slice(0, 2); + assert(array_slice.length === 2); + assert(array_slice[0] === "hello"); + assert(array_slice[1] === "friends"); + + array_slice = array.slice(-1); + assert(array_slice.length === 1); + assert(array_slice[0] === 1); + + array_slice = array.slice(1, 1); + assert(array_slice.length === 0); + + array_slice = array.slice(1, -1); + assert(array_slice.length === 2); + assert(array_slice[0] === "friends"); + assert(array_slice[1] === "serenity"); + + array_slice = array.slice(2, -1); + assert(array_slice.length === 1); + assert(array_slice[0] === "serenity"); + + array_slice = array.slice(0, 100); + assert(array_slice.length === 4); + assert(array_slice[0] === "hello"); + assert(array_slice[1] === "friends"); + assert(array_slice[2] === "serenity"); + assert(array_slice[3] === 1); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} -- cgit v1.2.3