merge GuestTypePtr and GuestTypeClone into a single GuestTypeClone<'a> trait (#14)

* merge GuestTypePtr and GuestTypeClone into a single GuestTypeClone<'a> trait

* GuestArray can derive Clone (but not impl GuestTypeClone)

* fix array tests

* Fix GuestTypeClone for flags

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
Pat Hickey
2020-02-21 08:43:45 -08:00
committed by GitHub
parent 3ef24a04fe
commit 2f223acc55
6 changed files with 38 additions and 67 deletions

View File

@@ -179,7 +179,7 @@ fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDatatype) -> Toke
} }
impl wiggle_runtime::GuestTypeCopy for #ident {} impl wiggle_runtime::GuestTypeCopy for #ident {}
impl wiggle_runtime::GuestTypeClone for #ident { impl<'a> wiggle_runtime::GuestTypeClone<'a> for #ident {
fn read_from_guest(location: &wiggle_runtime::GuestPtr<#ident>) -> Result<#ident, wiggle_runtime::GuestError> { fn read_from_guest(location: &wiggle_runtime::GuestPtr<#ident>) -> Result<#ident, wiggle_runtime::GuestError> {
Ok(*location.as_ref()?) Ok(*location.as_ref()?)
} }
@@ -267,7 +267,7 @@ fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenS
} }
impl wiggle_runtime::GuestTypeCopy for #ident {} impl wiggle_runtime::GuestTypeCopy for #ident {}
impl wiggle_runtime::GuestTypeClone for #ident { impl<'a> wiggle_runtime::GuestTypeClone<'a> for #ident {
fn read_from_guest(location: &wiggle_runtime::GuestPtr<#ident>) -> Result<#ident, wiggle_runtime::GuestError> { fn read_from_guest(location: &wiggle_runtime::GuestPtr<#ident>) -> Result<#ident, wiggle_runtime::GuestError> {
use ::std::convert::TryFrom; use ::std::convert::TryFrom;
let raw: #repr = unsafe { (location.as_raw() as *const #repr).read() }; let raw: #repr = unsafe { (location.as_raw() as *const #repr).read() };
@@ -502,7 +502,7 @@ fn define_ptr_struct(names: &Names, name: &witx::Id, s: &witx::StructDatatype) -
Ok(()) Ok(())
} }
} }
impl<'a> wiggle_runtime::GuestTypePtr<'a> for #ident<'a> { impl<'a> wiggle_runtime::GuestTypeClone<'a> for #ident<'a> {
fn read_from_guest(location: &wiggle_runtime::GuestPtr<'a, #ident<'a>>) -> Result<#ident<'a>, wiggle_runtime::GuestError> { fn read_from_guest(location: &wiggle_runtime::GuestPtr<'a, #ident<'a>>) -> Result<#ident<'a>, wiggle_runtime::GuestError> {
#(#member_reads)* #(#member_reads)*
Ok(#ident { #(#member_names),* }) Ok(#ident { #(#member_names),* })

View File

@@ -11,11 +11,7 @@ pub trait GuestType: Sized {
} }
pub trait GuestTypeCopy: GuestType + Copy {} pub trait GuestTypeCopy: GuestType + Copy {}
pub trait GuestTypeClone: GuestType + Clone { pub trait GuestTypeClone<'a>: GuestType + Clone {
fn read_from_guest<'a>(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError>;
fn write_to_guest<'a>(&self, location: &GuestPtrMut<'a, Self>);
}
pub trait GuestTypePtr<'a>: GuestType {
fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError>; fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError>;
fn write_to_guest(&self, location: &GuestPtrMut<'a, Self>); fn write_to_guest(&self, location: &GuestPtrMut<'a, Self>);
} }

View File

@@ -5,6 +5,6 @@ mod memory;
mod region; mod region;
pub use error::GuestError; pub use error::GuestError;
pub use guest_type::{GuestErrorType, GuestType, GuestTypeClone, GuestTypeCopy, GuestTypePtr}; pub use guest_type::{GuestErrorType, GuestType, GuestTypeClone, GuestTypeCopy};
pub use memory::{GuestArray, GuestMemory, GuestPtr, GuestPtrMut, GuestRef, GuestRefMut}; pub use memory::{GuestArray, GuestMemory, GuestPtr, GuestPtrMut, GuestRef, GuestRefMut};
pub use region::Region; pub use region::Region;

