Stream: git-wasmtime

Topic: wasmtime / issue #12128 component-model-async: Cannot ree...


view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2025 at 16:05):

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 executed

Specifically $yield-loop is, well, yielding, and then the second call to $noop I 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?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2025 at 16:05):

alexcrichton added the wasm-proposal:component-model-async label to Issue #12128.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2025 at 21:02):

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 executed

Specifically $yield-loop is, well, yielding, and then the second call to $noop I 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?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2025 at 21:03):

alexcrichton commented on issue #12128:

Ok in discussion with @lukewagner the conclusion is:

With #12043 as-is this test still traps in pretty much the same place, so this is something we'll want to fix.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2025 at 21:03):

alexcrichton assigned dicej to issue #12128.


Last updated: Dec 06 2025 at 07:03 UTC