Title: [272341] trunk
Revision
272341
Author
[email protected]
Date
2021-02-03 15:07:41 -0800 (Wed, 03 Feb 2021)

Log Message

[JSC] Atomics should support BigInt64Array / BigUint64Array
https://bugs.webkit.org/show_bug.cgi?id=221245

Reviewed by Keith Miller.

JSTests:

* stress/atomic-increment-bigint64.js: Added.
(shouldBe):
(i.agent.start.262.agent.receiveBroadcast):
* stress/bigint-atomics-fail.js: Added.
(shouldThrow):
* stress/bigint64-atomics.js: Added.
(shouldBe):
(test):
* stress/biguint64-atomics.js: Added.
(shouldBe):
(test):
* stress/isLockFree.js:
(foo6):
(foo7):
(foo8):
(foo9):
* stress/shared-array-buffer-bigint.js: Added.
(shouldFail):
(shouldSucceed):
(runAtomic):
* test262/config.yaml:

Source/_javascript_Core:

This patch adds BigInt64Array / BigUint64Array support for Atomics.

1. Atomics.store should be rewritten since it returns non-type-coerced result, so we cannot use atomicReadModifyWrite.
   The spec also describes Atomics.store without using AtomicReadModifyWrite[1].
2. Extend Atomics.isLockFree to also accept a size of 8.
3. Currently, DFG / FTL handle Atomics + BigInt64Array/BigUint64Array as Array::Generic.

[1]: https://tc39.es/ecma262/#sec-atomics.store

* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileAtomicsIsLockFree):
* runtime/AtomicsObject.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::atomicsWaitImpl):
(JSC::JSC_DEFINE_JIT_OPERATION):
* runtime/ToNativeFromValue.h:
(JSC::toNativeFromValue):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (272340 => 272341)


--- trunk/JSTests/ChangeLog	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/JSTests/ChangeLog	2021-02-03 23:07:41 UTC (rev 272341)
@@ -1,3 +1,32 @@
+2021-02-01  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Atomics should support BigInt64Array / BigUint64Array
+        https://bugs.webkit.org/show_bug.cgi?id=221245
+
+        Reviewed by Keith Miller.
+
+        * stress/atomic-increment-bigint64.js: Added.
+        (shouldBe):
+        (i.agent.start.262.agent.receiveBroadcast):
+        * stress/bigint-atomics-fail.js: Added.
+        (shouldThrow):
+        * stress/bigint64-atomics.js: Added.
+        (shouldBe):
+        (test):
+        * stress/biguint64-atomics.js: Added.
+        (shouldBe):
+        (test):
+        * stress/isLockFree.js:
+        (foo6):
+        (foo7):
+        (foo8):
+        (foo9):
+        * stress/shared-array-buffer-bigint.js: Added.
+        (shouldFail):
+        (shouldSucceed):
+        (runAtomic):
+        * test262/config.yaml:
+
 2021-02-02  Ross Kirsling  <[email protected]>
 
         Completion value of a finally block should not be ignored if completion is abrupt

Added: trunk/JSTests/stress/atomic-increment-bigint64.js (0 => 272341)


--- trunk/JSTests/stress/atomic-increment-bigint64.js	                        (rev 0)
+++ trunk/JSTests/stress/atomic-increment-bigint64.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -0,0 +1,35 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+const num = 3;
+const count = 1e5;
+
+let buffer = new SharedArrayBuffer(128);
+let array = new BigInt64Array(buffer);
+
+for (let i = 0; i < num; ++i) {
+    $.agent.start(`
+        $262.agent.receiveBroadcast(function(buffer) {
+            let array = new BigInt64Array(buffer);
+            $262.agent.sleep(1);
+            for (var i = 0; i < ${count}; ++i)
+                Atomics.add(array, 0, 1n);
+            $262.agent.report(0);
+            $262.agent.leaving();
+        });
+    `);
+}
+
+$262.agent.broadcast(buffer);
+let done = 0;
+while (true) {
+    let report = $262.agent.getReport();
+    if (report !== null)
+        done++;
+    if (done === num)
+        break;
+    $262.agent.sleep(1);
+}
+shouldBe(array[0], BigInt(count * num));

Added: trunk/JSTests/stress/bigint-atomics-fail.js (0 => 272341)


--- trunk/JSTests/stress/bigint-atomics-fail.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-atomics-fail.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -0,0 +1,25 @@
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+let i64a = new BigInt64Array(new SharedArrayBuffer(128));
+let u64a = new BigUint64Array(new SharedArrayBuffer(128));
+
+shouldThrow(() => {
+    Atomics.wait(u64a, 0, 0n);
+}, `TypeError: Typed array argument must be an Int32Array or BigInt64Array.`);
+
+shouldThrow(() => {
+    Atomics.load(new Float64Array(8), 0);
+}, `TypeError: Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, BigInt64Array, or BigUint64Array.`);

