Skip to content

Commit 167e590

Browse files
committed
add component-model-async/lift.wast test
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes two components: one which exports a function using the async-with-callback ABI, and another which uses the async-without-callback ABI. It doesn't actually instantiate or run either component yet. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
1 parent 3948f66 commit 167e590

File tree

11 files changed

+89
-5
lines changed

11 files changed

+89
-5
lines changed

crates/fuzzing/src/generators/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ impl Config {
139139
extended_const,
140140
wide_arithmetic,
141141
component_model_more_flags,
142+
component_model_async,
142143
simd,
143144

144145
hogs_memory: _,
@@ -151,6 +152,7 @@ impl Config {
151152
self.module_config.function_references_enabled =
152153
function_references.or(gc).unwrap_or(false);
153154
self.module_config.component_model_more_flags = component_model_more_flags.unwrap_or(false);
155+
self.module_config.component_model_async = component_model_async.unwrap_or(false);
154156

155157
// Enable/disable proposals that wasm-smith has knobs for which will be
156158
// read when creating `wasmtime::Config`.
@@ -266,6 +268,7 @@ impl Config {
266268
.wasm_wide_arithmetic(self.module_config.config.wide_arithmetic_enabled)
267269
.wasm_extended_const(self.module_config.config.extended_const_enabled)
268270
.wasm_component_model_more_flags(self.module_config.component_model_more_flags)
271+
.wasm_component_model_async(self.module_config.component_model_async)
269272
.native_unwind_info(cfg!(target_os = "windows") || self.wasmtime.native_unwind_info)
270273
.cranelift_nan_canonicalization(self.wasmtime.canonicalize_nans)
271274
.cranelift_opt_level(self.wasmtime.opt_level.to_wasmtime())

crates/fuzzing/src/generators/module.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub struct ModuleConfig {
1616
// config-to-`wasmtime::Config` translation.
1717
pub function_references_enabled: bool,
1818
pub component_model_more_flags: bool,
19+
pub component_model_async: bool,
1920
}
2021

2122
impl<'a> Arbitrary<'a> for ModuleConfig {
@@ -62,6 +63,7 @@ impl<'a> Arbitrary<'a> for ModuleConfig {
6263

6364
Ok(ModuleConfig {
6465
component_model_more_flags: false,
66+
component_model_async: false,
6567
function_references_enabled: config.gc_enabled,
6668
config,
6769
})

crates/misc/component-test-util/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ publish = false
1111
env_logger = { workspace = true }
1212
anyhow = { workspace = true }
1313
arbitrary = { workspace = true, features = ["derive"] }
14-
wasmtime = { workspace = true, features = ["component-model", "async"] }
14+
wasmtime = { workspace = true, features = ["component-model", "async", "component-model-async"] }
1515
wasmtime-environ = { workspace = true }
1616
wasmtime-wast-util = { path = '../../wast-util' }
1717
target-lexicon = { workspace = true }

crates/misc/component-test-util/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
166166
extended_const,
167167
wide_arithmetic,
168168
component_model_more_flags,
169+
component_model_async,
169170
nan_canonicalization,
170171
simd,
171172

@@ -184,6 +185,7 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
184185
let extended_const = extended_const.unwrap_or(false);
185186
let wide_arithmetic = wide_arithmetic.unwrap_or(false);
186187
let component_model_more_flags = component_model_more_flags.unwrap_or(false);
188+
let component_model_async = component_model_async.unwrap_or(false);
187189
let nan_canonicalization = nan_canonicalization.unwrap_or(false);
188190
let relaxed_simd = relaxed_simd.unwrap_or(false);
189191

@@ -210,5 +212,6 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
210212
.wasm_extended_const(extended_const)
211213
.wasm_wide_arithmetic(wide_arithmetic)
212214
.wasm_component_model_more_flags(component_model_more_flags)
215+
.wasm_component_model_async(component_model_async)
213216
.cranelift_nan_canonicalization(nan_canonicalization);
214217
}

crates/wasmtime/src/config.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,19 @@ impl Config {
11111111
self
11121112
}
11131113

1114+
/// Configures whether components support the async ABI [proposal] for
1115+
/// lifting and lowering functions, as well as `stream`, `future`, and
1116+
/// `error-context` types.
1117+
///
1118+
/// Please note that Wasmtime's support for this feature is _very_ incomplete.
1119+
///
1120+
/// [proposal]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md
1121+
#[cfg(feature = "component-model-async")]
1122+
pub fn wasm_component_model_async(&mut self, enable: bool) -> &mut Self {
1123+
self.wasm_feature(WasmFeatures::COMPONENT_MODEL_ASYNC, enable);
1124+
self
1125+
}
1126+
11141127
/// Configures which compilation strategy will be used for wasm modules.
11151128
///
11161129
/// This method can be used to configure which compiler is used for wasm

crates/wasmtime/src/engine/serialization.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ struct WasmFeatures {
202202
custom_page_sizes: bool,
203203
component_model_more_flags: bool,
204204
component_model_multiple_returns: bool,
205+
component_model_async: bool,
205206
gc_types: bool,
206207
wide_arithmetic: bool,
207208
}
@@ -253,7 +254,6 @@ impl Metadata<'_> {
253254
assert!(!shared_everything_threads);
254255
assert!(!legacy_exceptions);
255256
assert!(!stack_switching);
256-
assert!(!component_model_async);
257257

258258
Metadata {
259259
target: engine.compiler().triple().to_string(),
@@ -278,6 +278,7 @@ impl Metadata<'_> {
278278
custom_page_sizes,
279279
component_model_more_flags,
280280
component_model_multiple_returns,
281+
component_model_async,
281282
gc_types,
282283
wide_arithmetic,
283284
},
@@ -488,6 +489,7 @@ impl Metadata<'_> {
488489
custom_page_sizes,
489490
component_model_more_flags,
490491
component_model_multiple_returns,
492+
component_model_async,
491493
gc_types,
492494
wide_arithmetic,
493495
} = self.features;
@@ -574,6 +576,11 @@ impl Metadata<'_> {
574576
other.contains(F::COMPONENT_MODEL_MULTIPLE_RETURNS),
575577
"WebAssembly component model support for multiple returns",
576578
)?;
579+
Self::check_bool(
580+
component_model_async,
581+
other.contains(F::COMPONENT_MODEL_ASYNC),
582+
"WebAssembly component model support for async lifts/lowers, futures, streams, and errors",
583+
)?;
577584
Self::check_cfg_bool(
578585
cfg!(feature = "gc"),
579586
"gc",

crates/wasmtime/src/runtime/component/instance.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,7 @@ impl<'a> Instantiator<'a> {
608608
}
609609

610610
GlobalInitializer::ExtractCallback(callback) => {
611-
_ = callback;
612-
todo!()
611+
self.extract_callback(store.0, callback)
613612
}
614613

615614
GlobalInitializer::ExtractPostReturn(post_return) => {
@@ -659,6 +658,16 @@ impl<'a> Instantiator<'a> {
659658
self.data.state.set_runtime_realloc(realloc.index, func_ref);
660659
}
661660

661+
fn extract_callback(&mut self, store: &mut StoreOpaque, callback: &ExtractCallback) {
662+
let func_ref = match self.data.lookup_def(store, &callback.def) {
663+
crate::runtime::vm::Export::Function(f) => f.func_ref,
664+
_ => unreachable!(),
665+
};
666+
self.data
667+
.state
668+
.set_runtime_callback(callback.index, func_ref);
669+
}
670+
662671
fn extract_post_return(&mut self, store: &mut StoreOpaque, post_return: &ExtractPostReturn) {
663672
let func_ref = match self.data.lookup_def(store, &post_return.def) {
664673
crate::runtime::vm::Export::Function(f) => f.func_ref,

crates/wasmtime/src/runtime/vm/component.rs

+20
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,16 @@ impl ComponentInstance {
375375
}
376376
}
377377

378+
/// Same as `set_runtime_memory` but for async callback function pointers.
379+
pub fn set_runtime_callback(&mut self, idx: RuntimeCallbackIndex, ptr: NonNull<VMFuncRef>) {
380+
unsafe {
381+
let storage =
382+
self.vmctx_plus_offset_mut::<VmPtr<VMFuncRef>>(self.offsets.runtime_callback(idx));
383+
debug_assert!((*storage).as_ptr() as usize == INVALID_PTR);
384+
*storage = ptr.into();
385+
}
386+
}
387+
378388
/// Same as `set_runtime_memory` but for post-return function pointers.
379389
pub fn set_runtime_post_return(
380390
&mut self,
@@ -493,6 +503,11 @@ impl ComponentInstance {
493503
let offset = self.offsets.runtime_realloc(i);
494504
*self.vmctx_plus_offset_mut(offset) = INVALID_PTR;
495505
}
506+
for i in 0..self.offsets.num_runtime_callbacks {
507+
let i = RuntimeCallbackIndex::from_u32(i);
508+
let offset = self.offsets.runtime_callback(i);
509+
*self.vmctx_plus_offset_mut(offset) = INVALID_PTR;
510+
}
496511
for i in 0..self.offsets.num_runtime_post_returns {
497512
let i = RuntimePostReturnIndex::from_u32(i);
498513
let offset = self.offsets.runtime_post_return(i);
@@ -734,6 +749,11 @@ impl OwnedComponentInstance {
734749
unsafe { self.instance_mut().set_runtime_realloc(idx, ptr) }
735750
}
736751

752+
/// See `ComponentInstance::set_runtime_callback`
753+
pub fn set_runtime_callback(&mut self, idx: RuntimeCallbackIndex, ptr: NonNull<VMFuncRef>) {
754+
unsafe { self.instance_mut().set_runtime_callback(idx, ptr) }
755+
}
756+
737757
/// See `ComponentInstance::set_runtime_post_return`
738758
pub fn set_runtime_post_return(
739759
&mut self,

crates/wast-util/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ macro_rules! foreach_config_option {
185185
hogs_memory
186186
nan_canonicalization
187187
component_model_more_flags
188+
component_model_async
188189
simd
189190
gc_types
190191
}

crates/wast/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ wast = { workspace = true }
2020
log = { workspace = true }
2121

2222
[features]
23-
component-model = ['wasmtime/component-model']
23+
component-model = ['wasmtime/component-model', 'wasmtime/component-model-async']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
;;! component_model_async = true
2+
3+
;; async lift; no callback
4+
(component
5+
(core module $m
6+
(func (export "foo") (param i32) unreachable)
7+
)
8+
(core instance $i (instantiate $m))
9+
10+
(func (export "foo") (param "p1" u32) (result u32)
11+
(canon lift (core func $i "foo") async)
12+
)
13+
)
14+
15+
;; async lift; with callback
16+
(component
17+
(core module $m
18+
(func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
19+
(func (export "foo") (param i32) (result i32) unreachable)
20+
)
21+
(core instance $i (instantiate $m))
22+
23+
(func (export "foo") (param "p1" u32) (result u32)
24+
(canon lift (core func $i "foo") async (callback (func $i "callback")))
25+
)
26+
)

0 commit comments

Comments
 (0)