Repository: WebKit/WebKit
Pull request #44351: [JSC] Implement `Array#toSpliced` in C++
Author: login: sosukesuzuki
Labels: name: JavaScriptCore
description: For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.
Created: 2025-04-21T23:36:07Z | Merged: 2025-04-25T04:54:21Z

#### c52c8eeff4dce2712b1420f2b1f6d83a7183aa69
<pre>
[JSC] Implement `Array#toSpliced` in C++
<a href="https://bugs.webkit.org/show_bug.cgi?id=291870">https://bugs.webkit.org/show_bug.cgi?id=291870</a>

Reviewed by Yusuke Suzuki.

This patch implements `Array#toSpliced` in C++.

                                                  TipOfTree                  Patched

array-prototype-toSpliced-double-double       138.8817+-17.6257    ^    105.4402+-14.7788       ^ definitely 1.3172x faster
array-prototype-toSpliced-int32-int32         149.2978+-14.7220         122.7447+-15.4135         might be 1.2163x faster
array-prototype-toSpliced-int32-contiguous
                                              140.1942+-7.7697     ^    108.4701+-11.8983       ^ definitely 1.2925x faster
array-prototype-toSpliced-double-contiguous
                                              149.8610+-20.7910         115.2025+-19.0198         might be 1.3008x faster
array-prototype-toSpliced-contiguous-contiguous
                                              146.6007+-1.9984     ^    100.1849+-13.2062       ^ definitely 1.4633x faster
array-prototype-toSpliced-int32-double        143.4620+-11.6133         120.8056+-12.1655         might be 1.1875x faster

* Source/JavaScriptCore/runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::finishCreation):
(JSC::argumentClampedIndexFromStartOrEnd):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/CommonIdentifiers.h:

Canonical link: <a href="https://commits.webkit.org/294096@main">https://commits.webkit.org/294096@main</a>
</pre>
<!--EWS-Status-Bubble-Start-->
https://github.com/WebKit/WebKit/commit/5f31c276a3f523c26c8769f35ed4cafc91e66c7d

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [❌ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100822 "4 style errors") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20474 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10773 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105959 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51411 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20783 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28948 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/76768 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33809 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103829 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15976 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91069 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/57121 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15786 "Passed tests") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/9078 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50787 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93486 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85687 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9152 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108314 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99430 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27940 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/20526 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/1/builds/85731 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28303 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87271 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85274 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21702 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29988 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7718 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21946 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27875 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33132 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123056 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27686 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34295 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/31004 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29244 "Built successfully") | | | 
<!--EWS-Status-Bubble-End-->


