summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorObinna Ikeh <hikenike6@gmail.com>2022-07-11 17:15:50 +0100
committerLinus Groh <mail@linusgroh.de>2022-07-12 00:44:34 +0100
commit45d07f648e846270af13c0440dd35ae26870f29a (patch)
tree90ad089e15e771ad0748fe685103a8b479649800 /Userland/Libraries/LibJS
parentf089c11b5bc8365dcc87f9f6faf13c5dde121896 (diff)
downloadserenity-45d07f648e846270af13c0440dd35ae26870f29a.zip
LibJS: Add %TypedArray%.prototype.toSpliced
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp136
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h1
2 files changed, 137 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
index 97711ec013..9407062efe 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
@@ -59,6 +59,7 @@ void TypedArrayPrototype::initialize(GlobalObject& object)
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.toSorted, to_sorted, 1, attr);
+ define_native_function(vm.names.toSpliced, to_spliced, 2, attr);
define_native_accessor(*vm.well_known_symbol_to_string_tag(), to_string_tag_getter, nullptr, Attribute::Configurable);
@@ -1597,4 +1598,139 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted)
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
+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;
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
index 038b35b3a5..857dfa8a46 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h
@@ -54,6 +54,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
JS_DECLARE_NATIVE_FUNCTION(to_reversed);
JS_DECLARE_NATIVE_FUNCTION(to_sorted);
+ JS_DECLARE_NATIVE_FUNCTION(to_spliced);
};
}