Skip to content

Commit 6bd7188

Browse files
authored
Fix Wasm Workers + proxied JS functions to emit a proper runtime error message, instead of failing at parse error at compile time, and add a test. Fixes emscripten-core#18162. (emscripten-core#18167)
1 parent ed897a5 commit 6bd7188

4 files changed

Lines changed: 63 additions & 8 deletions

File tree

src/jsifier.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,19 @@ function ${name}(${args}) {
374374
return _emscripten_proxy_to_main_thread_js(${proxiedFunctionTable.length}, ${+sync}${args ? ', ' : ''}${args});
375375
${body}
376376
}\n`);
377-
} else if (WASM_WORKERS && ASSERTIONS) {
378-
// In ASSERTIONS builds add runtime checks that proxied functions are not attempted to be called in Wasm Workers
379-
// (since there is no automatic proxying architecture available)
380-
contentText = modifyFunction(snippet, (name, args, body) => `
381-
function ${name}(${args}) {
382-
assert(!ENVIRONMENT_IS_WASM_WORKER, "Attempted to call proxied function '${name}' in a Wasm Worker, but in Wasm Worker enabled builds, proxied function architecture is not available!");
383-
${body}
384-
}\n`);
377+
} else if (WASM_WORKERS) {
378+
if (ASSERTIONS) {
379+
// In ASSERTIONS builds add runtime checks that proxied functions are not attempted to be called in Wasm Workers
380+
// (since there is no automatic proxying architecture available)
381+
contentText = modifyFunction(snippet, (name, args, body) => `
382+
function ${name}(${args}) {
383+
assert(!ENVIRONMENT_IS_WASM_WORKER, "Attempted to call proxied function '${name}' in a Wasm Worker, but in Wasm Worker enabled builds, proxied function architecture is not available!");
384+
${body}
385+
}\n`);
386+
} else {
387+
// In non-ASSERTIONS builds directly emit the original function.
388+
contentText = snippet;
389+
}
385390
}
386391
proxiedFunctionTable.push(finalName);
387392
} else if ((USE_ASAN || USE_LSAN || UBSAN_RUNTIME) && LibraryManager.library[ident + '__noleakcheck']) {

test/test_browser.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5281,6 +5281,14 @@ def test_wasm_worker_semaphore_waitinf_acquire(self):
52815281
def test_wasm_worker_semaphore_try_acquire(self):
52825282
self.btest(test_file('wasm_worker/semaphore_try_acquire.c'), expected='0', args=['-sWASM_WORKERS'])
52835283

5284+
# Tests that calling any proxied function in a Wasm Worker will abort at runtime when ASSERTIONS are enabled.
5285+
def test_wasm_worker_proxied_function(self):
5286+
error_msg = "abort:Assertion failed: Attempted to call proxied function '_proxied_js_function' in a Wasm Worker, but in Wasm Worker enabled builds, proxied function architecture is not available!"
5287+
# Test that program aborts in ASSERTIONS-enabled builds
5288+
self.btest(test_file('wasm_worker/proxied_function.c'), expected=error_msg, args=['--js-library', test_file('wasm_worker/proxied_function.js'), '-sWASM_WORKERS', '-sASSERTIONS'])
5289+
# Test that code does not crash in ASSERTIONS-disabled builds
5290+
self.btest(test_file('wasm_worker/proxied_function.c'), expected='0', args=['--js-library', test_file('wasm_worker/proxied_function.js'), '-sWASM_WORKERS', '-sASSERTIONS=0'])
5291+
52845292
@no_firefox('no 4GB support yet')
52855293
@requires_v8
52865294
def test_zzz_zzz_4gb(self):
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This test checks whether attempting to call a proxied JS function (one with __proxy signature) will throw
2+
// an exception.
3+
4+
#include <emscripten.h>
5+
#include <emscripten/wasm_worker.h>
6+
7+
void proxied_js_function(void);
8+
9+
void test_finished()
10+
{
11+
REPORT_RESULT(0);
12+
}
13+
14+
void run_in_worker()
15+
{
16+
int threw = EM_ASM_INT({
17+
try {
18+
_proxied_js_function();
19+
} catch(e) {
20+
console.error(e);
21+
return 1;
22+
}
23+
return 0;
24+
});
25+
26+
if (!threw) {
27+
emscripten_wasm_worker_post_function_v(EMSCRIPTEN_WASM_WORKER_ID_PARENT, test_finished);
28+
}
29+
}
30+
31+
int main()
32+
{
33+
emscripten_wasm_worker_post_function_v(emscripten_malloc_wasm_worker(1024), run_in_worker);
34+
proxied_js_function(); // Pin a dependency from C code to the JS function to avoid needing to mess with cmdline export directives
35+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mergeInto(LibraryManager.library, {
2+
proxied_js_function__proxy: 'sync',
3+
proxied_js_function__sig: 'v',
4+
proxied_js_function: function() {
5+
console.log('In proxied_js_function');
6+
}
7+
});

0 commit comments

Comments
 (0)