Changeset 269531 in webkit


Ignore:
Timestamp:
Nov 6, 2020 12:23:25 PM (21 months ago)
Author:
ysuzuki@apple.com
Message:

Re-enable SharedArrayBuffer for JSC shell and Testers
https://bugs.webkit.org/show_bug.cgi?id=212069

Reviewed by Keith Miller.

JSTests:

Update tests to align to the latest spec.

  • stress/SharedArrayBuffer-opt.js:

(shouldSucceed):
(idx.of.string_appeared_here.a.of.arrays.m.of.atomics):
(string_appeared_here.a.of.arrays.m.of.atomics): Deleted.

  • stress/SharedArrayBuffer.js:

(shouldSucceed):
(Symbol):

  • stress/array-buffer-byte-length.js:

(shouldThrow):
(Symbol):

  • stress/atomics-add-uint32.js:
  • stress/atomics-known-int-use.js:
  • stress/atomics-neg-zero.js:
  • stress/atomics-store-return.js:
  • stress/lars-sab-workers.js:

(resources):
(notify):
(wake): Deleted.

  • stress/regress-170473.js:
  • stress/regress-189317.js:
  • stress/shared-array-buffer-sort-while-different-thread-is-modifying.js: Added.

(262.agent.waitUntil):
(262.agent.start.262.agent.receiveBroadcast):

  • test262/config.yaml:
  • test262/expectations.yaml:

LayoutTests/imported/w3c:

  • web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any-expected.txt:
  • web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any.serviceworker-expected.txt:
  • web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt:
  • web-platform-tests/workers/postMessage_block.https-expected.txt:

Source/JavaScriptCore:

This patch revives SharedArrayBuffer and Atomics and aligning them to the latest spec.

  1. SharedArrayBuffer's sort should be done in JS side. C++ sort is not safe for SharedArrayBuffer since the buffer can be modified by different threads while sorting.
  2. Atomics.wait should be renamed to Atomics.notify.
  3. Atomics operation should be VarArgs in DFG because DFGSSALoweringPhase assumes that they are VarArgs and they can have another arg for CheckInBounds dependency.
  4. For test262, JSC shell should support "--can-block-is-false" flag. If it is true, the main thread's CanBlock? becomes false. This means that Atomics.wait cannot be used.
  • builtins/BuiltinNames.h:
  • builtins/TypedArrayPrototype.js:

(sort):

  • bytecode/LinkTimeConstant.h:
  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsicCall):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNode.h:

(JSC::DFG::Node::mustGenerate const):
(JSC::DFG::Node::hasVarArgs const):
(JSC::DFG::Node::mustGenerate): Deleted.

  • dfg/DFGNodeType.h:
  • dfg/DFGSSALoweringPhase.cpp:

(JSC::DFG::SSALoweringPhase::handleNode):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileAtomicsIsLockFree):

  • jsc.cpp:

(printUsageStatement):
(CommandLine::parseArguments):
(runJSC):

  • runtime/AtomicsObject.cpp:

(JSC::AtomicsObject::finishCreation):
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSC_DEFINE_JIT_OPERATION):

  • runtime/CommonIdentifiers.h:
  • runtime/Intrinsic.cpp:

(JSC::intrinsicName):

  • runtime/Intrinsic.h:
  • runtime/JSArrayBufferPrototype.cpp:

(JSC::arrayBufferSlice):
(JSC::arrayBufferByteLength):
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSArrayBufferPrototype::finishCreation):

  • runtime/JSCJSValue.h:
  • runtime/JSCJSValueInlines.h:

(JSC::JSValue::toIntegerOrInfinity const):

  • runtime/JSGenericTypedArrayViewPrototypeFunctions.h:

(JSC::genericTypedArrayViewProtoFuncReverse):
(JSC::genericTypedArrayViewPrivateFuncSort):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSTypedArrayViewPrototype.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/JSTypedArrayViewPrototype.h:
  • runtime/OptionsList.h:
  • runtime/SimpleTypedArrayController.cpp:

(JSC::SimpleTypedArrayController::SimpleTypedArrayController):
(JSC::SimpleTypedArrayController::isAtomicsWaitAllowedOnCurrentThread):

  • runtime/SimpleTypedArrayController.h:
  • runtime/SmallStrings.cpp:

(JSC::SmallStrings::initializeCommonStrings):
(JSC::SmallStrings::visitStrongReferences):

  • runtime/SmallStrings.h:

(JSC::SmallStrings::notEqualString const):
(JSC::SmallStrings::timedOutString const):
(JSC::SmallStrings::okString const):

Source/WTF:

  • wtf/PlatformEnable.h:

Tools:

  • Scripts/test262/Runner.pm:

(getFeatureFlags):

  • Scripts/webkitpy/layout_tests/run_webkit_tests.py:

(main):

LayoutTests:

  • webaudio/dom-exceptions-expected.txt:
