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:
@@ -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),* })
|
||||||
|
|||||||
@@ -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>);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user