Skip to content
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
1 change: 1 addition & 0 deletions crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ debug-builtins = ['wasmtime/debug-builtins']
wat = ['dep:wat', 'wasmtime/wat']
pooling-allocator = ["wasmtime/pooling-allocator"]
component-model = ["wasmtime/component-model"]
component-model-async = ["component-model", "async", "wasmtime/component-model-async"]
pulley = ["wasmtime/pulley"]
all-arch = ["wasmtime/all-arch"]
# ... if you add a line above this be sure to change the other locations
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/artifact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ default = [
'debug-builtins',
'pooling-allocator',
'component-model',
'component-model-async',
'pulley',
# 'all-arch', # intentionally off-by-default
# ... if you add a line above this be sure to change the other locations
Expand All @@ -68,6 +69,7 @@ winch = ["wasmtime-c-api/winch"]
debug-builtins = ["wasmtime-c-api/debug-builtins"]
pooling-allocator = ["wasmtime-c-api/pooling-allocator"]
component-model = ["wasmtime-c-api/component-model"]
component-model-async = ["wasmtime-c-api/component-model-async"]
pulley = ["wasmtime-c-api/pulley"]
all-arch = ["wasmtime-c-api/all-arch"]
# ... if you add a line above this be sure to read the comment at the end of
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const FEATURES: &[&str] = &[
"WAT",
"POOLING_ALLOCATOR",
"COMPONENT_MODEL",
"COMPONENT_MODEL_ASYNC",
"PULLEY",
"ALL_ARCH",
];
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/cmake/features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ feature(winch ON)
feature(debug-builtins ON)
feature(pooling-allocator ON)
feature(component-model ON)
feature(component-model-async ON)
feature(pulley ON)
feature(all-arch OFF)
# ... if you add a line above this be sure to change the other locations
Expand Down
25 changes: 25 additions & 0 deletions crates/c-api/include/wasmtime/component/func.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef WASMTIME_COMPONENT_FUNC_H
#define WASMTIME_COMPONENT_FUNC_H

#include <wasmtime/async.h>
#include <wasmtime/component/types/func.h>
#include <wasmtime/component/val.h>
#include <wasmtime/conf.h>
Expand Down Expand Up @@ -69,6 +70,30 @@ WASM_API_EXTERN wasmtime_error_t *
wasmtime_component_func_post_return(const wasmtime_component_func_t *func,
wasmtime_context_t *context);

#ifdef WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

/**
* \brief Invokes \p func with the \p args given, returning the results
* asynchronously.
*
* This is the same as #wasmtime_component_func_call except that it is
* asynchronous. This is only compatible with stores associated with an
* asynchronous config.
*
* The result is a future that is owned by the caller and must be deleted via
* #wasmtime_call_future_delete.
*
* All parameters to this function must be kept alive and not modified until the
* returned #wasmtime_call_future_t is deleted.
*/
WASM_API_EXTERN wasmtime_call_future_t *wasmtime_component_func_call_async(
const wasmtime_component_func_t *func, wasmtime_context_t *context,
const wasmtime_component_val_t *args, size_t args_size,
wasmtime_component_val_t *results, size_t results_size,
wasmtime_error_t **error_ret);

#endif // WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
82 changes: 82 additions & 0 deletions crates/c-api/include/wasmtime/component/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define WASMTIME_COMPONENT_LINKER_H

#include <wasm.h>
#include <wasmtime/async.h>
#include <wasmtime/component/component.h>
#include <wasmtime/component/instance.h>
#include <wasmtime/component/types/func.h>
Expand Down Expand Up @@ -209,6 +210,87 @@ wasmtime_component_linker_instance_add_resource(
WASM_API_EXTERN void wasmtime_component_linker_instance_delete(
wasmtime_component_linker_instance_t *linker_instance);

#ifdef WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

/**
* \brief Instantiate a component in \p linker asynchronously.
*
* This is the same as #wasmtime_component_linker_instantiate except that it
* is asynchronous. This is only compatible with stores associated with an
* asynchronous config.
*
* The result is a future that is owned by the caller and must be deleted via
* #wasmtime_call_future_delete.
*
* All parameters to this function must be kept alive and not modified until the
* returned #wasmtime_call_future_t is deleted.
*
* \param linker the linker to instantiate with
* \param context the store context
* \param component the component to instantiate
* \param instance_out where to store the returned instance
* \param error_ret where to store the returned error
*/
WASM_API_EXTERN wasmtime_call_future_t *
wasmtime_component_linker_instantiate_async(
const wasmtime_component_linker_t *linker, wasmtime_context_t *context,
const wasmtime_component_t *component,
wasmtime_component_instance_t *instance_out, wasmtime_error_t **error_ret);

/// Type of the async callback used in
/// #wasmtime_component_linker_instance_add_func_async
typedef void (*wasmtime_component_func_async_callback_t)(
void *env, wasmtime_context_t *context,
const wasmtime_component_func_type_t *ty, wasmtime_component_val_t *args,
size_t nargs, wasmtime_component_val_t *results, size_t nresults,
wasmtime_error_t **error_ret,
wasmtime_async_continuation_t *continuation_ret);

/**
* \brief Define an async function within this instance.
*
* This is the same as #wasmtime_component_linker_instance_add_func except
* that it supports async callbacks.
*
* \param linker_instance the instance to define the function in
* \param name the function name
* \param name_len length of \p name in bytes
* \param callback the async callback when this function gets called
* \param data host-specific data passed to the callback invocation, can be
* `NULL`
* \param finalizer optional finalizer for \p data, can be `NULL`
* \return on success `NULL`, otherwise an error
*/
WASM_API_EXTERN wasmtime_error_t *
wasmtime_component_linker_instance_add_func_async(
wasmtime_component_linker_instance_t *linker_instance, const char *name,
size_t name_len, wasmtime_component_func_async_callback_t callback,
void *data, void (*finalizer)(void *));

#ifdef WASMTIME_FEATURE_WASI

/**
* \brief Add all WASI interfaces into the \p linker provided using async
* bindings.
*/
WASM_API_EXTERN wasmtime_error_t *
wasmtime_component_linker_add_wasip2_async(wasmtime_component_linker_t *linker);

#endif // WASMTIME_FEATURE_WASI

#ifdef WASMTIME_FEATURE_WASI_HTTP

/**
* \brief Add WASI HTTP interfaces into the \p linker provided using async
* bindings.
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_component_linker_add_wasi_http_async(
wasmtime_component_linker_t *linker);

#endif // WASMTIME_FEATURE_WASI_HTTP

#endif // WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
38 changes: 38 additions & 0 deletions crates/c-api/include/wasmtime/component/linker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,44 @@ class Linker {
return std::monostate();
}
#endif // WASMTIME_FEATURE_WASI_HTTP

#ifdef WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC
#ifdef WASMTIME_FEATURE_WASI
/**
* \brief Adds WASIp2 API definitions to this linker using async bindings.
*
* This is the same as \ref add_wasip2 except that it adds *asynchronous*
* versions of WASIp2 definitions. Only compatible with stores associated
* with an asynchronous config.
*/
Result<std::monostate> add_wasip2_async() {
wasmtime_error_t *error =
wasmtime_component_linker_add_wasip2_async(ptr.get());
if (error != nullptr) {
return Error(error);
}
return std::monostate();
}
#endif // WASMTIME_FEATURE_WASI

#ifdef WASMTIME_FEATURE_WASI_HTTP
/**
* \brief Adds WASI HTTP definitions to this linker using async bindings.
*
* This is the same as \ref add_wasi_http except that it adds
* *asynchronous* versions. Only compatible with stores associated with an
* asynchronous config.
*/
Result<std::monostate> add_wasi_http_async() {
wasmtime_error_t *error =
wasmtime_component_linker_add_wasi_http_async(ptr.get());
if (error != nullptr) {
return Error(error);
}
return std::monostate();
}
#endif // WASMTIME_FEATURE_WASI_HTTP
#endif // WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC
};

} // namespace component
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/include/wasmtime/conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#cmakedefine WASMTIME_FEATURE_DEBUG_BUILTINS
#cmakedefine WASMTIME_FEATURE_POOLING_ALLOCATOR
#cmakedefine WASMTIME_FEATURE_COMPONENT_MODEL
#cmakedefine WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC
#cmakedefine WASMTIME_FEATURE_PULLEY
#cmakedefine WASMTIME_FEATURE_ALL_ARCH
// ... if you add a line above this be sure to change the other locations
Expand Down
31 changes: 31 additions & 0 deletions crates/c-api/include/wasmtime/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,37 @@ WASMTIME_CONFIG_PROP(void, wasm_component_model_map, bool)

