Fix read/write for GuestTypeCopy members of non-copy structs

This commit fixes stubs for struct members that are `GuestTypeCopy`
but are not `GuestTypeClone`. In this case, we cannot rely on methods
`T::read_from_guest` or `T::write_to_guest` since these are only
available if `T: GuestTypeClone`. In those cases, we can and should
dereference the location pointer to `T` and copy the result in/out
respectively.
This commit is contained in:
Jakub Konka
2020-02-23 18:16:26 +01:00
committed by Jakub Konka
parent 678065011e
commit 7a4c881409

View File

@@ -567,14 +567,14 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
witx::TypeRef::Name(nt) => {
let type_ = names.type_(&nt.name);
quote! {
let #name = #type_::read_from_guest(&location.cast(#offset)?)?;
let #name: #type_ = *location.cast(#offset)?.as_ref()?;
}
}
witx::TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => {
let type_ = names.builtin_type(*builtin, anon_lifetime());
quote! {
let #name = #type_::read_from_guest(&location.cast(#offset)?)?;
let #name: #type_ = *location.cast(#offset)?.as_ref()?;
}
}
witx::Type::Pointer(pointee) => {
@@ -597,7 +597,31 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
let member_writes = s.member_layout().into_iter().map(|ml| {
let name = names.struct_member(&ml.member.name);
let offset = ml.offset as u32;
quote!( self.#name.write_to_guest(&location.cast(#offset).expect("cast to inner member")); )
match &ml.member.tref {
witx::TypeRef::Name(_) => {
quote! {
*location.cast(#offset).expect("cast to inner member").as_ref_mut().expect("inner member as ref mut") = self.#name;
}
}
witx::TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(_) => {
quote! {
*location.cast(#offset).expect("cast to inner member").as_ref_mut().expect("inner member as ref mut") = self.#name;
}
}
witx::Type::Pointer(_) => {
quote! {
self.#name.write_to_guest(&location.cast(#offset).expect("cast to inner member"));
}
}
witx::Type::ConstPointer(_) => {
quote! {
self.#name.write_to_guest(&location.cast(#offset).expect("cast to inner member"));
}
}
_ => unimplemented!("other anonymous struct members"),
},
}
});
quote! {