alexcrichton opened issue #12128:
This test case:
(component (component $a (core module $a (import "" "yield" (func $yield (result i32))) (func (export "yield-loop") (result i32) ;; simulate `waitable-set.poll` with a yield loop (loop call $yield drop br 0 ) unreachable ) ;; not reached (func (export "callback") (param i32 i32 i32) (result i32) unreachable) (func (export "noop")) ) (core func $yield (canon thread.yield)) (core instance $a (instantiate $a (with "" (instance (export "yield" (func $yield)) )) )) (func (export "yield-loop") (canon lift (core func $a "yield-loop") async (callback (func $a "callback")) ) ) (func (export "noop") (canon lift (core func $a "noop"))) ) (instance $a (instantiate $a)) (component $b (import "yield-loop" (func $yield-loop)) (import "noop" (func $noop)) (core func $yield-loop (canon lower (func $yield-loop) async)) (core func $noop (canon lower (func $noop))) (core module $b (import "" "yield-loop" (func $yield-loop (result i32))) (import "" "noop" (func $noop)) (func (export "run") ;; call `yield-loop`, double-check it's in the "started" state. call $yield-loop i32.const 0xf i32.and i32.const 1 i32.ne if unreachable end ;; now try to reenter the other component with some other function. call $noop ) ) (core instance $b (instantiate $b (with "" (instance (export "yield-loop" (func $yield-loop)) (export "noop" (func $noop)) )) )) (func (export "run") (canon lift (core func $b "run"))) ) (instance $b (instantiate $b (with "yield-loop" (func $a "yield-loop")) (with "noop" (func $a "noop")) )) (export "run" (func $b "run")) ) (assert_return (invoke "run"))fails with:
$ WASMTIME_BACKTRACE_DETAILS=1 wasmtime wast foo.wast -W component-model-async Error: failed to run script file 'foo.wast' Caused by: 0: failed directive on foo.wast:77 1: error while executing at wasm backtrace: 0: 0x185 - <unknown>!<wasm function 8> 1: 0x333 - wasm-function[2] at ./foo.wast:59:9 2: wasm trap: wasm `unreachable` instruction executedSpecifically
$yield-loopis, well, yielding, and then the second call to$noopI believe is dying in the fused adapter. My best guess is due to component reentrance, but I'm not 100% certain since errors from the fused adapter are pretty opaque.Is this intended behavior? Accidental behavior?
alexcrichton added the wasm-proposal:component-model-async label to Issue #12128.
alexcrichton edited issue #12128:
This test case:
(component (component $a (core module $a (import "" "yield" (func $yield (result i32))) (func (export "yield-loop") (result i32) ;; simulate `waitable-set.poll` with a yield loop (loop call $yield drop br 0 ) unreachable ) ;; not reached (func (export "callback") (param i32 i32 i32) (result i32) unreachable) (func (export "noop")) ) (core func $yield (canon thread.yield)) (core instance $a (instantiate $a (with "" (instance (export "yield" (func $yield)) )) )) (func (export "yield-loop") async (canon lift (core func $a "yield-loop") async (callback (func $a "callback")) ) ) (func (export "noop") (canon lift (core func $a "noop"))) ) (instance $a (instantiate $a)) (component $b (import "yield-loop" (func $yield-loop async)) (import "noop" (func $noop)) (core func $yield-loop (canon lower (func $yield-loop) async)) (core func $noop (canon lower (func $noop))) (core module $b (import "" "yield-loop" (func $yield-loop (result i32))) (import "" "noop" (func $noop)) (func (export "run") ;; call `yield-loop`, double-check it's in the "started" state. call $yield-loop i32.const 0xf i32.and i32.const 1 i32.ne if unreachable end ;; now try to reenter the other component with some other function. call $noop ) ) (core instance $b (instantiate $b (with "" (instance (export "yield-loop" (func $yield-loop)) (export "noop" (func $noop)) )) )) (func (export "run") async (canon lift (core func $b "run"))) ) (instance $b (instantiate $b (with "yield-loop" (func $a "yield-loop")) (with "noop" (func $a "noop")) )) (export "run" (func $b "run")) ) (assert_return (invoke "run"))fails with:
$ WASMTIME_BACKTRACE_DETAILS=1 wasmtime wast foo.wast -W component-model-async Error: failed to run script file 'foo.wast' Caused by: 0: failed directive on foo.wast:77 1: error while executing at wasm backtrace: 0: 0x185 - <unknown>!<wasm function 8> 1: 0x333 - wasm-function[2] at ./foo.wast:59:9 2: wasm trap: wasm `unreachable` instruction executedSpecifically
$yield-loopis, well, yielding, and then the second call to$noopI believe is dying in the fused adapter. My best guess is due to component reentrance, but I'm not 100% certain since errors from the fused adapter are pretty opaque.Is this intended behavior? Accidental behavior?
alexcrichton commented on issue #12128:
Ok in discussion with @lukewagner the conclusion is:
- Prior to #12043 this test should block forever. Notably the
noopcall sould be blocked on backpressure being turned on as part ofyield-loop- Post-#12043 this test should pass (with some minor
asyncedits I've applied to the OP now)With #12043 as-is this test still traps in pretty much the same place, so this is something we'll want to fix.
alexcrichton assigned dicej to issue #12128.
Last updated: Dec 06 2025 at 07:03 UTC