LibJS: Add Array.prototype.slice

This commit is contained in:
Kesse Jones 2020-04-18 17:50:19 -03:00 committed by Andreas Kling
parent 3474d7c88e
commit 856ab9c600
Notes: sideshowbarker 2024-07-19 07:29:23 +09:00
3 changed files with 95 additions and 0 deletions

View file

@ -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<ssize_t>(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;
}
}

View file

@ -49,6 +49,7 @@ private:
static Value unshift(Interpreter&);
static Value join(Interpreter&);
static Value concat(Interpreter&);
static Value slice(Interpreter&);
};
}

View file

@ -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);
}