Diff:
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-contiguous-contiguous.js b/JSTests/microbenchmarks/array-prototype-toSpliced-contiguous-contiguous.js
new file mode 100644
index 000000000000..02e4cd016726
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-contiguous-contiguous.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => ({ v: i }));
+const insert = Array.from({ length: 32   }, (_, i) => ({ v: -i }));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-double-contiguous.js b/JSTests/microbenchmarks/array-prototype-toSpliced-double-contiguous.js
new file mode 100644
index 000000000000..cc86cfa4c0d4
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-double-contiguous.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => i + 0.5);
+const insert = Array.from({ length: 32   }, (_, i) => ({ v: -i }));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-double-double.js b/JSTests/microbenchmarks/array-prototype-toSpliced-double-double.js
new file mode 100644
index 000000000000..e9e7e6d81ada
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-double-double.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => i + 0.5);
+const insert = Array.from({ length: 32   }, (_, i) => -(i + 0.25));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-int32-contiguous.js b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-contiguous.js
new file mode 100644
index 000000000000..c83c050a00ea
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-contiguous.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => i | 0);
+const insert = Array.from({ length: 32   }, (_, i) => ({ v: -i }));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-int32-double.js b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-double.js
new file mode 100644
index 000000000000..218d1f2bbf7c
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-double.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => i | 0);
+const insert = Array.from({ length: 32   }, (_, i) => -(i + 0.25));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/microbenchmarks/array-prototype-toSpliced-int32-int32.js b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-int32.js
new file mode 100644
index 000000000000..033cd06adaf2
--- /dev/null
+++ b/JSTests/microbenchmarks/array-prototype-toSpliced-int32-int32.js
@@ -0,0 +1,18 @@
+function test(array, start, del, insert) {
+    return array.toSpliced(start, del, ...insert);
+}
+noInline(test);
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const src    = Array.from({ length: 1024 }, (_, i) => i | 0);
+const insert = Array.from({ length: 32   }, (_, i) => -(i | 0));
+
+let result;
+for (let i = 0; i < 1e5; ++i)
+    result = test(src, 496, 32, insert);
+
+shouldBe(result.length, 1024);
diff --git a/JSTests/stress/array-prototype-toSpliced-fast-path.js b/JSTests/stress/array-prototype-toSpliced-fast-path.js
new file mode 100644
index 000000000000..c747801d1b7c
--- /dev/null
+++ b/JSTests/stress/array-prototype-toSpliced-fast-path.js
@@ -0,0 +1,77 @@
+function sameArray(a, b) {
+    if (a.length !== b.length)
+        throw new Error(`length: expected ${b.length} but got ${a.length}`);
+    for (let i = 0; i < a.length; ++i) {
+        if (a[i] !== b[i])
+            throw new Error(`${i}: expected ${b[i]} but got ${a[i]}`);
+    }
+}
+
+/* int32 → int32, delete only */
+{
+    const src = [0, 1, 2, 3, 4, 5];
+    sameArray(src.toSpliced(2, 2), [0, 1, 4, 5]);
+    sameArray(src, [0, 1, 2, 3, 4, 5]);
+}
+
+/* int32 → int32, insert int32 */
+{
+    const src = [10, 11, 12, 13];
+    sameArray(src.toSpliced(2, 0, 99, 98), [10, 11, 99, 98, 12, 13]);
+    sameArray(src, [10, 11, 12, 13]);
+}
+
+/* int32 → double, insert double */
+{
+    const src = [1, 2, 3, 4];
+    sameArray(src.toSpliced(2, 1, 3.25, 4.25), [1, 2, 3.25, 4.25, 4]);
+    sameArray(src, [1, 2, 3, 4]);
+}
+
+/* int32 → contiguous, insert object */
+{
+    const src = [7, 8, 9];
+    const obj = { v: 42 };
+    sameArray(src.toSpliced(1, 1, obj), [7, obj, 9]);
+    sameArray(src, [7, 8, 9]);
+}
+
+/* double → double, delete last */
+{
+    const src = [0.5, 1.5, 2.5, 3.5];
+    sameArray(src.toSpliced(-1), [0.5, 1.5, 2.5]);
+    sameArray(src, [0.5, 1.5, 2.5, 3.5]);
+}
+
+/* double → double, insert int32 */
+{
+    const src = [5.5, 6.5, 7.5];
+    sameArray(src.toSpliced(1, 0, 100), [5.5, 100, 6.5, 7.5]);
+    sameArray(src, [5.5, 6.5, 7.5]);
+}
+
+/* double → contiguous, insert string & object */
+{
+    const src = [2.2, 3.3, 4.4];
+    const o = { x: 1 };
+    sameArray(src.toSpliced(0, 1, "str", o), ["str", o, 3.3, 4.4]);
+    sameArray(src, [2.2, 3.3, 4.4]);
+}
+
+/* contiguous → contiguous, delete middle */
+{
+    const a = { a: 1 };
+    const b = { b: 2 };
+    const c = { c: 3 };
+    const src = [a, b, c];
+    sameArray(src.toSpliced(1, 1), [a, c]);
+    sameArray(src, [a, b, c]);
+}
+
+/* contiguous → contiguous, insert mix */
+{
+    const src = ["x", "y", "z"];
+    sameArray(src.toSpliced(2, 0, 7, 8.8), ["x", "y", 7, 8.8, "z"]);
+    sameArray(src, ["x", "y", "z"]);
+}
+
diff --git a/JSTests/stress/array-prototype-toSpliced-hole-check.js b/JSTests/stress/array-prototype-toSpliced-hole-check.js
new file mode 100644
index 000000000000..e1afdaec594b
--- /dev/null
+++ b/JSTests/stress/array-prototype-toSpliced-hole-check.js
@@ -0,0 +1,22 @@
+function sameArray(a, b) {
+    if (a.length !== b.length)
+        throw new Error(`length: expected ${b.length} but got ${a.length}`);
+    for (let i = 0; i < a.length; ++i) {
+        if (a[i] !== b[i])
+            throw new Error(`${i}: expected ${b[i]} but got ${a[i]}`);
+    }
+}
+
+function shouldBe(a, b) {
+    if (a !== b)
+        throw new Error(`Expected ${b} but got ${a}`);
+}
+
+const array = [, , , 1, 2, 3, 4];
+const result = array.toSpliced(0, 0, 9, 8, 7);
+
+sameArray(result, [9, 8, 7, undefined, undefined, undefined, 1, 2, 3, 4]);
+
+shouldBe(Object.hasOwn(result, 3), true);
+shouldBe(Object.hasOwn(result, 4), true);
+shouldBe(Object.hasOwn(result, 5), true);
diff --git a/Source/JavaScriptCore/builtins/ArrayPrototype.js b/Source/JavaScriptCore/builtins/ArrayPrototype.js
index 14290b162e23..b8ac97facff9 100644
--- a/Source/JavaScriptCore/builtins/ArrayPrototype.js
+++ b/Source/JavaScriptCore/builtins/ArrayPrototype.js
@@ -363,73 +363,3 @@ function at(index)
 
     return (k >= 0 && k < length) ? array[k] : @undefined;
 }
