alexcrichton opened issue #13890:
This test:
;;! component_model_async = true ;;! component_model_threading = true (component (import "host" (instance $host (export "never-return" (func async)) )) (core module $m (import "" "never-return" (func $never-return (result i32))) (import "" "cancel" (func $cancel (param i32) (result i32))) (import "" "drop-subtask" (func $drop-subtask (param i32))) (import "" "thread.new-indirect" (func $thread-new (param i32 i32) (result i32))) (import "" "thread.index" (func $thread-index (result i32))) (import "" "thread.suspend-then-resume" (func $thread-suspend-then-resume (param i32) (result i32))) (import "" "thread.resume-later" (func $thread-resume-later (param i32))) (import "" "table" (table $table 1 funcref)) (global $main-thread (mut i32) (i32.const 0)) (global $subtask (mut i32) (i32.const 0)) (global $done (mut i32) (i32.const 0)) (elem (i32.const 0) $creator) (func (export "run") (global.set $main-thread (call $thread-index)) ;; Spawn a thread to start a task. (drop (call $thread-suspend-then-resume (call $thread-new (i32.const 0) (i32.const 0)))) (if (i32.ne (global.get $done) (i32.const 1)) (then unreachable)) ;; Should be able to cancel the subtask on this thread. (i32.ne (call $cancel (global.get $subtask)) (i32.const 4)) ;; RETURN_CANCELLED if unreachable end (call $drop-subtask (global.get $subtask)) ) ;; Start an import call then exit this thread. (func $creator (param i32) (local $ret i32) (local.set $ret (call $never-return)) (i32.ne (i32.and (local.get $ret) (i32.const 0xf)) (i32.const 1)) ;; STARTED if unreachable end (global.set $subtask (i32.shr_u (local.get $ret) (i32.const 4))) (global.set $done (i32.const 1)) (call $thread-resume-later (global.get $main-thread)) ) ) (core module $libc (table (export "table") 1 funcref)) (core instance $libc (instantiate $libc)) (alias core export $libc "table" (core table $table)) (core type $start-func-ty (func (param i32))) (core func $never-return (canon lower (func $host "never-return") async)) (core func $cancel (canon subtask.cancel)) (core func $drop-subtask (canon subtask.drop)) (core func $thread.new-indirect (canon thread.new-indirect $start-func-ty (table $table))) (core func $thread.index (canon thread.index)) (core func $thread.suspend-then-resume (canon thread.suspend-then-resume)) (core func $thread.resume-later (canon thread.resume-later)) (core instance $i (instantiate $m (with "" (instance (export "never-return" (func $never-return)) (export "cancel" (func $cancel)) (export "drop-subtask" (func $drop-subtask)) (export "thread.new-indirect" (func $thread.new-indirect)) (export "thread.index" (func $thread.index)) (export "thread.suspend-then-resume" (func $thread.suspend-then-resume)) (export "thread.resume-later" (func $thread.resume-later)) (export "table" (table $table)) )) )) (func (export "f") async (canon lift (core func $i "run"))) ) (assert_return (invoke "f"))currently fails:
$ cargo test --test wast CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast Finished `test` profile [unoptimized + debuginfo] target(s) in 0.11s Running tests/wast.rs (target/debug/deps/wast-6171bb5a11b49538) running 1 test F failures: ---- CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast ---- failed to run spec test with default engine Caused by: 0: failed directive on /home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast:86 1: resource not present failures: CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 3517 filtered out; finished in 0.02s error: test failed, to rerun pass `--test wast`The reason for this is that the host stores the caller's thread in a
HostTaskwhich is then used during lowering the results of the host task once it completes.
alexcrichton added the wasm-proposal:component-model-async label to Issue #13890.
alexcrichton added the wasm-proposal:component-threading label to Issue #13890.
alexcrichton commented on issue #13890:
In attempting to fix this I've discovered surprising behavior to the point that I'm not actually sure what we should be doing in Wasmtime. I've opened an upstream spec issue - https://github.com/WebAssembly/component-model/issues/678 - for discussion.
alexcrichton closed issue #13890:
This test:
;;! component_model_async = true ;;! component_model_threading = true (component (import "host" (instance $host (export "never-return" (func async)) )) (core module $m (import "" "never-return" (func $never-return (result i32))) (import "" "cancel" (func $cancel (param i32) (result i32))) (import "" "drop-subtask" (func $drop-subtask (param i32))) (import "" "thread.new-indirect" (func $thread-new (param i32 i32) (result i32))) (import "" "thread.index" (func $thread-index (result i32))) (import "" "thread.suspend-then-resume" (func $thread-suspend-then-resume (param i32) (result i32))) (import "" "thread.resume-later" (func $thread-resume-later (param i32))) (import "" "table" (table $table 1 funcref)) (global $main-thread (mut i32) (i32.const 0)) (global $subtask (mut i32) (i32.const 0)) (global $done (mut i32) (i32.const 0)) (elem (i32.const 0) $creator) (func (export "run") (global.set $main-thread (call $thread-index)) ;; Spawn a thread to start a task. (drop (call $thread-suspend-then-resume (call $thread-new (i32.const 0) (i32.const 0)))) (if (i32.ne (global.get $done) (i32.const 1)) (then unreachable)) ;; Should be able to cancel the subtask on this thread. (i32.ne (call $cancel (global.get $subtask)) (i32.const 4)) ;; RETURN_CANCELLED if unreachable end (call $drop-subtask (global.get $subtask)) ) ;; Start an import call then exit this thread. (func $creator (param i32) (local $ret i32) (local.set $ret (call $never-return)) (i32.ne (i32.and (local.get $ret) (i32.const 0xf)) (i32.const 1)) ;; STARTED if unreachable end (global.set $subtask (i32.shr_u (local.get $ret) (i32.const 4))) (global.set $done (i32.const 1)) (call $thread-resume-later (global.get $main-thread)) ) ) (core module $libc (table (export "table") 1 funcref)) (core instance $libc (instantiate $libc)) (alias core export $libc "table" (core table $table)) (core type $start-func-ty (func (param i32))) (core func $never-return (canon lower (func $host "never-return") async)) (core func $cancel (canon subtask.cancel)) (core func $drop-subtask (canon subtask.drop)) (core func $thread.new-indirect (canon thread.new-indirect $start-func-ty (table $table))) (core func $thread.index (canon thread.index)) (core func $thread.suspend-then-resume (canon thread.suspend-then-resume)) (core func $thread.resume-later (canon thread.resume-later)) (core instance $i (instantiate $m (with "" (instance (export "never-return" (func $never-return)) (export "cancel" (func $cancel)) (export "drop-subtask" (func $drop-subtask)) (export "thread.new-indirect" (func $thread.new-indirect)) (export "thread.index" (func $thread.index)) (export "thread.suspend-then-resume" (func $thread.suspend-then-resume)) (export "thread.resume-later" (func $thread.resume-later)) (export "table" (table $table)) )) )) (func (export "f") async (canon lift (core func $i "run"))) ) (assert_return (invoke "f"))currently fails:
$ cargo test --test wast CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast Finished `test` profile [unoptimized + debuginfo] target(s) in 0.11s Running tests/wast.rs (target/debug/deps/wast-6171bb5a11b49538) running 1 test F failures: ---- CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast ---- failed to run spec test with default engine Caused by: 0: failed directive on /home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast:86 1: resource not present failures: CraneliftNative//home/alex/code/wasmtime/tests/misc_testsuite/component-model-threading/test.wast test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 3517 filtered out; finished in 0.02s error: test failed, to rerun pass `--test wast`The reason for this is that the host stores the caller's thread in a
HostTaskwhich is then used during lowering the results of the host task once it completes.
Last updated: Jul 29 2026 at 05:03 UTC