Added: trunk/JSTests/stress/bigint64-atomics.js (0 => 272341)


--- trunk/JSTests/stress/bigint64-atomics.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint64-atomics.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -0,0 +1,34 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var array = new BigInt64Array(new SharedArrayBuffer(8 * 8));
+shouldBe(array.length, 8);
+
+function test(array) {
+    shouldBe(Atomics.add(array, 0, 8n), 0n);
+    shouldBe(array[0], 8n);
+    shouldBe(Atomics.sub(array, 0, 1n), 8n);
+    shouldBe(array[0], 7n);
+    shouldBe(Atomics.and(array, 0, 0b11110n), 7n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.compareExchange(array, 0, 5n, 0n), 6n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.compareExchange(array, 0, 6n, 1n), 6n);
+    shouldBe(array[0], 1n);
+    shouldBe(Atomics.exchange(array, 0, 2n), 1n);
+    shouldBe(array[0], 2n);
+    shouldBe(Atomics.load(array, 0), 2n);
+    shouldBe(Atomics.or(array, 0, 1n), 2n);
+    shouldBe(array[0], 3n);
+    shouldBe(Atomics.store(array, 0, 6n), 6n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.xor(array, 0, 0b11111n), 6n);
+    shouldBe(array[0], 25n);
+    shouldBe(Atomics.store(array, 0, 0n), 0n);
+}
+noInline(array);
+
+for (var i = 0; i < 1e4; ++i)
+    test(array);

Added: trunk/JSTests/stress/biguint64-atomics.js (0 => 272341)


--- trunk/JSTests/stress/biguint64-atomics.js	                        (rev 0)
+++ trunk/JSTests/stress/biguint64-atomics.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -0,0 +1,34 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var array = new BigUint64Array(new SharedArrayBuffer(8 * 8));
+shouldBe(array.length, 8);
+
+function test(array) {
+    shouldBe(Atomics.add(array, 0, 8n), 0n);
+    shouldBe(array[0], 8n);
+    shouldBe(Atomics.sub(array, 0, 1n), 8n);
+    shouldBe(array[0], 7n);
+    shouldBe(Atomics.and(array, 0, 0b11110n), 7n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.compareExchange(array, 0, 5n, 0n), 6n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.compareExchange(array, 0, 6n, 1n), 6n);
+    shouldBe(array[0], 1n);
+    shouldBe(Atomics.exchange(array, 0, 2n), 1n);
+    shouldBe(array[0], 2n);
+    shouldBe(Atomics.load(array, 0), 2n);
+    shouldBe(Atomics.or(array, 0, 1n), 2n);
+    shouldBe(array[0], 3n);
+    shouldBe(Atomics.store(array, 0, 6n), 6n);
+    shouldBe(array[0], 6n);
+    shouldBe(Atomics.xor(array, 0, 0b11111n), 6n);
+    shouldBe(array[0], 25n);
+    shouldBe(Atomics.store(array, 0, 0n), 0n);
+}
+noInline(array);
+
+for (var i = 0; i < 1e4; ++i)
+    test(array);

Modified: trunk/JSTests/stress/isLockFree.js (272340 => 272341)


--- trunk/JSTests/stress/isLockFree.js	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/JSTests/stress/isLockFree.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -35,6 +35,26 @@
 }
 noInline(foo5);
 
+function foo6(bytes) {
+    return Atomics.isLockFree(6);
+}
+noInline(foo6);
+
+function foo7(bytes) {
+    return Atomics.isLockFree(7);
+}
+noInline(foo7);
+
+function foo8(bytes) {
+    return Atomics.isLockFree(8);
+}
+noInline(foo8);
+
+function foo9(bytes) {
+    return Atomics.isLockFree(9);
+}
+noInline(foo9);
+
 for (var i = 0; i < 10000; ++i) {
     var result = foo(0);
     if (result !== false)
@@ -54,6 +74,18 @@
     var result = foo(5);
     if (result !== false)
         throw new Error("Bad result: " + result);
+    var result = foo(6);
+    if (result !== false)
+        throw new Error("Bad result: " + result);
+    var result = foo(7);
+    if (result !== false)
+        throw new Error("Bad result: " + result);
+    var result = foo(8);
+    if (result !== true)
+        throw new Error("Bad result: " + result);
+    var result = foo(9);
+    if (result !== false)
+        throw new Error("Bad result: " + result);
     var result = foo0();
     if (result !== false)
         throw new Error("Bad result: " + result);
@@ -72,4 +104,16 @@
     var result = foo5();
     if (result !== false)
         throw new Error("Bad result: " + result);
+    var result = foo6();
+    if (result !== false)
+        throw new Error("Bad result: " + result);
+    var result = foo7();
+    if (result !== false)
+        throw new Error("Bad result: " + result);
+    var result = foo8();
+    if (result !== true)
+        throw new Error("Bad result: " + result);
+    var result = foo9();
+    if (result !== false)
+        throw new Error("Bad result: " + result);
 }

