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
65 changes: 19 additions & 46 deletions crates/guest-rust/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{braced, token, LitStr, Token};
use wit_bindgen_core::wit_parser::{PackageId, Resolve, UnresolvedPackageGroup, WorldId};
use wit_bindgen_rust::{AsyncConfig, Opts, Ownership, WithOption};
use wit_bindgen_rust::{Async, AsyncFilter, Opts, Ownership, WithOption};

#[proc_macro]
pub fn generate(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand Down Expand Up @@ -155,7 +155,7 @@ impl Parse for Config {
return Err(Error::new(span, "cannot specify second async config"));
}
async_configured = true;
if !matches!(val, AsyncConfig::None) && !cfg!(feature = "async") {
if val.iter().any(|v| v.enabled) && !cfg!(feature = "async") {
return Err(Error::new(
span,
"must enable `async` feature to enable async imports and/or exports",
Expand Down Expand Up @@ -369,11 +369,6 @@ impl From<ExportKey> for wit_bindgen_rust::ExportKey {
}
}

enum AsyncConfigSomeKind {
Imports,
Exports,
}

enum Opt {
World(syn::LitStr),
Path(Span, Vec<syn::LitStr>),
Expand All @@ -399,7 +394,7 @@ enum Opt {
GenerateUnusedTypes(syn::LitBool),
Features(Vec<syn::LitStr>),
DisableCustomSectionLinkHelpers(syn::LitBool),
Async(AsyncConfig, Span),
Async(Vec<Async>, Span),
Debug(syn::LitBool),
}

Expand Down Expand Up @@ -563,25 +558,22 @@ impl Parse for Opt {
let span = input.parse::<Token![async]>()?.span;
input.parse::<Token![:]>()?;
if input.peek(syn::LitBool) {
if input.parse::<syn::LitBool>()?.value {
Ok(Opt::Async(AsyncConfig::All, span))
} else {
Ok(Opt::Async(AsyncConfig::None, span))
}
let enabled = input.parse::<syn::LitBool>()?.value;
Ok(Opt::Async(
vec![Async {
enabled,
filter: AsyncFilter::All,
}],
span,
))
} else {
let mut imports = Vec::new();
let mut exports = Vec::new();
let mut vals = Vec::new();
let contents;
syn::braced!(contents in input);
for (kind, values) in
contents.parse_terminated(parse_async_some_field, Token![,])?
{
match kind {
AsyncConfigSomeKind::Imports => imports = values,
AsyncConfigSomeKind::Exports => exports = values,
}
syn::bracketed!(contents in input);
for val in contents.parse_terminated(parse_async, Token![,])? {
vals.push(val);
}
Ok(Opt::Async(AsyncConfig::Some { imports, exports }, span))
Ok(Opt::Async(vals, span))
}
} else {
Err(l.error())
Expand Down Expand Up @@ -642,26 +634,7 @@ fn fmt(input: &str) -> Result<String> {
Ok(prettyplease::unparse(&syntax_tree))
}

fn parse_async_some_field(input: ParseStream<'_>) -> Result<(AsyncConfigSomeKind, Vec<String>)> {
let lookahead = input.lookahead1();
let kind = if lookahead.peek(kw::imports) {
input.parse::<kw::imports>()?;
input.parse::<Token![:]>()?;
AsyncConfigSomeKind::Imports
} else if lookahead.peek(kw::exports) {
input.parse::<kw::exports>()?;
input.parse::<Token![:]>()?;
AsyncConfigSomeKind::Exports
} else {
return Err(lookahead.error());
};

let list;
syn::bracketed!(list in input);
let fields = list.parse_terminated(Parse::parse, Token![,])?;

Ok((
kind,
fields.iter().map(|s: &syn::LitStr| s.value()).collect(),
))
fn parse_async(input: ParseStream<'_>) -> Result<Async> {
let value = input.parse::<syn::LitStr>()?.value();
Ok(Async::parse(&value))
}
25 changes: 13 additions & 12 deletions crates/guest-rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,18 +839,19 @@
/// //
/// // The resulting bindings will use the component model
/// // [async ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md).
/// // This may be specified either as a boolean (e.g. `async: true`, meaning
/// // all imports and exports should use the async ABI) or as lists of
/// // specific imports and/or exports as shown here:
/// async: {
/// imports: [
/// "wasi:http/types@0.3.0-draft#[static]body.finish",
/// "wasi:http/handler@0.3.0-draft#handle",
/// ],
/// exports: [
/// "wasi:http/handler@0.3.0-draft#handle",
/// ]
/// }
/// //
/// // If this option is not provided then the WIT's source annotation will
/// // be used instead.
/// async: true, // all bindings are async
/// async: false, // all bindings are sync
/// // With an array per-function configuration can be specified. A leading
/// // '-' will disable async for that particular function.
/// async: [
/// "wasi:http/types@0.3.0-draft#[static]body.finish",
/// "import:wasi:http/handler@0.3.0-draft#handle",
/// "-export:wasi:http/handler@0.3.0-draft#handle",
/// "all",
/// ],
/// });
/// ```
///
Expand Down
2 changes: 1 addition & 1 deletion crates/rust/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
self.push_str(&prev_src);
let constructor_type = match &func.kind {
FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => {
self.push_str(&format!("T::{}", to_rust_ident(&func.name)));
self.push_str(&format!("T::{}", to_rust_ident(func.item_name())));
None
}
FunctionKind::Method(_)
Expand Down
45 changes: 10 additions & 35 deletions crates/rust/src/interface.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::bindgen::{FunctionBindgen, POINTER_SIZE_EXPRESSION};
use crate::{
full_wit_type_name, int_repr, to_rust_ident, to_upper_camel_case, wasm_type, AsyncConfig,
FnSig, Identifier, InterfaceName, Ownership, RuntimeItem, RustFlagsRepr, RustWasm,
TypeGeneration,
full_wit_type_name, int_repr, to_rust_ident, to_upper_camel_case, wasm_type, FnSig, Identifier,
InterfaceName, Ownership, RuntimeItem, RustFlagsRepr, RustWasm, TypeGeneration,
};
use anyhow::Result;
use heck::*;
Expand Down Expand Up @@ -162,17 +161,9 @@ impl<'i> InterfaceGenerator<'i> {
continue;
}

let async_ = match &self.r#gen.opts.async_ {
AsyncConfig::None => false,
AsyncConfig::All => true,
AsyncConfig::Some { exports, .. } => {
exports.contains(&if let Some((_, key)) = interface {
format!("{}#{}", self.resolve.name_world_key(key), func.name)
} else {
func.name.clone()
})
}
};
let async_ = self
.r#gen
.is_async(self.resolve, interface.map(|p| p.1), func, false);
let resource = func.kind.resource();

funcs_to_export.push((func, resource, async_));
Expand Down Expand Up @@ -712,15 +703,7 @@ pub mod vtable{ordinal} {{

self.generate_payloads("", func, interface);

let async_ = match &self.r#gen.opts.async_ {
AsyncConfig::None => false,
AsyncConfig::All => true,
AsyncConfig::Some { imports, .. } => imports.contains(&if let Some(key) = interface {
format!("{}#{}", self.resolve.name_world_key(key), func.name)
} else {
func.name.clone()
}),
};
let async_ = self.r#gen.is_async(self.resolve, interface, func, true);
let mut sig = FnSig {
async_,
..Default::default()
Expand Down Expand Up @@ -1227,17 +1210,9 @@ unsafe fn call_import(params: *mut u8, results: *mut u8) -> u32 {{
if self.r#gen.skip.contains(&func.name) {
continue;
}
let async_ = match &self.r#gen.opts.async_ {
AsyncConfig::None => false,
AsyncConfig::All => true,
AsyncConfig::Some { exports, .. } => {
exports.contains(&if let Some((_, key)) = interface {
format!("{}#{}", self.resolve.name_world_key(key), func.name)
} else {
func.name.clone()
})
}
};
let async_ = self
.r#gen
.is_async(self.resolve, interface.map(|p| p.1), func, false);
let mut sig = FnSig {
async_,
use_item_name: true,
Expand Down Expand Up @@ -1349,7 +1324,7 @@ unsafe fn call_import(params: *mut u8, results: *mut u8) -> u32 {{
func.item_name()
}
} else {
&func.name
func.item_name()
};
self.push_str(&to_rust_ident(func_name));
if let Some(generics) = &sig.generics {
Expand Down
Loading