Merge pull request #1470 from bytecodealliance/pch/wiggle_error_model

Wiggle: changes to traits used for error conversion and reporting
This commit is contained in:
Pat Hickey
2020-04-06 19:46:00 -07:00
committed by GitHub
23 changed files with 111 additions and 105 deletions

View File

@@ -62,9 +62,10 @@ pub fn define_func(
_ => unreachable!("err should always be passed by value"),
};
let err_typename = names.type_ref(&tref, anon_lifetime());
let err_method = names.guest_error_conversion_method(&tref);
quote! {
let e = wiggle::GuestError::InFunc { funcname: #funcname, location: #location, err: Box::new(e.into()) };
let err: #err_typename = wiggle::GuestErrorType::from_error(e, ctx);
let err: #err_typename = GuestErrorConversion::#err_method(ctx, e); // XXX replace with conversion method on trait!
return #abi_ret::from(err);
}
} else {

View File

@@ -8,6 +8,8 @@ mod types;
use proc_macro2::TokenStream;
use quote::quote;
use lifetimes::anon_lifetime;
pub use config::Config;
pub use funcs::define_func;
pub use module_trait::define_module_trait;
@@ -21,6 +23,17 @@ pub fn generate(doc: &witx::Document, config: &Config) -> TokenStream {
let types = doc.typenames().map(|t| define_datatype(&names, &t));
let guest_error_methods = doc.error_types().map(|t| {
let typename = names.type_ref(&t, anon_lifetime());
let err_method = names.guest_error_conversion_method(&t);
quote!(fn #err_method(&self, e: wiggle::GuestError) -> #typename;)
});
let guest_error_conversion = quote! {
pub trait GuestErrorConversion {
#(#guest_error_methods)*
}
};
let modules = doc.modules().map(|module| {
let modname = names.module(&module.name);
let trait_name = names.trait_name(&module.name);
@@ -57,6 +70,7 @@ pub fn generate(doc: &witx::Document, config: &Config) -> TokenStream {
quote!(
pub mod types {
#(#types)*
#guest_error_conversion
}
#(#modules)*
#metadata

View File

@@ -1,7 +1,7 @@
use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use witx::{AtomType, BuiltinType, Id, TypeRef};
use witx::{AtomType, BuiltinType, Id, Type, TypeRef};
use crate::lifetimes::LifetimeExt;
@@ -59,12 +59,12 @@ impl Names {
}
}
TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => self.builtin_type(*builtin, lifetime.clone()),
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
Type::Builtin(builtin) => self.builtin_type(*builtin, lifetime.clone()),
Type::Pointer(pointee) | Type::ConstPointer(pointee) => {
let pointee_type = self.type_ref(&pointee, lifetime.clone());
quote!(wiggle::GuestPtr<#lifetime, #pointee_type>)
}
witx::Type::Array(pointee) => {
Type::Array(pointee) => {
let pointee_type = self.type_ref(&pointee, lifetime.clone());
quote!(wiggle::GuestPtr<#lifetime, [#pointee_type]>)
}
@@ -139,4 +139,28 @@ impl Names {
pub fn func_len_binding(&self, id: &Id) -> Ident {
format_ident!("{}_len", id.as_str().to_snake_case())
}
pub fn guest_error_conversion_method(&self, tref: &TypeRef) -> Ident {
match tref {
TypeRef::Name(nt) => format_ident!("into_{}", nt.name.as_str().to_snake_case()),
TypeRef::Value(ty) => match &**ty {
Type::Builtin(b) => match b {
BuiltinType::String => unreachable!("error type must be atom"),
BuiltinType::U8 => format_ident!("into_u8"),
BuiltinType::U16 => format_ident!("into_u16"),
BuiltinType::U32 => format_ident!("into_u32"),
BuiltinType::U64 => format_ident!("into_u64"),
BuiltinType::S8 => format_ident!("into_i8"),
BuiltinType::S16 => format_ident!("into_i16"),
BuiltinType::S32 => format_ident!("into_i32"),
BuiltinType::S64 => format_ident!("into_i64"),
BuiltinType::F32 => format_ident!("into_f32"),
BuiltinType::F64 => format_ident!("into_f64"),
BuiltinType::Char8 => format_ident!("into_char8"),
BuiltinType::USize => format_ident!("into_usize"),
},
_ => panic!("unexpected anonymous error type: {:?}", ty),
},
}
}
}