add manual interface for borrowing a GuestPtr (#40)

* add manual interface for borrowing a GuestPtr

* add manual borrow checking methods for slice and str as well

* update test to use borrow_slice
This commit is contained in:
Pat Hickey
2020-03-10 12:33:02 -07:00
committed by GitHub
parent 06bcac3e43
commit 2139020d6d
2 changed files with 43 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
use crate::region::Region;
use crate::GuestError;
use crate::{GuestError, GuestPtr, GuestType};
#[derive(Debug)]
pub struct GuestBorrows {
@@ -17,7 +17,7 @@ impl GuestBorrows {
!self.borrows.iter().all(|b| !b.overlaps(r))
}
pub fn borrow(&mut self, r: Region) -> Result<(), GuestError> {
pub(crate) fn borrow(&mut self, r: Region) -> Result<(), GuestError> {
if self.is_borrowed(r) {
Err(GuestError::PtrBorrowed(r))
} else {
@@ -25,6 +25,41 @@ impl GuestBorrows {
Ok(())
}
}
/// Borrow the region of memory pointed to by a `GuestPtr`. This is required for safety if
/// you are dereferencing `GuestPtr`s while holding a reference to a slice via
/// `GuestPtr::as_raw`.
pub fn borrow_pointee<'a, T>(&mut self, p: &GuestPtr<'a, T>) -> Result<(), GuestError>
where
T: GuestType<'a>,
{
self.borrow(Region {
start: p.offset(),
len: T::guest_size(),
})
}
/// Borrow the slice of memory pointed to by a `GuestPtr<[T]>`. This is required for safety if
/// you are dereferencing the `GuestPtr`s while holding a reference to another slice via
/// `GuestPtr::as_raw`. Not required if using `GuestPtr::as_raw` on this pointer.
pub fn borrow_slice<'a, T>(&mut self, p: &GuestPtr<'a, [T]>) -> Result<(), GuestError>
where
T: GuestType<'a>,
{
let (start, elems) = p.offset();
let len = T::guest_size()
.checked_mul(elems)
.ok_or_else(|| GuestError::PtrOverflow)?;
self.borrow(Region { start, len })
}
/// Borrow the slice of memory pointed to by a `GuestPtr<str>`. This is required for safety if
/// you are dereferencing the `GuestPtr`s while holding a reference to another slice via
/// `GuestPtr::as_raw`. Not required if using `GuestPtr::as_raw` on this pointer.
pub fn borrow_str(&mut self, p: &GuestPtr<str>) -> Result<(), GuestError> {
let (start, len) = p.offset();
self.borrow(Region { start, len })
}
}
#[cfg(test)]