#endif // WASMTIME_FEATURE_COMPONENT_MODEL

#ifdef WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

/**
* \brief Configures whether the WebAssembly component-model async support will
* be enabled.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_async.
*/
WASMTIME_CONFIG_PROP(void, wasm_component_model_async, bool)

/**
* \brief Configures whether async built-in intrinsics are enabled for the
* component model.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_async_builtins.
*/
WASMTIME_CONFIG_PROP(void, wasm_component_model_async_builtins, bool)

/**
* \brief Configures whether stackful coroutine support is enabled for async
* components.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_async_stackful.
*/
WASMTIME_CONFIG_PROP(void, wasm_component_model_async_stackful, bool)

#endif // WASMTIME_FEATURE_COMPONENT_MODEL_ASYNC

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
12 changes: 9 additions & 3 deletions crates/c-api/src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ pub struct wasmtime_call_future_t<'a> {
underlying: Pin<Box<dyn Future<Output = ()> + 'a>>,
}

impl<'a> wasmtime_call_future_t<'a> {
pub(crate) fn new(future: Pin<Box<dyn Future<Output = ()> + 'a>>) -> Self {
Self { underlying: future }
}
}

#[unsafe(no_mangle)]
pub extern "C" fn wasmtime_call_future_delete(_future: Box<wasmtime_call_future_t>) {}