-
-function toSpliced(start, deleteCount /*, ...items */)
-{
-    "use strict"
-
-    // Step 1.
-    var array = @toObject(this, "Array.prototype.toSpliced requires that |this| not be null or undefined");
-
-    // Step 2.
-    var length = @toLength(array.length);
-
-    // Step 3.
-    var relativeStart = @toIntegerOrInfinity(start);
-
-    var actualStart;
-    // Step 4-6.
-    if (relativeStart === -@Infinity)
-        actualStart = 0;
-    else if (relativeStart < 0)
-        actualStart = length + relativeStart > 0 ? length + relativeStart : 0;
-    else
-        actualStart = @min(relativeStart, length);
-
-    // Step 7.
-    var insertCount = 0;
-    var actualDeleteCount;
-
-    // Step 8-10.
-    var argCount = @argumentCount();
-    if (argCount === 0)
-        actualDeleteCount = 0;
-    else if (argCount === 1)
-        actualDeleteCount = length - actualStart;
-    else {
-        insertCount = argCount - 2;
-        var tempDeleteCount = @toIntegerOrInfinity(deleteCount);
-        tempDeleteCount = tempDeleteCount > 0 ? tempDeleteCount : 0;
-        actualDeleteCount = @min(tempDeleteCount, length - actualStart);
-    }
-
-    // Step 11.
-    var newLen = length + insertCount - actualDeleteCount;
-
-    // Step 12.
-    if (newLen >= @MAX_SAFE_INTEGER)
-        @throwTypeError("Array length exceeds 2**53 - 1");
-
-    // Step 13.
-    var result = @newArrayWithSize(newLen);
-
-    // Step 14.
-    var k = 0;
-
-    // Step 16.
-    for (; k < actualStart; k++)
-        @putByValDirect(result, k, array[k]);
-
-    // Step 17.
-    for (var i = 0; i < insertCount; i++, k++)
-        @putByValDirect(result, k, arguments[i + 2]);
-
-    // Step 18.
-    for (; k < newLen; k++) {
-        var from = k + actualDeleteCount - insertCount;
-        @putByValDirect(result, k, array[from]);
-    }
-
-    return result;
-
-}
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index ff535238f960..1333de4c32d2 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -70,6 +70,7 @@ static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncToSorted);
 static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncWith);
 static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncIncludes);
 static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncCopyWithin);
+static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncToSpliced);
 
 // ------------------------------ ArrayPrototype ----------------------------
 
@@ -132,7 +133,7 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().atPublicName(), arrayPrototypeAtCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toReversed, arrayProtoFuncToReversed, static_cast<unsigned>(PropertyAttribute::DontEnum), 0, ImplementationVisibility::Public);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toSorted, arrayProtoFuncToSorted, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, ImplementationVisibility::Public);
-    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().toSplicedPublicName(), arrayPrototypeToSplicedCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toSpliced, arrayProtoFuncToSpliced, static_cast<unsigned>(PropertyAttribute::DontEnum), 2, ImplementationVisibility::Public);
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->with, arrayProtoFuncWith, static_cast<unsigned>(PropertyAttribute::DontEnum), 2, ImplementationVisibility::Public);
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().entriesPrivateName(), getDirect(vm, vm.propertyNames->builtinNames().entriesPublicName()), static_cast<unsigned>(PropertyAttribute::ReadOnly));
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().forEachPrivateName(), getDirect(vm, vm.propertyNames->builtinNames().forEachPublicName()), static_cast<unsigned>(PropertyAttribute::ReadOnly));
@@ -160,7 +161,7 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
         &vm.propertyNames->builtinNames().keysPublicName(),
         &vm.propertyNames->toReversed,
         &vm.propertyNames->toSorted,
-        &vm.propertyNames->builtinNames().toSplicedPublicName(),
+        &vm.propertyNames->toSpliced,
         &vm.propertyNames->builtinNames().valuesPublicName()
     };
     for (const auto* unscopableName : unscopableNames) {
@@ -1756,17 +1757,17 @@ static JSArray* concatAppendArray(JSGlobalObject* globalObject, VM& vm, JSArray*
     if (type == ArrayWithDouble) {
         double* buffer = butterfly->contiguousDouble().data();
         if (firstType == ArrayWithDouble)
-            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguousDouble().data(), firstArraySize, firstType);
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguousDouble().data(), 0, firstArraySize, firstType);
         else
-            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguous().data(), firstArraySize, firstType);
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguous().data(), 0, firstArraySize, firstType);
         if (secondType == ArrayWithDouble)
-            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguousDouble().data(), secondArraySize, secondType);
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguousDouble().data(), 0, secondArraySize, secondType);
         else
-            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguous().data(), secondArraySize, secondType);
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguous().data(), 0, secondArraySize, secondType);
     } else if (type != ArrayWithUndecided) {
         WriteBarrier<Unknown>* buffer = butterfly->contiguous().data();
-        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguous().data(), firstArraySize, firstType);
-        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguous().data(), secondArraySize, secondType);
+        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, firstButterfly->contiguous().data(), 0, firstArraySize, firstType);
+        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, firstArraySize, secondButterfly->contiguous().data(), 0, secondArraySize, secondType);
     }
 
     Butterfly::clearOptimalVectorLengthGap(type, butterfly, vectorLength, resultSize);