Added: trunk/JSTests/stress/shared-array-buffer-bigint.js (0 => 272341)


--- trunk/JSTests/stress/shared-array-buffer-bigint.js	                        (rev 0)
+++ trunk/JSTests/stress/shared-array-buffer-bigint.js	2021-02-03 23:07:41 UTC (rev 272341)
@@ -0,0 +1,90 @@
+// These should all succeed.
+var bi64a = new BigInt64Array(new SharedArrayBuffer(128));
+var bu64a = new BigUint64Array(new SharedArrayBuffer(128));
+
+function shouldFail(f, name)
+{
+    try {
+        f();
+    } catch (e) {
+        if (e.name == name.name)
+            return;
+        throw new Error(f + " threw the wrong error: " + e);
+    }
+    throw new Error(f + " succeeded!");
+}
+
+function shouldSucceed(f)
+{
+    f();
+}
+
+for (bad of [bu64a]) {
+    shouldFail(() => Atomics.notify(bad, 0, 0n), TypeError);
+    shouldFail(() => Atomics.wait(bad, 0, 0n), TypeError);
+}
+
+for (idx of [-1, -1000000000000, 10000, 10000000000000]) {
+    for (a of [bi64a, bu64a]) {
+        shouldFail(() => Atomics.add(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.and(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.compareExchange(a, idx, 0n, 0n), RangeError);
+        shouldFail(() => Atomics.exchange(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.load(a, idx), RangeError);
+        shouldFail(() => Atomics.or(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.store(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.sub(a, idx, 0n), RangeError);
+        shouldFail(() => Atomics.xor(a, idx, 0n), RangeError);
+    }
+    shouldFail(() => Atomics.notify(bi64a, idx, 0n), RangeError);
+    shouldFail(() => Atomics.wait(bi64a, idx, 0n), RangeError);
+}
+
+for (idx of ["hello"]) {
+    for (a of [bi64a, bu64a]) {
+        shouldSucceed(() => Atomics.add(a, idx, 0n));
+        shouldSucceed(() => Atomics.and(a, idx, 0n));
+        shouldSucceed(() => Atomics.compareExchange(a, idx, 0n, 0n));
+        shouldSucceed(() => Atomics.exchange(a, idx, 0n));
+        shouldSucceed(() => Atomics.load(a, idx));
+        shouldSucceed(() => Atomics.or(a, idx, 0n));
+        shouldSucceed(() => Atomics.store(a, idx, 0n));
+        shouldSucceed(() => Atomics.sub(a, idx, 0n));
+        shouldSucceed(() => Atomics.xor(a, idx, 0n));
+    }
+    shouldSucceed(() => Atomics.notify(bi64a, idx, 0));
+    shouldSucceed(() => Atomics.wait(bi64a, idx, 0n, 1));
+}
+
+function runAtomic(array, index, init, name, args, expectedResult, expectedOutcome)
+{
+    array[index] = init;
+    var result = Atomics[name](array, index, ...args);
+    if (result != expectedResult)
+        throw new Error("Expected Atomics." + name + "(array, " + index + ", " + args.join(", ") + ") to return " + expectedResult + " but returned " + result + " for " + Object.prototype.toString.apply(array));
+    if (array[index] !== expectedOutcome)
+        throw new Error("Expected Atomics." + name + "(array, " + index + ", " + args.join(", ") + ") to result in array[" + index + "] = " + expectedOutcome + " but got " + array[index] + " for " + Object.prototype.toString.apply(array));
+}
+
+for (a of [bi64a, bu64a]) {
+    runAtomic(a, 0, 13n, "add", [42n], 13n, 55n);
+    runAtomic(a, 0, 13n, "and", [42n], 13n, 8n);
+    runAtomic(a, 0, 13n, "compareExchange", [25n, 42n], 13n, 13n);
+    runAtomic(a, 0, 13n, "compareExchange", [13n, 42n], 13n, 42n);
+    runAtomic(a, 0, 13n, "exchange", [42n], 13n, 42n);
+    runAtomic(a, 0, 13n, "load", [], 13n, 13n);
+    runAtomic(a, 0, 13n, "or", [42n], 13n, 47n);
+    runAtomic(a, 0, 13n, "store", [42n], 42n, 42n);
+    runAtomic(a, 0, 42n, "sub", [13n], 42n, 29n);
+    runAtomic(a, 0, 13n, "xor", [42n], 13n, 39n);
+}
+
+bi64a[0] = 0n;
+var result = Atomics.wait(bi64a, 0, 1n);
+if (result != "not-equal")
+    throw "Error: bad result from Atomics.wait: " + result;
+for (timeout of [0, 1, 10]) {
+    var result = Atomics.wait(bi64a, 0, 0n, timeout);
+    if (result != "timed-out")
+        throw "Error: bad result from Atomics.wait: " + result;
+}

Modified: trunk/JSTests/test262/config.yaml (272340 => 272341)


--- trunk/JSTests/test262/config.yaml	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/JSTests/test262/config.yaml	2021-02-03 23:07:41 UTC (rev 272341)
@@ -28,19 +28,6 @@
     - top-level-await
     - Intl.ListFormat
   paths:
-    - test/built-ins/Atomics/add/bigint
-    - test/built-ins/Atomics/and/bigint
-    - test/built-ins/Atomics/compareExchange/bigint
-    - test/built-ins/Atomics/exchange/bigint
-    - test/built-ins/Atomics/isLockFree/bigint
-    - test/built-ins/Atomics/load/bigint
-    - test/built-ins/Atomics/notify/bigint
-    - test/built-ins/Atomics/or/bigint
-    - test/built-ins/Atomics/store/bigint
-    - test/built-ins/Atomics/sub/bigint
-    - test/built-ins/Atomics/wait/bigint
-    - test/built-ins/Atomics/xor/bigint
-
     # test262 bot is using Catalina's ICU 64, upgrading to Big Sur is required
     # https://bugs.webkit.org/show_bug.cgi?id=218844
     - test/intl402/DateTimeFormat/prototype/formatRangeToParts

Modified: trunk/Source/_javascript_Core/ChangeLog (272340 => 272341)


--- trunk/Source/_javascript_Core/ChangeLog	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-02-03 23:07:41 UTC (rev 272341)
@@ -1,3 +1,30 @@
+2021-02-01  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Atomics should support BigInt64Array / BigUint64Array
+        https://bugs.webkit.org/show_bug.cgi?id=221245
+
+        Reviewed by Keith Miller.
+
+        This patch adds BigInt64Array / BigUint64Array support for Atomics.
+
+        1. Atomics.store should be rewritten since it returns non-type-coerced result, so we cannot use atomicReadModifyWrite.
+           The spec also describes Atomics.store without using AtomicReadModifyWrite[1].
+        2. Extend Atomics.isLockFree to also accept a size of 8.
+        3. Currently, DFG / FTL handle Atomics + BigInt64Array/BigUint64Array as Array::Generic.
+
+        [1]: https://tc39.es/ecma262/#sec-atomics.store
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileAtomicsIsLockFree):
+        * runtime/AtomicsObject.cpp:
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        (JSC::atomicsWaitImpl):
+        (JSC::JSC_DEFINE_JIT_OPERATION):
+        * runtime/ToNativeFromValue.h:
+        (JSC::toNativeFromValue):
+
 2021-02-03  Yusuke Suzuki  <[email protected]>
 
         [AppleWin 32bit][LLInt] LLIntData.h(104) : warning C4172: returning address of local variable or temporary: id

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (272340 => 272341)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2021-02-03 23:07:41 UTC (rev 272341)
@@ -3455,6 +3455,7 @@
         GPRReg resultGPR = result.gpr();
         m_jit.move(TrustedImm32(JSValue::ValueTrue), resultGPR);
         JITCompiler::JumpList done;
+        done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(8)));
         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(4)));
         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(1)));
         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(2)));

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (272340 => 272341)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-02-03 23:07:41 UTC (rev 272341)
@@ -4295,10 +4295,11 @@
         
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(trueCase);
         