Expand Down Expand Up @@ -265,7 +271,7 @@ pub unsafe extern "C" fn wasmtime_func_call_async<'a>(
trap_ret,
err_ret,
));
Box::new(wasmtime_call_future_t { underlying: fut })
Box::new(wasmtime_call_future_t::new(fut))
}

#[unsafe(no_mangle)]
Expand Down Expand Up @@ -323,7 +329,7 @@ pub extern "C" fn wasmtime_linker_instantiate_async<'a>(
trap_ret,
err_ret,
));
Box::new(crate::wasmtime_call_future_t { underlying: fut })
Box::new(crate::wasmtime_call_future_t::new(fut))
}

async fn do_instance_pre_instantiate_async(
Expand Down Expand Up @@ -355,7 +361,7 @@ pub extern "C" fn wasmtime_instance_pre_instantiate_async<'a>(
trap_ret,
err_ret,
));
Box::new(crate::wasmtime_call_future_t { underlying: fut })
Box::new(crate::wasmtime_call_future_t::new(fut))
}

pub type wasmtime_stack_memory_get_callback_t =
Expand Down
27 changes: 27 additions & 0 deletions crates/c-api/src/component/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ pub extern "C" fn wasmtime_config_wasm_component_model_map_set(
c.config.wasm_component_model_map(enable);
}

#[unsafe(no_mangle)]
#[cfg(feature = "component-model-async")]
pub extern "C" fn wasmtime_config_wasm_component_model_async_set(
c: &mut wasm_config_t,
enable: bool,
) {
c.config.wasm_component_model_async(enable);
}

#[unsafe(no_mangle)]
#[cfg(feature = "component-model-async")]
pub extern "C" fn wasmtime_config_wasm_component_model_async_builtins_set(
c: &mut wasm_config_t,
enable: bool,
) {
c.config.wasm_component_model_async_builtins(enable);
}

#[unsafe(no_mangle)]
#[cfg(feature = "component-model-async")]
pub extern "C" fn wasmtime_config_wasm_component_model_async_stackful_set(
c: &mut wasm_config_t,
enable: bool,
) {
c.config.wasm_component_model_async_stackful(enable);
}

#[derive(Clone)]
#[repr(transparent)]
pub struct wasmtime_component_t {
Expand Down
31 changes: 31 additions & 0 deletions crates/c-api/src/component/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@ pub unsafe extern "C" fn wasmtime_component_func_call(
})
}

#[unsafe(no_mangle)]
#[cfg(feature = "component-model-async")]
pub unsafe extern "C" fn wasmtime_component_func_call_async<'a>(
func: &'a Func,
mut context: WasmtimeStoreContextMut<'a>,
args: *const wasmtime_component_val_t,
args_len: usize,
results: *mut wasmtime_component_val_t,
results_len: usize,
err_ret: &'a mut *mut wasmtime_error_t,
) -> Box<crate::wasmtime_call_future_t<'a>> {
let c_args = unsafe { crate::slice_from_raw_parts(args, args_len) };
let c_results = unsafe { crate::slice_from_raw_parts_mut(results, results_len) };
let fut = Box::pin(async move {
let args = c_args.iter().map(Val::from).collect::<Vec<_>>();
let mut results = vec![Val::Bool(false); c_results.len()];

match func.call_async(&mut context, &args, &mut results).await {
Ok(()) => {
for (c_val, rust_val) in std::iter::zip(c_results.iter_mut(), results) {
*c_val = wasmtime_component_val_t::from(&rust_val);
}
}
Err(err) => {
*err_ret = Box::into_raw(Box::new(wasmtime_error_t::from(err)));
}
}
});
Box::new(crate::wasmtime_call_future_t::new(fut))
}

#[deprecated(note = "no longer has any effect")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wasmtime_component_func_post_return(
Expand Down
Loading
Loading