Location:
trunk
Files:
1 added
57 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r269502 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        Update tests to align to the latest spec.
     9
     10        * stress/SharedArrayBuffer-opt.js:
     11        (shouldSucceed):
     12        (idx.of.string_appeared_here.a.of.arrays.m.of.atomics):
     13        (string_appeared_here.a.of.arrays.m.of.atomics): Deleted.
     14        * stress/SharedArrayBuffer.js:
     15        (shouldSucceed):
     16        (Symbol):
     17        * stress/array-buffer-byte-length.js:
     18        (shouldThrow):
     19        (Symbol):
     20        * stress/atomics-add-uint32.js:
     21        * stress/atomics-known-int-use.js:
     22        * stress/atomics-neg-zero.js:
     23        * stress/atomics-store-return.js:
     24        * stress/lars-sab-workers.js:
     25        (resources):
     26        (notify):
     27        (wake): Deleted.
     28        * stress/regress-170473.js:
     29        * stress/regress-189317.js:
     30        * stress/shared-array-buffer-sort-while-different-thread-is-modifying.js: Added.
     31        (262.agent.waitUntil):
     32        (262.agent.start.262.agent.receiveBroadcast):
     33        * test262/config.yaml:
     34        * test262/expectations.yaml:
     35
    1362020-11-05  Yusuke Suzuki  <ysuzuki@apple.com>
    237
  • trunk/JSTests/stress/SharedArrayBuffer-opt.js

    r226386 r269531  
    1 //@ skip
    21var dv = new DataView(new SharedArrayBuffer(128));
    32var i8a = new Int8Array(new SharedArrayBuffer(128));
     
    105104}
    106105
     106function shouldSucceed(f)
     107{
     108    f();
     109}
     110
    107111for (var bad of [void 0, null, false, true, 1, 0.5, Symbol(), {}, "hello", dv, u8ca, f32a, f64a]) {
    108112    shouldFail(() => genericAtomics.get("add")(bad, 0, 0), TypeError);
     
    117121}
    118122
    119 for (var idx of [-1, -1000000000000, 10000, 10000000000000, "hello"]) {
     123for (var idx of [-1, -1000000000000, 10000000000000, 10000]) {
    120124    for (var a of arrays) {
    121125        for (var m of [atomics.get(a), genericAtomics]) {
     
    133137}
    134138
     139for (var idx of ["hello"]) {
     140    for (var a of arrays) {
     141        for (var m of [atomics.get(a), genericAtomics]) {
     142            shouldSucceed(() => m.get("add")(a, idx, 0));
     143            shouldSucceed(() => m.get("and")(a, idx, 0));
     144            shouldSucceed(() => m.get("compareExchange")(a, idx, 0, 0));
     145            shouldSucceed(() => m.get("exchange")(a, idx, 0));
     146            shouldSucceed(() => m.get("load")(a, idx));
     147            shouldSucceed(() => m.get("or")(a, idx, 0));
     148            shouldSucceed(() => m.get("store")(a, idx, 0));
     149            shouldSucceed(() => m.get("sub")(a, idx, 0));
     150            shouldSucceed(() => m.get("xor")(a, idx, 0));
     151        }
     152    }
     153}
     154
  • trunk/JSTests/stress/SharedArrayBuffer.js

    r226386 r269531  
    1 //@ skip
    21// This is a basic test of SharedArrayBuffer API as we understand it.
    32
     
    3635checkAtomics("isLockFree", 1);
    3736checkAtomics("load", 2);
     37checkAtomics("notify", 3);
    3838checkAtomics("or", 3);
    3939checkAtomics("store", 3);
    4040checkAtomics("sub", 3);
    4141checkAtomics("wait", 4);
    42 checkAtomics("wake", 3);
    4342checkAtomics("xor", 3);
    4443
     
    6766}
    6867
     68function shouldSucceed(f)
     69{
     70    f();
     71}
     72
    6973for (bad of [void 0, null, false, true, 1, 0.5, Symbol(), {}, "hello", dv, u8ca, f32a, f64a]) {
    7074    shouldFail(() => Atomics.add(bad, 0, 0), TypeError);
     
    8084
    8185for (bad of [void 0, null, false, true, 1, 0.5, Symbol(), {}, "hello", dv, i8a, i16a, u8a, u8ca, u16a, u32a, f32a, f64a]) {
     86    shouldFail(() => Atomics.notify(bad, 0, 0), TypeError);
    8287    shouldFail(() => Atomics.wait(bad, 0, 0), TypeError);
    83     shouldFail(() => Atomics.wake(bad, 0, 0), TypeError);
    8488}
    8589
    86 for (idx of [-1, -1000000000000, 10000, 10000000000000, "hello"]) {
     90for (idx of [-1, -1000000000000, 10000, 10000000000000]) {
    8791    for (a of [i8a, i16a, i32a, u8a, u16a, u32a]) {
    8892        shouldFail(() => Atomics.add(a, idx, 0), RangeError);
     
    96100        shouldFail(() => Atomics.xor(a, idx, 0), RangeError);
    97101    }
     102    shouldFail(() => Atomics.notify(i32a, idx, 0), RangeError);
    98103    shouldFail(() => Atomics.wait(i32a, idx, 0), RangeError);
    99     shouldFail(() => Atomics.wake(i32a, idx, 0), RangeError);
     104}
     105
     106for (idx of ["hello"]) {
     107    for (a of [i8a, i16a, i32a, u8a, u16a, u32a]) {
     108        shouldSucceed(() => Atomics.add(a, idx, 0));
     109        shouldSucceed(() => Atomics.and(a, idx, 0));
     110        shouldSucceed(() => Atomics.compareExchange(a, idx, 0, 0));
     111        shouldSucceed(() => Atomics.exchange(a, idx, 0));
     112        shouldSucceed(() => Atomics.load(a, idx));
     113        shouldSucceed(() => Atomics.or(a, idx, 0));
     114        shouldSucceed(() => Atomics.store(a, idx, 0));
     115        shouldSucceed(() => Atomics.sub(a, idx, 0));
     116        shouldSucceed(() => Atomics.xor(a, idx, 0));
     117    }
     118    shouldSucceed(() => Atomics.notify(i32a, idx, 0));
     119    shouldSucceed(() => Atomics.wait(i32a, idx, 0, 1));
    100120}
    101121
  • trunk/JSTests/stress/array-buffer-byte-length.js

    r226386 r269531  
    1 //@ skip
    21function shouldBe(actual, expected)
    32{
     
    4342    shouldThrow(() => {
    4443        Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get.call(sharedArrayBuffer);
    45     }, `TypeError: Receiver should not be a shared array buffer`);
     44    }, `TypeError: Receiver must be ArrayBuffer`);
    4645
    4746    shouldThrow(() => {
    4847        Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, 'byteLength').get.call(arrayBuffer);
    49     }, `TypeError: Receiver should be a shared array buffer`);
     48    }, `TypeError: Receiver must be SharedArrayBuffer`);
    5049
    5150    for (let value of [ 0, true, "Cocoa", null, undefined, Symbol("Cappuccino") ]) {
    5251        shouldThrow(() => {
    5352            Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get.call(value);
    54         }, `TypeError: Receiver should be an array buffer but was not an object`);
     53        }, `TypeError: Receiver must be ArrayBuffer`);
    5554        shouldThrow(() => {
    5655            Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, 'byteLength').get.call(value);
    57         }, `TypeError: Receiver should be an array buffer but was not an object`);
     56        }, `TypeError: Receiver must be SharedArrayBuffer`);
    5857    }
    5958
    6059    shouldThrow(() => {
    6160        Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get.call({});
    62     }, `TypeError: Receiver should be an array buffer`);
     61    }, `TypeError: Receiver must be ArrayBuffer`);
    6362    shouldThrow(() => {
    6463        Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, 'byteLength').get.call({});
    65     }, `TypeError: Receiver should be an array buffer`);
     64    }, `TypeError: Receiver must be SharedArrayBuffer`);
    6665}
  • trunk/JSTests/stress/atomics-add-uint32.js

    r226386 r269531  
    1 //@ skip
    21var sab = new SharedArrayBuffer(4);
    32var a = new Uint32Array(sab);
  • trunk/JSTests/stress/atomics-known-int-use.js

    r226386 r269531  
    1 //@ skip
    21// Break type inference.
    32var o = {f: 42.5};
  • trunk/JSTests/stress/atomics-neg-zero.js

    r226386 r269531  
    1 //@ skip
    21var sab = new SharedArrayBuffer(4);
    32var a = new Int32Array(sab);
  • trunk/JSTests/stress/atomics-store-return.js

    r226386 r269531  
    1 //@ skip
    21var sab = new SharedArrayBuffer(1);
    32var a = new Int8Array(sab);
  • trunk/JSTests/stress/lars-sab-workers.js

    r226386 r269531  
    1 //@ skip
    2 
    31var sab = new SharedArrayBuffer(100 * 4);
    42
     
    1513
    1614resources = `
    17 function wait(memory, index, waitCondition, wakeCondition)
     15function wait(memory, index, waitCondition, notifyCondition)
    1816{
    1917    while (memory[index] == waitCondition) {
     
    2927        }
    3028        var value = memory[index];
    31         if (value != wakeCondition) {
     29        if (value != notifyCondition) {
    3230            $.agent.report("Error: wait returned not-equal but the memory has a bad value: " + value);
    3331            $.agent.report("error");
     
    3533    }
    3634    var value = memory[index];
    37     if (value != wakeCondition) {
     35    if (value != notifyCondition) {
    3836        $.agent.report("Error: done waiting but the memory has a bad value: " + value);
    3937        $.agent.report("error");
     
    4139}
    4240
    43 function wake(memory, index)
     41function notify(memory, index)
    4442{
    45     var result = Atomics.wake(memory, index, 1);
     43    var result = Atomics.notify(memory, index, 1);
    4644    if (result != 0 && result != 1) {
    47         $.agent.report("Error: bad result from wake: " + result);
     45        $.agent.report("Error: bad result from notify: " + result);
    4846        $.agent.report("error");
    4947    }
     
    6765       
    6866        memory[shouldGoIdx] = 1;
    69         wake(memory, shouldGoIdx);
     67        notify(memory, shouldGoIdx);
    7068       
    7169        wait(memory, didEndIdx, 0, 1);
     
    8987       
    9088        Atomics.store(memory, didStartIdx, 1);
    91         wake(memory, didStartIdx);
     89        notify(memory, didStartIdx);
    9290       
    9391        wait(memory, shouldGoIdx, 0, 1);
    9492       
    9593        Atomics.store(memory, didEndIdx, 1);
    96         wake(memory, didEndIdx, 1);
     94        notify(memory, didEndIdx, 1);
    9795       
    9896        $.agent.report("2: Memory: " + memory);
  • trunk/JSTests/stress/regress-170473.js

    r226386 r269531  
    1 //@ skip
    21var heap = new SharedArrayBuffer(4096);
    32var Uint8ArrayView = new Uint8Array(heap);
  • trunk/JSTests/stress/regress-189317.js

    r235827 r269531  
    9393        "Atomics.sub",
    9494        "Atomics.wait",
    95         "Atomics.wake",
     95        "Atomics.notify",
    9696        "Atomics.xor",
    9797    ]);
  • trunk/JSTests/test262/config.yaml

    r268760 r269531  
    77  class-fields-private: usePrivateClassFields
    88  Intl.DateTimeFormat-dayPeriod: useIntlDateTimeFormatDayPeriod
     9  SharedArrayBuffer: useSharedArrayBuffer
     10  Atomics: useSharedArrayBuffer
    911skip:
    1012  features:
    11     - SharedArrayBuffer
    12     - Atomics
    1313    - Atomics.waitAsync
    1414    # https://bugs.webkit.org/show_bug.cgi?id=174931
     
    8282    - test/built-ins/TypedArrayConstructors/internals/Set/BigInt
    8383    - test/built-ins/TypedArrayConstructors/of/BigInt
     84
     85    - test/built-ins/Atomics/add/bigint
     86    - test/built-ins/Atomics/and/bigint
     87    - test/built-ins/Atomics/compareExchange/bigint
     88    - test/built-ins/Atomics/exchange/bigint
     89    - test/built-ins/Atomics/isLockFree/bigint
     90    - test/built-ins/Atomics/load/bigint
     91    - test/built-ins/Atomics/notify/bigint
     92    - test/built-ins/Atomics/or/bigint
     93    - test/built-ins/Atomics/store/bigint
     94    - test/built-ins/Atomics/sub/bigint
     95    - test/built-ins/Atomics/wait/bigint
     96    - test/built-ins/Atomics/xor/bigint
    8497
    8598    # requires ICU APIs implementation
  • trunk/JSTests/test262/expectations.yaml

    r268773 r269531  
    848848  default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
    849849  strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
     850test/built-ins/SharedArrayBuffer/prototype/slice/species-constructor-is-not-object.js:
     851  default: 'Test262Error: `constructor` value is null Expected a TypeError to be thrown but no exception was thrown at all'
     852  strict mode: 'Test262Error: `constructor` value is null Expected a TypeError to be thrown but no exception was thrown at all'
     853test/built-ins/SharedArrayBuffer/prototype/slice/species-is-not-constructor.js:
     854  default: 'Test262Error: `constructor[Symbol.species]` value is Object Expected a TypeError to be thrown but no exception was thrown at all'
     855  strict mode: 'Test262Error: `constructor[Symbol.species]` value is Object Expected a TypeError to be thrown but no exception was thrown at all'
     856test/built-ins/SharedArrayBuffer/prototype/slice/species-is-not-object.js:
     857  default: 'Test262Error: `constructor[Symbol.species]` value is Boolean Expected a TypeError to be thrown but no exception was thrown at all'
     858  strict mode: 'Test262Error: `constructor[Symbol.species]` value is Boolean Expected a TypeError to be thrown but no exception was thrown at all'
     859test/built-ins/SharedArrayBuffer/prototype/slice/species-returns-larger-arraybuffer.js:
     860  default: 'Test262Error: Expected SameValue(«8», «10») to be true'
     861  strict mode: 'Test262Error: Expected SameValue(«8», «10») to be true'
     862test/built-ins/SharedArrayBuffer/prototype/slice/species-returns-not-arraybuffer.js:
     863  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     864  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     865test/built-ins/SharedArrayBuffer/prototype/slice/species-returns-same-arraybuffer.js:
     866  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     867  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     868test/built-ins/SharedArrayBuffer/prototype/slice/species-returns-smaller-arraybuffer.js:
     869  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     870  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     871test/built-ins/SharedArrayBuffer/prototype/slice/species.js:
     872  default: 'Test262Error: Expected SameValue(«[object SharedArrayBuffer]», «undefined») to be true'
     873  strict mode: 'Test262Error: Expected SameValue(«[object SharedArrayBuffer]», «undefined») to be true'
    850874test/built-ins/TypedArray/prototype/every/callbackfn-detachbuffer.js:
    851875  default: 'Test262Error: Expected a TypeError but got a Test262Error (Testing with Float64Array.)'
  • trunk/LayoutTests/ChangeLog

    r269525 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        * webaudio/dom-exceptions-expected.txt:
     9
    1102020-11-06  Wenson Hsieh  <wenson_hsieh@apple.com>
    211
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r269500 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        * web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any-expected.txt:
     9        * web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any.serviceworker-expected.txt:
     10        * web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt:
     11        * web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt:
     12        * web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt:
     13        * web-platform-tests/workers/postMessage_block.https-expected.txt:
     14
    1152020-11-05  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any-expected.txt

    r264035 r269531  
    11
    2 FAIL [[CanBlock]] in a Window assert_throws_js: function "() => {
    3     Atomics.wait(ta, 0, 0, 10);
    4   }" threw object "ReferenceError: Can't find variable: Atomics" ("ReferenceError") expected instance of function "function TypeError() {
    5     [native code]
    6 }" ("TypeError")
     2PASS [[CanBlock]] in a Window
    73
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-failure.https.any.serviceworker-expected.txt

    r264035 r269531  
    11
    2 FAIL [[CanBlock]] in a ServiceWorkerGlobalScope assert_throws_js: function "() => {
    3     Atomics.wait(ta, 0, 0, 10);
    4   }" threw object "ReferenceError: Can't find variable: Atomics" ("ReferenceError") expected instance of function "function TypeError() {
    5     [native code]
    6 }" ("TypeError")
     2PASS [[CanBlock]] in a ServiceWorkerGlobalScope
    73
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt

    r264035 r269531  
    11
    2 FAIL [[CanBlock]] in a DedicatedWorkerGlobalScope Can't find variable: Atomics
     2FAIL [[CanBlock]] in a DedicatedWorkerGlobalScope Typed array for wait/notify must wrap a SharedArrayBuffer.
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt

    r267649 r269531  
    2626PASS Non-zero initial
    2727FAIL Stray argument WebAssembly.Memory expects exactly one argument
    28 FAIL Shared memory undefined is not an object (evaluating 'bufferType.prototype')
     28FAIL Shared memory assert_equals: prototype of buffer expected object "[object SharedArrayBuffer]" but got object "[object ArrayBuffer]"
    2929
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt

    r267649 r269531  
    2626PASS Non-zero initial
    2727FAIL Stray argument WebAssembly.Memory expects exactly one argument
    28 FAIL Shared memory undefined is not an object (evaluating 'bufferType.prototype')
     28FAIL Shared memory assert_equals: prototype of buffer expected object "[object SharedArrayBuffer]" but got object "[object ArrayBuffer]"
    2929
  • trunk/LayoutTests/imported/w3c/web-platform-tests/workers/postMessage_block.https-expected.txt

    r264183 r269531  
    11
    2 FAIL postMessage and block Can't find variable: SharedArrayBuffer
     2PASS postMessage and block
    33
  • trunk/LayoutTests/webaudio/dom-exceptions-expected.txt

    r268812 r269531  
    9696PASS   AnalyserNode.getFloatTimeDomainData(null) threw TypeError: "Argument 1 ('array') to AnalyserNode.getFloatTimeDomainData must be an instance of Float32Array".
    9797PASS   AnalyserNode.getByteTimeDomainData(null) threw TypeError: "Argument 1 ('array') to AnalyserNode.getByteTimeDomainData must be an instance of Uint8Array".
     98PASS   AnalyserNode.getFloatFrequencyData(SharedArrayBuffer view) threw TypeError: "Argument 1 ('array') to AnalyserNode.getFloatFrequencyData must be an instance of Float32Array".
     99PASS   AnalyserNode.getByteFrequencyData(SharedArrayBuffer view) threw TypeError: "Argument 1 ('array') to AnalyserNode.getByteFrequencyData must be an instance of Uint8Array".
     100PASS   AnalyserNode.getFloatTimeDomainData(SharedArrayBuffer view) threw TypeError: "Argument 1 ('array') to AnalyserNode.getFloatTimeDomainData must be an instance of Float32Array".
     101PASS   AnalyserNode.getByteTimeDomainData(SharedArrayBuffer view) threw TypeError: "Argument 1 ('array') to AnalyserNode.getByteTimeDomainData must be an instance of Uint8Array".
    98102PASS   AudioBuffer.getChannelData(2) threw IndexSizeError: "Index must be less than number of channels.".
    99 PASS < [createAnalyser] All assertions passed. (total 24 assertions)
     103PASS < [createAnalyser] All assertions passed. (total 28 assertions)
    100104PASS > [Init test nodes] Create test nodes for the following tests
    101105PASS   node = context.createGain() did not throw an exception.
     
    132136PASS   node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1)) threw TypeError: "Argument 2 ('magResponse') to BiquadFilterNode.getFrequencyResponse must be an instance of Float32Array".
    133137PASS   node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null) threw TypeError: "Argument 3 ('phaseResponse') to BiquadFilterNode.getFrequencyResponse must be an instance of Float32Array".
    134 PASS < [biquad] All assertions passed. (total 4 assertions)
     138PASS   node.getFrequencyResponse(shared_view, nonshared_view, nonshared_view) threw TypeError: "Argument 1 ('frequencyHz') to BiquadFilterNode.getFrequencyResponse must be an instance of Float32Array".
     139PASS   node.getFrequencyResponse(nonshared_view, shared_view, nonshared_view) threw TypeError: "Argument 2 ('magResponse') to BiquadFilterNode.getFrequencyResponse must be an instance of Float32Array".
     140PASS   node.getFrequencyResponse(nonshared_view, nonshared_view, shared_view) threw TypeError: "Argument 3 ('phaseResponse') to BiquadFilterNode.getFrequencyResponse must be an instance of Float32Array".
     141PASS < [biquad] All assertions passed. (total 7 assertions)
    135142PASS > [offline-audio-context] supports 32 channels
    136143PASS   new OfflineAudioContext(32, 100, context.sampleRate) did not throw an exception.
  • trunk/Source/JavaScriptCore/ChangeLog

    r269511 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        This patch revives SharedArrayBuffer and Atomics and aligning them to the latest spec.
     9
     10        1. SharedArrayBuffer's sort should be done in JS side. C++ sort is not safe for SharedArrayBuffer since the buffer
     11           can be modified by different threads while sorting.
     12        2. Atomics.wait should be renamed to Atomics.notify.
     13        3. Atomics operation should be VarArgs in DFG because DFGSSALoweringPhase assumes that they are VarArgs and they can
     14           have another arg for CheckInBounds dependency.
     15        4. For test262, JSC shell should support "--can-block-is-false" flag. If it is true, the main thread's [[CanBlock]] becomes false.
     16           This means that `Atomics.wait` cannot be used.
     17
     18        * builtins/BuiltinNames.h:
     19        * builtins/TypedArrayPrototype.js:
     20        (sort):
     21        * bytecode/LinkTimeConstant.h:
     22        * dfg/DFGAbstractInterpreterInlines.h:
     23        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     24        * dfg/DFGByteCodeParser.cpp:
     25        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
     26        * dfg/DFGClobberize.h:
     27        (JSC::DFG::clobberize):
     28        * dfg/DFGFixupPhase.cpp:
     29        (JSC::DFG::FixupPhase::fixupNode):
     30        * dfg/DFGNode.h:
     31        (JSC::DFG::Node::mustGenerate const):
     32        (JSC::DFG::Node::hasVarArgs const):
     33        (JSC::DFG::Node::mustGenerate): Deleted.
     34        * dfg/DFGNodeType.h:
     35        * dfg/DFGSSALoweringPhase.cpp:
     36        (JSC::DFG::SSALoweringPhase::handleNode):
     37        * dfg/DFGSpeculativeJIT64.cpp:
     38        (JSC::DFG::SpeculativeJIT::compile):
     39        * ftl/FTLLowerDFGToB3.cpp:
     40        (JSC::FTL::DFG::LowerDFGToB3::compileAtomicsIsLockFree):
     41        * jsc.cpp:
     42        (printUsageStatement):
     43        (CommandLine::parseArguments):
     44        (runJSC):
     45        * runtime/AtomicsObject.cpp:
     46        (JSC::AtomicsObject::finishCreation):
     47        (JSC::JSC_DEFINE_HOST_FUNCTION):
     48        (JSC::JSC_DEFINE_JIT_OPERATION):
     49        * runtime/CommonIdentifiers.h:
     50        * runtime/Intrinsic.cpp:
     51        (JSC::intrinsicName):
     52        * runtime/Intrinsic.h:
     53        * runtime/JSArrayBufferPrototype.cpp:
     54        (JSC::arrayBufferSlice):
     55        (JSC::arrayBufferByteLength):
     56        (JSC::JSC_DEFINE_HOST_FUNCTION):
     57        (JSC::JSArrayBufferPrototype::finishCreation):
     58        * runtime/JSCJSValue.h:
     59        * runtime/JSCJSValueInlines.h:
     60        (JSC::JSValue::toIntegerOrInfinity const):
     61        * runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
     62        (JSC::genericTypedArrayViewProtoFuncReverse):
     63        (JSC::genericTypedArrayViewPrivateFuncSort):
     64        * runtime/JSGlobalObject.cpp:
     65        (JSC::JSGlobalObject::init):
     66        * runtime/JSTypedArrayViewPrototype.cpp:
     67        (JSC::JSC_DEFINE_HOST_FUNCTION):
     68        * runtime/JSTypedArrayViewPrototype.h:
     69        * runtime/OptionsList.h:
     70        * runtime/SimpleTypedArrayController.cpp:
     71        (JSC::SimpleTypedArrayController::SimpleTypedArrayController):
     72        (JSC::SimpleTypedArrayController::isAtomicsWaitAllowedOnCurrentThread):
     73        * runtime/SimpleTypedArrayController.h:
     74        * runtime/SmallStrings.cpp:
     75        (JSC::SmallStrings::initializeCommonStrings):
     76        (JSC::SmallStrings::visitStrongReferences):
     77        * runtime/SmallStrings.h:
     78        (JSC::SmallStrings::notEqualString const):
     79        (JSC::SmallStrings::timedOutString const):
     80        (JSC::SmallStrings::okString const):
     81
    1822020-11-06  Mark Lam  <mark.lam@apple.com>
    283
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r269343 r269531  
    118118    macro(derivedConstructor) \
    119119    macro(isTypedArrayView) \
     120    macro(isSharedTypedArrayView) \
    120121    macro(isDetached) \
     122    macro(typedArrayDefaultComparator) \
    121123    macro(isBoundFunction) \
    122124    macro(hasInstanceBoundFunction) \
  • trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js

    r269343 r269531  
    239239        return;
    240240
    241     if (comparator !== @undefined)
     241    // typedArraySort is not safe when the other thread is modifying content. So if |this| is SharedArrayBuffer,
     242    // use JS-implemented sorting.
     243    if (comparator !== @undefined || @isSharedTypedArrayView(this)) {
     244        if (comparator === @undefined)
     245            comparator = @typedArrayDefaultComparator;
    242246        @typedArrayMergeSort(this, length, comparator);
    243     else
     247    } else
    244248        @typedArraySort(this);
    245249
  • trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h

    r269343 r269531  
    5454    v(typedArraySort, nullptr) \
    5555    v(isTypedArrayView, nullptr) \
     56    v(isSharedTypedArrayView, nullptr) \
    5657    v(isDetached, nullptr) \
     58    v(typedArrayDefaultComparator, nullptr) \
    5759    v(typedArraySubarrayCreate, nullptr) \
    5860    v(isBoundFunction, nullptr) \
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r269343 r269531  
    827827       
    828828    case AtomicsIsLockFree: {
    829         if (node->child1().useKind() != Int32Use)
     829        if (m_graph.child(node, 0).useKind() != Int32Use)
    830830            clobberWorld();
    831831        setNonCellTypeForNode(node, SpecBoolInt32);
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r269343 r269531  
    27182718            if (static_cast<unsigned>(argumentCountIncludingThis) < 1 + numArgs)
    27192719                return false;
     2720
     2721            if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType)
     2722                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantCache)
     2723                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
     2724                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
     2725                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds))
     2726                return false;
    27202727           
    27212728            insertChecks();
    27222729           
    2723             Vector<Node*, 3> args;
    27242730            for (unsigned i = 0; i < numArgs; ++i)
    2725                 args.append(get(virtualRegisterForArgumentIncludingThis(1 + i, registerOffset)));
    2726            
    2727             Node* resultNode;
    2728             if (numArgs + 1 <= 3) {
    2729                 while (args.size() < 3)
    2730                     args.append(nullptr);
    2731                 resultNode = addToGraph(op, OpInfo(ArrayMode(Array::SelectUsingPredictions, action).asWord()), OpInfo(prediction), args[0], args[1], args[2]);
    2732             } else {
    2733                 for (Node* node : args)
    2734                     addVarArgChild(node);
    2735                 addVarArgChild(nullptr);
    2736                 resultNode = addToGraph(Node::VarArg, op, OpInfo(ArrayMode(Array::SelectUsingPredictions, action).asWord()), OpInfo(prediction));
    2737             }
     2731                addVarArgChild(get(virtualRegisterForArgumentIncludingThis(1 + i, registerOffset)));
     2732            addVarArgChild(nullptr); // For storage edge.
     2733            Node* resultNode = addToGraph(Node::VarArg, op, OpInfo(ArrayMode(Array::SelectUsingPredictions, action).asWord()), OpInfo(prediction));
    27382734           
    27392735            setResult(resultNode);
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r269343 r269531  
    254254
    255255    case AtomicsIsLockFree:
    256         if (node->child1().useKind() == Int32Use)
    257             def(PureValue(node));
     256        if (graph.child(node, 0).useKind() == Int32Use)
     257            def(PureValue(graph, node));
    258258        else
    259259            clobberTop();
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r269343 r269531  
    13661366           
    13671367        case AtomicsIsLockFree:
    1368             if (node->child1()->shouldSpeculateInt32())
    1369                 fixIntOrBooleanEdge(node->child1());
     1368            if (m_graph.child(node, 0)->shouldSpeculateInt32())
     1369                fixIntOrBooleanEdge(m_graph.child(node, 0));
    13701370            break;
    13711371           
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r268794 r269531  
    505505    void convertToIdentityOn(Node*);
    506506
    507     bool mustGenerate()
     507    bool mustGenerate() const
    508508    {
    509509        return m_flags & NodeMustGenerate;
     510    }
     511
     512    bool hasVarArgs() const
     513    {
     514        return m_flags & NodeHasVarArgs;
    510515    }
    511516   
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r269343 r269531  
    300300    macro(AtomicsCompareExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    301301    macro(AtomicsExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    302     macro(AtomicsIsLockFree, NodeResultBoolean) \
    303     macro(AtomicsLoad, NodeResultJS | NodeMustGenerate) \
     302    macro(AtomicsIsLockFree, NodeResultBoolean | NodeHasVarArgs) \
     303    macro(AtomicsLoad, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    304304    macro(AtomicsOr, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    305305    macro(AtomicsStore, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
  • trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp

    r261895 r269531  
    7676        case AtomicsStore:
    7777        case AtomicsSub:
    78         case AtomicsXor:
     78        case AtomicsXor: {
     79            unsigned numExtraArgs = numExtraAtomicsArgs(m_node->op());
     80            lowerBoundsCheck(m_graph.child(m_node, 0), m_graph.child(m_node, 1), m_graph.child(m_node, 2 + numExtraArgs));
     81            break;
     82        }
     83
    7984        case HasIndexedProperty:
    8085            lowerBoundsCheck(m_graph.child(m_node, 0), m_graph.child(m_node, 1), m_graph.child(m_node, 2));
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r269343 r269531  
    34313431       
    34323432    case AtomicsIsLockFree: {
    3433         if (node->child1().useKind() != Int32Use) {
    3434             JSValueOperand operand(this, node->child1());
     3433        Edge child1 = m_graph.child(node, 0);
     3434        if (child1.useKind() != Int32Use) {
     3435            JSValueOperand operand(this, child1);
    34353436            GPRReg operandGPR = operand.gpr();
    34363437            flushRegisters();
     
    34433444        }
    34443445
    3445         SpeculateInt32Operand operand(this, node->child1());
     3446        SpeculateInt32Operand operand(this, child1);
    34463447        GPRTemporary result(this);
    34473448        GPRReg operandGPR = operand.gpr();
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r269343 r269531  
    42784278    {
    42794279        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
    4280         if (m_node->child1().useKind() != Int32Use) {
    4281             setJSValue(vmCall(Int64, operationAtomicsIsLockFree, weakPointer(globalObject), lowJSValue(m_node->child1())));
    4282             return;
    4283         }
    4284        
    4285         LValue bytes = lowInt32(m_node->child1());
     4280        Edge child1 = m_graph.child(m_node, 0);
     4281        if (child1.useKind() != Int32Use) {
     4282            setJSValue(vmCall(Int64, operationAtomicsIsLockFree, weakPointer(globalObject), lowJSValue(child1)));
     4283            return;
     4284        }
     4285       
     4286        LValue bytes = lowInt32(child1);
    42864287       
    42874288        LBasicBlock trueCase = m_out.newBlock();
  • trunk/Source/JavaScriptCore/jsc.cpp

    r269350 r269531  
    6262#include "ReleaseHeapAccessScope.h"
    6363#include "SamplingProfiler.h"
     64#include "SimpleTypedArrayController.h"
    6465#include "StackVisitor.h"
    6566#include "StructureInlines.h"
     
    425426    bool m_dumpSamplingProfilerData { false };
    426427    bool m_enableRemoteDebugging { false };
     428    bool m_canBlockIsFalse { false };
    427429
    428430    void parseArguments(int, char**);
     
    30983100    fprintf(stderr, "  --<jsc VM option>=<value>  Sets the specified JSC VM option\n");
    30993101    fprintf(stderr, "  --destroy-vm               Destroy VM before exiting\n");
     3102    fprintf(stderr, "  --can-block-is-false       Make main thread's Atomics.wait throw\n");
    31003103    fprintf(stderr, "\n");
    31013104    fprintf(stderr, "Files with a .mjs extension will always be evaluated as modules.\n");
     
    31193122    Options::AllowUnfinalizedAccessScope scope;
    31203123    Options::initialize();
     3124    Options::useSharedArrayBuffer() = true;
    31213125   
    31223126#if PLATFORM(IOS_FAMILY)
     
    32323236            continue;
    32333237        }
     3238        if (!strcmp(arg, "--can-block-is-false")) {
     3239            m_canBlockIsFalse = true;
     3240            continue;
     3241        }
    32343242        if (!strcmp(arg, "--disableOptionsFreezingForTesting")) {
    32353243            Config::disableFreezingForTesting();
     
    33303338   
    33313339    VM& vm = VM::create(LargeHeap).leakRef();
     3340    if (!isWorker && options.m_canBlockIsFalse)
     3341        vm.m_typedArrayController = adoptRef(new JSC::SimpleTypedArrayController(false));
    33323342#if ENABLE(WEBASSEMBLY)
    33333343    Wasm::enableFastMemory();
  • trunk/Source/JavaScriptCore/runtime/AtomicsObject.cpp

    r268990 r269531  
    4444    macro(isLockFree, IsLockFree, 1)                                    \
    4545    macro(load, Load, 2)                                                \
     46    macro(notify, Notify, 3)                                            \
    4647    macro(or, Or, 3)                                                    \
    4748    macro(store, Store, 3)                                              \
    4849    macro(sub, Sub, 3)                                                  \
    4950    macro(wait, Wait, 4)                                                \
    50     macro(wake, Wake, 3)                                                \
    5151    macro(xor, Xor, 3)
    5252
     
    8484    FOR_EACH_ATOMICS_FUNC(PUT_DIRECT_NATIVE_FUNC)
    8585#undef PUT_DIRECT_NATIVE_FUNC
     86
     87    JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
    8688}
    8789
     
    8991
    9092template<typename Adaptor, typename Func>
    91 EncodedJSValue atomicOperationWithArgsCase(JSGlobalObject* globalObject, const JSValue* args, ThrowScope& scope, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func)
     93EncodedJSValue atomicReadModifyWriteCase(JSGlobalObject* globalObject, const JSValue* args, ThrowScope& scope, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func)
    9294{
    9395    JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView);
     
    9597    double extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS.
    9698    for (unsigned i = 0; i < Func::numExtraArgs; ++i) {
    97         double value = args[2 + i].toInteger(globalObject);
     99        double value = args[2 + i].toIntegerOrInfinity(globalObject);
    98100        RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    99101        extraArgs[i] = value;
    100102    }
    101103
     104    if (typedArray->isDetached())
     105        return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage);
     106
    102107    return JSValue::encode(func(typedArray->typedVector() + accessIndex, extraArgs));
    103108}
    104109
    105 unsigned validatedAccessIndex(VM& vm, JSGlobalObject* globalObject, JSValue accessIndexValue, JSArrayBufferView* typedArrayView)
    106 {
    107     auto scope = DECLARE_THROW_SCOPE(vm);
    108     if (UNLIKELY(!accessIndexValue.isInt32())) {
    109         double accessIndexDouble = accessIndexValue.toNumber(globalObject);
     110static unsigned validateAtomicAccess(VM& vm, JSGlobalObject* globalObject, JSArrayBufferView* typedArrayView, JSValue accessIndexValue)
     111{
     112    auto scope = DECLARE_THROW_SCOPE(vm);
     113    unsigned accessIndex = 0;
     114    if (LIKELY(accessIndexValue.isUInt32()))
     115        accessIndex = accessIndexValue.asUInt32();
     116    else {
     117        accessIndex = accessIndexValue.toIndex(globalObject, "accessIndex");
    110118        RETURN_IF_EXCEPTION(scope, 0);
    111         if (accessIndexDouble == 0)
    112             accessIndexValue = jsNumber(0);
    113         else {
    114             accessIndexValue = jsNumber(accessIndexDouble);
    115             if (!accessIndexValue.isInt32()) {
    116                 throwRangeError(globalObject, scope, "Access index is not an integer."_s);
    117                 return 0;
    118             }
    119         }
    120     }
    121     int32_t accessIndex = accessIndexValue.asInt32();
     119    }
    122120   
    123121    ASSERT(typedArrayView->length() <= static_cast<unsigned>(INT_MAX));
    124     if (static_cast<unsigned>(accessIndex) >= typedArrayView->length()) {
     122    if (accessIndex >= typedArrayView->length()) {
    125123        throwRangeError(globalObject, scope, "Access index out of bounds for atomic access."_s);
    126124        return 0;
     
    130128}
    131129
     130static JSArrayBufferView* validateTypedArray(JSGlobalObject* globalObject, JSValue typedArrayValue)
     131{
     132    VM& vm = globalObject->vm();
     133    auto scope = DECLARE_THROW_SCOPE(vm);
     134
     135    if (!typedArrayValue.isCell()) {
     136        throwTypeError(globalObject, scope, "Argument needs to be a typed array."_s);
     137        return nullptr;
     138    }
     139
     140    JSCell* typedArrayCell = typedArrayValue.asCell();
     141    if (!isTypedView(typedArrayCell->classInfo(vm)->typedArrayStorageType)) {
     142        throwTypeError(globalObject, scope, "Argument needs to be a typed array."_s);
     143        return nullptr;
     144    }
     145
     146    JSArrayBufferView* typedArray = jsCast<JSArrayBufferView*>(typedArrayCell);
     147    if (typedArray->isDetached()) {
     148        throwTypeError(globalObject, scope, "Argument typed array is detached."_s);
     149        return nullptr;
     150    }
     151    return typedArray;
     152}
     153
     154enum class TypedArrayOperationMode { Read, Write };
     155template<TypedArrayOperationMode mode>
     156inline JSArrayBufferView* validateIntegerTypedArray(JSGlobalObject* globalObject, JSValue typedArrayValue)
     157{
     158    VM& vm = globalObject->vm();
     159    auto scope = DECLARE_THROW_SCOPE(vm);
     160
     161    JSArrayBufferView* typedArray = validateTypedArray(globalObject, typedArrayValue);
     162    RETURN_IF_EXCEPTION(scope, { });
     163
     164    if constexpr (mode == TypedArrayOperationMode::Write) {
     165        switch (typedArray->type()) {
     166        case Int32ArrayType:
     167            break;
     168        default:
     169            throwTypeError(globalObject, scope, "Typed array argument must be an Int32Array."_s);
     170            return { };
     171        }
     172    } else {
     173        switch (typedArray->type()) {
     174        case Int8ArrayType:
     175        case Int16ArrayType:
     176        case Int32ArrayType:
     177        case Uint8ArrayType:
     178        case Uint16ArrayType:
     179        case Uint32ArrayType:
     180            break;
     181        default:
     182            throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, or Uint32Array."_s);
     183            return { };
     184        }
     185    }
     186    return typedArray;
     187}
     188
    132189template<typename Func>
    133 EncodedJSValue atomicOperationWithArgs(VM& vm, JSGlobalObject* globalObject, const JSValue* args, const Func& func)
    134 {
    135     auto scope = DECLARE_THROW_SCOPE(vm);
    136 
    137     JSValue typedArrayValue = args[0];
    138     if (!typedArrayValue.isCell()) {
    139         throwTypeError(globalObject, scope, "Typed array argument must be a cell."_s);
    140         return JSValue::encode(jsUndefined());
    141     }
    142    
    143     JSCell* typedArrayCell = typedArrayValue.asCell();
    144    
    145     JSType type = typedArrayCell->type();
    146     switch (type) {
     190EncodedJSValue atomicReadModifyWrite(VM& vm, JSGlobalObject* globalObject, const JSValue* args, const Func& func)
     191{
     192    auto scope = DECLARE_THROW_SCOPE(vm);
     193
     194    JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Read>(globalObject, args[0]);
     195    RETURN_IF_EXCEPTION(scope, { });
     196
     197    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArrayView, args[1]);
     198    RETURN_IF_EXCEPTION(scope, { });
     199
     200    switch (typedArrayView->type()) {
    147201    case Int8ArrayType:
     202        return atomicReadModifyWriteCase<Int8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    148203    case Int16ArrayType:
     204        return atomicReadModifyWriteCase<Int16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    149205    case Int32ArrayType:
     206        return atomicReadModifyWriteCase<Int32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    150207    case Uint8ArrayType:
     208        return atomicReadModifyWriteCase<Uint8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    151209    case Uint16ArrayType:
     210        return atomicReadModifyWriteCase<Uint16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    152211    case Uint32ArrayType:
    153         break;
    154     default:
    155         throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, or Uint32Array."_s);
    156         return JSValue::encode(jsUndefined());
    157     }
    158    
    159     JSArrayBufferView* typedArrayView = jsCast<JSArrayBufferView*>(typedArrayCell);
    160     if (!typedArrayView->isShared()) {
    161         throwTypeError(globalObject, scope, "Typed array argument must wrap a SharedArrayBuffer."_s);
    162         return JSValue::encode(jsUndefined());
    163     }
    164    
    165     unsigned accessIndex = validatedAccessIndex(vm, globalObject, args[1], typedArrayView);
    166     RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    167    
    168     switch (type) {
    169     case Int8ArrayType:
    170         return atomicOperationWithArgsCase<Int8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    171     case Int16ArrayType:
    172         return atomicOperationWithArgsCase<Int16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    173     case Int32ArrayType:
    174         return atomicOperationWithArgsCase<Int32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    175     case Uint8ArrayType:
    176         return atomicOperationWithArgsCase<Uint8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    177     case Uint16ArrayType:
    178         return atomicOperationWithArgsCase<Uint16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    179     case Uint32ArrayType:
    180         return atomicOperationWithArgsCase<Uint32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
     212        return atomicReadModifyWriteCase<Uint32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);
    181213    default:
    182214        RELEASE_ASSERT_NOT_REACHED();
     
    186218
    187219template<typename Func>
    188 EncodedJSValue atomicOperationWithArgs(JSGlobalObject* globalObject, CallFrame* callFrame, const Func& func)
     220EncodedJSValue atomicReadModifyWrite(JSGlobalObject* globalObject, CallFrame* callFrame, const Func& func)
    189221{
    190222    JSValue args[2 + Func::numExtraArgs];
    191223    for (unsigned i = 2 + Func::numExtraArgs; i--;)
    192224        args[i] = callFrame->argument(i);
    193     return atomicOperationWithArgs(globalObject->vm(), globalObject, args, func);
     225    return atomicReadModifyWrite(globalObject->vm(), globalObject, args, func);
    194226}
    195227
     
    315347JSC_DEFINE_HOST_FUNCTION(atomicsFuncAdd, (JSGlobalObject* globalObject, CallFrame* callFrame))
    316348{
    317     return atomicOperationWithArgs(globalObject, callFrame, AddFunc());
     349    return atomicReadModifyWrite(globalObject, callFrame, AddFunc());
    318350}
    319351
    320352JSC_DEFINE_HOST_FUNCTION(atomicsFuncAnd, (JSGlobalObject* globalObject, CallFrame* callFrame))
    321353{
    322     return atomicOperationWithArgs(globalObject, callFrame, AndFunc());
     354    return atomicReadModifyWrite(globalObject, callFrame, AndFunc());
    323355}
    324356
    325357JSC_DEFINE_HOST_FUNCTION(atomicsFuncCompareExchange, (JSGlobalObject* globalObject, CallFrame* callFrame))
    326358{
    327     return atomicOperationWithArgs(globalObject, callFrame, CompareExchangeFunc());
     359    return atomicReadModifyWrite(globalObject, callFrame, CompareExchangeFunc());
    328360}
    329361
    330362JSC_DEFINE_HOST_FUNCTION(atomicsFuncExchange, (JSGlobalObject* globalObject, CallFrame* callFrame))
    331363{
    332     return atomicOperationWithArgs(globalObject, callFrame, ExchangeFunc());
     364    return atomicReadModifyWrite(globalObject, callFrame, ExchangeFunc());
    333365}
    334366
     
    340372JSC_DEFINE_HOST_FUNCTION(atomicsFuncLoad, (JSGlobalObject* globalObject, CallFrame* callFrame))
    341373{
    342     return atomicOperationWithArgs(globalObject, callFrame, LoadFunc());
     374    return atomicReadModifyWrite(globalObject, callFrame, LoadFunc());
    343375}
    344376
    345377JSC_DEFINE_HOST_FUNCTION(atomicsFuncOr, (JSGlobalObject* globalObject, CallFrame* callFrame))
    346378{
    347     return atomicOperationWithArgs(globalObject, callFrame, OrFunc());
     379    return atomicReadModifyWrite(globalObject, callFrame, OrFunc());
    348380}
    349381
    350382JSC_DEFINE_HOST_FUNCTION(atomicsFuncStore, (JSGlobalObject* globalObject, CallFrame* callFrame))
    351383{
    352     return atomicOperationWithArgs(globalObject, callFrame, StoreFunc());
     384    return atomicReadModifyWrite(globalObject, callFrame, StoreFunc());
    353385}
    354386
    355387JSC_DEFINE_HOST_FUNCTION(atomicsFuncSub, (JSGlobalObject* globalObject, CallFrame* callFrame))
    356388{
    357     return atomicOperationWithArgs(globalObject, callFrame, SubFunc());
     389    return atomicReadModifyWrite(globalObject, callFrame, SubFunc());
    358390}
    359391
     
    362394    VM& vm = globalObject->vm();
    363395    auto scope = DECLARE_THROW_SCOPE(vm);
    364    
    365     JSInt32Array* typedArray = jsDynamicCast<JSInt32Array*>(vm, callFrame->argument(0));
    366     if (!typedArray) {
    367         throwTypeError(globalObject, scope, "Typed array for wait/wake must be an Int32Array."_s);
     396
     397    auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0));
     398    RETURN_IF_EXCEPTION(scope, { });
     399    auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer);
     400
     401    if (!typedArray->isShared()) {
     402        throwTypeError(globalObject, scope, "Typed array for wait/notify must wrap a SharedArrayBuffer."_s);
    368403        return JSValue::encode(jsUndefined());
    369404    }
    370    
    371     if (!typedArray->isShared()) {
    372         throwTypeError(globalObject, scope, "Typed array for wait/wake must wrap a SharedArrayBuffer."_s);
    373         return JSValue::encode(jsUndefined());
    374     }
    375 
    376     unsigned accessIndex = validatedAccessIndex(vm, globalObject, callFrame->argument(1), typedArray);
    377     RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    378    
     405
     406    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1));
     407    RETURN_IF_EXCEPTION(scope, { });
     408
    379409    int32_t* ptr = typedArray->typedVector() + accessIndex;
    380    
     410
    381411    int32_t expectedValue = callFrame->argument(2).toInt32(globalObject);
    382412    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    383    
     413
    384414    double timeoutInMilliseconds = callFrame->argument(3).toNumber(globalObject);
    385415    RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    386    
     416    Seconds timeout = Seconds::infinity();
     417    if (!std::isnan(timeoutInMilliseconds))
     418        timeout = std::max(Seconds::fromMilliseconds(timeoutInMilliseconds), 0_s);
     419
    387420    if (!vm.m_typedArrayController->isAtomicsWaitAllowedOnCurrentThread()) {
    388421        throwTypeError(globalObject, scope, "Atomics.wait cannot be called from the current thread."_s);
    389422        return JSValue::encode(jsUndefined());
    390423    }
    391    
    392     Seconds timeout = Seconds::fromMilliseconds(timeoutInMilliseconds);
    393 
    394     // This covers the proposed rule:
    395     //
    396     // 4. If timeout is not provided or is undefined then let t be +inf. Otherwise:
    397     //     a. Let q be ? ToNumber(timeout).
    398     //     b. If q is NaN then let t be +inf, otherwise let t be max(0, q).
    399     //
    400     // callFrame->argument(3) returns undefined if it's not provided and ToNumber(undefined) returns NaN,
    401     // so NaN is the only special case.
    402     if (!std::isnan(timeout))
    403         timeout = std::max(0_s, timeout);
    404     else
    405         timeout = Seconds::infinity();
    406    
     424
    407425    bool didPassValidation = false;
    408426    ParkingLot::ParkResult result;
     
    418436            MonotonicTime::now() + timeout);
    419437    }
    420     const char* resultString;
    421438    if (!didPassValidation)
    422         resultString = "not-equal";
    423     else if (!result.wasUnparked)
    424         resultString = "timed-out";
    425     else
    426         resultString = "ok";
    427     return JSValue::encode(jsString(vm, resultString));
    428 }
    429 
    430 JSC_DEFINE_HOST_FUNCTION(atomicsFuncWake, (JSGlobalObject* globalObject, CallFrame* callFrame))
    431 {
    432     VM& vm = globalObject->vm();
    433     auto scope = DECLARE_THROW_SCOPE(vm);
    434    
    435     JSInt32Array* typedArray = jsDynamicCast<JSInt32Array*>(vm, callFrame->argument(0));
    436     if (!typedArray) {
    437         throwTypeError(globalObject, scope, "Typed array for wait/wake must be an Int32Array."_s);
    438         return JSValue::encode(jsUndefined());
    439     }
    440    
    441     if (!typedArray->isShared()) {
    442         throwTypeError(globalObject, scope, "Typed array for wait/wake must wrap a SharedArrayBuffer."_s);
    443         return JSValue::encode(jsUndefined());
    444     }
    445 
    446     unsigned accessIndex = validatedAccessIndex(vm, globalObject, callFrame->argument(1), typedArray);
    447     RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    448    
    449     int32_t* ptr = typedArray->typedVector() + accessIndex;
    450    
     439        return JSValue::encode(vm.smallStrings.notEqualString());
     440    if (!result.wasUnparked)
     441        return JSValue::encode(vm.smallStrings.timedOutString());
     442    return JSValue::encode(vm.smallStrings.okString());
     443}
     444
     445JSC_DEFINE_HOST_FUNCTION(atomicsFuncNotify, (JSGlobalObject* globalObject, CallFrame* callFrame))
     446{
     447    VM& vm = globalObject->vm();
     448    auto scope = DECLARE_THROW_SCOPE(vm);
     449
     450    auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0));
     451    RETURN_IF_EXCEPTION(scope, { });
     452    auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer);
     453
     454    unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1));
     455    RETURN_IF_EXCEPTION(scope, { });
     456
    451457    JSValue countValue = callFrame->argument(2);
    452458    unsigned count = UINT_MAX;
    453459    if (!countValue.isUndefined()) {
    454         int32_t countInt = countValue.toInt32(globalObject);
    455         RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
    456         count = std::max(0, countInt);
    457     }
    458 
     460        double countInt = countValue.toIntegerOrInfinity(globalObject);
     461        RETURN_IF_EXCEPTION(scope, { });
     462        double countDouble = std::max(0.0, countInt);
     463        if (countDouble < UINT_MAX)
     464            count = static_cast<unsigned>(countDouble);
     465    }
     466
     467    if (!typedArray->isShared())
     468        return JSValue::encode(jsNumber(0));
     469
     470    int32_t* ptr = typedArray->typedVector() + accessIndex;
    459471    return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count)));
    460472}
     
    462474JSC_DEFINE_HOST_FUNCTION(atomicsFuncXor, (JSGlobalObject* globalObject, CallFrame* callFrame))
    463475{
    464     return atomicOperationWithArgs(globalObject, callFrame, XorFunc());
     476    return atomicReadModifyWrite(globalObject, callFrame, XorFunc());
    465477}
    466478
     
    473485    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    474486    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    475     return atomicOperationWithArgs(vm, globalObject, args, AddFunc());
     487    return atomicReadModifyWrite(vm, globalObject, args, AddFunc());
    476488}
    477489
     
    482494    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    483495    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    484     return atomicOperationWithArgs(vm, globalObject, args, AndFunc());
     496    return atomicReadModifyWrite(vm, globalObject, args, AndFunc());
    485497}
    486498
     
    491503    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    492504    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(expected), JSValue::decode(newValue)};
    493     return atomicOperationWithArgs(vm, globalObject, args, CompareExchangeFunc());
     505    return atomicReadModifyWrite(vm, globalObject, args, CompareExchangeFunc());
    494506}
    495507
     
    500512    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    501513    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    502     return atomicOperationWithArgs(vm, globalObject, args, ExchangeFunc());
     514    return atomicReadModifyWrite(vm, globalObject, args, ExchangeFunc());
    503515}
    504516
     
    517529    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    518530    JSValue args[] = {JSValue::decode(base), JSValue::decode(index)};
    519     return atomicOperationWithArgs(vm, globalObject, args, LoadFunc());
     531    return atomicReadModifyWrite(vm, globalObject, args, LoadFunc());
    520532}
    521533
     
    526538    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    527539    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    528     return atomicOperationWithArgs(vm, globalObject, args, OrFunc());
     540    return atomicReadModifyWrite(vm, globalObject, args, OrFunc());
    529541}
    530542
     
    535547    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    536548    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    537     return atomicOperationWithArgs(vm, globalObject, args, StoreFunc());
     549    return atomicReadModifyWrite(vm, globalObject, args, StoreFunc());
    538550}
    539551
     
    544556    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    545557    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    546     return atomicOperationWithArgs(vm, globalObject, args, SubFunc());
     558    return atomicReadModifyWrite(vm, globalObject, args, SubFunc());
    547559}
    548560
     
    553565    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    554566    JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)};
    555     return atomicOperationWithArgs(vm, globalObject, args, XorFunc());
     567    return atomicReadModifyWrite(vm, globalObject, args, XorFunc());
    556568}
    557569
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r268956 r269531  
    2929    macro(Array) \
    3030    macro(ArrayBuffer) \
     31    macro(Atomics) \
    3132    macro(BYTES_PER_ELEMENT) \
    3233    macro(BigInt) \
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.cpp

    r265934 r269531  
    262262    case AtomicsLoadIntrinsic:
    263263        return "AtomicsLoadIntrinsic";
     264    case AtomicsNotifyIntrinsic:
     265        return "AtomicsNotifyIntrinsic";
    264266    case AtomicsOrIntrinsic:
    265267        return "AtomicsOrIntrinsic";
     
    270272    case AtomicsWaitIntrinsic:
    271273        return "AtomicsWaitIntrinsic";
    272     case AtomicsWakeIntrinsic:
    273         return "AtomicsWakeIntrinsic";
    274274    case AtomicsXorIntrinsic:
    275275        return "AtomicsXorIntrinsic";
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.h

    r265934 r269531  
    147147    AtomicsIsLockFreeIntrinsic,
    148148    AtomicsLoadIntrinsic,
     149    AtomicsNotifyIntrinsic,
    149150    AtomicsOrIntrinsic,
    150151    AtomicsStoreIntrinsic,
    151152    AtomicsSubIntrinsic,
    152153    AtomicsWaitIntrinsic,
    153     AtomicsWakeIntrinsic,
    154154    AtomicsXorIntrinsic,
    155155    ParseIntIntrinsic,
  • trunk/Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp

    r267594 r269531  
    3434static JSC_DECLARE_HOST_FUNCTION(arrayBufferProtoFuncSlice);
    3535static JSC_DECLARE_HOST_FUNCTION(arrayBufferProtoGetterFuncByteLength);
     36static JSC_DECLARE_HOST_FUNCTION(sharedArrayBufferProtoFuncSlice);
    3637static JSC_DECLARE_HOST_FUNCTION(sharedArrayBufferProtoGetterFuncByteLength);
    3738
    38 JSC_DEFINE_HOST_FUNCTION(arrayBufferProtoFuncSlice, (JSGlobalObject* globalObject, CallFrame* callFrame))
     39static EncodedJSValue arrayBufferSlice(JSGlobalObject* globalObject, JSValue arrayBufferValue, JSValue startValue, JSValue endValue, ArrayBufferSharingMode mode)
    3940{
    4041    VM& vm = globalObject->vm();
    4142    auto scope = DECLARE_THROW_SCOPE(vm);
    4243
    43     JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, callFrame->thisValue());
    44     if (!thisObject || thisObject->impl()->isShared())
    45         return throwVMTypeError(globalObject, scope, "Receiver of slice must be an ArrayBuffer."_s);
     44    JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, arrayBufferValue);
     45    if (!thisObject || (mode != thisObject->impl()->sharingMode()))
     46        return throwVMTypeError(globalObject, scope, makeString("Receiver must be "_s, mode == ArrayBufferSharingMode::Default ? "ArrayBuffer"_s : "SharedArrayBuffer"_s));
    4647
    47     double begin = callFrame->argument(0).toInteger(globalObject);
     48    if (mode == ArrayBufferSharingMode::Default && thisObject->impl()->isDetached())
     49        return throwVMTypeError(globalObject, scope, "Receiver is detached"_s);
     50
     51    double begin = startValue.toIntegerOrInfinity(globalObject);
    4852    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    49    
     53
    5054    double end;
    51     if (!callFrame->argument(1).isUndefined()) {
    52         end = callFrame->uncheckedArgument(1).toInteger(globalObject);
     55    if (!endValue.isUndefined()) {
     56        end = endValue.toIntegerOrInfinity(globalObject);
    5357        RETURN_IF_EXCEPTION(scope, encodedJSValue());
    5458    } else
    5559        end = thisObject->impl()->byteLength();
    56    
     60
     61    // 23. If IsDetachedBuffer(O) is true, throw a TypeError exception.
     62    // Check detach status again since toIntegerOrInfinity can have side effect.
     63    if (mode == ArrayBufferSharingMode::Default && thisObject->impl()->isDetached())
     64        return throwVMTypeError(globalObject, scope, "Receiver is detached"_s);
     65
    5766    auto newBuffer = thisObject->impl()->slice(begin, end);
    5867    if (!newBuffer)
    5968        return JSValue::encode(throwOutOfMemoryError(globalObject, scope));
    60    
     69
    6170    Structure* structure = globalObject->arrayBufferStructure(newBuffer->sharingMode());
    62    
     71
    6372    JSArrayBuffer* result = JSArrayBuffer::create(vm, structure, WTFMove(newBuffer));
    64    
     73
    6574    return JSValue::encode(result);
     75}
     76
     77static EncodedJSValue arrayBufferByteLength(JSGlobalObject* globalObject, JSValue arrayBufferValue, ArrayBufferSharingMode mode)
     78{
     79    VM& vm = globalObject->vm();
     80    auto scope = DECLARE_THROW_SCOPE(vm);
     81
     82    auto* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, arrayBufferValue);
     83    if (!thisObject || (mode != thisObject->impl()->sharingMode()))
     84        return throwVMTypeError(globalObject, scope, makeString("Receiver must be "_s, mode == ArrayBufferSharingMode::Default ? "ArrayBuffer"_s : "SharedArrayBuffer"_s));
     85
     86    if (mode == ArrayBufferSharingMode::Default && thisObject->impl()->isDetached())
     87        return JSValue::encode(jsNumber(0));
     88
     89    return JSValue::encode(jsNumber(thisObject->impl()->byteLength()));
     90}
     91
     92JSC_DEFINE_HOST_FUNCTION(arrayBufferProtoFuncSlice, (JSGlobalObject* globalObject, CallFrame* callFrame))
     93{
     94    return arrayBufferSlice(globalObject, callFrame->thisValue(), callFrame->argument(0), callFrame->argument(1), ArrayBufferSharingMode::Default);
    6695}
    6796
     
    6998JSC_DEFINE_HOST_FUNCTION(arrayBufferProtoGetterFuncByteLength, (JSGlobalObject* globalObject, CallFrame* callFrame))
    7099{
    71     VM& vm = globalObject->vm();
    72     auto scope = DECLARE_THROW_SCOPE(vm);
    73     JSValue thisValue = callFrame->thisValue();
    74     if (!thisValue.isObject())
    75         return throwVMTypeError(globalObject, scope, "Receiver should be an array buffer but was not an object"_s);
     100    return arrayBufferByteLength(globalObject, callFrame->thisValue(), ArrayBufferSharingMode::Default);
     101}
    76102
    77     auto* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, thisValue);
    78     if (!thisObject)
    79         return throwVMTypeError(globalObject, scope, "Receiver should be an array buffer"_s);
    80     if (thisObject->isShared())
    81         return throwVMTypeError(globalObject, scope, "Receiver should not be a shared array buffer"_s);
    82 
    83     RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(thisObject->impl()->byteLength())));
     103JSC_DEFINE_HOST_FUNCTION(sharedArrayBufferProtoFuncSlice, (JSGlobalObject* globalObject, CallFrame* callFrame))
     104{
     105    return arrayBufferSlice(globalObject, callFrame->thisValue(), callFrame->argument(0), callFrame->argument(1), ArrayBufferSharingMode::Shared);
    84106}
    85107
     
    87109JSC_DEFINE_HOST_FUNCTION(sharedArrayBufferProtoGetterFuncByteLength, (JSGlobalObject* globalObject, CallFrame* callFrame))
    88110{
    89     VM& vm = globalObject->vm();
    90     auto scope = DECLARE_THROW_SCOPE(vm);
    91     JSValue thisValue = callFrame->thisValue();
    92     if (!thisValue.isObject())
    93         return throwVMTypeError(globalObject, scope, "Receiver should be an array buffer but was not an object"_s);
    94 
    95     auto* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, thisValue);
    96     if (!thisObject)
    97         return throwVMTypeError(globalObject, scope, "Receiver should be an array buffer"_s);
    98     if (!thisObject->isShared())
    99         return throwVMTypeError(globalObject, scope, "Receiver should be a shared array buffer"_s);
    100 
    101     RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(thisObject->impl()->byteLength())));
     111    return arrayBufferByteLength(globalObject, callFrame->thisValue(), ArrayBufferSharingMode::Shared);
    102112}
    103113
     
    115125    Base::finishCreation(vm);
    116126   
    117     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, arrayBufferProtoFuncSlice, static_cast<unsigned>(PropertyAttribute::DontEnum), 2);
    118127    putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, arrayBufferSharingModeName(sharingMode)), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
    119     if (sharingMode == ArrayBufferSharingMode::Default)
     128    if (sharingMode == ArrayBufferSharingMode::Default) {
     129        JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, arrayBufferProtoFuncSlice, static_cast<unsigned>(PropertyAttribute::DontEnum), 2);
    120130        JSC_NATIVE_GETTER_WITHOUT_TRANSITION(vm.propertyNames->byteLength, arrayBufferProtoGetterFuncByteLength, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
    121     else
     131    } else {
     132        JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, sharedArrayBufferProtoFuncSlice, static_cast<unsigned>(PropertyAttribute::DontEnum), 2);
    122133        JSC_NATIVE_GETTER_WITHOUT_TRANSITION(vm.propertyNames->byteLength, sharedArrayBufferProtoGetterFuncByteLength, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
     134    }
    123135}
    124136
  • trunk/Source/JavaScriptCore/runtime/JSCJSValue.h

    r268993 r269531  
    295295    JS_EXPORT_PRIVATE double toInteger(JSGlobalObject*) const;
    296296    JS_EXPORT_PRIVATE double toIntegerPreserveNaN(JSGlobalObject*) const;
     297    double toIntegerOrInfinity(JSGlobalObject*) const;
    297298    int32_t toInt32(JSGlobalObject*) const;
    298299    uint32_t toUInt32(JSGlobalObject*) const;
  • trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h

    r266251 r269531  
    7878        return asInt32();
    7979    RELEASE_AND_RETURN(scope, JSC::toInt32(d));
     80}
     81
     82// https://tc39.es/ecma262/#sec-tointegerorinfinity
     83// FIXME: We will replace toInteger with toIntegerOrInfinity. The difference is that toIntegerOrInfinity will convert -0 to +0.
     84// https://bugs.webkit.org/show_bug.cgi?id=218642
     85inline double JSValue::toIntegerOrInfinity(JSGlobalObject* globalObject) const
     86{
     87    if (isInt32())
     88        return asInt32();
     89    double d = toNumber(globalObject);
     90    if (std::isnan(d) || !d)
     91        return 0.0;
     92    return trunc(d);
    8093}
    8194
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h

    r269343 r269531  
    389389ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReverse(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame)
    390390{
    391 //    VM& vm = getVM(globalObject);
    392391    auto scope = DECLARE_THROW_SCOPE(vm);
    393392
     
    406405ALWAYS_INLINE EncodedJSValue genericTypedArrayViewPrivateFuncSort(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame)
    407406{
    408 //    VM& vm = getVM(globalObject);
    409407    auto scope = DECLARE_THROW_SCOPE(vm);
    410408
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r269343 r269531  
    4444#include "AsyncGeneratorPrototype.h"
    4545#include "AsyncIteratorPrototype.h"
     46#include "AtomicsObject.h"
    4647#include "BigIntConstructor.h"
    4748#include "BigIntObject.h"
     
    829830            init.set(JSFunction::create(init.vm, init.owner, 1, init.vm.propertyNames->parseFloat.string(), globalFuncParseFloat, NoIntrinsic));
    830831        });
    831    
     832
    832833#if ENABLE(SHARED_ARRAY_BUFFER)
    833     m_sharedArrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Shared));
    834     m_sharedArrayBufferStructure.set(vm, this, JSArrayBuffer::createStructure(vm, this, m_sharedArrayBufferPrototype.get()));
     834    if (Options::useSharedArrayBuffer()) {
     835        m_sharedArrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Shared));
     836        m_sharedArrayBufferStructure.set(vm, this, JSArrayBuffer::createStructure(vm, this, m_sharedArrayBufferPrototype.get()));
     837    }
    835838#endif
    836839
     
    900903#if ENABLE(SHARED_ARRAY_BUFFER)
    901904    JSSharedArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;
    902     sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get());
    903     m_sharedArrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
    904 
    905     AtomicsObject* atomicsObject = AtomicsObject::create(vm, this, AtomicsObject::createStructure(vm, this, m_objectPrototype.get()));
     905    AtomicsObject* atomicsObject = nullptr;
     906    if (Options::useSharedArrayBuffer()) {
     907        sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get());
     908        m_sharedArrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     909
     910        atomicsObject = AtomicsObject::create(vm, this, AtomicsObject::createStructure(vm, this, m_objectPrototype.get()));
     911    }
    906912#endif
    907913
     
    983989
    984990#if ENABLE(SHARED_ARRAY_BUFFER)
    985     putDirectWithoutTransition(vm, vm.propertyNames->SharedArrayBuffer, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
    986     putDirectWithoutTransition(vm, Identifier::fromString(vm, "Atomics"), atomicsObject, static_cast<unsigned>(PropertyAttribute::DontEnum));
     991    if (Options::useSharedArrayBuffer()) {
     992        putDirectWithoutTransition(vm, vm.propertyNames->SharedArrayBuffer, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     993        putDirectWithoutTransition(vm, vm.propertyNames->Atomics, atomicsObject, static_cast<unsigned>(PropertyAttribute::DontEnum));
     994    }
    987995#endif
    988996
     
    12151223            init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), typedArrayViewPrivateFuncIsTypedArrayView, IsTypedArrayViewIntrinsic));
    12161224        });
     1225    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::isSharedTypedArrayView)].initLater([] (const Initializer<JSCell>& init) {
     1226            init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), typedArrayViewPrivateFuncIsSharedTypedArrayView));
     1227        });
    12171228    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::isDetached)].initLater([] (const Initializer<JSCell>& init) {
    12181229            init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 1, String(), typedArrayViewPrivateFuncIsDetached));
     1230        });
     1231    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::typedArrayDefaultComparator)].initLater([] (const Initializer<JSCell>& init) {
     1232            init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), typedArrayViewPrivateFuncDefaultComparator));
    12191233        });
    12201234    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::typedArraySubarrayCreate)].initLater([] (const Initializer<JSCell>& init) {
  • trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp

    r269343 r269531  
    3232#include "JSCInlines.h"
    3333#include "JSGenericTypedArrayViewPrototypeFunctions.h"
     34#include "Operations.h"
    3435
    3536namespace JSC {
     
    8687}
    8788
     89JSC_DEFINE_HOST_FUNCTION(typedArrayViewPrivateFuncIsSharedTypedArrayView, (JSGlobalObject* globalObject, CallFrame* callFrame))
     90{
     91    JSValue value = callFrame->uncheckedArgument(0);
     92    if (!value.isCell())
     93        return JSValue::encode(jsBoolean(false));
     94    if (!isTypedView(value.asCell()->classInfo(globalObject->vm())->typedArrayStorageType))
     95        return JSValue::encode(jsBoolean(false));
     96    return JSValue::encode(jsBoolean(jsCast<JSArrayBufferView*>(value)->isShared()));
     97}
     98
    8899JSC_DEFINE_HOST_FUNCTION(typedArrayViewPrivateFuncIsDetached, (JSGlobalObject* globalObject, CallFrame* callFrame))
    89100{
     
    91102    ASSERT_UNUSED(globalObject, argument.isCell() && isTypedView(argument.asCell()->classInfo(globalObject->vm())->typedArrayStorageType));
    92103    return JSValue::encode(jsBoolean(jsCast<JSArrayBufferView*>(argument)->isDetached()));
     104}
     105
     106JSC_DEFINE_HOST_FUNCTION(typedArrayViewPrivateFuncDefaultComparator, (JSGlobalObject*, CallFrame* callFrame))
     107{
     108    // https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort
     109
     110    JSValue x = callFrame->uncheckedArgument(0);
     111    JSValue y = callFrame->uncheckedArgument(1);
     112
     113    if (x.isNumber()) {
     114        ASSERT(y.isNumber());
     115        if (x.isInt32() && y.isInt32()) {
     116            int32_t xInt32 = x.asInt32();
     117            int32_t yInt32 = y.asInt32();
     118            if (xInt32 < yInt32)
     119                return JSValue::encode(jsNumber(-1));
     120            if (xInt32 > yInt32)
     121                return JSValue::encode(jsNumber(1));
     122            return JSValue::encode(jsNumber(0));
     123        }
     124
     125        double xDouble = x.asNumber();
     126        double yDouble = y.asNumber();
     127        if (std::isnan(xDouble) && std::isnan(yDouble))
     128            return JSValue::encode(jsNumber(0));
     129        if (std::isnan(xDouble))
     130            return JSValue::encode(jsNumber(1));
     131        if (std::isnan(yDouble))
     132            return JSValue::encode(jsNumber(-1));
     133        if (xDouble < yDouble)
     134            return JSValue::encode(jsNumber(-1));
     135        if (xDouble > yDouble)
     136            return JSValue::encode(jsNumber(1));
     137        if (!xDouble && !yDouble) {
     138            if (std::signbit(xDouble) && !std::signbit(yDouble))
     139                return JSValue::encode(jsNumber(-1));
     140            if (!std::signbit(xDouble) && std::signbit(yDouble))
     141                return JSValue::encode(jsNumber(1));
     142        }
     143        return JSValue::encode(jsNumber(0));
     144    }
     145    ASSERT(x.isBigInt() && y.isBigInt());
     146    switch (compareBigInt(x, y)) {
     147    case JSBigInt::ComparisonResult::Equal:
     148    case JSBigInt::ComparisonResult::Undefined:
     149        return JSValue::encode(jsNumber(0));
     150    case JSBigInt::ComparisonResult::GreaterThan:
     151        return JSValue::encode(jsNumber(1));
     152    case JSBigInt::ComparisonResult::LessThan:
     153        return JSValue::encode(jsNumber(-1));
     154    }
     155    return JSValue::encode(jsNumber(0));
    93156}
    94157
  • trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.h

    r269343 r269531  
    5353
    5454JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncIsTypedArrayView);
     55JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncIsSharedTypedArrayView);
    5556JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncIsDetached);
     57JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncDefaultComparator);
    5658JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncSort);
    5759JSC_DECLARE_HOST_FUNCTION(typedArrayViewPrivateFuncLength);
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r269349 r269531  
    495495    v(Bool, useIntlDateTimeFormatDayPeriod, true, Normal, "Expose the Intl.DateTimeFormat dayPeriod feature.") \
    496496    v(Bool, useAtMethod, false, Normal, "Expose the at() method on Array and %TypedArray%.") \
     497    v(Bool, useSharedArrayBuffer, false, Normal, nullptr) \
    497498    v(Bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.") \
    498499    v(Bool, forcePolyProto, false, Normal, "If true, create_this will always create an object with a poly proto structure.") \
  • trunk/Source/JavaScriptCore/runtime/SimpleTypedArrayController.cpp

    r261895 r269531  
    3434namespace JSC {
    3535
    36 SimpleTypedArrayController::SimpleTypedArrayController() { }
     36SimpleTypedArrayController::SimpleTypedArrayController(bool allowAtomicsWait)
     37    : m_allowAtomicsWait(allowAtomicsWait)
     38{
     39}
     40
    3741SimpleTypedArrayController::~SimpleTypedArrayController() { }
    3842
     
    5660bool SimpleTypedArrayController::isAtomicsWaitAllowedOnCurrentThread()
    5761{
    58     return true;
     62    return m_allowAtomicsWait;
    5963}
    6064
  • trunk/Source/JavaScriptCore/runtime/SimpleTypedArrayController.h

    r261567 r269531  
    4949class SimpleTypedArrayController final : public TypedArrayController {
    5050public:
    51     SimpleTypedArrayController();
     51    JS_EXPORT_PRIVATE SimpleTypedArrayController(bool allowAtomicsWait = true);
    5252    ~SimpleTypedArrayController() final;
    5353   
     
    6464
    6565    JSArrayBufferOwner m_owner;
     66    bool m_allowAtomicsWait { false };
    6667};
    6768
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp

    r261895 r269531  
    6060    initialize(&vm, m_undefinedObjectString, "[object Undefined]");
    6161    initialize(&vm, m_boundPrefixString, "bound ");
     62    initialize(&vm, m_notEqualString, "not-equal");
     63    initialize(&vm, m_timedOutString, "timed-out");
     64    initialize(&vm, m_okString, "ok");
    6265
    6366    setIsInitialized(true);
     
    7780    visitor.appendUnbarriered(m_undefinedObjectString);
    7881    visitor.appendUnbarriered(m_boundPrefixString);
     82    visitor.appendUnbarriered(m_notEqualString);
     83    visitor.appendUnbarriered(m_timedOutString);
     84    visitor.appendUnbarriered(m_okString);
    7985}
    8086
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.h

    r253982 r269531  
    118118    JSString* undefinedObjectString() const { return m_undefinedObjectString; }
    119119    JSString* boundPrefixString() const { return m_boundPrefixString; }
     120    JSString* notEqualString() const { return m_notEqualString; }
     121    JSString* timedOutString() const { return m_timedOutString; }
     122    JSString* okString() const { return m_okString; }
    120123
    121124    bool needsToBeVisited(CollectionScope scope) const
     
    139142    JSString* m_undefinedObjectString { nullptr };
    140143    JSString* m_boundPrefixString { nullptr };
     144    JSString* m_notEqualString { nullptr };
     145    JSString* m_timedOutString { nullptr };
     146    JSString* m_okString { nullptr };
    141147    JSString* m_singleCharacterStrings[singleCharacterStringCount] { nullptr };
    142148    bool m_needsToBeVisited { true };
  • trunk/Source/WTF/ChangeLog

    r269479 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        * wtf/PlatformEnable.h:
     9
    1102020-11-05  Saam Barati  <sbarati@apple.com>
    211
  • trunk/Source/WTF/wtf/PlatformEnable.h

    r269349 r269531  
    831831
    832832/* Disable SharedArrayBuffers until Spectre security concerns are mitigated. */
    833 #define ENABLE_SHARED_ARRAY_BUFFER 0
     833#define ENABLE_SHARED_ARRAY_BUFFER 1
    834834
    835835
  • trunk/Tools/ChangeLog

    r269524 r269531  
     12020-11-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Re-enable SharedArrayBuffer for JSC shell and Testers
     4        https://bugs.webkit.org/show_bug.cgi?id=212069
     5
     6        Reviewed by Keith Miller.
     7
     8        * Scripts/test262/Runner.pm:
     9        (getFeatureFlags):
     10        * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
     11        (main):
     12
    1132020-11-06  Truitt Savell  <tsavell@apple.com>
    214
  • trunk/Tools/Scripts/test262/Runner.pm

    r259668 r269531  
    704704    }
    705705
     706    if (grep $_ eq 'CanBlockIsFalse', @{$data->{flags}}) {
     707        $featureFlags .= ' --can-block-is-false';
     708    }
     709
    706710    return $featureFlags;
    707711}
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py

    r268925 r269531  
    8989        options.additional_env_var.append('JSC_maxPerThreadStackUsage=' + str(stackSizeInBytes))
    9090        options.additional_env_var.append('__XPC_JSC_maxPerThreadStackUsage=' + str(stackSizeInBytes))
     91        options.additional_env_var.append('JSC_useSharedArrayBuffer=1')
     92        options.additional_env_var.append('__XPC_JSC_useSharedArrayBuffer=1')
    9193        run_details = run(port, options, args, stderr)
    9294        if run_details.exit_code != -1 and run_details.skipped_all_tests:
Note: See TracChangeset for help on using the changeset viewer.