@@ -2294,6 +2295,83 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncCopyWithin, (JSGlobalObject* globalObject
     return JSValue::encode(thisObject);
 }
 
+JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncToSpliced, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (UNLIKELY(thisValue.isUndefinedOrNull()))
+        return throwVMTypeError(globalObject, scope, "Array.prototype.toSpliced requires that |this| not be null or undefined"_s);
+    auto* thisObject = thisValue.toObject(globalObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t length = toLength(globalObject, thisObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t start = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::Yes>(globalObject, callFrame->argument(0), length);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t insertCount = 0;
+    uint64_t deleteCount = 0;
+    if (callFrame->argumentCount() == 1)
+        deleteCount = length - start;
+    else if (callFrame->argumentCount() > 1) {
+        insertCount = callFrame->argumentCount() - 2;
+        deleteCount = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::No>(globalObject, callFrame->uncheckedArgument(1), length - start);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    uint64_t newLen = length + insertCount - deleteCount;
+
+    if (UNLIKELY(newLen >= static_cast<uint64_t>(maxSafeInteger()))) {
+        throwTypeError(globalObject, scope, "Array length exceeds 2**53 - 1"_s);
+        return { };
+    }
+
+    if (UNLIKELY(newLen > std::numeric_limits<uint32_t>::max())) {
+        throwRangeError(globalObject, scope, "Array length must be a positive integer of safe magnitude."_s);
+        return { };
+    }
+
+    if (LIKELY(isJSArray(thisObject))) {
+        JSArray* thisArray = asArray(thisObject);
+        if (JSArray* result = thisArray->fastToSpliced(globalObject, callFrame, length, newLen, start, deleteCount, insertCount))
+            return JSValue::encode(result);
+    }
+
+    JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), newLen);
+    if (UNLIKELY(!result)) {
+        throwOutOfMemoryError(globalObject, scope);
+        return { };
+    }
+
+    uint64_t k = 0;
+
+    for (; k < start; k++) {
+        JSValue fromValue = thisObject->getIndex(globalObject, k);
+        RETURN_IF_EXCEPTION(scope, { });
+        result->putDirectIndex(globalObject, k, fromValue, 0, PutDirectIndexShouldThrow);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    for (uint64_t i = 0; i < insertCount; i++, k++) {
+        result->putDirectIndex(globalObject, k, callFrame->argument(i + 2), 0, PutDirectIndexShouldThrow);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    for (; k < newLen; k++) {
+        JSValue fromValue = thisObject->getIndex(globalObject, k + deleteCount - insertCount);
+        RETURN_IF_EXCEPTION(scope, { });
+        result->putDirectIndex(globalObject, k, fromValue, 0, PutDirectIndexShouldThrow);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    return JSValue::encode(result);
+}
+
 } // namespace JSC
 
 WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
index 8b1672c35ba1..4654634281c6 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -291,6 +291,7 @@
     macro(toPrecision) \
     macro(toReversed) \
     macro(toSorted) \
+    macro(toSpliced) \
     macro(toString) \
     macro(toTemporalInstant) \
     macro(toWellFormed) \
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 7294016c1038..62d3b6d3b8e7 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -856,6 +856,102 @@ bool JSArray::fastCopyWithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (uint64_t i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer) {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, 0, sourceBuffer, 0, start, sourceType);
+        };
+        auto copyArraySuffixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer) {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, start + insertCount, sourceBuffer, start + deleteCount, length - start - deleteCount, sourceType);
+        };
+
+        auto* sourceButterfly = this->butterfly();
+        if (hasDouble(resultIndexingType)) {
+            ASSERT(sourceType == ArrayWithInt32 || sourceType == ArrayWithDouble);
+            double* resultBuffer = resultButterfly->contiguousDouble().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (uint64_t i = 0; i < insertCount; ++i) {
+                JSValue value = callFrame->uncheckedArgument(i + 2);
+                ASSERT(value.isNumber());
+                resultButterfly->contiguousDouble().atUnsafe(start + i) = value.asNumber();
+            }
+            if (sourceType == ArrayWithDouble)
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguous().data());
+        } else if (hasInt32(resultIndexingType) || hasContiguous(resultIndexingType)) {
+            auto* resultBuffer = resultButterfly->contiguous().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (uint64_t i = 0; i < insertCount; ++i) {
+                JSValue value = callFrame->uncheckedArgument(i + 2);
+                resultButterfly->contiguous().atUnsafe(start + i).setWithoutWriteBarrier(value);
+            }
+            if (sourceType == ArrayWithDouble)
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguous().data());
+        } else
+            RELEASE_ASSERT_NOT_REACHED();
+
+        Butterfly::clearOptimalVectorLengthGap(resultIndexingType, resultButterfly, vectorLength, newLength);
+        return createWithButterfly(vm, nullptr, resultStructure, resultButterfly);
+    }
+    default: {
+        return nullptr;
+    }
+    }
+}
+
 bool JSArray::appendMemcpy(JSGlobalObject* globalObject, VM& vm, unsigned startIndex, IndexingType otherType, std::span<const EncodedJSValue> values)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -1957,21 +2053,21 @@ JSArray* tryCloneArrayFromFast(JSGlobalObject* globalObject, JSValue arrayValue)
     case ArrayWithDouble: {
         ASSERT(sourceType == ArrayWithDouble);
         double* buffer = resultButterfly->contiguousDouble().data();
-        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguousDouble().data(), resultSize, ArrayWithDouble);
+        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguousDouble().data(), 0, resultSize, ArrayWithDouble);
         break;
     }
     case ArrayWithInt32: {
         ASSERT(sourceType == ArrayWithInt32);
         auto* buffer = resultButterfly->contiguous().data();
-        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguous().data(), resultSize, ArrayWithInt32);
+        copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguous().data(), 0, resultSize, ArrayWithInt32);
         break;
     }
     case ArrayWithContiguous: {
         auto* buffer = resultButterfly->contiguous().data();
         if (sourceType == ArrayWithDouble)
-            copyArrayElements<fillMode, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguousDouble().data(), resultSize, ArrayWithDouble);
+            copyArrayElements<fillMode, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguousDouble().data(), 0, resultSize, ArrayWithDouble);
         else
