diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 569463d537..83be93ba4c 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -205,12 +205,29 @@ Value ArrayPrototype::unshift(Interpreter& interpreter) Value ArrayPrototype::pop(Interpreter& interpreter) { - auto* array = array_from(interpreter); - if (!array) + auto* this_object = interpreter.this_value().to_object(interpreter); + if (!this_object) return {}; - if (array->elements().is_empty()) + if (this_object->is_array()) { + auto* array = static_cast(this_object); + if (array->elements().is_empty()) + return js_undefined(); + return array->elements().take_last().value_or(js_undefined()); + } + auto length = get_length(interpreter, *this_object); + if (length == 0) { + this_object->put("length", Value(0)); return js_undefined(); - return array->elements().take_last().value_or(js_undefined()); + } + auto index = length - 1; + auto element = this_object->get_by_index(index).value_or(js_undefined()); + if (interpreter.exception()) + return {}; + this_object->delete_property(PropertyName(index)); + this_object->put("length", Value((i32)index)); + if (interpreter.exception()) + return {}; + return element; } Value ArrayPrototype::shift(Interpreter& interpreter) diff --git a/Libraries/LibJS/Tests/Array.prototype-generic-functions.js b/Libraries/LibJS/Tests/Array.prototype-generic-functions.js index d906d2be3b..aed23c4ad3 100644 --- a/Libraries/LibJS/Tests/Array.prototype-generic-functions.js +++ b/Libraries/LibJS/Tests/Array.prototype-generic-functions.js @@ -12,6 +12,19 @@ try { assert(o[0] === "foo"); assert(o[1] === "bar"); assert(o[2] === "baz"); + + assert(Array.prototype.pop.call(o) === "baz"); + assert(o.length === 2); + assert(Array.prototype.pop.call(o) === "bar"); + assert(o.length === 1); + assert(Array.prototype.pop.call(o) === "foo"); + assert(o.length === 0); + assert(Array.prototype.pop.call(o) === undefined); + assert(o.length === 0); + + o.length = length; + assert(Array.prototype.pop.call(o) === undefined); + assert(o.length === 0); }); const o = { length: 5, 0: "foo", 1: "bar", 3: "baz" };