Skip to content

fix(bindgen): fix WASM3/GC transpilation and P3 async stream runtime bugs#1346

Open
gfx wants to merge 2 commits intobytecodealliance:mainfrom
gfx:fix/wasm3-gc-p3-async-transpile
Open

fix(bindgen): fix WASM3/GC transpilation and P3 async stream runtime bugs#1346
gfx wants to merge 2 commits intobytecodealliance:mainfrom
gfx:fix/wasm3-gc-p3-async-transpile

Conversation

@gfx
Copy link
Copy Markdown
Contributor

@gfx gfx commented Mar 28, 2026

Summary

  • Enable WASM3 and wide arithmetic features so components using GC (rec groups, structs, arrays) can be validated and transpiled
  • Fix multiple P3 async/stream runtime bugs:
    • waitable-set.wait trampoline missing JSPI Suspending wrapper
    • waitableSetWait calling undefined task.waitForEvent()
    • Missing intrinsic dependencies (LowerFlatResultLowerFlatVariant, LowerFlatOptionLowerFlatVariant, WaitableSetWaitStoreEventInComponentMemory, StreamReadAsyncEventCodeEnum)
    • _lowerFlatVariant null payload crash and payloadOffset typo
    • Stream naming inconsistency (streamEndIdx vs streamEndWaitableIdx)
    • Async export void return not falling back to task.completionPromise()
  • Add globalThis._jcoStreamWriteHook for host stream delivery — without this, host-provided streams (e.g. stdout) deadlock because both the host's stream.next() and the component's stream.write suspend via JSPI and neither can make progress

🤖 Generated with Claude Code


P.S. The wasm in this PR is generated by Wado, a programming language targeted to Wasm CM + WASI-p3.

Currently, jco does not handle any wasm generated by Wado compiler. With this PR, some examples get working.

cf. wado-lang/wado#714

gfx and others added 2 commits March 28, 2026 20:44
…bugs

Enable WASM3 and wide arithmetic features so components using GC (rec
groups, structs, arrays) can be validated and transpiled. Fix multiple
P3 async/stream runtime bugs: waitable-set.wait missing JSPI Suspending
wrapper, waitableSetWait calling undefined waitForEvent(), missing
intrinsic dependencies, _lowerFlatVariant null payload crash and typo,
stream naming inconsistency, and async export void return handling.

Add a GC + WASI P3 test fixture (hello-gc-p3.wasm) to the P3 transpile
test suite.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…very

For host-provided streams (e.g. stdout), the host's writeViaStream
receives a Stream object and must read from it via stream.next(), while
the component writes to the writable end via stream.write. However,
both operations suspend via JSPI, creating a deadlock: the host awaits
stream.next() while the component awaits stream.write, and neither can
make progress because JSPI cannot interleave them.

Add a globalThis._jcoStreamWriteHook callback that intercepts
stream.write and delivers data directly to the host from linear memory,
bypassing the rendezvous mechanism entirely. This is the only workable
approach until jco's async runtime can interleave JSPI-suspended host
reads with component writes.

Add a runtime test that verifies a GC + WASI P3 component outputs
"Hello, world!\n" via the stream write hook.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gfx gfx marked this pull request as ready for review March 29, 2026 00:36
@gfx gfx requested a review from vados-cosmonic as a code owner March 29, 2026 00:36
@vados-cosmonic
Copy link
Copy Markdown
Collaborator

vados-cosmonic commented Mar 30, 2026

Hey @gfx thanks for submitting this PR -- I'd like to take the runtime fixes but not the stream write write hook solution here -- if you could split these up that would make this PR much easier to take.

There seem to be at least 3 different changes in here:

  • Runtime fixes
  • Introduction of Wasm GC/changing of features
  • Adding of jco stream write hook for stream delivery

These would be beneficial if split apart -- I will likely also adopt some of these changes in ongoing work on streams/futures in #1343 so either way thanks for the PR!

Comment on lines +1505 to +1507
if (ret === undefined) {{
const taskResult = await task.completionPromise();
if (taskResult !== undefined) {{ return taskResult; }}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code isn't quite right -- async exports will go through Instruction::AsyncTaskReturn which will return the completion promise. Did you find that to not work? An examlpe case here would be great to add to the test suite as a regression test if that's the case.

self.src.js,
r#"
const trampoline{i} = {waitable_set_wait_fn}.bind(null, {{
const trampoline{i} = new WebAssembly.Suspending({waitable_set_wait_fn}.bind(null, {{
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great catch!

try {
const { instance, cleanup } = await setupAsyncTest({
component: {
path: join(P3_COMPONENT_FIXTURES_DIR, "gc/hello-gc-p3.wasm"),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind including the source of this component? Is it written in Wado? Is there any way it can be written in Rust instead and built with the rest of the test components?

It's also possible to add the wado code + toolchain to testing infrastructure, but that should be under a separate PR if possible.

@vados-cosmonic
Copy link
Copy Markdown
Collaborator

Preparing a PR with the changes that I'm ready to take from here -- will open and merge that soon!

vados-cosmonic added a commit to vados-cosmonic/jco that referenced this pull request Mar 30, 2026
This commit enables wasm 3.0 spec features and wide arithmetic
features, as introduced by the PR against Jco by Wado compiler
maintainers.

(see: bytecodealliance#1346)
(see
https://github.com/WebAssembly/spec/tree/main/specification/wasm-3.0)

Co-Authored-By: FUJI Goro <g.psy.va@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
vados-cosmonic added a commit to vados-cosmonic/jco that referenced this pull request Mar 30, 2026
This commit enables wasm 3.0 spec features and wide arithmetic
features, as introduced by the PR against Jco by Wado compiler
maintainers.

(see: bytecodealliance#1346)

(see
https://github.com/WebAssembly/spec/tree/main/specification/wasm-3.0)

Co-Authored-By: FUJI Goro <g.psy.va@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
vados-cosmonic added a commit to vados-cosmonic/jco that referenced this pull request Mar 30, 2026
This commit enables wasm 3.0 spec features and wide arithmetic
features, as introduced by the PR against Jco by Wado compiler
maintainers.

(see: bytecodealliance#1346)

(see
https://github.com/WebAssembly/spec/tree/main/specification/wasm-3.0)

Co-Authored-By: FUJI Goro <g.psy.va@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
vados-cosmonic added a commit to vados-cosmonic/jco that referenced this pull request Mar 30, 2026
This commit enables wasm 3.0 spec features and wide arithmetic
features, as introduced by the PR against Jco by Wado compiler
maintainers.

(see: bytecodealliance#1346)

(see
https://github.com/WebAssembly/spec/tree/main/specification/wasm-3.0)

Co-Authored-By: FUJI Goro <g.psy.va@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
github-merge-queue bot pushed a commit that referenced this pull request Mar 30, 2026
This commit enables wasm 3.0 spec features and wide arithmetic
features, as introduced by the PR against Jco by Wado compiler
maintainers.

(see: #1346)

(see
https://github.com/WebAssembly/spec/tree/main/specification/wasm-3.0)

Co-Authored-By: FUJI Goro <g.psy.va@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants