Skip to content

fix(wasm): ccall({async:true}) — fixes ASYNCIFY streaming#34

Merged
unamedkr merged 1 commit intomainfrom
fix/wasm-ccall-async
Apr 10, 2026
Merged

fix(wasm): ccall({async:true}) — fixes ASYNCIFY streaming#34
unamedkr merged 1 commit intomainfrom
fix/wasm-ccall-async

Conversation

@unamedkr
Copy link
Copy Markdown
Collaborator

The actual root cause of ALL WASM hanging

Module._wasm_generate_async(ptr, 0.7, 256) is a direct C function call. Even with ASYNCIFY enabled, direct calls do NOT return Promises. The await resolves immediately, and when emscripten_sleep(0) fires inside the C code, the ASYNCIFY unwind has nowhere to go — it hangs.

The try/catch was then calling Module._wasm_generate() (sync), which blocks the entire main thread. We never saw the error because the catch was silent.

Fix

Replace with Module.ccall('wasm_generate_async', ..., {async: true}). This is Emscripten's documented ASYNCIFY pattern — ccall with {async: true} creates a proper async wrapper that returns a Promise and correctly handles sleep/unwind/rewind cycles.

Added ccall and cwrap to EXPORTED_RUNTIME_METHODS.

This explains everything

Symptom Cause
PR #25-27: hang after generation Direct call, silent catch fallback to sync
PR #28: Web Worker "fix" Worked around it but broke pthreads
PR #30: prefill sleep hang Made it worse — more sleep calls in broken path
PR #32: remove pthreads Didn't help — pthreads weren't the issue
PR #33: remove prefill sleep Didn't help — generation sleep was broken too
This PR: ccall({async:true}) Fixes the actual calling convention

🤖 Generated with Claude Code

Root cause of all WASM hanging: Module._wasm_generate_async() is a
DIRECT function call that does NOT return a Promise even with ASYNCIFY.
Only Module.ccall('fn', ..., {async: true}) makes Emscripten create
the async wrapper that properly unwinds/rewinds the C stack.

The try/catch was silently falling through to Module._wasm_generate()
(the sync version), blocking the entire main thread.

Fix: replace Module._wasm_generate_async() with Module.ccall() using
{async: true}. Add ccall/cwrap to EXPORTED_RUNTIME_METHODS.

This is the documented Emscripten ASYNCIFY pattern:
https://emscripten.org/docs/porting/asyncify.html#making-async-web-apis-behave-as-if-they-were-synchronous

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@unamedkr unamedkr merged commit 60e44c6 into main Apr 10, 2026
@unamedkr unamedkr deleted the fix/wasm-ccall-async branch April 10, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant