diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index a101a19a13..a7f890ca56 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -306,7 +306,7 @@ impl<'a, T: ?Sized + Pointee> GuestPtr<'a, T> { 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 /// 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)) } + + /// 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, + { + GuestPtr::new(self.mem, (self.pointer, elems)) + } } impl<'a, T> GuestPtr<'a, [T]> { diff --git a/tests/wasi.rs b/tests/wasi.rs index 6841926b9d..0b27fb3ea0 100644 --- a/tests/wasi.rs +++ b/tests/wasi.rs @@ -1,4 +1,4 @@ -use wiggle_runtime::{GuestError, GuestErrorType, GuestPtr}; +use wiggle_runtime::{GuestBorrows, GuestError, GuestErrorType, GuestPtr}; use wiggle_test::WasiCtx; wiggle::from_witx!({ @@ -120,9 +120,27 @@ impl crate::wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { fn fd_pread( &self, _fd: types::Fd, - _iovs: &types::IovecArray<'_>, + iovs: &types::IovecArray<'_>, _offset: types::Filesize, ) -> Result { + // 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 = 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") }