-        Vector<SwitchCase> cases;
+        Vector<SwitchCase, 4> cases;
         cases.append(SwitchCase(m_out.constInt32(1), trueCase, Weight()));
         cases.append(SwitchCase(m_out.constInt32(2), trueCase, Weight()));
         cases.append(SwitchCase(m_out.constInt32(4), trueCase, Weight()));
+        cases.append(SwitchCase(m_out.constInt32(8), trueCase, Weight()));
         m_out.switchInstruction(bytes, cases, falseCase, Weight());
         
         m_out.appendTo(trueCase, falseCase);

Modified: trunk/Source/_javascript_Core/runtime/AtomicsObject.cpp (272340 => 272341)


--- trunk/Source/_javascript_Core/runtime/AtomicsObject.cpp	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/Source/_javascript_Core/runtime/AtomicsObject.cpp	2021-02-03 23:07:41 UTC (rev 272341)
@@ -90,14 +90,16 @@
 namespace {
 
 template<typename Adaptor, typename Func>
-EncodedJSValue atomicReadModifyWriteCase(JSGlobalObject* globalObject, const JSValue* args, ThrowScope& scope, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func)
+EncodedJSValue atomicReadModifyWriteCase(JSGlobalObject* globalObject, VM& vm, const JSValue* args, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func)
 {
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
     JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView);
     
-    double extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS.
+    typename Adaptor::Type extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS.
     for (unsigned i = 0; i < Func::numExtraArgs; ++i) {
-        double value = args[2 + i].toIntegerOrInfinity(globalObject);
-        RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+        auto value = toNativeFromValue<Adaptor>(globalObject, args[2 + i]);
+        RETURN_IF_EXCEPTION(scope, { });
         extraArgs[i] = value;
     }
 
@@ -104,10 +106,11 @@
     if (typedArray->isDetached())
         return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage);
 
