use lifetimes on types that require it
This commit is contained in:
@@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
use crate::names::Names;
|
use crate::names::Names;
|
||||||
use crate::types::struct_is_copy;
|
use crate::types::{anon_lifetime, struct_is_copy};
|
||||||
|
|
||||||
pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
||||||
let ident = names.func(&func.name);
|
let ident = names.func(&func.name);
|
||||||
@@ -58,7 +58,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
|||||||
witx::TypePassedBy::Value(atom) => names.atom_type(atom),
|
witx::TypePassedBy::Value(atom) => names.atom_type(atom),
|
||||||
_ => unreachable!("err should always be passed by value"),
|
_ => unreachable!("err should always be passed by value"),
|
||||||
};
|
};
|
||||||
let err_typename = names.type_ref(&tref);
|
let err_typename = names.type_ref(&tref, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let err: #err_typename = ::memory::GuestErrorType::from_error(e, ctx);
|
let err: #err_typename = ::memory::GuestErrorType::from_error(e, ctx);
|
||||||
return #abi_ret::from(err);
|
return #abi_ret::from(err);
|
||||||
@@ -106,7 +106,7 @@ pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
|
|||||||
let marshal_rets_post = marshal_rets.map(|(_pre, post)| post);
|
let marshal_rets_post = marshal_rets.map(|(_pre, post)| post);
|
||||||
|
|
||||||
let success = if let Some(err_type) = err_type {
|
let success = if let Some(err_type) = err_type {
|
||||||
let err_typename = names.type_ref(&err_type);
|
let err_typename = names.type_ref(&err_type, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let success:#err_typename = ::memory::GuestErrorType::success();
|
let success:#err_typename = ::memory::GuestErrorType::success();
|
||||||
#abi_ret::from(success)
|
#abi_ret::from(success)
|
||||||
@@ -133,7 +133,7 @@ fn marshal_arg(
|
|||||||
error_handling: TokenStream,
|
error_handling: TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let tref = ¶m.tref;
|
let tref = ¶m.tref;
|
||||||
let interface_typename = names.type_ref(&tref);
|
let interface_typename = names.type_ref(&tref, anon_lifetime());
|
||||||
|
|
||||||
let try_into_conversion = {
|
let try_into_conversion = {
|
||||||
let name = names.func_param(¶m.name);
|
let name = names.func_param(¶m.name);
|
||||||
@@ -180,7 +180,7 @@ fn marshal_arg(
|
|||||||
witx::BuiltinType::String => unimplemented!("string types unimplemented"),
|
witx::BuiltinType::String => unimplemented!("string types unimplemented"),
|
||||||
},
|
},
|
||||||
witx::Type::Pointer(pointee) => {
|
witx::Type::Pointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(pointee);
|
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 = match memory.ptr_mut::<#pointee_type>(#name as u32) {
|
let #name = match memory.ptr_mut::<#pointee_type>(#name as u32) {
|
||||||
@@ -192,7 +192,7 @@ fn marshal_arg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(pointee) => {
|
witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(pointee);
|
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 = match memory.ptr::<#pointee_type>(#name as u32) {
|
let #name = match memory.ptr::<#pointee_type>(#name as u32) {
|
||||||
@@ -204,7 +204,7 @@ fn marshal_arg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Struct(s) if struct_is_copy(&s) => {
|
witx::Type::Struct(s) if struct_is_copy(&s) => {
|
||||||
let pointee_type = names.type_ref(tref);
|
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||||
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! {
|
||||||
@@ -222,7 +222,7 @@ fn marshal_arg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Struct(s) if !struct_is_copy(&s) => {
|
witx::Type::Struct(s) if !struct_is_copy(&s) => {
|
||||||
let pointee_type = names.type_ref(tref);
|
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||||
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! {
|
||||||
@@ -251,7 +251,7 @@ fn marshal_result(
|
|||||||
let tref = &result.tref;
|
let tref = &result.tref;
|
||||||
|
|
||||||
let write_val_to_ptr = {
|
let write_val_to_ptr = {
|
||||||
let pointee_type = names.type_ref(tref);
|
let pointee_type = names.type_ref(tref, anon_lifetime());
|
||||||
// core type is given func_ptr_binding name.
|
// core type is given func_ptr_binding name.
|
||||||
let ptr_name = names.func_ptr_binding(&result.name);
|
let ptr_name = names.func_ptr_binding(&result.name);
|
||||||
let pre = quote! {
|
let pre = quote! {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use proc_macro2::TokenStream;
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
use crate::names::Names;
|
use crate::names::Names;
|
||||||
|
use crate::types::anon_lifetime;
|
||||||
use witx::Module;
|
use witx::Module;
|
||||||
|
|
||||||
pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
||||||
@@ -10,7 +11,7 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
|||||||
let funcname = names.func(&f.name);
|
let funcname = names.func(&f.name);
|
||||||
let args = f.params.iter().map(|arg| {
|
let args = f.params.iter().map(|arg| {
|
||||||
let arg_name = names.func_param(&arg.name);
|
let arg_name = names.func_param(&arg.name);
|
||||||
let arg_typename = names.type_ref(&arg.tref);
|
let arg_typename = names.type_ref(&arg.tref, anon_lifetime());
|
||||||
let arg_type = match arg.tref.type_().passed_by() {
|
let arg_type = match arg.tref.type_().passed_by() {
|
||||||
witx::TypePassedBy::Value { .. } => quote!(#arg_typename),
|
witx::TypePassedBy::Value { .. } => quote!(#arg_typename),
|
||||||
witx::TypePassedBy::Pointer { .. } => quote!(&#arg_typename),
|
witx::TypePassedBy::Pointer { .. } => quote!(&#arg_typename),
|
||||||
@@ -22,11 +23,11 @@ pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
|||||||
.results
|
.results
|
||||||
.iter()
|
.iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|ret| names.type_ref(&ret.tref));
|
.map(|ret| names.type_ref(&ret.tref, anon_lifetime()));
|
||||||
let err = f
|
let err = f
|
||||||
.results
|
.results
|
||||||
.get(0)
|
.get(0)
|
||||||
.map(|err_result| names.type_ref(&err_result.tref))
|
.map(|err_result| names.type_ref(&err_result.tref, anon_lifetime()))
|
||||||
.unwrap_or(quote!(()));
|
.unwrap_or(quote!(()));
|
||||||
quote!(fn #funcname(&mut self, #(#args),*) -> Result<(#(#rets),*), #err>;)
|
quote!(fn #funcname(&mut self, #(#args),*) -> Result<(#(#rets),*), #err>;)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use proc_macro2::{Ident, TokenStream};
|
|||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use witx::{AtomType, BuiltinType, Id, TypeRef};
|
use witx::{AtomType, BuiltinType, Id, TypeRef};
|
||||||
|
|
||||||
|
use crate::types::type_needs_lifetime;
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -47,21 +48,25 @@ impl Names {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_ref(&self, tref: &TypeRef) -> TokenStream {
|
pub fn type_ref(&self, tref: &TypeRef, lifetime: TokenStream) -> TokenStream {
|
||||||
match tref {
|
match tref {
|
||||||
TypeRef::Name(nt) => {
|
TypeRef::Name(nt) => {
|
||||||
let ident = self.type_(&nt.name);
|
let ident = self.type_(&nt.name);
|
||||||
quote!(#ident)
|
if type_needs_lifetime(&nt.tref) {
|
||||||
|
quote!(#ident<#lifetime>)
|
||||||
|
} else {
|
||||||
|
quote!(#ident)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TypeRef::Value(ty) => match &**ty {
|
TypeRef::Value(ty) => match &**ty {
|
||||||
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
|
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
|
||||||
witx::Type::Pointer(pointee) => {
|
witx::Type::Pointer(pointee) => {
|
||||||
let pointee_type = self.type_ref(&pointee);
|
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||||
quote!(::memory::GuestPtrMut<#pointee_type>)
|
quote!(::memory::GuestPtrMut<#lifetime, #pointee_type>)
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(pointee) => {
|
witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = self.type_ref(&pointee);
|
let pointee_type = self.type_ref(&pointee, lifetime.clone());
|
||||||
quote!(::memory::GuestPtr<#pointee_type>)
|
quote!(::memory::GuestPtr<#lifetime, #pointee_type>)
|
||||||
}
|
}
|
||||||
_ => unimplemented!("anonymous type ref"),
|
_ => unimplemented!("anonymous type ref"),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
|
|||||||
witx::Type::Union(_) => unimplemented!("union types"),
|
witx::Type::Union(_) => unimplemented!("union types"),
|
||||||
witx::Type::Handle(_h) => unimplemented!("handle types"),
|
witx::Type::Handle(_h) => unimplemented!("handle types"),
|
||||||
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
|
witx::Type::Builtin(b) => define_builtin(names, &namedtype.name, *b),
|
||||||
witx::Type::Pointer { .. } => unimplemented!("pointer types"),
|
witx::Type::Pointer(p) => {
|
||||||
witx::Type::ConstPointer { .. } => unimplemented!("constpointer types"),
|
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtrMut), p)
|
||||||
|
}
|
||||||
|
witx::Type::ConstPointer(p) => {
|
||||||
|
define_witx_pointer(names, &namedtype.name, quote!(::memory::GuestPtr), p)
|
||||||
|
}
|
||||||
witx::Type::Array { .. } => unimplemented!("array types"),
|
witx::Type::Array { .. } => unimplemented!("array types"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -30,9 +34,12 @@ pub fn define_datatype(names: &Names, namedtype: &witx::NamedType) -> TokenStrea
|
|||||||
|
|
||||||
fn define_alias(names: &Names, name: &witx::Id, to: &witx::NamedType) -> TokenStream {
|
fn define_alias(names: &Names, name: &witx::Id, to: &witx::NamedType) -> TokenStream {
|
||||||
let ident = names.type_(name);
|
let ident = names.type_(name);
|
||||||
let to = names.type_(&to.name);
|
let rhs = names.type_(&to.name);
|
||||||
|
if type_needs_lifetime(&to.tref) {
|
||||||
quote!(pub type #ident = #to;)
|
quote!(pub type #ident<'a> = #rhs<'a>;)
|
||||||
|
} else {
|
||||||
|
quote!(pub type #ident = #rhs;)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenStream {
|
fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenStream {
|
||||||
@@ -133,6 +140,23 @@ fn define_builtin(names: &Names, name: &witx::Id, builtin: witx::BuiltinType) ->
|
|||||||
quote!(pub type #ident = #built;)
|
quote!(pub type #ident = #built;)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_needs_lifetime(tref: &witx::TypeRef) -> bool {
|
||||||
|
match &*tref.type_() {
|
||||||
|
witx::Type::Builtin(b) => match b {
|
||||||
|
witx::BuiltinType::String => unimplemented!(),
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
witx::Type::Enum { .. }
|
||||||
|
| witx::Type::Flags { .. }
|
||||||
|
| witx::Type::Int { .. }
|
||||||
|
| witx::Type::Handle { .. } => false,
|
||||||
|
witx::Type::Struct(s) => !struct_is_copy(&s),
|
||||||
|
witx::Type::Union { .. } => true,
|
||||||
|
witx::Type::Pointer { .. } | witx::Type::ConstPointer { .. } => true,
|
||||||
|
witx::Type::Array { .. } => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn struct_is_copy(s: &witx::StructDatatype) -> bool {
|
pub fn struct_is_copy(s: &witx::StructDatatype) -> bool {
|
||||||
s.members.iter().all(|m| match &*m.tref.type_() {
|
s.members.iter().all(|m| match &*m.tref.type_() {
|
||||||
witx::Type::Struct(s) => struct_is_copy(&s),
|
witx::Type::Struct(s) => struct_is_copy(&s),
|
||||||
@@ -158,11 +182,11 @@ fn define_copy_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype)
|
|||||||
|
|
||||||
let member_decls = s.members.iter().map(|m| {
|
let member_decls = s.members.iter().map(|m| {
|
||||||
let name = names.struct_member(&m.name);
|
let name = names.struct_member(&m.name);
|
||||||
let type_ = names.type_ref(&m.tref);
|
let type_ = names.type_ref(&m.tref, anon_lifetime());
|
||||||
quote!(pub #name: #type_)
|
quote!(pub #name: #type_)
|
||||||
});
|
});
|
||||||
let member_valids = s.member_layout().into_iter().map(|ml| {
|
let member_valids = s.member_layout().into_iter().map(|ml| {
|
||||||
let type_ = names.type_ref(&ml.member.tref);
|
let type_ = names.type_ref(&ml.member.tref, anon_lifetime());
|
||||||
let offset = ml.offset as u32;
|
let offset = ml.offset as u32;
|
||||||
let fieldname = names.struct_member(&ml.member.name);
|
let fieldname = names.struct_member(&ml.member.name);
|
||||||
quote! {
|
quote! {
|
||||||
@@ -221,11 +245,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
|||||||
witx::TypeRef::Value(ty) => match &**ty {
|
witx::TypeRef::Value(ty) => match &**ty {
|
||||||
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
||||||
witx::Type::Pointer(pointee) => {
|
witx::Type::Pointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, quote!('a));
|
||||||
quote!(::memory::GuestPtrMut<'a, #pointee_type>)
|
quote!(::memory::GuestPtrMut<'a, #pointee_type>)
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(pointee) => {
|
witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, quote!('a));
|
||||||
quote!(::memory::GuestPtr<'a, #pointee_type>)
|
quote!(::memory::GuestPtr<'a, #pointee_type>)
|
||||||
}
|
}
|
||||||
_ => unimplemented!("other anonymous struct members"),
|
_ => unimplemented!("other anonymous struct members"),
|
||||||
@@ -239,11 +263,11 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
|||||||
witx::TypeRef::Value(ty) => match &**ty {
|
witx::TypeRef::Value(ty) => match &**ty {
|
||||||
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
witx::Type::Builtin(builtin) => names.builtin_type(*builtin),
|
||||||
witx::Type::Pointer(pointee) => {
|
witx::Type::Pointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||||
quote!(::memory::GuestPtrMut::<#pointee_type>)
|
quote!(::memory::GuestPtrMut::<#pointee_type>)
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(pointee) => {
|
witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||||
quote!(::memory::GuestPtr::<#pointee_type>)
|
quote!(::memory::GuestPtr::<#pointee_type>)
|
||||||
}
|
}
|
||||||
_ => unimplemented!("other anonymous struct members"),
|
_ => unimplemented!("other anonymous struct members"),
|
||||||
@@ -286,13 +310,13 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::Pointer(pointee) => {
|
witx::Type::Pointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let #name = ::memory::GuestPtrMut::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
let #name = ::memory::GuestPtrMut::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
witx::Type::ConstPointer(pointee) => {
|
witx::Type::ConstPointer(pointee) => {
|
||||||
let pointee_type = names.type_ref(&pointee);
|
let pointee_type = names.type_ref(&pointee, anon_lifetime());
|
||||||
quote! {
|
quote! {
|
||||||
let #name = ::memory::GuestPtr::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
let #name = ::memory::GuestPtr::<#pointee_type>::read_from_guest(&location.cast(#offset)?)?;
|
||||||
}
|
}
|
||||||
@@ -340,6 +364,19 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn define_witx_pointer(
|
||||||
|
names: &Names,
|
||||||
|
name: &witx::Id,
|
||||||
|
pointer_type: TokenStream,
|
||||||
|
pointee: &witx::TypeRef,
|
||||||
|
) -> TokenStream {
|
||||||
|
let ident = names.type_(name);
|
||||||
|
let pointee_type = names.type_ref(pointee, quote!('a));
|
||||||
|
|
||||||
|
quote!(pub type #ident<'a> = #pointer_type<'a, #pointee_type>;)
|
||||||
|
}
|
||||||
|
|
||||||
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
|
fn int_repr_tokens(int_repr: witx::IntRepr) -> TokenStream {
|
||||||
match int_repr {
|
match int_repr {
|
||||||
witx::IntRepr::U8 => quote!(u8),
|
witx::IntRepr::U8 => quote!(u8),
|
||||||
@@ -356,3 +393,7 @@ fn atom_token(atom: witx::AtomType) -> TokenStream {
|
|||||||
witx::AtomType::F64 => quote!(f64),
|
witx::AtomType::F64 => quote!(f64),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn anon_lifetime() -> TokenStream {
|
||||||
|
quote!('_)
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
(field $first (@witx const_pointer s32))
|
(field $first (@witx const_pointer s32))
|
||||||
(field $second (@witx const_pointer s32))))
|
(field $second (@witx const_pointer s32))))
|
||||||
|
|
||||||
|
(typename $named_ptr (@witx pointer f32))
|
||||||
|
(typename $named_ptr_to_ptr (@witx pointer (@witx pointer f64)))
|
||||||
|
|
||||||
(module $foo
|
(module $foo
|
||||||
(@interface func (export "bar")
|
(@interface func (export "bar")
|
||||||
(param $an_int u32)
|
(param $an_int u32)
|
||||||
|
|||||||
Reference in New Issue
Block a user