Skip to content

Commit d9e0690

Browse files
authored
Delete the Atomics.waitAsync() polyfill (#25494)
Delete the Atomics.waitAsync() polyfill, which is not good enough to polyfill over the usage pattern in Emscripten mailbox implementation. See #25449 (comment) . The mailbox implementation has its own postMessage() fallback, so does not need the polyfill. Fixes test browser.test_gl_textures_pthreads_main_module in Firefox." This will be a breaking change to any users who successfully depended on the polyfill (i.e. only needed the partial support it brought), though it is uncertain if there are any. Fixes test `browser.test_gl_textures_pthreads_main_module` on Firefox.
1 parent b70f2d4 commit d9e0690

File tree

2 files changed

+1
-64
lines changed

2 files changed

+1
-64
lines changed

src/lib/libatomic.js

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,14 @@
77
assert(SHARED_MEMORY);
88

99
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-
7210
$atomicWaitStates__internal: true,
7311
$atomicWaitStates: ['ok', 'not-equal', 'timed-out'],
7412
$liveAtomicWaitAsyncs: {},
7513
$liveAtomicWaitAsyncs__internal: true,
7614
$liveAtomicWaitAsyncCounter: 0,
7715
$liveAtomicWaitAsyncCounter__internal: true,
7816

79-
emscripten_atomic_wait_async__deps: ['$atomicWaitStates', '$liveAtomicWaitAsyncs', '$liveAtomicWaitAsyncCounter', '$polyfillWaitAsync', '$callUserCallback'],
17+
emscripten_atomic_wait_async__deps: ['$atomicWaitStates', '$liveAtomicWaitAsyncs', '$liveAtomicWaitAsyncCounter', '$callUserCallback'],
8018
emscripten_atomic_wait_async: (addr, val, asyncWaitFinished, userData, maxWaitMilliseconds) => {
8119
let wait = Atomics.waitAsync(HEAP32, {{{ getHeapOffset('addr', 'i32') }}}, val, maxWaitMilliseconds);
8220
if (!wait.async) return atomicWaitStates.indexOf(wait.value);

src/lib/libwasm_worker.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ if (ENVIRONMENT_IS_WASM_WORKER
298298
return Atomics.isLockFree(width);
299299
},
300300

301-
emscripten_lock_async_acquire__deps: ['$polyfillWaitAsync'],
302301
emscripten_lock_async_acquire: (lock, asyncWaitFinished, userData, maxWaitMilliseconds) => {
303302
let dispatch = (val, ret) => {
304303
setTimeout(() => {

0 commit comments

Comments
 (0)