-    return JSValue::encode(func(typedArray->typedVector() + accessIndex, extraArgs));
+    auto result = func(typedArray->typedVector() + accessIndex, extraArgs);
+    RELEASE_AND_RETURN(scope, JSValue::encode(Adaptor::toJSValue(globalObject, result)));
 }
 
-static unsigned validateAtomicAccess(VM& vm, JSGlobalObject* globalObject, JSArrayBufferView* typedArrayView, JSValue accessIndexValue)
+static unsigned validateAtomicAccess(JSGlobalObject* globalObject, VM& vm, JSArrayBufferView* typedArrayView, JSValue accessIndexValue)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     unsigned accessIndex = 0;
@@ -127,7 +130,7 @@
     return accessIndex;
 }
 
-enum class TypedArrayOperationMode { Read, Write };
+enum class TypedArrayOperationMode { ReadWrite, Wait };
 template<TypedArrayOperationMode mode>
 inline JSArrayBufferView* validateIntegerTypedArray(JSGlobalObject* globalObject, JSValue typedArrayValue)
 {
@@ -137,12 +140,13 @@
     JSArrayBufferView* typedArray = validateTypedArray(globalObject, typedArrayValue);
     RETURN_IF_EXCEPTION(scope, { });
 
-    if constexpr (mode == TypedArrayOperationMode::Write) {
+    if constexpr (mode == TypedArrayOperationMode::Wait) {
         switch (typedArray->type()) {
         case Int32ArrayType:
+        case BigInt64ArrayType:
             break;
         default:
-            throwTypeError(globalObject, scope, "Typed array argument must be an Int32Array."_s);
+            throwTypeError(globalObject, scope, "Typed array argument must be an Int32Array or BigInt64Array."_s);
             return { };
         }
     } else {
@@ -153,9 +157,11 @@
         case Uint8ArrayType:
         case Uint16ArrayType:
         case Uint32ArrayType:
+        case BigInt64ArrayType:
+        case BigUint64ArrayType:
             break;
         default:
-            throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, or Uint32Array."_s);
+            throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, BigInt64Array, or BigUint64Array."_s);
             return { };
         }
     }
@@ -163,29 +169,34 @@
 }
 
 template<typename Func>
-EncodedJSValue atomicReadModifyWrite(VM& vm, JSGlobalObject* globalObject, const JSValue* args, const Func& func)
+EncodedJSValue atomicReadModifyWrite(JSGlobalObject* globalObject, VM& vm, const JSValue* args, const Func& func)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Read>(globalObject, args[0]);
+    JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::ReadWrite>(globalObject, args[0]);
     RETURN_IF_EXCEPTION(scope, { });
 
-    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArrayView, args[1]);
+    unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, args[1]);
     RETURN_IF_EXCEPTION(scope, { });
 
