|
7 | 7 | assert(SHARED_MEMORY);
|
8 | 8 |
|
9 | 9 | addToLibrary({
|
10 |
| -// Chrome 87 shipped Atomics.waitAsync: |
11 |
| -// https://www.chromestatus.com/feature/6243382101803008 |
12 |
| -// However its implementation is faulty: |
13 |
| -// https://bugs.chromium.org/p/chromium/issues/detail?id=1167541 |
14 |
| -// Firefox Nightly 86.0a1 (2021-01-15) does not yet have it: |
15 |
| -// https://bugzilla.mozilla.org/show_bug.cgi?id=1467846 |
16 |
| -// And at the time of writing, no other browser has it either. |
17 |
| -#if MIN_CHROME_VERSION < 91 || MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED || MIN_FIREFOX_VERSION != TARGET_NOT_SUPPORTED || ENVIRONMENT_MAY_BE_NODE |
18 |
| - // Partially polyfill Atomics.waitAsync() if not available in the browser. |
19 |
| - // Also polyfill for old Chrome-based browsers, where Atomics.waitAsync is |
20 |
| - // broken until Chrome 91, see: |
21 |
| - // https://bugs.chromium.org/p/chromium/issues/detail?id=1167541 |
22 |
| - // https://github.com/tc39/proposal-atomics-wait-async/blob/master/PROPOSAL.md |
23 |
| - // This polyfill performs polling with setTimeout() to observe a change in the |
24 |
| - // target memory location. |
25 |
| - $polyfillWaitAsync__postset: `if (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91)) { |
26 |
| - let __Atomics_waitAsyncAddresses = [/*[i32a, index, value, maxWaitMilliseconds, promiseResolve]*/]; |
27 |
| - function __Atomics_pollWaitAsyncAddresses() { |
28 |
| - let now = performance.now(); |
29 |
| - let l = __Atomics_waitAsyncAddresses.length; |
30 |
| - for (let i = 0; i < l; ++i) { |
31 |
| - let a = __Atomics_waitAsyncAddresses[i]; |
32 |
| - let expired = (now > a[3]); |
33 |
| - let awoken = (Atomics.load(a[0], a[1]) != a[2]); |
34 |
| - if (expired || awoken) { |
35 |
| - __Atomics_waitAsyncAddresses[i--] = __Atomics_waitAsyncAddresses[--l]; |
36 |
| - __Atomics_waitAsyncAddresses.length = l; |
37 |
| - a[4](awoken ? 'ok': 'timed-out'); |
38 |
| - } |
39 |
| - } |
40 |
| - if (l) { |
41 |
| - // If we still have addresses to wait, loop the timeout handler to continue polling. |
42 |
| - setTimeout(__Atomics_pollWaitAsyncAddresses, 10); |
43 |
| - } |
44 |
| - } |
45 |
| - #if ASSERTIONS && WASM_WORKERS |
46 |
| - if (!ENVIRONMENT_IS_WASM_WORKER) err('Current environment does not support Atomics.waitAsync(): polyfilling it, but this is going to be suboptimal.'); |
47 |
| - #endif |
48 |
| - /** |
49 |
| - * @param {number=} maxWaitMilliseconds |
50 |
| - */ |
51 |
| - Atomics.waitAsync = (i32a, index, value, maxWaitMilliseconds) => { |
52 |
| - let val = Atomics.load(i32a, index); |
53 |
| - if (val != value) return { async: false, value: 'not-equal' }; |
54 |
| - if (maxWaitMilliseconds <= 0) return { async: false, value: 'timed-out' }; |
55 |
| - maxWaitMilliseconds = performance.now() + (maxWaitMilliseconds || Infinity); |
56 |
| - let promiseResolve; |
57 |
| - let promise = new Promise((resolve) => { promiseResolve = resolve; }); |
58 |
| - if (!__Atomics_waitAsyncAddresses[0]) setTimeout(__Atomics_pollWaitAsyncAddresses, 10); |
59 |
| - __Atomics_waitAsyncAddresses.push([i32a, index, value, maxWaitMilliseconds, promiseResolve]); |
60 |
| - return { async: true, value: promise }; |
61 |
| - }; |
62 |
| -}`, |
63 |
| -#endif |
64 |
| - |
65 |
| - $polyfillWaitAsync__internal: true, |
66 |
| - $polyfillWaitAsync: () => { |
67 |
| - // nop, used for its postset to ensure `Atomics.waitAsync()` polyfill is |
68 |
| - // included exactly once and only included when needed. |
69 |
| - // Any function using Atomics.waitAsync should depend on this. |
70 |
| - }, |
71 |
| - |
72 | 10 | $atomicWaitStates__internal: true,
|
73 | 11 | $atomicWaitStates: ['ok', 'not-equal', 'timed-out'],
|
74 | 12 | $liveAtomicWaitAsyncs: {},
|
75 | 13 | $liveAtomicWaitAsyncs__internal: true,
|
76 | 14 | $liveAtomicWaitAsyncCounter: 0,
|
77 | 15 | $liveAtomicWaitAsyncCounter__internal: true,
|
78 | 16 |
|
79 |
| - emscripten_atomic_wait_async__deps: ['$atomicWaitStates', '$liveAtomicWaitAsyncs', '$liveAtomicWaitAsyncCounter', '$polyfillWaitAsync', '$callUserCallback'], |
| 17 | + emscripten_atomic_wait_async__deps: ['$atomicWaitStates', '$liveAtomicWaitAsyncs', '$liveAtomicWaitAsyncCounter', '$callUserCallback'], |
80 | 18 | emscripten_atomic_wait_async: (addr, val, asyncWaitFinished, userData, maxWaitMilliseconds) => {
|
81 | 19 | let wait = Atomics.waitAsync(HEAP32, {{{ getHeapOffset('addr', 'i32') }}}, val, maxWaitMilliseconds);
|
82 | 20 | if (!wait.async) return atomicWaitStates.indexOf(wait.value);
|
|
0 commit comments