1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 07:48:12 +00:00

Revert "LibJS: Align array splice with spec"

This reverts commit b6cb8d8dea as it broke
11 test262 tests.
This commit is contained in:
Linus Groh 2023-07-16 15:21:29 +01:00
parent b6cb8d8dea
commit a83ae9f8a7

View file

@ -1445,158 +1445,87 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
// 23.1.3.31 Array.prototype.splice ( start, deleteCount, ...items ), https://tc39.es/ecma262/#sec-array.prototype.splice
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
{
// 1. Let O be ? ToObject(this value).
auto this_object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto initial_length = TRY(length_of_array_like(vm, this_object));
// 3. Let relativeStart be ? ToIntegerOrInfinity(start).
auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm));
if (Value(relative_start).is_negative_infinity())
relative_start = 0;
u64 actual_start;
// 4. If relativeStart = -∞, let actualStart be 0.
if (Value(relative_start).is_negative_infinity())
actual_start = 0;
// 5. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
else if (relative_start < 0)
if (relative_start < 0)
actual_start = max((ssize_t)initial_length + relative_start, (ssize_t)0);
// 6. Else, let actualStart be min(relativeStart, len).
else
actual_start = min(relative_start, initial_length);
// 7. Let itemCount be the number of elements in items.
u64 item_count = vm.argument_count() >= 2 ? vm.argument_count() - 2 : 0;
u64 insert_count = 0;
double actual_delete_count = 0;
u64 actual_delete_count;
// 8. If start is not present, then
if (vm.argument_count() == 0) {
// a. Let actualDeleteCount be 0.
actual_delete_count = 0;
}
// 9. Else if deleteCount is not present, then
else if (vm.argument_count() == 1) {
// a. Let actualDeleteCount be len - actualStart.
if (vm.argument_count() == 1) {
actual_delete_count = initial_length - actual_start;
}
// 10. Else,
else {
// a. Let dc be ? ToIntegerOrInfinity(deleteCount).
} else if (vm.argument_count() >= 2) {
insert_count = vm.argument_count() - 2;
auto delete_count = TRY(vm.argument(1).to_integer_or_infinity(vm));
// b. Let actualDeleteCount be the result of clamping dc between 0 and len - actualStart.
actual_delete_count = clamp(delete_count, 0, initial_length - actual_start);
auto temp = max(delete_count, 0);
actual_delete_count = min(temp, initial_length - actual_start);
}
// 11. If len + itemCount - actualDeleteCount > 2^53 - 1, throw a TypeError exception.
if (initial_length + item_count - actual_delete_count > MAX_ARRAY_LIKE_INDEX)
double new_length = initial_length + insert_count - actual_delete_count;
if (new_length > MAX_ARRAY_LIKE_INDEX)
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
// 12. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
auto* removed_elements = TRY(array_species_create(vm, this_object, actual_delete_count));
// 13. Let k be 0.
// 14. Repeat, while k < actualDeleteCount,
for (u64 k = 0; k < actual_delete_count; ++k) {
// a. Let from be ! ToString(𝔽(actualStart + k)).
auto from = PropertyKey { actual_start + k };
for (u64 i = 0; i < actual_delete_count; ++i) {
auto from = actual_start + i;
// b. If ? HasProperty(O, from) is true, then
if (TRY(this_object->has_property(from))) {
// i. Let fromValue be ? Get(O, from).
auto from_value = TRY(this_object->get(from));
// ii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(k)), fromValue).
TRY(removed_elements->create_data_property_or_throw(k, from_value));
TRY(removed_elements->create_data_property_or_throw(i, from_value));
}
// c. Set k to k + 1.
}
// 15. Perform ? Set(A, "length", 𝔽(actualDeleteCount), true).
TRY(removed_elements->set(vm.names.length, Value(actual_delete_count), Object::ShouldThrowExceptions::Yes));
// 16. If itemCount < actualDeleteCount, then
if (item_count < actual_delete_count) {
// a. Set k to actualStart.
// b. Repeat, while k < (len - actualDeleteCount),
for (u64 k = actual_start; k < initial_length - actual_delete_count; ++k) {
// i. Let from be ! ToString(𝔽(k + actualDeleteCount)).
auto from = PropertyKey { k + actual_delete_count };
if (insert_count < actual_delete_count) {
for (u64 i = actual_start; i < initial_length - actual_delete_count; ++i) {
auto to = i + insert_count;
u64 from = i + actual_delete_count;
// ii. Let to be ! ToString(𝔽(k + itemCount)).
auto to = PropertyKey { k + item_count };
// iii. If ? HasProperty(O, from) is true, then
if (TRY(this_object->has_property(from))) {
// 1. Let fromValue be ? Get(O, from).
auto from_value = TRY(this_object->get(from));
// 2. Perform ? Set(O, to, fromValue, true).
TRY(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
}
// iv. Else,
else {
// 1. Perform ? DeletePropertyOrThrow(O, to).
} else {
TRY(this_object->delete_property_or_throw(to));
}
// v. Set k to k + 1.
}
// c. Set k to len.
// d. Repeat, while k > (len - actualDeleteCount + itemCount),
for (u64 k = initial_length; k > initial_length - actual_delete_count + item_count; --k) {
// i. Perform ? DeletePropertyOrThrow(O, ! ToString(𝔽(k - 1))).
TRY(this_object->delete_property_or_throw(k - 1));
for (u64 i = initial_length; i > new_length; --i)
TRY(this_object->delete_property_or_throw(i - 1));
} else if (insert_count > actual_delete_count) {
for (u64 i = initial_length - actual_delete_count; i > actual_start; --i) {
u64 from_index = i + actual_delete_count - 1;
auto to = i + insert_count - 1;
// ii. Set k to k - 1.
}
}
// 17. Else if itemCount > actualDeleteCount, then
else if (item_count > actual_delete_count) {
// a. Set k to (len - actualDeleteCount).
// b. Repeat, while k > actualStart,
for (u64 k = initial_length - actual_delete_count; k > actual_start; --k) {
// i. Let from be ! ToString(𝔽(k + actualDeleteCount - 1)).
auto from = PropertyKey { k + actual_delete_count - 1 };
// ii. Let to be ! ToString(𝔽(k + itemCount - 1)).
auto to = PropertyKey { k + item_count - 1 };
// iii. If ? HasProperty(O, from) is true, then
if (TRY(this_object->has_property(from))) {
// 1. Let fromValue be ? Get(O, from).
auto from_value = TRY(this_object->get(from));
// 2. Perform ? Set(O, to, fromValue, true).
if (TRY(this_object->has_property(from_index))) {
auto from_value = TRY(this_object->get(from_index));
TRY(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
}
// iv. Else,
else {
// 1. Perform ? DeletePropertyOrThrow(O, to).
} else {
TRY(this_object->delete_property_or_throw(to));
}
// v. Set k to k - 1.
}
}
// 18. Set k to actualStart.
// 19. For each element E of items, do
for (u64 k = actual_start; k < actual_start + item_count; ++k) {
// a. Perform ? Set(O, ! ToString(𝔽(k)), E, true).
TRY(this_object->set(k, vm.argument(k + 2), Object::ShouldThrowExceptions::Yes));
for (u64 i = 0; i < insert_count; ++i)
TRY(this_object->set(actual_start + i, vm.argument(i + 2), Object::ShouldThrowExceptions::Yes));
// b. Set k to k + 1.
}
TRY(this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes));
// 20. Perform ? Set(O, "length", 𝔽(len - actualDeleteCount + itemCount), true).
TRY(this_object->set(vm.names.length, Value(initial_length - actual_delete_count + item_count), Object::ShouldThrowExceptions::Yes));
// 21. Return A.
return removed_elements;
}