Implement RFC 11: Redesigning Wasmtime's APIs (#2897)
Implement Wasmtime's new API as designed by RFC 11. This is quite a large commit which has had lots of discussion externally, so for more information it's best to read the RFC thread and the PR thread.
This commit is contained in:
@@ -17,15 +17,19 @@ use syn::parse_macro_input;
|
||||
/// * For each `@interface func` defined in a witx module, an abi-level
|
||||
/// function is generated which takes ABI-level arguments, along with
|
||||
/// a ref that impls the module trait, and a `GuestMemory` implementation.
|
||||
/// Users typically won't use these abi-level functions: The `wasmtime-wiggle`
|
||||
/// and `lucet-wiggle` crates adapt these to work with a particular WebAssembly
|
||||
/// engine.
|
||||
/// Users typically won't use these abi-level functions: Either the
|
||||
/// `wasmtime_integration` macro or the `lucet-wiggle` crates adapt these
|
||||
/// to work with a particular WebAssembly engine.
|
||||
///
|
||||
/// * A public "module trait" is defined (called the module name, in
|
||||
/// SnakeCase) which has a `&self` method for each function in the
|
||||
/// module. These methods takes idiomatic Rust types for each argument
|
||||
/// and return `Result<($return_types),$error_type>`
|
||||
///
|
||||
/// * When the `wiggle` crate is built with the `wasmtime_integration`
|
||||
/// feature, each module contains an `add_to_linker` function to add it to
|
||||
/// a `wasmtime::Linker`.
|
||||
///
|
||||
/// Arguments are provided using Rust struct value syntax.
|
||||
///
|
||||
/// * `witx` takes a list of string literal paths. Paths are relative to the
|
||||
@@ -95,11 +99,11 @@ use syn::parse_macro_input;
|
||||
/// /// whereas the witx-defined types like `Excuse` and `Errno` come
|
||||
/// /// from the `pub mod types` emitted by the `wiggle::from_witx!`
|
||||
/// /// invocation above.
|
||||
/// fn int_float_args(&self, _int: u32, _floats: &GuestPtr<[f32]>)
|
||||
/// fn int_float_args(&mut self, _int: u32, _floats: &GuestPtr<[f32]>)
|
||||
/// -> Result<(), YourRichError> {
|
||||
/// unimplemented!()
|
||||
/// }
|
||||
/// async fn double_int_return_float(&self, int: u32)
|
||||
/// async fn double_int_return_float(&mut self, int: u32)
|
||||
/// -> Result<f32, YourRichError> {
|
||||
/// Ok(int.checked_mul(2).ok_or(YourRichError::Overflow)? as f32)
|
||||
/// }
|
||||
@@ -121,7 +125,7 @@ use syn::parse_macro_input;
|
||||
/// /// to terminate WebAssembly execution by trapping.
|
||||
///
|
||||
/// impl types::UserErrorConversion for YourCtxType {
|
||||
/// fn errno_from_your_rich_error(&self, e: YourRichError)
|
||||
/// fn errno_from_your_rich_error(&mut self, e: YourRichError)
|
||||
/// -> Result<types::Errno, wiggle::Trap>
|
||||
/// {
|
||||
/// println!("Rich error: {:?}", e);
|
||||
@@ -144,11 +148,15 @@ pub fn from_witx(args: TokenStream) -> TokenStream {
|
||||
let doc = config.load_document();
|
||||
let names = wiggle_generate::Names::new(quote!(wiggle));
|
||||
|
||||
let error_transform =
|
||||
wiggle_generate::CodegenSettings::new(&config.errors, &config.async_, &doc)
|
||||
.expect("validating codegen settings");
|
||||
let settings = wiggle_generate::CodegenSettings::new(
|
||||
&config.errors,
|
||||
&config.async_,
|
||||
&doc,
|
||||
cfg!(feature = "wasmtime") && config.wasmtime,
|
||||
)
|
||||
.expect("validating codegen settings");
|
||||
|
||||
let code = wiggle_generate::generate(&doc, &names, &error_transform);
|
||||
let code = wiggle_generate::generate(&doc, &names, &settings);
|
||||
let metadata = if cfg!(feature = "wiggle_metadata") {
|
||||
wiggle_generate::generate_metadata(&doc, &names)
|
||||
} else {
|
||||
@@ -163,7 +171,35 @@ pub fn async_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let _ = parse_macro_input!(attr as syn::parse::Nothing);
|
||||
let item = proc_macro2::TokenStream::from(item);
|
||||
TokenStream::from(quote! {
|
||||
#[wiggle::async_trait_crate::async_trait(?Send)]
|
||||
#[wiggle::async_trait_crate::async_trait]
|
||||
#item
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasmtime")]
|
||||
/// Define the structs required to integrate a Wiggle implementation with Wasmtime.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// Arguments are provided using struct syntax e.g. `{ arg_name: value }`.
|
||||
///
|
||||
/// * `target`: The path of the module where the Wiggle implementation is defined.
|
||||
#[proc_macro]
|
||||
pub fn wasmtime_integration(args: TokenStream) -> TokenStream {
|
||||
let config = parse_macro_input!(args as wiggle_generate::WasmtimeConfig);
|
||||
let doc = config.c.load_document();
|
||||
let names = wiggle_generate::Names::new(quote!(wiggle));
|
||||
|
||||
let settings = wiggle_generate::CodegenSettings::new(
|
||||
&config.c.errors,
|
||||
&config.c.async_,
|
||||
&doc,
|
||||
cfg!(feature = "wasmtime"),
|
||||
)
|
||||
.expect("validating codegen settings");
|
||||
|
||||
let modules = doc.modules().map(|module| {
|
||||
wiggle_generate::wasmtime::link_module(&module, &names, Some(&config.target), &settings)
|
||||
});
|
||||
quote!( #(#modules)* ).into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user