mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 11:07:45 +00:00
LibJS: Remove %TypedArray%.prototype.toSpliced
This was removed from the change-array-by-copy proposal. See:
4c194d9
This commit is contained in:
parent
a8d532c4fe
commit
60f3880650
3 changed files with 1 additions and 297 deletions
|
@ -59,7 +59,6 @@ void TypedArrayPrototype::initialize(GlobalObject& object)
|
||||||
define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
|
define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr);
|
||||||
define_native_function(vm.names.toReversed, to_reversed, 0, attr);
|
define_native_function(vm.names.toReversed, to_reversed, 0, attr);
|
||||||
define_native_function(vm.names.toSorted, to_sorted, 1, attr);
|
define_native_function(vm.names.toSorted, to_sorted, 1, attr);
|
||||||
define_native_function(vm.names.toSpliced, to_spliced, 2, attr);
|
|
||||||
define_native_function(vm.names.with, with, 2, attr);
|
define_native_function(vm.names.with, with, 2, attr);
|
||||||
define_native_function(vm.names.values, values, 0, attr);
|
define_native_function(vm.names.values, values, 0, attr);
|
||||||
|
|
||||||
|
@ -1557,142 +1556,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted)
|
||||||
return return_array;
|
return return_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.2.2.1.5 %TypedArray%.prototype.toSpliced ( start, deleteCount, ...items ), https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSpliced
|
// 1.2.2.1.5 %TypedArray%.prototype.with ( index, value ), https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with
|
||||||
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_spliced)
|
|
||||||
{
|
|
||||||
auto start = vm.argument(0);
|
|
||||||
auto delete_count = vm.argument(1);
|
|
||||||
|
|
||||||
// 1. Let O be the this value.
|
|
||||||
// 2. Perform ? ValidateTypedArray(O).
|
|
||||||
auto* typed_array = TRY(validate_typed_array_from_this(global_object));
|
|
||||||
|
|
||||||
// 3. Let len be O.[[ArrayLength]].
|
|
||||||
auto length = typed_array->array_length();
|
|
||||||
|
|
||||||
// 4. Let relativeStart be ? ToIntegerOrInfinity(start).
|
|
||||||
auto relative_start = TRY(start.to_integer_or_infinity(global_object));
|
|
||||||
|
|
||||||
size_t actual_start;
|
|
||||||
|
|
||||||
// 5. If relativeStart is -∞, let actualStart be 0.
|
|
||||||
if (Value(relative_start).is_negative_infinity())
|
|
||||||
actual_start = 0;
|
|
||||||
// 6. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
|
|
||||||
else if (relative_start < 0)
|
|
||||||
actual_start = static_cast<size_t>(max(static_cast<double>(length) + relative_start, 0));
|
|
||||||
// 7. Else, let actualStart be min(relativeStart, len).
|
|
||||||
else
|
|
||||||
actual_start = static_cast<size_t>(min(relative_start, static_cast<double>(length)));
|
|
||||||
|
|
||||||
size_t 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.
|
|
||||||
actual_delete_count = length - actual_start;
|
|
||||||
}
|
|
||||||
// 10. Else,
|
|
||||||
else {
|
|
||||||
// a. Let dc be ? ToIntegerOrInfinity(deleteCount).
|
|
||||||
auto dc = TRY(delete_count.to_integer_or_infinity(global_object));
|
|
||||||
|
|
||||||
// b. Let actualDeleteCount be the result of clamping dc between 0 and len - actualStart.
|
|
||||||
actual_delete_count = static_cast<size_t>(clamp(dc, 0, static_cast<double>(length - actual_start)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 11. Let insertCount be the number of elements in items.
|
|
||||||
auto insert_count = vm.argument_count() >= 2 ? vm.argument_count() - 2 : 0;
|
|
||||||
|
|
||||||
// 12. Let convertedItems be a new empty List.
|
|
||||||
MarkedVector<Value> converted_items(vm.heap());
|
|
||||||
|
|
||||||
// 13. For each element E of items, do
|
|
||||||
for (size_t element_index = 2; element_index < vm.argument_count(); element_index++) {
|
|
||||||
auto element = vm.argument(element_index);
|
|
||||||
Value converted_value;
|
|
||||||
// a. If O.[[ContentType]] is BigInt, let convertedValue be ? ToBigInt(E).
|
|
||||||
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt)
|
|
||||||
converted_value = TRY(element.to_bigint(global_object));
|
|
||||||
// Else, let convertedValue be ? ToNumber(E).
|
|
||||||
else
|
|
||||||
converted_value = TRY(element.to_number(global_object));
|
|
||||||
|
|
||||||
// c. Append convertedValue as the last element of convertedItems.
|
|
||||||
converted_items.append(converted_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let newLen be len + insertCount - actualDeleteCount.
|
|
||||||
auto new_length = length + insert_count - actual_delete_count;
|
|
||||||
|
|
||||||
// 15. Let A be ? TypedArrayCreateSameType(O, « 𝔽(newLen) »).
|
|
||||||
MarkedVector<Value> arguments(vm.heap());
|
|
||||||
arguments.empend(length);
|
|
||||||
auto* return_array = TRY(typed_array_create_same_type(global_object, *typed_array, move(arguments)));
|
|
||||||
|
|
||||||
// 16. Let i be 0.
|
|
||||||
// 17. Let r be actualStart + actualDeleteCount.
|
|
||||||
size_t i = 0;
|
|
||||||
auto r = actual_start + actual_delete_count;
|
|
||||||
|
|
||||||
// 18. Repeat, while i < actualStart,
|
|
||||||
while (i < actual_start) {
|
|
||||||
// a. Let Pi be ! ToString(𝔽(i)).
|
|
||||||
auto property_key = PropertyKey { i };
|
|
||||||
|
|
||||||
// b. Let iValue be ! Get(O, Pi).
|
|
||||||
auto index_value = MUST(typed_array->get(property_key));
|
|
||||||
|
|
||||||
// c. Perform ! Set(target, Pi, iValue, true).
|
|
||||||
MUST(return_array->set(property_key, index_value, Object::ShouldThrowExceptions::Yes));
|
|
||||||
|
|
||||||
// d. Set i to i + 1.
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 19. For each element E of convertedItems, do
|
|
||||||
for (auto const& element : converted_items) {
|
|
||||||
// a. Let Pi be ! ToString(𝔽(i)).
|
|
||||||
auto property_key = PropertyKey { i };
|
|
||||||
|
|
||||||
// b. Perform ! Set(A, Pi, E, true).
|
|
||||||
MUST(return_array->set(property_key, element, Object::ShouldThrowExceptions::Yes));
|
|
||||||
|
|
||||||
// c. Set i to i + 1.
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 20. Repeat, while i < newLen,
|
|
||||||
while (i < new_length) {
|
|
||||||
// a. Let Pi be ! ToString(𝔽(i)).
|
|
||||||
auto property_key = PropertyKey { i };
|
|
||||||
|
|
||||||
// b. Let from be ! ToString(𝔽(r)).
|
|
||||||
auto from = PropertyKey { r };
|
|
||||||
|
|
||||||
// c. Let fromValue be ! Get(O, from).
|
|
||||||
auto from_value = TRY(typed_array->get(from));
|
|
||||||
|
|
||||||
// d. Perform ! Set(A, Pi, fromValue, true).
|
|
||||||
MUST(return_array->set(property_key, from_value, Object::ShouldThrowExceptions::Yes));
|
|
||||||
|
|
||||||
// e. Set i to i + 1.
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// f. Set r to r + 1.
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 21. Return A.
|
|
||||||
return return_array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.2.2.1.6 %TypedArray%.prototype.with ( index, value ), https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::with)
|
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::with)
|
||||||
{
|
{
|
||||||
auto index = vm.argument(0);
|
auto index = vm.argument(0);
|
||||||
|
|
|
@ -53,7 +53,6 @@ private:
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
|
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_reversed);
|
JS_DECLARE_NATIVE_FUNCTION(to_reversed);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_sorted);
|
JS_DECLARE_NATIVE_FUNCTION(to_sorted);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_spliced);
|
|
||||||
JS_DECLARE_NATIVE_FUNCTION(with);
|
JS_DECLARE_NATIVE_FUNCTION(with);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(values);
|
JS_DECLARE_NATIVE_FUNCTION(values);
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_string_tag_getter);
|
JS_DECLARE_NATIVE_FUNCTION(to_string_tag_getter);
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
const TYPED_ARRAYS = [
|
|
||||||
Uint8Array,
|
|
||||||
Uint8ClampedArray,
|
|
||||||
Uint16Array,
|
|
||||||
Uint32Array,
|
|
||||||
Int8Array,
|
|
||||||
Int16Array,
|
|
||||||
Int32Array,
|
|
||||||
Float32Array,
|
|
||||||
Float64Array,
|
|
||||||
];
|
|
||||||
|
|
||||||
const BIGINT_TYPED_ARRAYS = [BigUint64Array, BigInt64Array];
|
|
||||||
|
|
||||||
describe("normal behavior", () => {
|
|
||||||
test("length is 2", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(T.prototype.toSpliced).toHaveLength(2);
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(T.prototype.toSpliced).toHaveLength(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("no start or delete count argument", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1, 2, 3, 4, 5]);
|
|
||||||
const b = a.toSpliced();
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1, 2, 3, 4, 5]);
|
|
||||||
expect(b).toEqual([1, 2, 3, 4, 5]);
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
const b = a.toSpliced();
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
expect(b).toEqual([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("only start argument", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1, 2, 3, 4, 5]);
|
|
||||||
const values = [
|
|
||||||
[0, [0, 0, 0, 0, 0]],
|
|
||||||
[1, [1, 0, 0, 0, 0]],
|
|
||||||
[4, [1, 2, 3, 4, 0]],
|
|
||||||
[-1, [1, 2, 3, 4, 0]],
|
|
||||||
[999, [1, 2, 3, 4, 5]],
|
|
||||||
[Infinity, [1, 2, 3, 4, 5]],
|
|
||||||
];
|
|
||||||
for (const [start, expected] of values) {
|
|
||||||
const b = a.toSpliced(start);
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1, 2, 3, 4, 5]);
|
|
||||||
expect(b).toEqual(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
const values = [
|
|
||||||
[0, [0n, 0n, 0n, 0n, 0n]],
|
|
||||||
[1, [1n, 0n, 0n, 0n, 0n]],
|
|
||||||
[4, [1n, 2n, 3n, 4n, 0n]],
|
|
||||||
[-1, [1n, 2n, 3n, 4n, 0n]],
|
|
||||||
[999, [1n, 2n, 3n, 4n, 5n]],
|
|
||||||
[Infinity, [1n, 2n, 3n, 4n, 5n]],
|
|
||||||
];
|
|
||||||
for (const [start, expected] of values) {
|
|
||||||
const b = a.toSpliced(start);
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
expect(b).toEqual(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("start and delete count argument", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1, 2, 3, 4, 5]);
|
|
||||||
const values = [
|
|
||||||
[0, 5, [0, 0, 0, 0, 0]],
|
|
||||||
[1, 3, [1, 5, 0, 0, 0]],
|
|
||||||
[4, 1, [1, 2, 3, 4, 0]],
|
|
||||||
[-1, 1, [1, 2, 3, 4, 0]],
|
|
||||||
[999, 10, [1, 2, 3, 4, 5]],
|
|
||||||
[Infinity, Infinity, [1, 2, 3, 4, 5]],
|
|
||||||
];
|
|
||||||
for (const [start, deleteCount, expected] of values) {
|
|
||||||
const b = a.toSpliced(start, deleteCount);
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1, 2, 3, 4, 5]);
|
|
||||||
expect(b).toEqual(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
const a = new T([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
const values = [
|
|
||||||
[0, 5, [0n, 0n, 0n, 0n, 0n]],
|
|
||||||
[1, 3, [1n, 5n, 0n, 0n, 0n]],
|
|
||||||
[4, 1, [1n, 2n, 3n, 4n, 0n]],
|
|
||||||
[-1, 1, [1n, 2n, 3n, 4n, 0n]],
|
|
||||||
[999, 10, [1n, 2n, 3n, 4n, 5n]],
|
|
||||||
[Infinity, Infinity, [1n, 2n, 3n, 4n, 5n]],
|
|
||||||
];
|
|
||||||
for (const [start, deleteCount, expected] of values) {
|
|
||||||
const b = a.toSpliced(start, deleteCount);
|
|
||||||
expect(a).not.toBe(b);
|
|
||||||
expect(a).toEqual([1n, 2n, 3n, 4n, 5n]);
|
|
||||||
expect(b).toEqual(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("errors", () => {
|
|
||||||
test("null or undefined this value", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call();
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call(undefined);
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call(null);
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call();
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call(undefined);
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
T.prototype.toSpliced.call(null);
|
|
||||||
}).toThrowWithMessage(TypeError, "ToObject on null or undefined");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("invalid typed array length", () => {
|
|
||||||
TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(() => {
|
|
||||||
new T({ length: 2 ** 32 - 1 });
|
|
||||||
}).toThrowWithMessage(RangeError, "Invalid typed array length");
|
|
||||||
});
|
|
||||||
BIGINT_TYPED_ARRAYS.forEach(T => {
|
|
||||||
expect(() => {
|
|
||||||
new T({ length: 2 ** 32 - 1 });
|
|
||||||
}).toThrowWithMessage(RangeError, "Invalid typed array length");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Add table
Add a link
Reference in a new issue