Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add component-model-async/lift.wast test #10083

Merged
merged 1 commit into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/fuzzing/src/generators/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl Config {
extended_const,
wide_arithmetic,
component_model_more_flags,
component_model_async,
simd,

hogs_memory: _,
Expand All @@ -151,6 +152,7 @@ impl Config {
self.module_config.function_references_enabled =
function_references.or(gc).unwrap_or(false);
self.module_config.component_model_more_flags = component_model_more_flags.unwrap_or(false);
self.module_config.component_model_async = component_model_async.unwrap_or(false);

// Enable/disable proposals that wasm-smith has knobs for which will be
// read when creating `wasmtime::Config`.
Expand Down Expand Up @@ -266,6 +268,7 @@ impl Config {
.wasm_wide_arithmetic(self.module_config.config.wide_arithmetic_enabled)
.wasm_extended_const(self.module_config.config.extended_const_enabled)
.wasm_component_model_more_flags(self.module_config.component_model_more_flags)
.wasm_component_model_async(self.module_config.component_model_async)
.native_unwind_info(cfg!(target_os = "windows") || self.wasmtime.native_unwind_info)
.cranelift_nan_canonicalization(self.wasmtime.canonicalize_nans)
.cranelift_opt_level(self.wasmtime.opt_level.to_wasmtime())
Expand Down
2 changes: 2 additions & 0 deletions crates/fuzzing/src/generators/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct ModuleConfig {
// config-to-`wasmtime::Config` translation.
pub function_references_enabled: bool,
pub component_model_more_flags: bool,
pub component_model_async: bool,
}

impl<'a> Arbitrary<'a> for ModuleConfig {
Expand Down Expand Up @@ -62,6 +63,7 @@ impl<'a> Arbitrary<'a> for ModuleConfig {

Ok(ModuleConfig {
component_model_more_flags: false,
component_model_async: false,
function_references_enabled: config.gc_enabled,
config,
})
Expand Down
2 changes: 1 addition & 1 deletion crates/misc/component-test-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ publish = false
env_logger = { workspace = true }
anyhow = { workspace = true }
arbitrary = { workspace = true, features = ["derive"] }
wasmtime = { workspace = true, features = ["component-model", "async"] }
wasmtime = { workspace = true, features = ["component-model", "async", "component-model-async"] }
wasmtime-environ = { workspace = true }
wasmtime-wast-util = { path = '../../wast-util' }
target-lexicon = { workspace = true }
3 changes: 3 additions & 0 deletions crates/misc/component-test-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
extended_const,
wide_arithmetic,
component_model_more_flags,
component_model_async,
nan_canonicalization,
simd,

Expand All @@ -184,6 +185,7 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
let extended_const = extended_const.unwrap_or(false);
let wide_arithmetic = wide_arithmetic.unwrap_or(false);
let component_model_more_flags = component_model_more_flags.unwrap_or(false);
let component_model_async = component_model_async.unwrap_or(false);
let nan_canonicalization = nan_canonicalization.unwrap_or(false);
let relaxed_simd = relaxed_simd.unwrap_or(false);

Expand All @@ -210,5 +212,6 @@ pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::
.wasm_extended_const(extended_const)
.wasm_wide_arithmetic(wide_arithmetic)
.wasm_component_model_more_flags(component_model_more_flags)
.wasm_component_model_async(component_model_async)
.cranelift_nan_canonicalization(nan_canonicalization);
}
13 changes: 13 additions & 0 deletions crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,19 @@ impl Config {
self
}

/// Configures whether components support the async ABI [proposal] for
/// lifting and lowering functions, as well as `stream`, `future`, and
/// `error-context` types.
///
/// Please note that Wasmtime's support for this feature is _very_ incomplete.
///
/// [proposal]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md
#[cfg(feature = "component-model-async")]
pub fn wasm_component_model_async(&mut self, enable: bool) -> &mut Self {
self.wasm_feature(WasmFeatures::COMPONENT_MODEL_ASYNC, enable);
self
}

/// Configures which compilation strategy will be used for wasm modules.
///
/// This method can be used to configure which compiler is used for wasm
Expand Down
9 changes: 8 additions & 1 deletion crates/wasmtime/src/engine/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ struct WasmFeatures {
custom_page_sizes: bool,
component_model_more_flags: bool,
component_model_multiple_returns: bool,
component_model_async: bool,
gc_types: bool,
wide_arithmetic: bool,
}
Expand Down Expand Up @@ -253,7 +254,6 @@ impl Metadata<'_> {
assert!(!shared_everything_threads);
assert!(!legacy_exceptions);
assert!(!stack_switching);
assert!(!component_model_async);

Metadata {
target: engine.compiler().triple().to_string(),
Expand All @@ -278,6 +278,7 @@ impl Metadata<'_> {
custom_page_sizes,
component_model_more_flags,
component_model_multiple_returns,
component_model_async,
gc_types,
wide_arithmetic,
},
Expand Down Expand Up @@ -488,6 +489,7 @@ impl Metadata<'_> {
custom_page_sizes,
component_model_more_flags,
component_model_multiple_returns,
component_model_async,
gc_types,
wide_arithmetic,
} = self.features;
Expand Down Expand Up @@ -574,6 +576,11 @@ impl Metadata<'_> {
other.contains(F::COMPONENT_MODEL_MULTIPLE_RETURNS),
"WebAssembly component model support for multiple returns",
)?;
Self::check_bool(
component_model_async,
other.contains(F::COMPONENT_MODEL_ASYNC),
"WebAssembly component model support for async lifts/lowers, futures, streams, and errors",
)?;
Self::check_cfg_bool(
cfg!(feature = "gc"),
"gc",
Expand Down
13 changes: 11 additions & 2 deletions crates/wasmtime/src/runtime/component/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,7 @@ impl<'a> Instantiator<'a> {
}

GlobalInitializer::ExtractCallback(callback) => {
_ = callback;
todo!()
self.extract_callback(store.0, callback)
}

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

fn extract_callback(&mut self, store: &mut StoreOpaque, callback: &ExtractCallback) {
let func_ref = match self.data.lookup_def(store, &callback.def) {
crate::runtime::vm::Export::Function(f) => f.func_ref,
_ => unreachable!(),
};
self.data
.state
.set_runtime_callback(callback.index, func_ref);
}

fn extract_post_return(&mut self, store: &mut StoreOpaque, post_return: &ExtractPostReturn) {
let func_ref = match self.data.lookup_def(store, &post_return.def) {
crate::runtime::vm::Export::Function(f) => f.func_ref,
Expand Down
20 changes: 20 additions & 0 deletions crates/wasmtime/src/runtime/vm/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,16 @@ impl ComponentInstance {
}
}

/// Same as `set_runtime_memory` but for async callback function pointers.
pub fn set_runtime_callback(&mut self, idx: RuntimeCallbackIndex, ptr: NonNull<VMFuncRef>) {
unsafe {
let storage =
self.vmctx_plus_offset_mut::<VmPtr<VMFuncRef>>(self.offsets.runtime_callback(idx));
debug_assert!((*storage).as_ptr() as usize == INVALID_PTR);
*storage = ptr.into();
}
}

/// Same as `set_runtime_memory` but for post-return function pointers.
pub fn set_runtime_post_return(
&mut self,
Expand Down Expand Up @@ -493,6 +503,11 @@ impl ComponentInstance {
let offset = self.offsets.runtime_realloc(i);
*self.vmctx_plus_offset_mut(offset) = INVALID_PTR;
}
for i in 0..self.offsets.num_runtime_callbacks {
let i = RuntimeCallbackIndex::from_u32(i);
let offset = self.offsets.runtime_callback(i);
*self.vmctx_plus_offset_mut(offset) = INVALID_PTR;
}
for i in 0..self.offsets.num_runtime_post_returns {
let i = RuntimePostReturnIndex::from_u32(i);
let offset = self.offsets.runtime_post_return(i);
Expand Down Expand Up @@ -734,6 +749,11 @@ impl OwnedComponentInstance {
unsafe { self.instance_mut().set_runtime_realloc(idx, ptr) }
}

/// See `ComponentInstance::set_runtime_callback`
pub fn set_runtime_callback(&mut self, idx: RuntimeCallbackIndex, ptr: NonNull<VMFuncRef>) {
unsafe { self.instance_mut().set_runtime_callback(idx, ptr) }
}

/// See `ComponentInstance::set_runtime_post_return`
pub fn set_runtime_post_return(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions crates/wast-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ macro_rules! foreach_config_option {
hogs_memory
nan_canonicalization
component_model_more_flags
component_model_async
simd
gc_types
}
Expand Down
2 changes: 1 addition & 1 deletion crates/wast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ wast = { workspace = true }
log = { workspace = true }

[features]
component-model = ['wasmtime/component-model']
component-model = ['wasmtime/component-model', 'wasmtime/component-model-async']
26 changes: 26 additions & 0 deletions tests/misc_testsuite/component-model-async/lift.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
;;! component_model_async = true

;; async lift; no callback
(component
(core module $m
(func (export "foo") (param i32) unreachable)
)
(core instance $i (instantiate $m))

(func (export "foo") (param "p1" u32) (result u32)
(canon lift (core func $i "foo") async)
)
)

;; async lift; with callback
(component
(core module $m
(func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
(func (export "foo") (param i32) (result i32) unreachable)
)
(core instance $i (instantiate $m))

(func (export "foo") (param "p1" u32) (result u32)
(canon lift (core func $i "foo") async (callback (func $i "callback")))
)
)
Loading