diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 7eafef6173..ffa30ac1e9 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -48,6 +48,7 @@ ArrayPrototype::ArrayPrototype() put_native_function("toString", to_string, 0); put_native_function("unshift", unshift, 1); put_native_function("join", join, 1); + put_native_function("concat", concat, 1); put("length", Value(0)); } @@ -229,4 +230,26 @@ Value ArrayPrototype::join(Interpreter& interpreter) return join_array_with_separator(interpreter, *array, separator); } +Value ArrayPrototype::concat(Interpreter& interpreter) +{ + auto* array = array_from(interpreter); + if (!array) + return {}; + + auto* new_array = interpreter.heap().allocate(); + new_array->elements().append(array->elements()); + + for (size_t i = 0; i < interpreter.argument_count(); ++i) { + auto argument = interpreter.argument(i); + if (argument.is_array()) { + auto& argument_object = argument.as_object(); + new_array->elements().append(argument_object.elements()); + } else { + new_array->elements().append(argument); + } + } + + return Value(new_array); +} + } diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.h b/Libraries/LibJS/Runtime/ArrayPrototype.h index e7d120428d..2b9cfb89d1 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -48,6 +48,7 @@ private: static Value to_string(Interpreter&); static Value unshift(Interpreter&); static Value join(Interpreter&); + static Value concat(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Array.prototype.concat.js b/Libraries/LibJS/Tests/Array.prototype.concat.js new file mode 100644 index 0000000000..da311b5bc8 --- /dev/null +++ b/Libraries/LibJS/Tests/Array.prototype.concat.js @@ -0,0 +1,37 @@ +load("test-common.js"); + +try { + assert(Array.prototype.concat.length === 1); + + var array = ["hello", "friends"]; + + var array_concat = array.concat(); + assert(array_concat.length === array.length); + + array_concat = array.concat(1) + assert(array_concat.length === 3); + assert(array_concat[2] === 1); + + array_concat = array.concat([1, 2, 3]) + assert(array_concat.length === 5); + assert(array_concat[2] === 1); + assert(array_concat[3] === 2); + assert(array_concat[4] === 3); + + array_concat = array.concat(false, "serenity"); + assert(array_concat.length === 4); + assert(array_concat[2] === false); + assert(array_concat[3] === "serenity"); + + array_concat = array.concat({ name: "libjs" }, [1, [2, 3]]); + assert(array_concat.length === 5); + assert(array_concat[2].name === "libjs"); + assert(array_concat[3] === 1); + assert(array_concat[4][0] === 2); + assert(array_concat[4][1] === 3); + + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}