wiggle-generate: paramaterize library on module path to runtime (#1574)
* wiggle-generate: paramaterize library on module path to runtime This change makes no functional difference to users who only use the wiggle crate. Add a parameter to the `Names` constructor that determines the module that runtime components (e.g. GuestPtr, GuestError etc) of wiggle come from. For `wiggle` users this is just `quote!(wiggle)`, but other libraries which consume wiggle-generate may wrap and re-export wiggle under some other path, and not want their consumers to have to know about the wiggle dependency, e.g. `quote!(my_crate::some_path::wiggle)`. * wiggle-generate,macro: move more logic into macro better for code reuse elsewhere
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2366,6 +2366,7 @@ dependencies = [
|
|||||||
name = "wiggle-macro"
|
name = "wiggle-macro"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
"wiggle",
|
"wiggle",
|
||||||
"wiggle-generate",
|
"wiggle-generate",
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use syn::{
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub witx: WitxConf,
|
pub witx: WitxConf,
|
||||||
pub ctx: CtxConf,
|
pub ctx: CtxConf,
|
||||||
pub emit_metadata: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -60,7 +59,6 @@ impl Config {
|
|||||||
ctx: ctx
|
ctx: ctx
|
||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
|
.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
|
||||||
emit_metadata: false,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ pub fn define_func(
|
|||||||
let funcname = func.name.as_str();
|
let funcname = func.name.as_str();
|
||||||
|
|
||||||
let ident = names.func(&func.name);
|
let ident = names.func(&func.name);
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ctx_type = names.ctx_type();
|
let ctx_type = names.ctx_type();
|
||||||
let coretype = func.core_type();
|
let coretype = func.core_type();
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ pub fn define_func(
|
|||||||
});
|
});
|
||||||
|
|
||||||
let abi_args = quote!(
|
let abi_args = quote!(
|
||||||
ctx: &#ctx_type, memory: &dyn wiggle::GuestMemory,
|
ctx: &#ctx_type, memory: &dyn #rt::GuestMemory,
|
||||||
#(#params),*
|
#(#params),*
|
||||||
);
|
);
|
||||||
let abi_ret = if let Some(ret) = &coretype.ret {
|
let abi_ret = if let Some(ret) = &coretype.ret {
|
||||||
@@ -64,7 +65,7 @@ pub fn define_func(
|
|||||||
let err_typename = names.type_ref(&tref, anon_lifetime());
|
let err_typename = names.type_ref(&tref, anon_lifetime());
|
||||||
let err_method = names.guest_error_conversion_method(&tref);
|
let err_method = names.guest_error_conversion_method(&tref);
|
||||||
quote! {
|
quote! {
|
||||||
let e = wiggle::GuestError::InFunc { funcname: #funcname, location: #location, err: Box::new(e.into()) };
|
let e = #rt::GuestError::InFunc { funcname: #funcname, location: #location, err: Box::new(e.into()) };
|
||||||
let err: #err_typename = GuestErrorConversion::#err_method(ctx, e); // XXX replace with conversion method on trait!
|
let err: #err_typename = GuestErrorConversion::#err_method(ctx, e); // XXX replace with conversion method on trait!
|
||||||
return #abi_ret::from(err);
|
return #abi_ret::from(err);
|
||||||
}
|
}
|
||||||
@@ -139,7 +140,7 @@ pub fn define_func(
|
|||||||
let success = if let Some(ref err_type) = err_type {
|
let success = if let Some(ref err_type) = err_type {
|
||||||
let err_typename = names.type_ref(&err_type, anon_lifetime());
|
let err_typename = names.type_ref(&err_type, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let success:#err_typename = wiggle::GuestErrorType::success();
|
let success:#err_typename = #rt::GuestErrorType::success();
|
||||||
#[cfg(feature = "trace_log")]
|
#[cfg(feature = "trace_log")]
|
||||||
{
|
{
|
||||||
log::trace!(" | errno={}", success);
|
log::trace!(" | errno={}", success);
|
||||||
@@ -185,6 +186,7 @@ fn marshal_arg(
|
|||||||
param: &witx::InterfaceFuncParam,
|
param: &witx::InterfaceFuncParam,
|
||||||
error_handling: TokenStream,
|
error_handling: TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let tref = ¶m.tref;
|
let tref = ¶m.tref;
|
||||||
let interface_typename = names.type_ref(&tref, anon_lifetime());
|
let interface_typename = names.type_ref(&tref, anon_lifetime());
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ fn marshal_arg(
|
|||||||
let arg_name = names.func_ptr_binding(¶m.name);
|
let arg_name = names.func_ptr_binding(¶m.name);
|
||||||
let name = names.func_param(¶m.name);
|
let name = names.func_param(¶m.name);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = match wiggle::GuestPtr::<#pointee_type>::new(memory, #arg_name as u32).read() {
|
let #name = match #rt::GuestPtr::<#pointee_type>::new(memory, #arg_name as u32).read() {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
#error_handling
|
#error_handling
|
||||||
@@ -254,7 +256,7 @@ fn marshal_arg(
|
|||||||
let len_name = names.func_len_binding(¶m.name);
|
let len_name = names.func_len_binding(¶m.name);
|
||||||
let name = names.func_param(¶m.name);
|
let name = names.func_param(¶m.name);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = wiggle::GuestPtr::<#lifetime, str>::new(memory, (#ptr_name as u32, #len_name as u32));
|
let #name = #rt::GuestPtr::<#lifetime, str>::new(memory, (#ptr_name as u32, #len_name as u32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -262,7 +264,7 @@ fn marshal_arg(
|
|||||||
let pointee_type = names.type_ref(pointee, anon_lifetime());
|
let pointee_type = names.type_ref(pointee, anon_lifetime());
|
||||||
let name = names.func_param(¶m.name);
|
let name = names.func_param(¶m.name);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = wiggle::GuestPtr::<#pointee_type>::new(memory, #name as u32);
|
let #name = #rt::GuestPtr::<#pointee_type>::new(memory, #name as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Struct(_) => read_conversion,
|
witx::Type::Struct(_) => read_conversion,
|
||||||
@@ -272,7 +274,7 @@ fn marshal_arg(
|
|||||||
let len_name = names.func_len_binding(¶m.name);
|
let len_name = names.func_len_binding(¶m.name);
|
||||||
let name = names.func_param(¶m.name);
|
let name = names.func_param(¶m.name);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = wiggle::GuestPtr::<[#pointee_type]>::new(memory, (#ptr_name as u32, #len_name as u32));
|
let #name = #rt::GuestPtr::<[#pointee_type]>::new(memory, (#ptr_name as u32, #len_name as u32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Union(_u) => read_conversion,
|
witx::Type::Union(_u) => read_conversion,
|
||||||
@@ -292,6 +294,7 @@ fn marshal_result<F>(
|
|||||||
where
|
where
|
||||||
F: Fn(&str) -> TokenStream,
|
F: Fn(&str) -> TokenStream,
|
||||||
{
|
{
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let tref = &result.tref;
|
let tref = &result.tref;
|
||||||
|
|
||||||
let write_val_to_ptr = {
|
let write_val_to_ptr = {
|
||||||
@@ -300,7 +303,7 @@ where
|
|||||||
let ptr_name = names.func_ptr_binding(&result.name);
|
let ptr_name = names.func_ptr_binding(&result.name);
|
||||||
let ptr_err_handling = error_handling(&format!("{}:result_ptr_mut", result.name.as_str()));
|
let ptr_err_handling = error_handling(&format!("{}:result_ptr_mut", result.name.as_str()));
|
||||||
let pre = quote! {
|
let pre = quote! {
|
||||||
let #ptr_name = wiggle::GuestPtr::<#pointee_type>::new(memory, #ptr_name as u32);
|
let #ptr_name = #rt::GuestPtr::<#pointee_type>::new(memory, #ptr_name as u32);
|
||||||
};
|
};
|
||||||
// trait binding returns func_param name.
|
// trait binding returns func_param name.
|
||||||
let val_name = names.func_param(&result.name);
|
let val_name = names.func_param(&result.name);
|
||||||
|
|||||||
@@ -16,17 +16,17 @@ pub use module_trait::define_module_trait;
|
|||||||
pub use names::Names;
|
pub use names::Names;
|
||||||
pub use types::define_datatype;
|
pub use types::define_datatype;
|
||||||
|
|
||||||
pub fn generate(doc: &witx::Document, config: &Config) -> TokenStream {
|
pub fn generate(doc: &witx::Document, names: &Names) -> TokenStream {
|
||||||
// TODO at some point config should grow more ability to configure name
|
// TODO at some point config should grow more ability to configure name
|
||||||
// overrides.
|
// overrides.
|
||||||
let names = Names::new(&config.ctx.name);
|
let rt = names.runtime_mod();
|
||||||
|
|
||||||
let types = doc.typenames().map(|t| define_datatype(&names, &t));
|
let types = doc.typenames().map(|t| define_datatype(&names, &t));
|
||||||
|
|
||||||
let guest_error_methods = doc.error_types().map(|t| {
|
let guest_error_methods = doc.error_types().map(|t| {
|
||||||
let typename = names.type_ref(&t, anon_lifetime());
|
let typename = names.type_ref(&t, anon_lifetime());
|
||||||
let err_method = names.guest_error_conversion_method(&t);
|
let err_method = names.guest_error_conversion_method(&t);
|
||||||
quote!(fn #err_method(&self, e: wiggle::GuestError) -> #typename;)
|
quote!(fn #err_method(&self, e: #rt::GuestError) -> #typename;)
|
||||||
});
|
});
|
||||||
let guest_error_conversion = quote! {
|
let guest_error_conversion = quote! {
|
||||||
pub trait GuestErrorConversion {
|
pub trait GuestErrorConversion {
|
||||||
@@ -53,26 +53,24 @@ pub fn generate(doc: &witx::Document, config: &Config) -> TokenStream {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let metadata = if config.emit_metadata {
|
|
||||||
let doc_text = &format!("{}", doc);
|
|
||||||
quote! {
|
|
||||||
pub mod metadata {
|
|
||||||
pub const DOC_TEXT: &str = #doc_text;
|
|
||||||
pub fn document() -> wiggle::witx::Document {
|
|
||||||
wiggle::witx::parse(DOC_TEXT).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote!()
|
|
||||||
};
|
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
pub mod types {
|
pub mod types {
|
||||||
#(#types)*
|
#(#types)*
|
||||||
#guest_error_conversion
|
#guest_error_conversion
|
||||||
}
|
}
|
||||||
#(#modules)*
|
#(#modules)*
|
||||||
#metadata
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_metadata(doc: &witx::Document, names: &Names) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
|
let doc_text = &format!("{}", doc);
|
||||||
|
quote! {
|
||||||
|
pub mod metadata {
|
||||||
|
pub const DOC_TEXT: &str = #doc_text;
|
||||||
|
pub fn document() -> #rt::witx::Document {
|
||||||
|
#rt::witx::parse(DOC_TEXT).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,24 +7,32 @@ use crate::lifetimes::LifetimeExt;
|
|||||||
|
|
||||||
pub struct Names {
|
pub struct Names {
|
||||||
ctx_type: Ident,
|
ctx_type: Ident,
|
||||||
|
runtime_mod: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Names {
|
impl Names {
|
||||||
pub fn new(ctx_type: &Ident) -> Names {
|
pub fn new(ctx_type: &Ident, runtime_mod: TokenStream) -> Names {
|
||||||
Names {
|
Names {
|
||||||
ctx_type: ctx_type.clone(),
|
ctx_type: ctx_type.clone(),
|
||||||
|
runtime_mod,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn ctx_type(&self) -> Ident {
|
pub fn ctx_type(&self) -> Ident {
|
||||||
self.ctx_type.clone()
|
self.ctx_type.clone()
|
||||||
}
|
}
|
||||||
|
pub fn runtime_mod(&self) -> TokenStream {
|
||||||
|
self.runtime_mod.clone()
|
||||||
|
}
|
||||||
pub fn type_(&self, id: &Id) -> TokenStream {
|
pub fn type_(&self, id: &Id) -> TokenStream {
|
||||||
let ident = format_ident!("{}", id.as_str().to_camel_case());
|
let ident = format_ident!("{}", id.as_str().to_camel_case());
|
||||||
quote!(#ident)
|
quote!(#ident)
|
||||||
}
|
}
|
||||||
pub fn builtin_type(&self, b: BuiltinType, lifetime: TokenStream) -> TokenStream {
|
pub fn builtin_type(&self, b: BuiltinType, lifetime: TokenStream) -> TokenStream {
|
||||||
match b {
|
match b {
|
||||||
BuiltinType::String => quote!(wiggle::GuestPtr<#lifetime, str>),
|
BuiltinType::String => {
|
||||||
|
let rt = self.runtime_mod();
|
||||||
|
quote!(#rt::GuestPtr<#lifetime, str>)
|
||||||
|
}
|
||||||
BuiltinType::U8 => quote!(u8),
|
BuiltinType::U8 => quote!(u8),
|
||||||
BuiltinType::U16 => quote!(u16),
|
BuiltinType::U16 => quote!(u16),
|
||||||
BuiltinType::U32 => quote!(u32),
|
BuiltinType::U32 => quote!(u32),
|
||||||
@@ -61,12 +69,14 @@ impl Names {
|
|||||||
TypeRef::Value(ty) => match &**ty {
|
TypeRef::Value(ty) => match &**ty {
|
||||||
Type::Builtin(builtin) => self.builtin_type(*builtin, lifetime.clone()),
|
Type::Builtin(builtin) => self.builtin_type(*builtin, lifetime.clone()),
|
||||||
Type::Pointer(pointee) | Type::ConstPointer(pointee) => {
|
Type::Pointer(pointee) | Type::ConstPointer(pointee) => {
|
||||||
|
let rt = self.runtime_mod();
|
||||||
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||||
quote!(wiggle::GuestPtr<#lifetime, #pointee_type>)
|
quote!(#rt::GuestPtr<#lifetime, #pointee_type>)
|
||||||
}
|
}
|
||||||
Type::Array(pointee) => {
|
Type::Array(pointee) => {
|
||||||
|
let rt = self.runtime_mod();
|
||||||
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||||
quote!(wiggle::GuestPtr<#lifetime, [#pointee_type]>)
|
quote!(#rt::GuestPtr<#lifetime, [#pointee_type]>)
|
||||||
}
|
}
|
||||||
_ => unimplemented!("anonymous type ref {:?}", tref),
|
_ => unimplemented!("anonymous type ref {:?}", tref),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use quote::quote;
|
|||||||
|
|
||||||
pub(super) fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenStream {
|
pub(super) fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenStream {
|
||||||
let ident = names.type_(&name);
|
let ident = names.type_(&name);
|
||||||
|
let rt = names.runtime_mod();
|
||||||
|
|
||||||
let repr = int_repr_tokens(e.repr);
|
let repr = int_repr_tokens(e.repr);
|
||||||
let abi_repr = atom_token(match e.repr {
|
let abi_repr = atom_token(match e.repr {
|
||||||
@@ -46,18 +47,18 @@ pub(super) fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #repr) -> Result<#ident, wiggle::GuestError> {
|
fn try_from(value: #repr) -> Result<#ident, #rt::GuestError> {
|
||||||
match value as usize {
|
match value as usize {
|
||||||
#(#tryfrom_repr_cases),*,
|
#(#tryfrom_repr_cases),*,
|
||||||
_ => Err(wiggle::GuestError::InvalidEnumValue(stringify!(#ident))),
|
_ => Err( #rt::GuestError::InvalidEnumValue(stringify!(#ident))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #abi_repr) -> Result<#ident, wiggle::GuestError> {
|
fn try_from(value: #abi_repr) -> Result<#ident, #rt::GuestError> {
|
||||||
#ident::try_from(value as #repr)
|
#ident::try_from(value as #repr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +77,7 @@ pub(super) fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
impl<'a> #rt::GuestType<'a> for #ident {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#repr::guest_size()
|
#repr::guest_size()
|
||||||
}
|
}
|
||||||
@@ -85,23 +86,23 @@ pub(super) fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype
|
|||||||
#repr::guest_align()
|
#repr::guest_align()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<#ident>) -> Result<#ident, wiggle::GuestError> {
|
fn read(location: & #rt::GuestPtr<#ident>) -> Result<#ident, #rt::GuestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let reprval = #repr::read(&location.cast())?;
|
let reprval = #repr::read(&location.cast())?;
|
||||||
let value = #ident::try_from(reprval)?;
|
let value = #ident::try_from(reprval)?;
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, #ident>, val: Self)
|
fn write(location: & #rt::GuestPtr<'_, #ident>, val: Self)
|
||||||
-> Result<(), wiggle::GuestError>
|
-> Result<(), #rt::GuestError>
|
||||||
{
|
{
|
||||||
#repr::write(&location.cast(), #repr::from(val))
|
#repr::write(&location.cast(), #repr::from(val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl <'a> wiggle::GuestTypeTransparent<'a> for #ident {
|
unsafe impl <'a> #rt::GuestTypeTransparent<'a> for #ident {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate(location: *mut #ident) -> Result<(), wiggle::GuestError> {
|
fn validate(location: *mut #ident) -> Result<(), #rt::GuestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
// Validate value in memory using #ident::try_from(reprval)
|
// Validate value in memory using #ident::try_from(reprval)
|
||||||
let reprval = unsafe { (location as *mut #repr).read() };
|
let reprval = unsafe { (location as *mut #repr).read() };
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use quote::quote;
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDatatype) -> TokenStream {
|
pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDatatype) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ident = names.type_(&name);
|
let ident = names.type_(&name);
|
||||||
let repr = int_repr_tokens(f.repr);
|
let repr = int_repr_tokens(f.repr);
|
||||||
let abi_repr = atom_token(match f.repr {
|
let abi_repr = atom_token(match f.repr {
|
||||||
@@ -116,10 +117,10 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #repr) -> Result<Self, wiggle::GuestError> {
|
fn try_from(value: #repr) -> Result<Self, #rt::GuestError> {
|
||||||
if #repr::from(!#ident::all()) & value != 0 {
|
if #repr::from(!#ident::all()) & value != 0 {
|
||||||
Err(wiggle::GuestError::InvalidFlagValue(stringify!(#ident)))
|
Err(#rt::GuestError::InvalidFlagValue(stringify!(#ident)))
|
||||||
} else {
|
} else {
|
||||||
Ok(#ident(value))
|
Ok(#ident(value))
|
||||||
}
|
}
|
||||||
@@ -127,8 +128,8 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #abi_repr) -> Result<#ident, wiggle::GuestError> {
|
fn try_from(value: #abi_repr) -> Result<#ident, #rt::GuestError> {
|
||||||
#ident::try_from(value as #repr)
|
#ident::try_from(value as #repr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +146,7 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
impl<'a> #rt::GuestType<'a> for #ident {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#repr::guest_size()
|
#repr::guest_size()
|
||||||
}
|
}
|
||||||
@@ -154,21 +155,21 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
|||||||
#repr::guest_align()
|
#repr::guest_align()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<#ident>) -> Result<#ident, wiggle::GuestError> {
|
fn read(location: &#rt::GuestPtr<#ident>) -> Result<#ident, #rt::GuestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let reprval = #repr::read(&location.cast())?;
|
let reprval = #repr::read(&location.cast())?;
|
||||||
let value = #ident::try_from(reprval)?;
|
let value = #ident::try_from(reprval)?;
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, #ident>, val: Self) -> Result<(), wiggle::GuestError> {
|
fn write(location: &#rt::GuestPtr<'_, #ident>, val: Self) -> Result<(), #rt::GuestError> {
|
||||||
let val: #repr = #repr::from(val);
|
let val: #repr = #repr::from(val);
|
||||||
#repr::write(&location.cast(), val)
|
#repr::write(&location.cast(), val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl <'a> wiggle::GuestTypeTransparent<'a> for #ident {
|
unsafe impl<'a> #rt::GuestTypeTransparent<'a> for #ident {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate(location: *mut #ident) -> Result<(), wiggle::GuestError> {
|
fn validate(location: *mut #ident) -> Result<(), #rt::GuestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
// Validate value in memory using #ident::try_from(reprval)
|
// Validate value in memory using #ident::try_from(reprval)
|
||||||
let reprval = unsafe { (location as *mut #repr).read() };
|
let reprval = unsafe { (location as *mut #repr).read() };
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub(super) fn define_handle(
|
|||||||
name: &witx::Id,
|
name: &witx::Id,
|
||||||
h: &witx::HandleDatatype,
|
h: &witx::HandleDatatype,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ident = names.type_(name);
|
let ident = names.type_(name);
|
||||||
let size = h.mem_size_align().size as u32;
|
let size = h.mem_size_align().size as u32;
|
||||||
let align = h.mem_size_align().align as usize;
|
let align = h.mem_size_align().align as usize;
|
||||||
@@ -52,7 +53,7 @@ pub(super) fn define_handle(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
impl<'a> #rt::GuestType<'a> for #ident {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#size
|
#size
|
||||||
}
|
}
|
||||||
@@ -61,18 +62,18 @@ pub(super) fn define_handle(
|
|||||||
#align
|
#align
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<'a, #ident>) -> Result<#ident, wiggle::GuestError> {
|
fn read(location: &#rt::GuestPtr<'a, #ident>) -> Result<#ident, #rt::GuestError> {
|
||||||
Ok(#ident(u32::read(&location.cast())?))
|
Ok(#ident(u32::read(&location.cast())?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self) -> Result<(), wiggle::GuestError> {
|
fn write(location: &#rt::GuestPtr<'_, Self>, val: Self) -> Result<(), #rt::GuestError> {
|
||||||
u32::write(&location.cast(), val.0)
|
u32::write(&location.cast(), val.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a> wiggle::GuestTypeTransparent<'a> for #ident {
|
unsafe impl<'a> #rt::GuestTypeTransparent<'a> for #ident {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate(_location: *mut #ident) -> Result<(), wiggle::GuestError> {
|
fn validate(_location: *mut #ident) -> Result<(), #rt::GuestError> {
|
||||||
// All bit patterns accepted
|
// All bit patterns accepted
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use proc_macro2::TokenStream;
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
pub(super) fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype) -> TokenStream {
|
pub(super) fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ident = names.type_(&name);
|
let ident = names.type_(&name);
|
||||||
let repr = int_repr_tokens(i.repr);
|
let repr = int_repr_tokens(i.repr);
|
||||||
let abi_repr = atom_token(match i.repr {
|
let abi_repr = atom_token(match i.repr {
|
||||||
@@ -37,15 +38,15 @@ pub(super) fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype)
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #repr) -> Result<Self, wiggle::GuestError> {
|
fn try_from(value: #repr) -> Result<Self, #rt::GuestError> {
|
||||||
Ok(#ident(value))
|
Ok(#ident(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
impl ::std::convert::TryFrom<#abi_repr> for #ident {
|
||||||
type Error = wiggle::GuestError;
|
type Error = #rt::GuestError;
|
||||||
fn try_from(value: #abi_repr) -> Result<#ident, wiggle::GuestError> {
|
fn try_from(value: #abi_repr) -> Result<#ident, #rt::GuestError> {
|
||||||
#ident::try_from(value as #repr)
|
#ident::try_from(value as #repr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,7 @@ pub(super) fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
impl<'a> #rt::GuestType<'a> for #ident {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#repr::guest_size()
|
#repr::guest_size()
|
||||||
}
|
}
|
||||||
@@ -71,19 +72,19 @@ pub(super) fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype)
|
|||||||
#repr::guest_align()
|
#repr::guest_align()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<'a, #ident>) -> Result<#ident, wiggle::GuestError> {
|
fn read(location: &#rt::GuestPtr<'a, #ident>) -> Result<#ident, #rt::GuestError> {
|
||||||
Ok(#ident(#repr::read(&location.cast())?))
|
Ok(#ident(#repr::read(&location.cast())?))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, #ident>, val: Self) -> Result<(), wiggle::GuestError> {
|
fn write(location: &#rt::GuestPtr<'_, #ident>, val: Self) -> Result<(), #rt::GuestError> {
|
||||||
#repr::write(&location.cast(), val.0)
|
#repr::write(&location.cast(), val.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a> wiggle::GuestTypeTransparent<'a> for #ident {
|
unsafe impl<'a> #rt::GuestTypeTransparent<'a> for #ident {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate(_location: *mut #ident) -> Result<(), wiggle::GuestError> {
|
fn validate(_location: *mut #ident) -> Result<(), #rt::GuestError> {
|
||||||
// All bit patterns accepted
|
// All bit patterns accepted
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
|
|||||||
witx::Type::Handle(h) => handle::define_handle(names, &namedtype.name, &h),
|
witx::Type::Handle(h) => handle::define_handle(names, &namedtype.name, &h),
|
||||||
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
|
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
|
||||||
witx::Type::Pointer(p) => {
|
witx::Type::Pointer(p) => {
|
||||||
define_witx_pointer(names, &namedtype.name, quote!(wiggle::GuestPtr), p)
|
let rt = names.runtime_mod();
|
||||||
|
define_witx_pointer(names, &namedtype.name, quote!(#rt::GuestPtr), p)
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(p) => {
|
witx::Type::ConstPointer(p) => {
|
||||||
define_witx_pointer(names, &namedtype.name, quote!(wiggle::GuestPtr), p)
|
let rt = names.runtime_mod();
|
||||||
|
define_witx_pointer(names, &namedtype.name, quote!(#rt::GuestPtr), p)
|
||||||
}
|
}
|
||||||
witx::Type::Array(arr) => define_witx_array(names, &namedtype.name, &arr),
|
witx::Type::Array(arr) => define_witx_array(names, &namedtype.name, &arr),
|
||||||
},
|
},
|
||||||
@@ -67,8 +69,9 @@ fn define_witx_pointer(
|
|||||||
|
|
||||||
fn define_witx_array(names: &Names, name: &witx::Id, arr_raw: &witx::TypeRef) -> TokenStream {
|
fn define_witx_array(names: &Names, name: &witx::Id, arr_raw: &witx::TypeRef) -> TokenStream {
|
||||||
let ident = names.type_(name);
|
let ident = names.type_(name);
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let pointee_type = names.type_ref(arr_raw, quote!('a));
|
let pointee_type = names.type_ref(arr_raw, quote!('a));
|
||||||
quote!(pub type #ident<'a> = wiggle::GuestPtr<'a, [#pointee_type]>;)
|
quote!(pub type #ident<'a> = #rt::GuestPtr<'a, [#pointee_type]>;)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
|
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ pub(super) fn define_struct(
|
|||||||
name: &witx::Id,
|
name: &witx::Id,
|
||||||
s: &witx::StructDatatype,
|
s: &witx::StructDatatype,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ident = names.type_(name);
|
let ident = names.type_(name);
|
||||||
let size = s.mem_size_align().size as u32;
|
let size = s.mem_size_align().size as u32;
|
||||||
let align = s.mem_size_align().align as usize;
|
let align = s.mem_size_align().align as usize;
|
||||||
@@ -23,7 +24,7 @@ pub(super) fn define_struct(
|
|||||||
witx::Type::Builtin(builtin) => names.builtin_type(*builtin, quote!('a)),
|
witx::Type::Builtin(builtin) => names.builtin_type(*builtin, quote!('a)),
|
||||||
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
|
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee, quote!('a));
|
let pointee_type = names.type_ref(&pointee, quote!('a));
|
||||||
quote!(wiggle::GuestPtr<'a, #pointee_type>)
|
quote!(#rt::GuestPtr<'a, #pointee_type>)
|
||||||
}
|
}
|
||||||
_ => unimplemented!("other anonymous struct members"),
|
_ => unimplemented!("other anonymous struct members"),
|
||||||
},
|
},
|
||||||
@@ -39,20 +40,20 @@ pub(super) fn define_struct(
|
|||||||
witx::TypeRef::Name(nt) => {
|
witx::TypeRef::Name(nt) => {
|
||||||
let type_ = names.type_(&nt.name);
|
let type_ = names.type_(&nt.name);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = <#type_ as wiggle::GuestType>::read(&#location)?;
|
let #name = <#type_ as #rt::GuestType>::read(&#location)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::TypeRef::Value(ty) => match &**ty {
|
witx::TypeRef::Value(ty) => match &**ty {
|
||||||
witx::Type::Builtin(builtin) => {
|
witx::Type::Builtin(builtin) => {
|
||||||
let type_ = names.builtin_type(*builtin, anon_lifetime());
|
let type_ = names.builtin_type(*builtin, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let #name = <#type_ as wiggle::GuestType>::read(&#location)?;
|
let #name = <#type_ as #rt::GuestType>::read(&#location)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
|
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let #name = <wiggle::GuestPtr::<#pointee_type> as wiggle::GuestType>::read(&#location)?;
|
let #name = <#rt::GuestPtr::<#pointee_type> as #rt::GuestType>::read(&#location)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!("other anonymous struct members"),
|
_ => unimplemented!("other anonymous struct members"),
|
||||||
@@ -64,7 +65,7 @@ pub(super) fn define_struct(
|
|||||||
let name = names.struct_member(&ml.member.name);
|
let name = names.struct_member(&ml.member.name);
|
||||||
let offset = ml.offset as u32;
|
let offset = ml.offset as u32;
|
||||||
quote! {
|
quote! {
|
||||||
wiggle::GuestType::write(
|
#rt::GuestType::write(
|
||||||
&location.cast::<u8>().add(#offset)?.cast(),
|
&location.cast::<u8>().add(#offset)?.cast(),
|
||||||
val.#name,
|
val.#name,
|
||||||
)?;
|
)?;
|
||||||
@@ -91,9 +92,9 @@ pub(super) fn define_struct(
|
|||||||
});
|
});
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
unsafe impl<'a> wiggle::GuestTypeTransparent<'a> for #ident {
|
unsafe impl<'a> #rt::GuestTypeTransparent<'a> for #ident {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate(location: *mut #ident) -> Result<(), wiggle::GuestError> {
|
fn validate(location: *mut #ident) -> Result<(), #rt::GuestError> {
|
||||||
#(#member_validate)*
|
#(#member_validate)*
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ pub(super) fn define_struct(
|
|||||||
#(#member_decls),*
|
#(#member_decls),*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident #struct_lifetime {
|
impl<'a> #rt::GuestType<'a> for #ident #struct_lifetime {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#size
|
#size
|
||||||
}
|
}
|
||||||
@@ -118,12 +119,12 @@ pub(super) fn define_struct(
|
|||||||
#align
|
#align
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<'a, Self>) -> Result<Self, wiggle::GuestError> {
|
fn read(location: &#rt::GuestPtr<'a, Self>) -> Result<Self, #rt::GuestError> {
|
||||||
#(#member_reads)*
|
#(#member_reads)*
|
||||||
Ok(#ident { #(#member_names),* })
|
Ok(#ident { #(#member_names),* })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self) -> Result<(), wiggle::GuestError> {
|
fn write(location: &#rt::GuestPtr<'_, Self>, val: Self) -> Result<(), #rt::GuestError> {
|
||||||
#(#member_writes)*
|
#(#member_writes)*
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use quote::quote;
|
|||||||
use witx::Layout;
|
use witx::Layout;
|
||||||
|
|
||||||
pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDatatype) -> TokenStream {
|
pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDatatype) -> TokenStream {
|
||||||
|
let rt = names.runtime_mod();
|
||||||
let ident = names.type_(name);
|
let ident = names.type_(name);
|
||||||
let size = u.mem_size_align().size as u32;
|
let size = u.mem_size_align().size as u32;
|
||||||
let align = u.mem_size_align().align as usize;
|
let align = u.mem_size_align().align as usize;
|
||||||
@@ -33,7 +34,7 @@ pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDataty
|
|||||||
quote! {
|
quote! {
|
||||||
#tagname::#variantname => {
|
#tagname::#variantname => {
|
||||||
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
|
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
|
||||||
let variant_val = <#varianttype as wiggle::GuestType>::read(&variant_ptr.cast())?;
|
let variant_val = <#varianttype as #rt::GuestType>::read(&variant_ptr.cast())?;
|
||||||
Ok(#ident::#variantname(variant_val))
|
Ok(#ident::#variantname(variant_val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDataty
|
|||||||
#ident::#variantname(contents) => {
|
#ident::#variantname(contents) => {
|
||||||
#write_tag
|
#write_tag
|
||||||
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
|
let variant_ptr = location.cast::<u8>().add(#contents_offset)?;
|
||||||
<#varianttype as wiggle::GuestType>::write(&variant_ptr.cast(), contents)?;
|
<#varianttype as #rt::GuestType>::write(&variant_ptr.cast(), contents)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -77,7 +78,7 @@ pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDataty
|
|||||||
#(#variants),*
|
#(#variants),*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> wiggle::GuestType<'a> for #ident #enum_lifetime {
|
impl<'a> #rt::GuestType<'a> for #ident #enum_lifetime {
|
||||||
fn guest_size() -> u32 {
|
fn guest_size() -> u32 {
|
||||||
#size
|
#size
|
||||||
}
|
}
|
||||||
@@ -86,8 +87,8 @@ pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDataty
|
|||||||
#align
|
#align
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(location: &wiggle::GuestPtr<'a, Self>)
|
fn read(location: &#rt::GuestPtr<'a, Self>)
|
||||||
-> Result<Self, wiggle::GuestError>
|
-> Result<Self, #rt::GuestError>
|
||||||
{
|
{
|
||||||
let tag = location.cast().read()?;
|
let tag = location.cast().read()?;
|
||||||
match tag {
|
match tag {
|
||||||
@@ -96,8 +97,8 @@ pub(super) fn define_union(names: &Names, name: &witx::Id, u: &witx::UnionDataty
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self)
|
fn write(location: &#rt::GuestPtr<'_, Self>, val: Self)
|
||||||
-> Result<(), wiggle::GuestError>
|
-> Result<(), #rt::GuestError>
|
||||||
{
|
{
|
||||||
match val {
|
match val {
|
||||||
#(#write_variant)*
|
#(#write_variant)*
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
wiggle-generate = { path = "../generate", version = "0.15.0" }
|
wiggle-generate = { path = "../generate", version = "0.15.0" }
|
||||||
witx = { path = "../../wasi-common/WASI/tools/witx", version = "0.8.5" }
|
witx = { path = "../../wasi-common/WASI/tools/witx", version = "0.8.5" }
|
||||||
|
quote = "1.0"
|
||||||
syn = { version = "1.0", features = ["full"] }
|
syn = { version = "1.0", features = ["full"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
/// This macro expands to a set of `pub` Rust modules:
|
/// This macro expands to a set of `pub` Rust modules:
|
||||||
@@ -94,11 +95,15 @@ pub fn from_witx(args: TokenStream) -> TokenStream {
|
|||||||
std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var"),
|
std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var"),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "wiggle_metadata")]
|
|
||||||
{
|
|
||||||
config.emit_metadata = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let doc = witx::load(&config.witx.paths).expect("loading witx");
|
let doc = witx::load(&config.witx.paths).expect("loading witx");
|
||||||
TokenStream::from(wiggle_generate::generate(&doc, &config))
|
let names = wiggle_generate::Names::new(&config.ctx.name, quote!(wiggle));
|
||||||
|
|
||||||
|
let code = wiggle_generate::generate(&doc, &names);
|
||||||
|
let metadata = if cfg!(feature = "wiggle_metadata") {
|
||||||
|
wiggle_generate::generate_metadata(&doc, &names)
|
||||||
|
} else {
|
||||||
|
quote!()
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(quote! { #code #metadata })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user