HI, has [async] been dropped from the wasm function names, if so, does that mean a new version of wasmtime is needed?
Correct; it's due to https://github.com/WebAssembly/component-model/pull/578. If you're using the latest wasm-tools and wit-bindgen, you'll need to use Wasmtime's main branch until v40.0.0 is released.
Thanks! Looking at this wit https://github.com/bytecodealliance/wit-bindgen/blob/4284ea88f0b98e2e20e366298e95c9aa2ca4b488/tests/runtime-async/async/simple-import-params-results/test.wit#L18
It generates this c code
__attribute__((__export_name__("run")))
void __wasm_export_exports_runner_run(void) {
exports_runner_run();
}
and nothing to indicate it is async. Is that right?
I suppose more specifically why isn't [async-lift] required here any more?
async-ness is now (Wasmtime main / the above PR) part of the function signature so the flag doesn't need to be part of the name any more.
How is asyncness expressed in c in the signature? I'm wondering how that would be expressed in LLVM and c would give me a clue.
I'm not sure if async support has even been added to the C bindings generator yet.
ah ok, that might explain my confusion
Semantically, async now means "may block before returning".
Oh the C generator does have async support yeah. That specific test is this one which specifies that the run function does a sync lift into an async type, hence the lack of [async-lift]
The C bindings generator definitely supports async, and yes, the export should include [async-lift] by default for async-typed functions. This is what I see when I run wit-bindgen on main:
$ cargo run -- c -w runner tests/runtime-async/async/simple-import-params-results/test.wit
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/wit-bindgen c -w runner tests/runtime-async/async/simple-import-params-results/test.wit`
Generating "runner.c"
Generating "runner.h"
Generating "runner_component_type.o"
$ grep -B 5 -A 5 '\[async-lift\]run' runner.c
return ret;
}
// Helper Functions
__attribute__((__export_name__("[callback][async-lift]run")))
uint32_t __wasm_export_exports_runner_run_callback(uint32_t event_raw, uint32_t waitable, uint32_t code) {
runner_event_t event;
event.event = (runner_event_code_t) event_raw;
event.waitable = waitable;
event.code = code;
--
runner_subtask_status_t a_b_i_two_arguments_and_result(uint32_t x, uint32_t y, uint32_t *result) {
return __wasm_import_a_b_i_two_arguments_and_result((int32_t) (x), (int32_t) (y), (uint8_t*) result);
}
__attribute__((__export_name__("[async-lift]run")))
int32_t __wasm_export_exports_runner_run(void) {
runner_callback_code_t ret = exports_runner_run();
return ret;
}
with main wit-bindgen ?
correct
0.48/0.49 should work the same way too
Interesting, when I run target\debug\wit-bindgen.exe test --languages rust,c tests/runtime-async/async --artifacts target/artifacts --rust-wit-bindgen-path ./crates/guest-rust --runner "wasmtime -W component-model-async" I don't get that c generated. Let me debug to see where I've gone wrong
Ah; I'll bet it's this directive in runner.c: //@ args = '--rename a:b/i=test --async=-run'
That tells the test crate to disable async lift for the run function. When I run wit-bindgen-cli, it ignores that directive, hence the difference between my results and yours.
The upshot is that [async-lift] is indeed the default, but can be overridden via --async=-run
Last updated: Jan 09 2026 at 13:15 UTC