+    scope.release();
     switch (typedArrayView->type()) {
     case Int8ArrayType:
-        return atomicReadModifyWriteCase<Int8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Int8Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     case Int16ArrayType:
-        return atomicReadModifyWriteCase<Int16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Int16Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     case Int32ArrayType:
-        return atomicReadModifyWriteCase<Int32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Int32Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     case Uint8ArrayType:
-        return atomicReadModifyWriteCase<Uint8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Uint8Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     case Uint16ArrayType:
-        return atomicReadModifyWriteCase<Uint16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Uint16Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     case Uint32ArrayType:
-        return atomicReadModifyWriteCase<Uint32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
+        return atomicReadModifyWriteCase<Uint32Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
+    case BigInt64ArrayType:
+        return atomicReadModifyWriteCase<BigInt64Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
+    case BigUint64ArrayType:
+        return atomicReadModifyWriteCase<BigUint64Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func);
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return JSValue::encode(jsUndefined());
@@ -198,7 +209,7 @@
     JSValue args[2 + Func::numExtraArgs];
     for (unsigned i = 2 + Func::numExtraArgs; i--;)
         args[i] = callFrame->argument(i);
-    return atomicReadModifyWrite(globalObject->vm(), globalObject, args, func);
+    return atomicReadModifyWrite(globalObject, globalObject->vm(), args, func);
 }
 
 struct AddFunc {
@@ -205,9 +216,9 @@
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchangeAdd(ptr, toInt32(args[0])));
+        return WTF::atomicExchangeAdd(ptr, args[0]);
     }
 };
 
@@ -215,9 +226,9 @@
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchangeAnd(ptr, toInt32(args[0])));
+        return WTF::atomicExchangeAnd(ptr, args[0]);
     }
 };
 
@@ -225,11 +236,11 @@
     static constexpr unsigned numExtraArgs = 2;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        T expected = static_cast<T>(toInt32(args[0]));
-        T newValue = static_cast<T>(toInt32(args[1]));
-        return jsNumber(WTF::atomicCompareExchangeStrong(ptr, expected, newValue));
+        T expected = args[0];
+        T newValue = args[1];
+        return WTF::atomicCompareExchangeStrong(ptr, expected, newValue);
     }
 };
 
@@ -237,9 +248,9 @@
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchange(ptr, static_cast<T>(toInt32(args[0]))));
+        return WTF::atomicExchange(ptr, args[0]);
     }
 };
 
@@ -247,9 +258,9 @@
     static constexpr unsigned numExtraArgs = 0;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double*) const
+    T operator()(T* ptr, const T*) const
     {
-        return jsNumber(WTF::atomicLoadFullyFenced(ptr));
+        return WTF::atomicLoadFullyFenced(ptr);
     }
 };
 
@@ -257,32 +268,19 @@
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchangeOr(ptr, toInt32(args[0])));
+        return WTF::atomicExchangeOr(ptr, args[0]);
     }
 };
 
-struct StoreFunc {
-    static constexpr unsigned numExtraArgs = 1;
-    
-    template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
-    {
-        double valueAsInt = args[0];
-        T valueAsT = static_cast<T>(toInt32(valueAsInt));
-        WTF::atomicStoreFullyFenced(ptr, valueAsT);
-        return jsNumber(valueAsInt);
-    }
-};
-
 struct SubFunc {
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchangeSub(ptr, toInt32(args[0])));
+        return WTF::atomicExchangeSub(ptr, args[0]);
     }
 };
 
@@ -290,9 +288,9 @@
     static constexpr unsigned numExtraArgs = 1;
     
     template<typename T>
-    JSValue operator()(T* ptr, const double* args) const
+    T operator()(T* ptr, const T* args) const
     {
-        return jsNumber(WTF::atomicExchangeXor(ptr, toInt32(args[0])));
+        return WTF::atomicExchangeXor(ptr, args[0]);
     }
 };
 
@@ -309,6 +307,7 @@
     case 1:
     case 2:
     case 4:
+    case 8:
         result = true;
         break;
     default:
@@ -318,6 +317,70 @@
     return JSValue::encode(jsBoolean(result));
 }
 
