From e6f07ca27761c0f67ec3cb65e4e6420d8901616b Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 30 Apr 2025 16:50:52 -0700 Subject: [PATCH] Use normal unquoted names in wasm worker messages. NFC Now that the wasm worker code is always in the same file as the main JS code there is no need to quote or minify these names. See #24163. --- src/lib/libwasm_worker.js | 31 ++-- src/lib/libwebaudio.js | 12 +- src/runtime_debug.js | 4 +- src/wasm_worker.js | 19 ++- test/code_size/audio_worklet_wasm.js | 157 +++++++++++---------- test/code_size/audio_worklet_wasm.json | 12 +- test/code_size/hello_wasm_worker_wasm.js | 81 ++++++----- test/code_size/hello_wasm_worker_wasm.json | 8 +- tools/js_manipulation.py | 2 +- 9 files changed, 163 insertions(+), 163 deletions(-) diff --git a/src/lib/libwasm_worker.js b/src/lib/libwasm_worker.js index 5c957cd362d11..dbd2d8674cc38 100644 --- a/src/lib/libwasm_worker.js +++ b/src/lib/libwasm_worker.js @@ -91,14 +91,14 @@ addToLibrary({ #endif ], $_wasmWorkerInitializeRuntime: () => { - let m = Module; #if ASSERTIONS - assert(m && m['$ww']); - assert(m['sb'] % 16 == 0); - assert(m['sz'] % 16 == 0); + assert(wwParams); + assert(wwParams.wwID); + assert(wwParams.stackLowestAddress % 16 == 0); + assert(wwParams.stackSize % 16 == 0); #endif #if RUNTIME_DEBUG - dbg("wasmWorkerInitializeRuntime $ww:", m['$ww']); + dbg("wasmWorkerInitializeRuntime wwID:", wwParams.wwID); #endif #if !MINIMAL_RUNTIME && isSymbolNeeded('$noExitRuntime') @@ -113,11 +113,12 @@ addToLibrary({ // already exists". So for now, invoke this function from JS side. TODO: // remove this in the future. Note that this call is not exactly correct, // since this limit will include the TLS slot, that will be part of the - // region between m['sb'] and m['sz'], so we need to fix up the call below. - ___set_stack_limits(m['sb'] + m['sz'], m['sb']); + // region between wwParams.stackLowestAddress and wwParams.stackSize, so we + // need to fix up the call below. + ___set_stack_limits(wwParams.stackLowestAddress + wwParams.stackSize, wwParams.stackLowestAddress); #endif // Run the C side Worker initialization for stack and TLS. - __emscripten_wasm_worker_initialize(m['sb'], m['sz']); + __emscripten_wasm_worker_initialize(wwParams.stackLowestAddress, wwParams.stackSize); #if PTHREADS // Record the pthread configuration, and whether this Wasm Worker supports synchronous blocking in emscripten_futex_wait(). // (regular Wasm Workers do, AudioWorklets don't) @@ -198,15 +199,15 @@ if (ENVIRONMENT_IS_WASM_WORKER worker.postMessage({ // Signal with a non-zero value that this Worker will be a Wasm Worker, // and not the main browser thread. - '$ww': _wasmWorkersID, + wwID: _wasmWorkersID, #if MINIMAL_RUNTIME - 'wasm': Module['wasm'], + wasm: Module['wasm'], #else - 'wasm': wasmModule, + wasm: wasmModule, #endif - 'mem': wasmMemory, - 'sb': stackLowestAddress, // sb = stack bottom (lowest stack address, SP points at this when stack is full) - 'sz': stackSize, // sz = stack size + wasmMemory, + stackLowestAddress, // sb = stack bottom (lowest stack address, SP points at this when stack is full) + stackSize, // sz = stack size }); worker.onmessage = _wasmWorkerRunPostMessage; #if ENVIRONMENT_MAY_BE_NODE @@ -244,7 +245,7 @@ if (ENVIRONMENT_IS_WASM_WORKER #endif }, - emscripten_wasm_worker_self_id: () => Module['$ww'], + emscripten_wasm_worker_self_id: () => wwParams?.wwID, emscripten_wasm_worker_post_function_v: (id, funcPtr) => { _wasmWorkers[id].postMessage({'_wsc': funcPtr, 'x': [] }); // "WaSm Call" diff --git a/src/lib/libwebaudio.js b/src/lib/libwebaudio.js index 19ba189006fca..c01f55fdafa6f 100644 --- a/src/lib/libwebaudio.js +++ b/src/lib/libwebaudio.js @@ -190,15 +190,15 @@ let LibraryWebAudio = { // Assign the loaded AudioWorkletGlobalScope a Wasm Worker ID so that // it can utilized its own TLS slots, and it is recognized to not be // the main browser thread. - '$ww': _wasmWorkersID++, + wwID: _wasmWorkersID++, #if MINIMAL_RUNTIME - 'wasm': Module['wasm'], + wasm: Module['wasm'], #else - 'wasm': wasmModule, + wasm: wasmModule, #endif - 'mem': wasmMemory, - 'sb': stackLowestAddress, // sb = stack base - 'sz': stackSize, // sz = stack size + wasmMemory, + stackLowestAddress, // sb = stack base + stackSize, // sz = stack size } }); audioWorklet.bootstrapMessage.port.onmessage = _EmAudioDispatchProcessorCallback; diff --git a/src/runtime_debug.js b/src/runtime_debug.js index fa0896b7b3033..ffa8448f6b1d8 100644 --- a/src/runtime_debug.js +++ b/src/runtime_debug.js @@ -159,8 +159,8 @@ function unexportedRuntimeSymbol(sym) { function initWorkerLogging() { function getLogPrefix() { #if WASM_WORKERS - if (Module['$ww']) { - return `ww:${Module['$ww']}:` + if (wwParams?.wwID) { + return `ww:${wwParams?.wwID}:` } #endif #if PTHREADS diff --git a/src/wasm_worker.js b/src/wasm_worker.js index 7fc284f8955ad..0ce2dc08f238a 100644 --- a/src/wasm_worker.js +++ b/src/wasm_worker.js @@ -1,7 +1,8 @@ +var wwParams; + /** * Called once the intiial message has been recieved from the creating thread. - * The `props` object is the list of properties sent via postMessage to create - * the worker. + * The `props` object is property bag sent via postMessage to create the worker. * * This function is called both in normal wasm workers and in audio worklets. */ @@ -9,21 +10,19 @@ function startWasmWorker(props) { #if RUNTIME_DEBUG dbg('startWasmWorker', props); #endif -#if MINIMAL_RUNTIME - Module ||= {}; -#endif - /** @suppress {checkTypes} */ - Object.assign(Module, props); - wasmMemory = props['mem']; + wwParams = props; + wasmMemory = props.wasmMemory; updateMemoryViews(); #if MINIMAL_RUNTIME + Module ||= {}; + Module['wasm'] = props.wasm; loadModule() #else - wasmModuleReceived(props['wasm']); + wasmModuleReceived(props.wasm); #endif // Drop now unneeded references to from the Module object in this Worker, // these are not needed anymore. - props['wasm'] = props['mem'] = 0; + props.wasm = props.memMemory = 0; } #if AUDIO_WORKLET diff --git a/test/code_size/audio_worklet_wasm.js b/test/code_size/audio_worklet_wasm.js index bb6bfb0d56790..ba169271b1629 100644 --- a/test/code_size/audio_worklet_wasm.js +++ b/test/code_size/audio_worklet_wasm.js @@ -1,19 +1,20 @@ -var h = globalThis.Module || "undefined" != typeof Module ? Module : {}, p = "em-ww" == globalThis.name, q = "undefined" !== typeof AudioWorkletGlobalScope, r, t, v, x, y, H, X, Y, K, J, I, Z; +var h = globalThis.Module || "undefined" != typeof Module ? Module : {}, p = "em-ww" == globalThis.name, q = "undefined" !== typeof AudioWorkletGlobalScope, r, t, v, x, y, C, I, X, Y, L, K, J, Z; q && (p = !0); -function C(a) { +function D(a) { + C = a; + y = a.I; + E(); h ||= {}; - Object.assign(h, a); - y = a.mem; - D(); - F(); - a.wasm = a.mem = 0; + h.wasm = a.C; + G(); + a.C = a.J = 0; } p && !q && (onmessage = a => { onmessage = null; - C(a.data); + D(a.data); }); if (q) { @@ -22,7 +23,7 @@ if (q) { constructor(d) { super(); d = d.processorOptions; - this.u = H.get(d.u); + this.u = I.get(d.u); this.v = d.v; this.s = d.s; } @@ -30,11 +31,11 @@ if (q) { return c; } process(d, k, f) { - let m = d.length, w = k.length, E = 0, l, z, n, u = 4 * this.s, g = 12 * (m + w), V = I(), A, G, B; + let m = d.length, w = k.length, F = 0, l, z, n, u = 4 * this.s, g = 12 * (m + w), W = J(), A, H, B; for (l of d) g += l.length * u; for (l of k) g += l.length * u; - for (l in f) g += f[l].byteLength + 8, ++E; - A = J(g); + for (l in f) g += f[l].byteLength + 8, ++F; + A = K(g); g = A >> 2; n = A + 12 * m; for (l of d) { @@ -44,34 +45,34 @@ if (q) { g += 3; for (z of l) x.set(z, n >> 2), n += u; } - G = n; - g = G >> 2; + H = n; + g = H >> 2; d = (n += 12 * w) >> 2; for (l of k) v[g] = l.length, v[g + 1] = this.s, v[g + 2] = n, g += 3, n += u * l.length; u = n; g = u >> 2; - n += 8 * E; + n += 8 * F; for (l = 0; B = f[l++]; ) v[g] = B.length, v[g + 1] = n, g += 2, x.set(B, n >> 2), n += 4 * B.length; - if (f = this.u(m, A, w, G, E, u, this.v)) for (l of k) for (z of l) for (g = 0; g < this.s; ++g) z[g] = x[d++]; - K(V); + if (f = this.u(m, A, w, H, F, u, this.v)) for (l of k) for (z of l) for (g = 0; g < this.s; ++g) z[g] = x[d++]; + L(W); return !!f; } } return e; } - var L; + var M; class b extends AudioWorkletProcessor { constructor(c) { super(); - C(c.processorOptions); - L = this.port; - L.onmessage = async e => { + D(c.processorOptions); + M = this.port; + M.onmessage = async e => { e = e.data; - e._wpn ? (registerProcessor(e._wpn, a(e.C)), L.postMessage({ + e._wpn ? (registerProcessor(e._wpn, a(e.D)), M.postMessage({ _wsc: e.u, - A: [ e.D, 1, e.v ] - })) : e._wsc && H.get(e._wsc)(...e.A); + A: [ e.F, 1, e.v ] + })) : e._wsc && I.get(e._wsc)(...e.A); }; } process() {} @@ -79,7 +80,7 @@ if (q) { registerProcessor("em-bootstrap", b); } -function D() { +function E() { var a = y.buffer; t = new Uint8Array(a); r = new Int32Array(a); @@ -91,18 +92,18 @@ p || (y = h.mem || new WebAssembly.Memory({ initial: 256, maximum: 256, shared: !0 -}), D()); +}), E()); -var M = [], N = a => { +var N = [], O = a => { a = a.data; let b = a._wsc; - b && H.get(b)(...a.x); -}, O = a => { - M.push(a); -}, P = a => K(a), Q = () => I(), S = (a, b, c, e) => { - b = R[b]; - R[a].connect(b.destination || b, c, e); -}, R = {}, T = 0, U = "undefined" != typeof TextDecoder ? new TextDecoder : void 0, W = (a = 0) => { + b && I.get(b)(...a.x); +}, P = a => { + N.push(a); +}, Q = a => L(a), R = () => J(), aa = (a, b, c, e) => { + b = S[b]; + S[a].connect(b.destination || b, c, e); +}, S = {}, T = 0, U = "undefined" != typeof TextDecoder ? new TextDecoder : void 0, V = (a = 0) => { for (var b = t, c = a + NaN, e = a; b[e] && !(e >= c); ) ++e; if (16 < e - a && b.buffer && U) return U.decode(b.slice(a, e)); for (c = ""; a < e; ) { @@ -117,18 +118,18 @@ var M = [], N = a => { } else c += String.fromCharCode(d); } return c; -}, aa = a => { +}, ba = a => { var b = window.AudioContext || window.webkitAudioContext; if (a >>= 2) { - var c = v[a] ? (c = v[a]) ? W(c) : "" : void 0; + var c = v[a] ? (c = v[a]) ? V(c) : "" : void 0; a = { latencyHint: c, sampleRate: r[a + 1] || void 0 }; } else a = void 0; - if (c = b) b = new b(a), R[++T] = b, c = T; + if (c = b) b = new b(a), S[++T] = b, c = T; return c; -}, ba = (a, b, c, e, d) => { +}, ca = (a, b, c, e, d) => { if (c >>= 2) { var k = r[c], f = r[c + 1]; if (v[c + 2]) { @@ -149,10 +150,10 @@ var M = [], N = a => { } }; } else e = void 0; - a = new AudioWorkletNode(R[a], b ? W(b) : "", e); - R[++T] = a; + a = new AudioWorkletNode(S[a], b ? V(b) : "", e); + S[++T] = a; return T; -}, ca = (a, b, c, e) => { +}, da = (a, b, c, e) => { b >>= 2; let d = [], k = v[b + 1], f = v[b + 2] >> 2, m = 0; for (;k--; ) d.push({ @@ -162,59 +163,59 @@ var M = [], N = a => { maxValue: x[f++], automationRate: [ "a", "k" ][v[f++]] + "-rate" }); - k = R[a].audioWorklet.B.port; + k = S[a].audioWorklet.B.port; f = k.postMessage; - b = (b = v[b]) ? W(b) : ""; + b = (b = v[b]) ? V(b) : ""; f.call(k, { _wpn: b, - C: d, - D: a, + D: d, + F: a, u: c, v: e }); -}, da = () => !1, ea = 1, fa = a => { +}, ea = () => !1, fa = 1, ha = a => { a = a.data; let b = a._wsc; - b && H.get(b)(...a.A); -}, ha = a => J(a), ia = (a, b, c, e, d) => { - let k = R[a], f = k.audioWorklet, m = () => { - H.get(e)(a, 0, d); + b && I.get(b)(...a.A); +}, ia = a => K(a), ja = (a, b, c, e, d) => { + let k = S[a], f = k.audioWorklet, m = () => { + I.get(e)(a, 0, d); }; if (!f) return m(); f.addModule(h.js).then((() => { f.B = new AudioWorkletNode(k, "em-bootstrap", { processorOptions: { - $ww: ea++, - wasm: h.wasm, - mem: y, - sb: b, - sz: c + K: fa++, + C: h.wasm, + I: y, + G: b, + H: c } }); - f.B.port.onmessage = fa; - H.get(e)(a, 1, d); + f.B.port.onmessage = ha; + I.get(e)(a, 1, d); })).catch(m); }; -function ja(a) { +function ka(a) { let b = document.createElement("button"); b.innerHTML = "Toggle playback"; document.body.appendChild(b); - a = R[a]; + a = S[a]; b.onclick = () => { "running" != a.state ? a.resume() : a.suspend(); }; } -function F() { +function G() { X = { - f: ja, - g: S, - d: aa, - h: ba, - e: ca, - b: da, - c: ia, + f: ka, + g: aa, + d: ba, + h: ca, + e: da, + b: ea, + c: ja, a: y }; WebAssembly.instantiate(h.wasm, { @@ -222,19 +223,19 @@ function F() { }).then((a => { a = a.instance.exports; Y = a.j; - K = a.l; - J = a.m; - I = a.n; + L = a.l; + K = a.m; + J = a.n; Z = a.o; - H = a.k; - h.stackSave = Q; - h.stackAlloc = ha; - h.stackRestore = P; - h.wasmTable = H; - p ? (a = h, Z(a.sb, a.sz), "undefined" === typeof AudioWorkletGlobalScope && (removeEventListener("message", O), - M = M.forEach(N), addEventListener("message", N))) : a.i(); + I = a.k; + h.stackSave = R; + h.stackAlloc = ia; + h.stackRestore = Q; + h.wasmTable = I; + p ? (Z(C.G, C.H), "undefined" === typeof AudioWorkletGlobalScope && (removeEventListener("message", P), + N = N.forEach(O), addEventListener("message", O))) : a.i(); p || Y(); })); } -p || F(); \ No newline at end of file +p || G(); \ No newline at end of file diff --git a/test/code_size/audio_worklet_wasm.json b/test/code_size/audio_worklet_wasm.json index b46cd741eb3bf..92425c8604a28 100644 --- a/test/code_size/audio_worklet_wasm.json +++ b/test/code_size/audio_worklet_wasm.json @@ -1,10 +1,10 @@ { "a.html": 519, "a.html.gz": 364, - "a.js": 3872, - "a.js.gz": 2067, - "a.wasm": 1287, - "a.wasm.gz": 859, - "total": 5678, - "total_gz": 3290 + "a.js": 3850, + "a.js.gz": 2049, + "a.wasm": 1256, + "a.wasm.gz": 841, + "total": 5625, + "total_gz": 3254 } diff --git a/test/code_size/hello_wasm_worker_wasm.js b/test/code_size/hello_wasm_worker_wasm.js index 48ef493cac20b..517c40b6b10b1 100644 --- a/test/code_size/hello_wasm_worker_wasm.js +++ b/test/code_size/hello_wasm_worker_wasm.js @@ -1,75 +1,74 @@ -var b = Module, c = "em-ww" == globalThis.name, e, k, w, x, y; +var b = Module, c = "em-ww" == globalThis.name, e, f, l, x, y, z; c && (onmessage = a => { onmessage = null; - a = a.data; - b ||= {}; - Object.assign(b, a); - e = a.mem; - f(); + f = a = a.data; + e = a.o; g(); - a.wasm = a.mem = 0; + b ||= {}; + b.wasm = a.j; + h(); + a.j = a.s = 0; }); -function f() {} +function g() {} c || (e = b.mem || new WebAssembly.Memory({ initial: 256, maximum: 256, shared: !0 -}), f()); +}), g()); -var h = [], m = a => { +var k = [], n = a => { a = a.data; let d = a._wsc; - d && k.get(d)(...a.x); -}, n = a => { - h.push(a); -}, p = {}, q = 1, r = (a, d) => { - let l = p[q] = new Worker(b.js, { + d && l.get(d)(...a.x); +}, p = a => { + k.push(a); +}, q = {}, r = 1, t = (a, d) => { + let m = q[r] = new Worker(b.js, { name: "em-ww" }); - l.postMessage({ - $ww: q, - wasm: b.wasm, - mem: e, - sb: a, - sz: d + m.postMessage({ + u: r, + j: b.wasm, + o: e, + l: a, + m: d }); - l.onmessage = m; - return q++; -}, t = () => !1, u = (a, d) => { - p[a].postMessage({ + m.onmessage = n; + return r++; +}, u = () => !1, v = (a, d) => { + q[a].postMessage({ _wsc: d, x: [] }); }; -c && (p[0] = globalThis, addEventListener("message", n)); +c && (q[0] = globalThis, addEventListener("message", p)); -function v() { +function w() { console.log("Hello from wasm worker!"); } -function g() { - w = { - b: r, - c: t, - d: u, - e: v, +function h() { + x = { + b: t, + c: u, + d: v, + e: w, a: e }; WebAssembly.instantiate(b.wasm, { - a: w + a: x }).then((a => { a = a.instance.exports; - x = a.g; - y = a.i; - k = a.h; - c ? (a = b, y(a.sb, a.sz), removeEventListener("message", n), h = h.forEach(m), - addEventListener("message", m)) : a.f(); - c || x(); + y = a.g; + z = a.i; + l = a.h; + c ? (z(f.l, f.m), removeEventListener("message", p), k = k.forEach(n), addEventListener("message", n)) : a.f(); + c || y(); })); } -c || g(); \ No newline at end of file +c || h(); \ No newline at end of file diff --git a/test/code_size/hello_wasm_worker_wasm.json b/test/code_size/hello_wasm_worker_wasm.json index 130b44ce1ee91..05d3767404b39 100644 --- a/test/code_size/hello_wasm_worker_wasm.json +++ b/test/code_size/hello_wasm_worker_wasm.json @@ -1,10 +1,10 @@ { "a.html": 519, "a.html.gz": 364, - "a.js": 856, - "a.js.gz": 548, + "a.js": 830, + "a.js.gz": 530, "a.wasm": 1881, "a.wasm.gz": 1069, - "total": 3256, - "total_gz": 1981 + "total": 3230, + "total_gz": 1963 } diff --git a/tools/js_manipulation.py b/tools/js_manipulation.py index 63d20d8a1a4a9..fafc45372af93 100644 --- a/tools/js_manipulation.py +++ b/tools/js_manipulation.py @@ -44,7 +44,7 @@ def add_files_pre_js(pre_js_list, files_pre_js): utils.write_file(pre, ''' // All the pre-js content up to here must remain later on, we need to run // it. - if (Module['$ww'] || (typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD) || (typeof ENVIRONMENT_IS_AUDIO_WORKLET != 'undefined' && ENVIRONMENT_IS_AUDIO_WORKLET)) Module['preRun'] = []; + if ((typeof ENVIRONMENT_IS_WASM_WORKER != 'undefined' && ENVIRONMENT_IS_WASM_WORKER) || (typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD) || (typeof ENVIRONMENT_IS_AUDIO_WORKLET != 'undefined' && ENVIRONMENT_IS_AUDIO_WORKLET)) Module['preRun'] = []; var necessaryPreJSTasks = Module['preRun'].slice(); ''') utils.write_file(post, '''