Function wiggle_generate::names::wasm_type
source · pub fn wasm_type(ty: WasmType) -> TokenStream
Examples found in repository?
src/types/flags.rs (line 12)
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
pub(super) fn define_flags(
name: &witx::Id,
repr: witx::IntRepr,
record: &witx::RecordDatatype,
) -> TokenStream {
let ident = names::type_(&name);
let abi_repr = names::wasm_type(repr.into());
let repr = super::int_repr_tokens(repr);
let mut names_ = vec![];
let mut values_ = vec![];
for (i, member) in record.members.iter().enumerate() {
let name = names::flag_member(&member.name);
let value_token = Literal::usize_unsuffixed(1 << i);
names_.push(name);
values_.push(value_token);
}
quote! {
wiggle::bitflags::bitflags! {
pub struct #ident: #repr {
#(const #names_ = #values_;)*
}
}
impl ::std::fmt::Display for #ident {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
f.write_str(stringify!(#ident))?;
f.write_str("(")?;
::std::fmt::Debug::fmt(self, f)?;
f.write_str(" (0x")?;
::std::fmt::LowerHex::fmt(&self.bits, f)?;
f.write_str("))")?;
Ok(())
}
}
impl TryFrom<#repr> for #ident {
type Error = wiggle::GuestError;
fn try_from(value: #repr) -> Result<Self, wiggle::GuestError> {
if #repr::from(!#ident::all()) & value != 0 {
Err(wiggle::GuestError::InvalidFlagValue(stringify!(#ident)))
} else {
Ok(#ident { bits: value })
}
}
}
impl TryFrom<#abi_repr> for #ident {
type Error = wiggle::GuestError;
fn try_from(value: #abi_repr) -> Result<Self, wiggle::GuestError> {
#ident::try_from(#repr::try_from(value)?)
}
}
impl From<#ident> for #repr {
fn from(e: #ident) -> #repr {
e.bits
}
}
impl<'a> wiggle::GuestType<'a> for #ident {
fn guest_size() -> u32 {
#repr::guest_size()
}
fn guest_align() -> usize {
#repr::guest_align()
}
fn read(location: &wiggle::GuestPtr<#ident>) -> Result<#ident, wiggle::GuestError> {
use std::convert::TryFrom;
let reprval = #repr::read(&location.cast())?;
let value = #ident::try_from(reprval)?;
Ok(value)
}
fn write(location: &wiggle::GuestPtr<'_, #ident>, val: Self) -> Result<(), wiggle::GuestError> {
let val: #repr = #repr::from(val);
#repr::write(&location.cast(), val)
}
}
}
}
More examples
src/wasmtime.rs (line 86)
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
fn generate_func(
module: &witx::Module,
func: &witx::InterfaceFunc,
target_path: Option<&syn::Path>,
asyncness: Asyncness,
) -> TokenStream {
let module_str = module.name.as_str();
let module_ident = names::module(&module.name);
let field_str = func.name.as_str();
let field_ident = names::func(&func.name);
let (params, results) = func.wasm_signature();
let arg_names = (0..params.len())
.map(|i| Ident::new(&format!("arg{}", i), Span::call_site()))
.collect::<Vec<_>>();
let arg_decls = params
.iter()
.enumerate()
.map(|(i, ty)| {
let name = &arg_names[i];
let wasm = names::wasm_type(*ty);
quote! { #name: #wasm }
})
.collect::<Vec<_>>();
let ret_ty = match results.len() {
0 => quote!(()),
1 => names::wasm_type(results[0]),
_ => unimplemented!(),
};
let await_ = if asyncness.is_sync() {
quote!()
} else {
quote!(.await)
};
let abi_func = if let Some(target_path) = target_path {
quote!( #target_path::#module_ident::#field_ident )
} else {
quote!( #field_ident )
};
let body = quote! {
let export = caller.get_export("memory");
let (mem, ctx) = match &export {
Some(wiggle::wasmtime_crate::Extern::Memory(m)) => {
let (mem, ctx) = m.data_and_store_mut(&mut caller);
let ctx = get_cx(ctx);
(wiggle::wasmtime::WasmtimeGuestMemory::new(mem), ctx)
}
Some(wiggle::wasmtime_crate::Extern::SharedMemory(m)) => {
let ctx = get_cx(caller.data_mut());
(wiggle::wasmtime::WasmtimeGuestMemory::shared(m.data()), ctx)
}
_ => wiggle::anyhow::bail!("missing required memory export"),
};
Ok(<#ret_ty>::from(#abi_func(ctx, &mem #(, #arg_names)*) #await_ ?))
};
match asyncness {
Asyncness::Async => {
let wrapper = format_ident!("func_wrap{}_async", params.len());
quote! {
linker.#wrapper(
#module_str,
#field_str,
move |mut caller: wiggle::wasmtime_crate::Caller<'_, T> #(, #arg_decls)*| {
Box::new(async move { #body })
},
)?;
}
}
Asyncness::Blocking => {
quote! {
linker.func_wrap(
#module_str,
#field_str,
move |mut caller: wiggle::wasmtime_crate::Caller<'_, T> #(, #arg_decls)*| -> wiggle::anyhow::Result<#ret_ty> {
let result = async { #body };
wiggle::run_in_dummy_executor(result)?
},
)?;
}
}
Asyncness::Sync => {
quote! {
linker.func_wrap(
#module_str,
#field_str,
move |mut caller: wiggle::wasmtime_crate::Caller<'_, T> #(, #arg_decls)*| -> wiggle::anyhow::Result<#ret_ty> {
#body
},
)?;
}
}
}
}
src/funcs.rs (line 41)
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
fn _define_func(
module: &witx::Module,
func: &witx::InterfaceFunc,
settings: &CodegenSettings,
) -> (TokenStream, Vec<Ident>) {
let ident = names::func(&func.name);
let (wasm_params, wasm_results) = func.wasm_signature();
let param_names = (0..wasm_params.len())
.map(|i| Ident::new(&format!("arg{}", i), Span::call_site()))
.collect::<Vec<_>>();
let abi_params = wasm_params.iter().zip(¶m_names).map(|(arg, name)| {
let wasm = names::wasm_type(*arg);
quote!(#name : #wasm)
});
let abi_ret = match wasm_results.len() {
0 => quote!(()),
1 => {
let ty = names::wasm_type(wasm_results[0]);
quote!(#ty)
}
_ => unimplemented!(),
};
let mut body = TokenStream::new();
let mut bounds = vec![names::trait_name(&module.name)];
func.call_interface(
&module.name,
&mut Rust {
src: &mut body,
params: ¶m_names,
block_storage: Vec::new(),
blocks: Vec::new(),
module,
funcname: func.name.as_str(),
settings,
bounds: &mut bounds,
},
);
let mod_name = &module.name.as_str();
let func_name = &func.name.as_str();
let mk_span = quote!(
let _span = wiggle::tracing::span!(
wiggle::tracing::Level::TRACE,
"wiggle abi",
module = #mod_name,
function = #func_name
);
);
if settings.get_async(&module, &func).is_sync() {
let traced_body = if settings.tracing.enabled_for(&mod_name, &func_name) {
quote!(
#mk_span
_span.in_scope(|| {
#body
})
)
} else {
quote!(#body)
};
(
quote!(
#[allow(unreachable_code)] // deals with warnings in noreturn functions
pub fn #ident(
ctx: &mut (impl #(#bounds)+*),
memory: &dyn wiggle::GuestMemory,
#(#abi_params),*
) -> wiggle::anyhow::Result<#abi_ret> {
use std::convert::TryFrom as _;
#traced_body
}
),
bounds,
)
} else {
let traced_body = if settings.tracing.enabled_for(&mod_name, &func_name) {
quote!(
use wiggle::tracing::Instrument as _;
#mk_span
async move {
#body
}.instrument(_span)
)
} else {
quote!(
async move {
#body
}
)
};
(
quote!(
#[allow(unreachable_code)] // deals with warnings in noreturn functions
pub fn #ident<'a>(
ctx: &'a mut (impl #(#bounds)+*),
memory: &'a dyn wiggle::GuestMemory,
#(#abi_params),*
) -> impl std::future::Future<Output = wiggle::anyhow::Result<#abi_ret>> + 'a {
use std::convert::TryFrom as _;
#traced_body
}
),
bounds,
)
}
}
src/types/variant.rs (line 78)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
pub(super) fn define_variant(
name: &witx::Id,
v: &witx::Variant,
derive_std_error: bool,
) -> TokenStream {
let ident = names::type_(name);
let size = v.mem_size_align().size as u32;
let align = v.mem_size_align().align as usize;
let contents_offset = v.payload_offset() as u32;
let lifetime = quote!('a);
let tag_ty = super::int_repr_tokens(v.tag_repr);
let variants = v.cases.iter().map(|c| {
let var_name = names::enum_variant(&c.name);
if let Some(tref) = &c.tref {
let var_type = names::type_ref(&tref, lifetime.clone());
quote!(#var_name(#var_type))
} else {
quote!(#var_name)
}
});
let read_variant = v.cases.iter().enumerate().map(|(i, c)| {
let i = Literal::usize_unsuffixed(i);
let variantname = names::enum_variant(&c.name);
if let Some(tref) = &c.tref {
let varianttype = names::type_ref(tref, lifetime.clone());
quote! {
#i => {
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
let variant_val = <#varianttype as wiggle::GuestType>::read(&variant_ptr.cast())?;
Ok(#ident::#variantname(variant_val))
}
}
} else {
quote! { #i => Ok(#ident::#variantname), }
}
});
let write_variant = v.cases.iter().enumerate().map(|(i, c)| {
let variantname = names::enum_variant(&c.name);
let write_tag = quote! {
location.cast().write(#i as #tag_ty)?;
};
if let Some(tref) = &c.tref {
let varianttype = names::type_ref(tref, lifetime.clone());
quote! {
#ident::#variantname(contents) => {
#write_tag
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
<#varianttype as wiggle::GuestType>::write(&variant_ptr.cast(), contents)?;
}
}
} else {
quote! {
#ident::#variantname => {
#write_tag
}
}
}
});
let mut extra_derive = quote!();
let enum_try_from = if v.cases.iter().all(|c| c.tref.is_none()) {
let tryfrom_repr_cases = v.cases.iter().enumerate().map(|(i, c)| {
let variant_name = names::enum_variant(&c.name);
let n = Literal::usize_unsuffixed(i);
quote!(#n => Ok(#ident::#variant_name))
});
let abi_ty = names::wasm_type(v.tag_repr.into());
extra_derive = quote!(, Copy);
quote! {
impl TryFrom<#tag_ty> for #ident {
type Error = wiggle::GuestError;
fn try_from(value: #tag_ty) -> Result<#ident, wiggle::GuestError> {
match value {
#(#tryfrom_repr_cases),*,
_ => Err(wiggle::GuestError::InvalidEnumValue(stringify!(#ident))),
}
}
}
impl TryFrom<#abi_ty> for #ident {
type Error = wiggle::GuestError;
fn try_from(value: #abi_ty) -> Result<#ident, wiggle::GuestError> {
#ident::try_from(#tag_ty::try_from(value)?)
}
}
}
} else {
quote!()
};
let enum_from = if v.cases.iter().all(|c| c.tref.is_none()) {
let from_repr_cases = v.cases.iter().enumerate().map(|(i, c)| {
let variant_name = names::enum_variant(&c.name);
let n = Literal::usize_unsuffixed(i);
quote!(#ident::#variant_name => #n)
});
quote! {
impl From<#ident> for #tag_ty {
fn from(v: #ident) -> #tag_ty {
match v {
#(#from_repr_cases),*,
}
}
}
}
} else {
quote!()
};
let (enum_lifetime, extra_derive) = if v.needs_lifetime() {
(quote!(<'a>), quote!())
} else {
(quote!(), quote!(, PartialEq #extra_derive))
};
let error_impls = if derive_std_error {
quote! {
impl std::fmt::Display for #ident {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl std::error::Error for #ident {}
}
} else {
quote!()
};
quote! {
#[derive(Clone, Debug #extra_derive)]
pub enum #ident #enum_lifetime {
#(#variants),*
}
#error_impls
#enum_try_from
#enum_from
impl<'a> wiggle::GuestType<'a> for #ident #enum_lifetime {
fn guest_size() -> u32 {
#size
}
fn guest_align() -> usize {
#align
}
fn read(location: &wiggle::GuestPtr<'a, Self>)
-> Result<Self, wiggle::GuestError>
{
let tag = location.cast::<#tag_ty>().read()?;
match tag {
#(#read_variant)*
_ => Err(wiggle::GuestError::InvalidEnumValue(stringify!(#ident))),
}
}
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self)
-> Result<(), wiggle::GuestError>
{
match val {
#(#write_variant)*
}
Ok(())
}
}
}
}