+template<typename Adaptor>
+EncodedJSValue atomicStoreCase(JSGlobalObject* globalObject, VM& vm, JSValue operand, JSArrayBufferView* typedArrayView, unsigned accessIndex)
+{
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView);
+
+    typename Adaptor::Type extraArg;
+    JSValue value;
+    if constexpr (std::is_same_v<Adaptor, BigInt64Adaptor> || std::is_same_v<Adaptor, BigUint64Adaptor>) {
+        value = operand.toBigInt(globalObject);
+        RETURN_IF_EXCEPTION(scope, { });
+        extraArg = toNativeFromValue<Adaptor>(globalObject, value);
+        RETURN_IF_EXCEPTION(scope, { });
+    } else {
+        value = jsNumber(operand.toIntegerOrInfinity(globalObject));
+        RETURN_IF_EXCEPTION(scope, { });
+        extraArg = toNativeFromValue<Adaptor>(globalObject, value);
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    if (typedArray->isDetached())
+        return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage);
+
+    WTF::atomicStoreFullyFenced(typedArray->typedVector() + accessIndex, extraArg);
+    RELEASE_AND_RETURN(scope, JSValue::encode(value));
+}
+
+EncodedJSValue atomicStore(JSGlobalObject* globalObject, VM& vm, JSValue base, JSValue index, JSValue operand)
+{
+    // https://tc39.es/ecma262/#sec-atomics.store
+
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::ReadWrite>(globalObject, base);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, index);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    scope.release();
+    switch (typedArrayView->type()) {
+    case Int8ArrayType:
+        return atomicStoreCase<Int8Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case Int16ArrayType:
+        return atomicStoreCase<Int16Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case Int32ArrayType:
+        return atomicStoreCase<Int32Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case Uint8ArrayType:
+        return atomicStoreCase<Uint8Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case Uint16ArrayType:
+        return atomicStoreCase<Uint16Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case Uint32ArrayType:
+        return atomicStoreCase<Uint32Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case BigInt64ArrayType:
+        return atomicStoreCase<BigInt64Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    case BigUint64ArrayType:
+        return atomicStoreCase<BigUint64Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex);
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return { };
+    }
+}
+
 } // anonymous namespace
 
 JSC_DEFINE_HOST_FUNCTION(atomicsFuncAdd, (JSGlobalObject* globalObject, CallFrame* callFrame))
@@ -357,7 +420,7 @@
 
 JSC_DEFINE_HOST_FUNCTION(atomicsFuncStore, (JSGlobalObject* globalObject, CallFrame* callFrame))
 {
-    return atomicReadModifyWrite(globalObject, callFrame, StoreFunc());
+    return atomicStore(globalObject, globalObject->vm(), callFrame->argument(0), callFrame->argument(1), callFrame->argument(2));
 }
 
 JSC_DEFINE_HOST_FUNCTION(atomicsFuncSub, (JSGlobalObject* globalObject, CallFrame* callFrame))
@@ -365,30 +428,16 @@
     return atomicReadModifyWrite(globalObject, callFrame, SubFunc());
 }
 
-JSC_DEFINE_HOST_FUNCTION(atomicsFuncWait, (JSGlobalObject* globalObject, CallFrame* callFrame))
+template<typename ValueType, typename JSArrayType>
+JSValue atomicsWaitImpl(JSGlobalObject* globalObject, JSArrayType* typedArray, unsigned accessIndex, ValueType expectedValue, JSValue timeoutValue)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0));
-    RETURN_IF_EXCEPTION(scope, { });
-    auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer);
+    ValueType* ptr = typedArray->typedVector() + accessIndex;
 
-    if (!typedArray->isShared()) {
-        throwTypeError(globalObject, scope, "Typed array for wait/notify must wrap a SharedArrayBuffer."_s);
-        return JSValue::encode(jsUndefined());
-    }
-
-    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1));
+    double timeoutInMilliseconds = timeoutValue.toNumber(globalObject);
     RETURN_IF_EXCEPTION(scope, { });
-
-    int32_t* ptr = typedArray->typedVector() + accessIndex;
-
-    int32_t expectedValue = callFrame->argument(2).toInt32(globalObject);
-    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
-
-    double timeoutInMilliseconds = callFrame->argument(3).toNumber(globalObject);
-    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
     Seconds timeout = Seconds::infinity();
     if (!std::isnan(timeoutInMilliseconds))
         timeout = std::max(Seconds::fromMilliseconds(timeoutInMilliseconds), 0_s);
@@ -395,7 +444,7 @@
 
     if (!vm.m_typedArrayController->isAtomicsWaitAllowedOnCurrentThread()) {
         throwTypeError(globalObject, scope, "Atomics.wait cannot be called from the current thread."_s);
-        return JSValue::encode(jsUndefined());
+        return { };
     }
 
     bool didPassValidation = false;
@@ -412,22 +461,53 @@
             MonotonicTime::now() + timeout);
     }
     if (!didPassValidation)
-        return JSValue::encode(vm.smallStrings.notEqualString());
+        return vm.smallStrings.notEqualString();
     if (!result.wasUnparked)
-        return JSValue::encode(vm.smallStrings.timedOutString());
-    return JSValue::encode(vm.smallStrings.okString());
+        return vm.smallStrings.timedOutString();
+    return vm.smallStrings.okString();
 }
 