View File

@@ -2,6 +2,7 @@ use super::ptr::{GuestPtr, GuestRef};
use crate::{GuestError, GuestType, GuestTypeCopy}; use crate::{GuestError, GuestType, GuestTypeCopy};
use std::{fmt, ops::Deref}; use std::{fmt, ops::Deref};
#[derive(Clone)]
pub struct GuestArray<'a, T> pub struct GuestArray<'a, T>
where where
T: GuestType, T: GuestType,
@@ -145,9 +146,9 @@ where
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::super::{ use crate::{
ptr::{GuestPtr, GuestPtrMut}, memory::ptr::{GuestPtr, GuestPtrMut},
GuestError, GuestMemory, Region, GuestError, GuestMemory, GuestTypeClone, Region,
}; };
#[repr(align(4096))] #[repr(align(4096))]
@@ -248,9 +249,7 @@ mod test {
let contents = arr let contents = arr
.iter() .iter()
.map(|ptr_ptr| { .map(|ptr_ptr| {
*ptr_ptr *GuestTypeClone::read_from_guest(&ptr_ptr.expect("valid ptr to ptr"))
.expect("valid ptr to ptr")
.read_ptr_from_guest()
.expect("valid ptr to some value") .expect("valid ptr to some value")
.as_ref() .as_ref()
.expect("deref ptr to some value") .expect("deref ptr to some value")

View File

@@ -1,8 +1,5 @@
use super::{array::GuestArray, GuestMemory}; use super::{array::GuestArray, GuestMemory};
use crate::{ use crate::{borrow::BorrowHandle, GuestError, GuestType, GuestTypeClone, GuestTypeCopy, Region};
borrow::BorrowHandle, GuestError, GuestType, GuestTypeClone, GuestTypeCopy, GuestTypePtr,
Region,
};
use std::{ use std::{
fmt, fmt,
marker::PhantomData, marker::PhantomData,
@@ -81,22 +78,13 @@ where
impl<'a, T> GuestPtr<'a, T> impl<'a, T> GuestPtr<'a, T>
where where
T: GuestTypeClone, T: GuestTypeClone<'a>,
{ {
pub fn clone_from_guest(&self) -> Result<T, GuestError> { pub fn clone_from_guest(&self) -> Result<T, GuestError> {
T::read_from_guest(self) T::read_from_guest(self)
} }
} }
impl<'a, T> GuestPtr<'a, T>
where
T: GuestTypePtr<'a>,
{
pub fn read_ptr_from_guest(&self) -> Result<T, GuestError> {
T::read_from_guest(self)
}
}
impl<'a, T> GuestType for GuestPtr<'a, T> impl<'a, T> GuestType for GuestPtr<'a, T>
where where
T: GuestType, T: GuestType,
@@ -123,9 +111,9 @@ where
} }
// Operations for reading and writing Ptrs to memory: // Operations for reading and writing Ptrs to memory:
impl<'a, T> GuestTypePtr<'a> for GuestPtr<'a, T> impl<'a, T> GuestTypeClone<'a> for GuestPtr<'a, T>
where where
T: GuestType, T: GuestType + Clone,
{ {
fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError> { fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError> {
// location is guaranteed to be in GuestMemory and aligned to 4 // location is guaranteed to be in GuestMemory and aligned to 4
@@ -220,7 +208,7 @@ where
impl<'a, T> GuestPtrMut<'a, T> impl<'a, T> GuestPtrMut<'a, T>
where where
T: GuestTypePtr<'a>, T: GuestTypeClone<'a>,
{ {
pub fn read_ptr_from_guest(&self) -> Result<T, GuestError> { pub fn read_ptr_from_guest(&self) -> Result<T, GuestError> {
T::read_from_guest(&self.as_immut()) T::read_from_guest(&self.as_immut())
@@ -231,19 +219,6 @@ where
} }
} }
impl<'a, T> GuestPtrMut<'a, T>
where
T: GuestTypeClone,
{
pub fn clone_from_guest(&self) -> Result<T, GuestError> {
T::read_from_guest(&self.as_immut())
}
pub fn clone_to_guest(&self, val: &T) {
T::write_to_guest(val, &self)
}
}
impl<'a, T> GuestType for GuestPtrMut<'a, T> impl<'a, T> GuestType for GuestPtrMut<'a, T>
where where
T: GuestType, T: GuestType,
@@ -270,9 +245,9 @@ where
} }
// Reading and writing GuestPtrMuts to memory: // Reading and writing GuestPtrMuts to memory:
impl<'a, T> GuestTypePtr<'a> for GuestPtrMut<'a, T> impl<'a, T> GuestTypeClone<'a> for GuestPtrMut<'a, T>
where where
T: GuestType, T: GuestType + Clone,
{ {
fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError> { fn read_from_guest(location: &GuestPtr<'a, Self>) -> Result<Self, GuestError> {
// location is guaranteed to be in GuestMemory and aligned to 4 // location is guaranteed to be in GuestMemory and aligned to 4

View File

@@ -56,8 +56,10 @@ impl foo::Foo for WasiCtx {
println!("wrote to input2_ref {:?}", input3); println!("wrote to input2_ref {:?}", input3);
// Read ptr value from mutable ptr: // Read ptr value from mutable ptr:
let input4_ptr: GuestPtr<types::Excuse> = let input4_ptr: GuestPtr<types::Excuse> = wiggle_runtime::GuestTypeClone::read_from_guest(
input4_ptr_ptr.read_ptr_from_guest().map_err(|e| { &input4_ptr_ptr.as_immut(),
)
.map_err(|e| {
eprintln!("input4_ptr_ptr error: {}", e); eprintln!("input4_ptr_ptr error: {}", e);
types::Errno::InvalidArg types::Errno::InvalidArg
})?; })?;
@@ -99,21 +101,21 @@ impl foo::Foo for WasiCtx {
&mut self, &mut self,
excuses: &types::ConstExcuseArray, excuses: &types::ConstExcuseArray,
) -> Result<types::Excuse, types::Errno> { ) -> Result<types::Excuse, types::Errno> {
let last = excuses let last = wiggle_runtime::GuestTypeClone::read_from_guest(
&excuses
.iter() .iter()
.last() .last()
.expect("input array is non-empty") .expect("input array is non-empty")
.expect("valid ptr to ptr") .expect("valid ptr to ptr"),
.read_ptr_from_guest() )
.expect("valid ptr to some Excuse value"); .expect("valid ptr to some Excuse value");
Ok(*last.as_ref().expect("dereferencing ptr should succeed")) Ok(*last.as_ref().expect("dereferencing ptr should succeed"))
} }
fn populate_excuses(&mut self, excuses: &types::ExcuseArray) -> Result<(), types::Errno> { fn populate_excuses(&mut self, excuses: &types::ExcuseArray) -> Result<(), types::Errno> {
for excuse in excuses.iter() { for excuse in excuses.iter() {
let ptr_to_ptr = excuse let ptr_to_ptr =
.expect("valid ptr to ptr") wiggle_runtime::GuestTypeClone::read_from_guest(&excuse.expect("valid ptr to ptr"))
.read_ptr_from_guest()
.expect("valid ptr to some Excuse value"); .expect("valid ptr to some Excuse value");
let mut ptr = ptr_to_ptr let mut ptr = ptr_to_ptr
.as_ref_mut() .as_ref_mut()
@@ -767,9 +769,8 @@ impl PopulateExcusesExcercise {
.array(self.elements.len() as u32) .array(self.elements.len() as u32)
.expect("as array"); .expect("as array");
for el in arr.iter() { for el in arr.iter() {
let ptr_to_ptr = el let ptr_to_ptr =
.expect("valid ptr to ptr") wiggle_runtime::GuestTypeClone::read_from_guest(&el.expect("valid ptr to ptr"))
.read_ptr_from_guest()
.expect("valid ptr to some Excuse value"); .expect("valid ptr to some Excuse value");
assert_eq!( assert_eq!(
*ptr_to_ptr *ptr_to_ptr