Buckets:
| /** | |
| * @license | |
| * Copyright 2023 The Emscripten Authors | |
| * SPDX-License-Identifier: MIT | |
| */ | |
| assert(SHARED_MEMORY); | |
| addToLibrary({ | |
| // Chrome 87 shipped Atomics.waitAsync: | |
| // https://www.chromestatus.com/feature/6243382101803008 | |
| // However its implementation is faulty: | |
| // https://bugs.chromium.org/p/chromium/issues/detail?id=1167541 | |
| // Firefox Nightly 86.0a1 (2021-01-15) does not yet have it: | |
| // https://bugzilla.mozilla.org/show_bug.cgi?id=1467846 | |
| // And at the time of writing, no other browser has it either. | |
| #if MIN_CHROME_VERSION < 91 || MIN_SAFARI_VERSION != TARGET_NOT_SUPPORTED || MIN_FIREFOX_VERSION != TARGET_NOT_SUPPORTED || ENVIRONMENT_MAY_BE_NODE | |
| // Partially polyfill Atomics.waitAsync() if not available in the browser. | |
| // Also polyfill for old Chrome-based browsers, where Atomics.waitAsync is | |
| // broken until Chrome 91, see: | |
| // https://bugs.chromium.org/p/chromium/issues/detail?id=1167541 | |
| // https://github.com/tc39/proposal-atomics-wait-async/blob/master/PROPOSAL.md | |
| // This polyfill performs polling with setTimeout() to observe a change in the | |
| // target memory location. | |
| $waitAsyncPolyfilled: '=(!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91));', | |
| $polyfillWaitAsync__deps: ['$waitAsyncPolyfilled'], | |
| $polyfillWaitAsync__postset: `if (waitAsyncPolyfilled) { | |
| let __Atomics_waitAsyncAddresses = [/*[i32a, index, value, maxWaitMilliseconds, promiseResolve]*/]; | |
| function __Atomics_pollWaitAsyncAddresses() { | |
| let now = performance.now(); | |
| let l = __Atomics_waitAsyncAddresses.length; | |
| for (let i = 0; i < l; ++i) { | |
| let a = __Atomics_waitAsyncAddresses[i]; | |
| let expired = (now > a[3]); | |
| let awoken = (Atomics.load(a[0], a[1]) != a[2]); | |
| if (expired || awoken) { | |
| __Atomics_waitAsyncAddresses[i--] = __Atomics_waitAsyncAddresses[--l]; | |
| __Atomics_waitAsyncAddresses.length = l; | |
| a[4](awoken ? 'ok': 'timed-out'); | |
| } | |
| } | |
| if (l) { | |
| // If we still have addresses to wait, loop the timeout handler to continue polling. | |
| setTimeout(__Atomics_pollWaitAsyncAddresses, 10); | |
| } | |
| } | |
| #if ASSERTIONS && WASM_WORKERS | |
| if (!ENVIRONMENT_IS_WASM_WORKER) err('Current environment does not support Atomics.waitAsync(): polyfilling it, but this is going to be suboptimal.'); | |
| #endif | |
| /** | |
| * @param {number=} maxWaitMilliseconds | |
| */ | |
| Atomics.waitAsync = (i32a, index, value, maxWaitMilliseconds) => { | |
| let val = Atomics.load(i32a, index); | |
| if (val != value) return { async: false, value: 'not-equal' }; | |
| if (maxWaitMilliseconds <= 0) return { async: false, value: 'timed-out' }; | |
| maxWaitMilliseconds = performance.now() + (maxWaitMilliseconds || Infinity); | |
| let promiseResolve; | |
| let promise = new Promise((resolve) => { promiseResolve = resolve; }); | |
| if (!__Atomics_waitAsyncAddresses[0]) setTimeout(__Atomics_pollWaitAsyncAddresses, 10); | |
| __Atomics_waitAsyncAddresses.push([i32a, index, value, maxWaitMilliseconds, promiseResolve]); | |
| return { async: true, value: promise }; | |
| }; | |
| }`, | |
| #else | |
| $waitAsyncPolyfilled: false, | |
| #endif | |
| $polyfillWaitAsync__internal: true, | |
| $polyfillWaitAsync: () => { | |
| // nop, used for its postset to ensure `Atomics.waitAsync()` polyfill is | |
| // included exactly once and only included when needed. | |
| // Any function using Atomics.waitAsync should depend on this. | |
| }, | |
| $atomicWaitStates__internal: true, | |
| $atomicWaitStates: ['ok', 'not-equal', 'timed-out'], | |
| $liveAtomicWaitAsyncs: {}, | |
| $liveAtomicWaitAsyncs__internal: true, | |
| $liveAtomicWaitAsyncCounter: 0, | |
| $liveAtomicWaitAsyncCounter__internal: true, | |
| emscripten_atomic_wait_async__deps: ['$atomicWaitStates', '$liveAtomicWaitAsyncs', '$liveAtomicWaitAsyncCounter', '$polyfillWaitAsync', '$callUserCallback'], | |
| emscripten_atomic_wait_async: (addr, val, asyncWaitFinished, userData, maxWaitMilliseconds) => { | |
| let wait = Atomics.waitAsync(HEAP32, {{{ getHeapOffset('addr', 'i32') }}}, val, maxWaitMilliseconds); | |
| if (!wait.async) return atomicWaitStates.indexOf(wait.value); | |
| // Increment waitAsync generation counter, account for wraparound in case | |
| // application does huge amounts of waitAsyncs per second (not sure if | |
| // possible?) | |
| // Valid counter range: 0...2^31-1 | |
| let counter = liveAtomicWaitAsyncCounter; | |
| liveAtomicWaitAsyncCounter = Math.max(0, (liveAtomicWaitAsyncCounter+1)|0); | |
| liveAtomicWaitAsyncs[counter] = addr; | |
| {{{ runtimeKeepalivePush() }}} | |
| wait.value.then((value) => { | |
| if (liveAtomicWaitAsyncs[counter]) { | |
| {{{ runtimeKeepalivePop() }}} | |
| delete liveAtomicWaitAsyncs[counter]; | |
| callUserCallback(() => {{{ makeDynCall('vpiip', 'asyncWaitFinished') }}}(addr, val, atomicWaitStates.indexOf(value), userData)); | |
| } | |
| }); | |
| return -counter; | |
| }, | |
| emscripten_atomic_cancel_wait_async__deps: ['$liveAtomicWaitAsyncs'], | |
| emscripten_atomic_cancel_wait_async: (waitToken) => { | |
| #if ASSERTIONS | |
| if (waitToken == {{{ cDefs.ATOMICS_WAIT_NOT_EQUAL }}}) { | |
| warnOnce('Attempted to call emscripten_atomic_cancel_wait_async() with a value ATOMICS_WAIT_NOT_EQUAL (1) that is not a valid wait token! Check success in return value from call to emscripten_atomic_wait_async()'); | |
| } else if (waitToken == {{{ cDefs.ATOMICS_WAIT_TIMED_OUT }}}) { | |
| warnOnce('Attempted to call emscripten_atomic_cancel_wait_async() with a value ATOMICS_WAIT_TIMED_OUT (2) that is not a valid wait token! Check success in return value from call to emscripten_atomic_wait_async()'); | |
| } else if (waitToken > 0) { | |
| warnOnce(`Attempted to call emscripten_atomic_cancel_wait_async() with an invalid wait token value ${waitToken}`); | |
| } | |
| #endif | |
| var address = liveAtomicWaitAsyncs[waitToken]; | |
| if (address) { | |
| // Notify the waitAsync waiters on the memory location, so that JavaScript | |
| // garbage collection can occur. | |
| // See https://github.com/WebAssembly/threads/issues/176 | |
| // This has the unfortunate effect of causing spurious wakeup of all other | |
| // waiters at the address (which causes a small performance loss). | |
| Atomics.notify(HEAP32, {{{ getHeapOffset('address', 'i32') }}}); | |
| delete liveAtomicWaitAsyncs[waitToken]; | |
| {{{ runtimeKeepalivePop() }}} | |
| return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}}; | |
| } | |
| // This waitToken does not exist. | |
| return {{{ cDefs.EMSCRIPTEN_RESULT_INVALID_PARAM }}}; | |
| }, | |
| emscripten_atomic_cancel_all_wait_asyncs__deps: ['$liveAtomicWaitAsyncs'], | |
| emscripten_atomic_cancel_all_wait_asyncs: () => { | |
| let waitAsyncs = Object.values(liveAtomicWaitAsyncs); | |
| for (var address of waitAsyncs) { | |
| Atomics.notify(HEAP32, {{{ getHeapOffset('address', 'i32') }}}); | |
| } | |
| liveAtomicWaitAsyncs = {}; | |
| return waitAsyncs.length; | |
| }, | |
| emscripten_atomic_cancel_all_wait_asyncs_at_address__deps: ['$liveAtomicWaitAsyncs'], | |
| emscripten_atomic_cancel_all_wait_asyncs_at_address: (address) => { | |
| let numCancelled = 0; | |
| for (var [waitToken, waitAddress] of Object.entries(liveAtomicWaitAsyncs)) { | |
| if (waitAddress == address) { | |
| Atomics.notify(HEAP32, {{{ getHeapOffset('address', 'i32') }}}); | |
| delete liveAtomicWaitAsyncs[waitToken]; | |
| numCancelled++; | |
| } | |
| } | |
| return numCancelled; | |
| }, | |
| emscripten_has_threading_support: () => !!globalThis.SharedArrayBuffer, | |
| emscripten_num_logical_cores: () => | |
| #if ENVIRONMENT_MAY_BE_NODE | |
| ENVIRONMENT_IS_NODE ? require('node:os').cpus().length : | |
| #endif | |
| navigator['hardwareConcurrency'], | |
| emscripten_atomics_is_lock_free: (width) => Atomics.isLockFree(width), | |
| }); | |
Xet Storage Details
- Size:
- 7.66 kB
- Xet hash:
- 5f0e1f6460c6c6af06c21ec3bcc037ef31b70e264a07759abf71d618d02af574
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.