-            copyArrayElements<fillMode, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguous().data(), resultSize, sourceType);
+            copyArrayElements<fillMode, NeedsGCSafeOps::No>(buffer, 0, butterfly->contiguous().data(), 0, resultSize, sourceType);
         break;
     }
     default:
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index dfc8bf18f37c..07d863ab4011 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -129,6 +129,8 @@ class JSArray : public JSNonFinalObject {
 
     bool fastCopyWithin(JSGlobalObject*, uint64_t from64, uint64_t to64, uint64_t count64, uint64_t length64);
 
+    JSArray* fastToSpliced(JSGlobalObject*, CallFrame*, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount);
+
     ALWAYS_INLINE bool definitelyNegativeOneMiss() const;
 
     enum ShiftCountMode {
@@ -340,7 +342,7 @@ template<>
 void clearElement(double& element);
 
 template<ArrayFillMode fillMode, NeedsGCSafeOps needsGCSafeOps, typename T, typename U>
-ALWAYS_INLINE void copyArrayElements(T* buffer, unsigned offset, U* source, unsigned sourceSize, IndexingType sourceType)
+ALWAYS_INLINE void copyArrayElements(T* buffer, unsigned offset, U* source, unsigned sourceOffset, unsigned sourceSize, IndexingType sourceType)
 {
     if (sourceType == ArrayWithUndecided) {
         if constexpr (fillMode == ArrayFillMode::Empty) {
@@ -356,15 +358,15 @@ ALWAYS_INLINE void copyArrayElements(T* buffer, unsigned offset, U* source, unsi
     if constexpr (std::is_same_v<T, U>) {
         if constexpr (fillMode == ArrayFillMode::Empty) {
             if constexpr (needsGCSafeOps == NeedsGCSafeOps::No && sizeof(T) == sizeof(U))
-                memcpy(buffer + offset, source, sizeof(T) * sourceSize);
+                memcpy(buffer + offset, source + sourceOffset, sizeof(T) * sourceSize);
             else if constexpr (std::is_same_v<T, double>)
-                memcpy(buffer + offset, source, sizeof(double) * sourceSize);
+                memcpy(buffer + offset, source + sourceOffset, sizeof(double) * sourceSize);
             else
-                gcSafeMemcpy(buffer + offset, source, sizeof(JSValue) * sourceSize);
+                gcSafeMemcpy(buffer + offset, source + sourceOffset, sizeof(JSValue) * sourceSize);
             return;
         } else {
             for (unsigned i = 0; i < sourceSize; ++i) {
-                JSValue value = source[i].get();
+                JSValue value = source[i + sourceOffset].get();
                 if (!value)
                     value = jsUndefined();
                 buffer[i + offset].setWithoutWriteBarrier(value);
@@ -374,7 +376,7 @@ ALWAYS_INLINE void copyArrayElements(T* buffer, unsigned offset, U* source, unsi
         ASSERT(sourceType == ArrayWithInt32);
         static_assert(fillMode == ArrayFillMode::Empty);
         for (unsigned i = 0; i < sourceSize; ++i) {
-            JSValue value = source[i].get();
+            JSValue value = source[i + sourceOffset].get();
             if (value)
                 buffer[i + offset] = value.asInt32();
             else
@@ -383,7 +385,7 @@ ALWAYS_INLINE void copyArrayElements(T* buffer, unsigned offset, U* source, unsi
     } else {
         static_assert(std::is_same_v<U, double>);
         for (unsigned i = 0; i < sourceSize; ++i) {
-            double value = source[i];
+            double value = source[i + sourceOffset];
             if (value == value)
                 buffer[i + offset].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
             else {


Reviews:
user: login: Constellation
body: Nice. Pointing out some changes.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-04-22T22:51:53Z
user: login: Constellation
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-24T06:15:26Z

Review comments:
diff_hunk: @@ -2294,6 +2295,83 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncCopyWithin, (JSGlobalObject* globalObject
     return JSValue::encode(thisObject);
 }
 
+JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncToSpliced, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (UNLIKELY(thisValue.isUndefinedOrNull()))
+        return throwVMTypeError(globalObject, scope, "Array.prototype.toSpliced requires that |this| not be null or undefined"_s);
+    auto* thisObject = thisValue.toObject(globalObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t length = toLength(globalObject, thisObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t start = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::Yes>(globalObject, callFrame->argument(0), length);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t insertCount = 0;
+    uint64_t deleteCount = 0;
+    if (callFrame->argumentCount() == 1)
+        deleteCount = length - start;
+    else if (callFrame->argumentCount() > 1) {
+        insertCount = callFrame->argumentCount() - 2;
+        deleteCount = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::No>(globalObject, callFrame->uncheckedArgument(1), length - start);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    uint64_t newLen = length + insertCount - deleteCount;
+
+    if (UNLIKELY(newLen >= static_cast<uint64_t>(maxSafeInteger()))) {
+        throwTypeError(globalObject, scope, "Array length exceeds 2**53 - 1"_s);
+        return { };
+    }
+
+    if (UNLIKELY(newLen > std::numeric_limits<uint32_t>::max())) {
+        throwRangeError(globalObject, scope, "Array length must be a positive integer of safe magnitude."_s);
+        return { };
+    }
+
+    if (LIKELY(isJSArray(thisObject))) {
+        JSArray* thisArray = asArray(thisObject);
+        if (JSArray* result = thisArray->fastToSpliced(globalObject, callFrame, length, newLen, start, deleteCount, insertCount))
+            return JSValue::encode(result);
+    }
+
+    JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), newLen);
+    if (UNLIKELY(!result)) {
+        throwOutOfMemoryError(globalObject, scope);
+        return { };
+    }
+
+    uint32_t k = 0;
path: Source/JavaScriptCore/runtime/ArrayPrototype.cpp
user: login: Constellation
body: Use `uint64_t`.
created_at: 2025-04-22T22:46:53Z
author_association: MEMBER
diff_hunk: @@ -2294,6 +2295,83 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncCopyWithin, (JSGlobalObject* globalObject
     return JSValue::encode(thisObject);
 }
 
+JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncToSpliced, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (UNLIKELY(thisValue.isUndefinedOrNull()))
+        return throwVMTypeError(globalObject, scope, "Array.prototype.toSpliced requires that |this| not be null or undefined"_s);
+    auto* thisObject = thisValue.toObject(globalObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t length = toLength(globalObject, thisObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t start = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::Yes>(globalObject, callFrame->argument(0), length);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    uint64_t insertCount = 0;
+    uint64_t deleteCount = 0;
+    if (callFrame->argumentCount() == 1)
+        deleteCount = length - start;
+    else if (callFrame->argumentCount() > 1) {
+        insertCount = callFrame->argumentCount() - 2;
+        deleteCount = argumentClampedIndexFromStartOrEnd<RelativeNegativeIndex::No>(globalObject, callFrame->uncheckedArgument(1), length - start);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    uint64_t newLen = length + insertCount - deleteCount;
+
+    if (UNLIKELY(newLen >= static_cast<uint64_t>(maxSafeInteger()))) {
+        throwTypeError(globalObject, scope, "Array length exceeds 2**53 - 1"_s);
+        return { };
+    }
+
+    if (UNLIKELY(newLen > std::numeric_limits<uint32_t>::max())) {
+        throwRangeError(globalObject, scope, "Array length must be a positive integer of safe magnitude."_s);
+        return { };
+    }
+
+    if (LIKELY(isJSArray(thisObject))) {
+        JSArray* thisArray = asArray(thisObject);
+        if (JSArray* result = thisArray->fastToSpliced(globalObject, callFrame, length, newLen, start, deleteCount, insertCount))
+            return JSValue::encode(result);
+    }
+
+    JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), newLen);
+    if (UNLIKELY(!result)) {
+        throwOutOfMemoryError(globalObject, scope);
+        return { };
+    }
+
+    uint32_t k = 0;
+
+    for (; k < start; k++) {
+        JSValue fromValue = thisObject->getIndex(globalObject, k);
+        RETURN_IF_EXCEPTION(scope, { });
+        result->putDirectIndex(globalObject, k, fromValue, 0, PutDirectIndexShouldThrow);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    for (unsigned i = 0; i < insertCount; i++, k++) {
path: Source/JavaScriptCore/runtime/ArrayPrototype.cpp
user: login: Constellation
body: Use `uint64_t`.
created_at: 2025-04-22T22:47:02Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,106 @@ bool JSArray::fastCopywithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (unsigned i = 0; i < insertCount; i++)
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: Use uint64_t.
created_at: 2025-04-22T22:48:25Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,106 @@ bool JSArray::fastCopywithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (unsigned i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: We do not put `{` in a new line for lambda.
created_at: 2025-04-22T22:48:52Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,106 @@ bool JSArray::fastCopywithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (unsigned i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, 0, sourceBuffer, 0, start, sourceType);
+        };
+        auto copyArraySuffixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: Ditto.
created_at: 2025-04-22T22:48:59Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,106 @@ bool JSArray::fastCopywithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (unsigned i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, 0, sourceBuffer, 0, start, sourceType);
+        };
+        auto copyArraySuffixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, start + insertCount, sourceBuffer, start + deleteCount, length - start - deleteCount, sourceType);
+        };
+
+        auto* sourceButterfly = this->butterfly();
+        if (hasDouble(resultIndexingType)) {
+            ASSERT(sourceType == ArrayWithInt32 || sourceType == ArrayWithDouble);
+            double* resultBuffer = resultButterfly->contiguousDouble().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (unsigned i = 0; i < insertCount; ++i) {
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: Use `uint64_t`.
created_at: 2025-04-22T22:49:19Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,106 @@ bool JSArray::fastCopywithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (unsigned i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, 0, sourceBuffer, 0, start, sourceType);
+        };
+        auto copyArraySuffixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer)
+        {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, start + insertCount, sourceBuffer, start + deleteCount, length - start - deleteCount, sourceType);
+        };
+
+        auto* sourceButterfly = this->butterfly();
+        if (hasDouble(resultIndexingType)) {
+            ASSERT(sourceType == ArrayWithInt32 || sourceType == ArrayWithDouble);
+            double* resultBuffer = resultButterfly->contiguousDouble().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (unsigned i = 0; i < insertCount; ++i) {
+                JSValue value = callFrame->uncheckedArgument(i + 2);
+                ASSERT(value.isNumber());
+                resultButterfly->contiguousDouble().atUnsafe(start + i) = value.asNumber();
+            }
+            if (sourceType == ArrayWithDouble)
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguous().data());
+        } else if (hasInt32(resultIndexingType) || hasContiguous(resultIndexingType)) {
+            auto* resultBuffer = resultButterfly->contiguous().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (unsigned i = 0; i < insertCount; ++i) {
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: Use `uint64_t`.
created_at: 2025-04-22T22:49:27Z
author_association: MEMBER
diff_hunk: @@ -856,6 +856,104 @@ bool JSArray::fastCopyWithin(JSGlobalObject* globalObject, uint64_t from64, uint
     }
 }
 
+JSArray* JSArray::fastToSpliced(JSGlobalObject* globalObject, CallFrame* callFrame, uint64_t length, uint64_t newLength, uint64_t start, uint64_t deleteCount, uint64_t insertCount)
+{
+    VM& vm = globalObject->vm();
+
+    IndexingType sourceType = indexingType();
+    switch (sourceType) {
+    case ArrayWithInt32:
+    case ArrayWithContiguous:
+    case ArrayWithDouble: {
+        if (UNLIKELY(newLength > MAX_STORAGE_VECTOR_LENGTH))
+            return nullptr;
+
+        if (UNLIKELY(newLength >= MIN_SPARSE_ARRAY_INDEX))
+            return nullptr;
+
+        if (UNLIKELY(length > this->butterfly()->vectorLength()))
+            return nullptr;
+
+        if (hasDouble(sourceType)) {
+            if (containsHole(this->butterfly()->contiguousDouble().data(), static_cast<uint32_t>(length)))
+                return nullptr;
+        } else if (containsHole(this->butterfly()->contiguous().data(), static_cast<uint32_t>(length)))
+            return nullptr;
+
+        IndexingType insertedItemsIndexingType = sourceType;
+        for (uint64_t i = 0; i < insertCount; i++)
+            insertedItemsIndexingType = leastUpperBoundOfIndexingTypeAndValue(insertedItemsIndexingType, callFrame->uncheckedArgument(i + 2));
+
+        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(insertedItemsIndexingType);
+        IndexingType resultIndexingType = resultStructure->indexingType();
+
+        if (UNLIKELY(hasAnyArrayStorage(resultIndexingType)))
+            return nullptr;
+        ASSERT(!globalObject->isHavingABadTime());
+
+        auto vectorLength = Butterfly::optimalContiguousVectorLength(resultStructure, newLength);
+        void* memory = vm.auxiliarySpace().allocate(
+            vm,
+            Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)),
+            nullptr, AllocationFailureMode::ReturnNull);
+        if (UNLIKELY(!memory))
+            return nullptr;
+        auto* resultButterfly = Butterfly::fromBase(memory, 0, 0);
+        resultButterfly->setVectorLength(vectorLength);
+        resultButterfly->setPublicLength(newLength);
+
+        auto copyArrayPrefixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer) {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, 0, sourceBuffer, 0, start, sourceType);
+        };
+        auto copyArraySuffixElements = [&]<typename T, typename U>(T* resultBuffer, U* sourceBuffer) {
+            copyArrayElements<ArrayFillMode::Empty, NeedsGCSafeOps::No>(resultBuffer, start + insertCount, sourceBuffer, start + deleteCount, length - start - deleteCount, sourceType);
+        };
+
+        auto* sourceButterfly = this->butterfly();
+        if (hasDouble(resultIndexingType)) {
+            ASSERT(sourceType == ArrayWithInt32 || sourceType == ArrayWithDouble);
+            double* resultBuffer = resultButterfly->contiguousDouble().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (uint64_t i = 0; i < insertCount; ++i) {
+                JSValue value = callFrame->uncheckedArgument(i + 2);
+                ASSERT(value.isNumber());
+                resultButterfly->contiguousDouble().atUnsafe(start + i) = value.asNumber();
+            }
+            if (sourceType == ArrayWithDouble)
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguous().data());
+        } else if (hasInt32(resultIndexingType) || hasContiguous(resultIndexingType)) {
+            auto* resultBuffer = resultButterfly->contiguous().data();
+            if (sourceType == ArrayWithDouble)
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArrayPrefixElements(resultBuffer, sourceButterfly->contiguous().data());
+            for (uint64_t i = 0; i < insertCount; ++i) {
+                JSValue value = callFrame->uncheckedArgument(i + 2);
+                resultButterfly->contiguous().atUnsafe(start + i).setWithoutWriteBarrier(value);
+            }
+            if (sourceType == ArrayWithDouble)
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguousDouble().data());
+            else
+                copyArraySuffixElements(resultBuffer, sourceButterfly->contiguous().data());
+        } else
+            RELEASE_ASSERT_NOT_REACHED();
+
+        Butterfly::clearOptimalVectorLengthGap(resultIndexingType, resultButterfly, vectorLength, newLength);
+        JSArray* result = createWithButterfly(vm, nullptr, resultStructure, resultButterfly);
+
+        return result;
path: Source/JavaScriptCore/runtime/JSArray.cpp
user: login: Constellation
body: We should just return immediately.

```
return createWithButterfly(vm, nullptr, resultStructure, resultButterfly);
```
created_at: 2025-04-24T06:12:00Z
author_association: MEMBER

PR comments:
user: login: webkit-early-warning-system
created_at: 2025-04-21T23:36:15Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/204bb0764e89ffbca97dea58d0565db3e59b1ddd)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [❌ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100368 "2 style errors") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20020 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10319 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105504 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/50956 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20326 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28494 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/76426 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33481 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103375 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15569 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/90668 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/56781 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15386 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/8669 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50323 "Built successfully") | 
| [❌ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93030 "Found 2 new JSC stress test failures: stress/catch-from-function-inlining-simd-function.js.ftl-eager-no-cjit, wasm.yaml/wasm/gc-spec-tests/ref_eq.wast.js.wasm-omg (failure)") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85306 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/8751 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/107859 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/98976 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27486 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/20166 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/85382 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/27849 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/86868 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/84919 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29600 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7333 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21406 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27421 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/32662 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/122602 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27232 "Built successfully") | | [❌ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34205 "Found 1 new JSC stress test failure: ChakraCore.yaml/ChakraCore/test/es6/ES6MathAPIs.js.default (failure)") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/30550 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/28790 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-23T13:33:15Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/78024f2069509d5e25fa9a155da917e3f4da3ee7)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [❌ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100557 "4 style errors") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20209 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10508 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105694 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51145 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20517 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28683 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/76576 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33620 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103564 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15737 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/90833 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/56933 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15554 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/8838 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50521 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93221 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85468 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/8915 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108048 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99165 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27675 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/20321 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/85534 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28038 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87033 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85098 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29760 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7487 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21659 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27610 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/32860 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/122791 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27421 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34246 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/30739 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/28979 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-25T00:08:29Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/0fca411719889da815c919e466863797ece31e4e)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [❌ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100807 "4 style errors") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20459 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10758 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105944 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51396 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20768 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28933 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/76764 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33802 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103814 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15961 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91054 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/57117 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15771 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/9063 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50771 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93471 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85672 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9137 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108299 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99415 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27925 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/85717 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28288 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87256 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85261 "Passed tests") | 
| [❌ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21701 "") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29975 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7703 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21930 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27860 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33117 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123041 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27671 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34292 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/30989 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29229 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-04-25T03:41:02Z
body: No reviewer information in commit message, blocking PR #44351. Details: [Build #21701](https://ews-build.webkit.org/#/builders/19/builds/21701)
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-25T03:52:41Z
body: EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/5f31c276a3f523c26c8769f35ed4cafc91e66c7d)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [❌ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100822 "4 style errors") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20474 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10773 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105959 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51411 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20783 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28948 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/76768 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33809 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103829 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15976 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91069 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/57121 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15786 "Passed tests") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/9078 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50787 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93486 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85687 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9152 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108314 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99430 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27940 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/20526 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/1/builds/85731 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28303 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87271 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85274 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21702 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29988 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7718 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21946 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27875 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33132 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123056 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27686 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34295 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/31004 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29244 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-04-25T04:54:20Z
body: Committed 294096@main (c52c8eeff4dc): <https://commits.webkit.org/294096@main>

Reviewed commits have been landed. Closing PR #44351 and removing active labels.
author_association: COLLABORATOR