+JSC_DEFINE_HOST_FUNCTION(atomicsFuncWait, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Wait>(globalObject, callFrame->argument(0));
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (!typedArrayView->isShared())
+        return throwVMTypeError(globalObject, scope, "Typed array for wait/notify must wrap a SharedArrayBuffer."_s);
+
+    unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, callFrame->argument(1));
+    RETURN_IF_EXCEPTION(scope, { });
+
+    switch (typedArrayView->type()) {
+    case Int32ArrayType: {
+        int32_t expectedValue = callFrame->argument(2).toInt32(globalObject);
+        RETURN_IF_EXCEPTION(scope, { });
+        RELEASE_AND_RETURN(scope, JSValue::encode(atomicsWaitImpl<int32_t>(globalObject, jsCast<JSInt32Array*>(typedArrayView), accessIndex, expectedValue, callFrame->argument(3))));
+    }
+    case BigInt64ArrayType: {
+        int64_t expectedValue = callFrame->argument(2).toBigInt64(globalObject);
+        RETURN_IF_EXCEPTION(scope, { });
+        RELEASE_AND_RETURN(scope, JSValue::encode(atomicsWaitImpl<int64_t>(globalObject, jsCast<JSBigInt64Array*>(typedArrayView), accessIndex, expectedValue, callFrame->argument(3))));
+    }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+    return { };
+}
+
 JSC_DEFINE_HOST_FUNCTION(atomicsFuncNotify, (JSGlobalObject* globalObject, CallFrame* callFrame))
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0));
+    auto* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Wait>(globalObject, callFrame->argument(0));
     RETURN_IF_EXCEPTION(scope, { });
-    auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer);
 
-    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1));
+    unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, callFrame->argument(1));
     RETURN_IF_EXCEPTION(scope, { });
 
     JSValue countValue = callFrame->argument(2);
@@ -440,11 +520,23 @@
             count = static_cast<unsigned>(countDouble);
     }
 
-    if (!typedArray->isShared())
+    if (!typedArrayView->isShared())
         return JSValue::encode(jsNumber(0));
 
-    int32_t* ptr = typedArray->typedVector() + accessIndex;
-    return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count)));
+    switch (typedArrayView->type()) {
+    case Int32ArrayType: {
+        int32_t* ptr = jsCast<JSInt32Array*>(typedArrayView)->typedVector() + accessIndex;
+        return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count)));
+    }
+    case BigInt64ArrayType: {
+        int64_t* ptr = jsCast<JSBigInt64Array*>(typedArrayView)->typedVector() + accessIndex;
+        return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count)));
+    }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+    return { };
 }
 
 JSC_DEFINE_HOST_FUNCTION(atomicsFuncXor, (JSGlobalObject* globalObject, CallFrame* callFrame))
@@ -460,7 +552,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, AddFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, AddFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsAnd, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -469,7 +561,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, AndFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, AndFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsCompareExchange, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue expected, EncodedJSValue newValue))
@@ -478,7 +570,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(expected), JSValue::decode(newValue)};
-    return atomicReadModifyWrite(vm, globalObject, args, CompareExchangeFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, CompareExchangeFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsExchange, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -487,7 +579,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, ExchangeFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, ExchangeFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsIsLockFree, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue size))
@@ -504,7 +596,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index)};
-    return atomicReadModifyWrite(vm, globalObject, args, LoadFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, LoadFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsOr, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -513,7 +605,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, OrFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, OrFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsStore, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -521,8 +613,7 @@
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
-    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, StoreFunc());
+    return atomicStore(globalObject, vm, JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand));
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsSub, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -531,7 +622,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, SubFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, SubFunc());
 }
 
 JSC_DEFINE_JIT_OPERATION(operationAtomicsXor, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))
@@ -540,7 +631,7 @@
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
-    return atomicReadModifyWrite(vm, globalObject, args, XorFunc());
+    return atomicReadModifyWrite(globalObject, vm, args, XorFunc());
 }
 
 IGNORE_WARNINGS_END

Modified: trunk/Source/_javascript_Core/runtime/ToNativeFromValue.h (272340 => 272341)


--- trunk/Source/_javascript_Core/runtime/ToNativeFromValue.h	2021-02-03 22:46:37 UTC (rev 272340)
+++ trunk/Source/_javascript_Core/runtime/ToNativeFromValue.h	2021-02-03 23:07:41 UTC (rev 272341)
@@ -33,7 +33,7 @@
 template<typename Adaptor>
 typename Adaptor::Type toNativeFromValue(JSValue value)
 {
-    // FIXME: BigInt
+    ASSERT(!value.isBigInt());
     if (value.isInt32())
         return Adaptor::toNativeFromInt32(value.asInt32());
     return Adaptor::toNativeFromDouble(value.asDouble());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to