Allow creation of GuestPtr<[T]> from GuestPtr<T> and length (#39)

* add GuestPtr::as_array method

* wasi test: show with type signatures we have achieved the desired api
This commit is contained in:
Pat Hickey
2020-03-06 17:45:09 -08:00
committed by GitHub
parent 6e3ec6a96d
commit 06bcac3e43
2 changed files with 30 additions and 3 deletions

View File

@@ -306,7 +306,7 @@ impl<'a, T: ?Sized + Pointee> GuestPtr<'a, T> {
T::read(self) T::read(self)
} }
/// Safely write a valud to this pointer. /// Safely write a value to this pointer.
/// ///
/// This method, like [`GuestPtr::read`], is pretty crucial for the safe /// This method, like [`GuestPtr::read`], is pretty crucial for the safe
/// operation of this crate. All the same reasons apply though for why this /// operation of this crate. All the same reasons apply though for why this
@@ -342,6 +342,15 @@ impl<'a, T: ?Sized + Pointee> GuestPtr<'a, T> {
}; };
Ok(GuestPtr::new(self.mem, offset)) Ok(GuestPtr::new(self.mem, offset))
} }
/// Returns a `GuestPtr` for an array of `T`s using this pointer as the
/// base.
pub fn as_array(&self, elems: u32) -> GuestPtr<'a, [T]>
where
T: GuestType<'a> + Pointee<Pointer = u32>,
{
GuestPtr::new(self.mem, (self.pointer, elems))
}
} }
impl<'a, T> GuestPtr<'a, [T]> { impl<'a, T> GuestPtr<'a, [T]> {

View File

@@ -1,4 +1,4 @@
use wiggle_runtime::{GuestError, GuestErrorType, GuestPtr}; use wiggle_runtime::{GuestBorrows, GuestError, GuestErrorType, GuestPtr};
use wiggle_test::WasiCtx; use wiggle_test::WasiCtx;
wiggle::from_witx!({ wiggle::from_witx!({
@@ -120,9 +120,27 @@ impl crate::wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
fn fd_pread( fn fd_pread(
&self, &self,
_fd: types::Fd, _fd: types::Fd,
_iovs: &types::IovecArray<'_>, iovs: &types::IovecArray<'_>,
_offset: types::Filesize, _offset: types::Filesize,
) -> Result<types::Size> { ) -> Result<types::Size> {
// This is not functional code, but the type annotations demonstrate
// that we can use the wiggle API to create the datastructures we want
// for efficient implementation of this function elsewhere.
let mut bc = GuestBorrows::new();
let mut slices: Vec<&'_ mut [u8]> = Vec::new();
for iov_ptr in iovs.iter() {
let iov: types::Iovec = iov_ptr
.expect("iovec element pointer is valid")
.read()
.expect("read iovec element");
let base: GuestPtr<u8> = iov.buf;
let len: u32 = iov.buf_len;
let buf: GuestPtr<[u8]> = base.as_array(len);
let slice = buf.as_raw(&mut bc).expect("borrow slice from iovec");
slices.push(unsafe { &mut *slice });
}
println!("iovec slices: {:?}", slices);
unimplemented!("fd_pread") unimplemented!("fd_pread")
} }