wiggle: automate borrow checking, explicitly passing borrow checker throughout

This commit is contained in:
Pat Hickey
2020-05-18 11:45:12 -07:00
parent e229fbc79c
commit 52e8300f01
14 changed files with 313 additions and 191 deletions

View File

@@ -1,5 +1,5 @@
use proptest::prelude::*;
use wiggle::{GuestBorrows, GuestMemory, GuestPtr};
use wiggle::{BorrowChecker, GuestMemory, GuestPtr};
use wiggle_test::{impl_errno, HostMemory, MemArea, MemAreas, WasiCtx};
wiggle::from_witx!({
@@ -11,12 +11,9 @@ impl_errno!(types::Errno, types::GuestErrorConversion);
impl<'a> strings::Strings for WasiCtx<'a> {
fn hello_string(&self, a_string: &GuestPtr<str>) -> Result<u32, types::Errno> {
let mut bc = GuestBorrows::new();
let s = a_string.as_raw(&mut bc).expect("should be valid string");
unsafe {
println!("a_string='{}'", &*s);
Ok((*s).len() as u32)
}
let s = a_string.as_str().expect("should be valid string");
println!("a_string='{}'", &*s);
Ok(s.len() as u32)
}
fn multi_string(
@@ -25,18 +22,15 @@ impl<'a> strings::Strings for WasiCtx<'a> {
b: &GuestPtr<str>,
c: &GuestPtr<str>,
) -> Result<u32, types::Errno> {
let mut bc = GuestBorrows::new();
let sa = a.as_raw(&mut bc).expect("A should be valid string");
let sb = b.as_raw(&mut bc).expect("B should be valid string");
let sc = c.as_raw(&mut bc).expect("C should be valid string");
unsafe {
let total_len = (&*sa).len() + (&*sb).len() + (&*sc).len();
println!(
"len={}, a='{}', b='{}', c='{}'",
total_len, &*sa, &*sb, &*sc
);
Ok(total_len as u32)
}
let sa = a.as_str().expect("A should be valid string");
let sb = b.as_str().expect("B should be valid string");
let sc = c.as_str().expect("C should be valid string");
let total_len = sa.len() + sb.len() + sc.len();
println!(
"len={}, a='{}', b='{}', c='{}'",
total_len, &*sa, &*sb, &*sc
);
Ok(total_len as u32)
}
}
@@ -75,9 +69,11 @@ impl HelloStringExercise {
pub fn test(&self) {
let ctx = WasiCtx::new();
let host_memory = HostMemory::new();
let bc = BorrowChecker::new();
// Populate string in guest's memory
let ptr = host_memory.ptr::<str>((self.string_ptr_loc.ptr, self.test_word.len() as u32));
let ptr =
host_memory.ptr::<str>(&bc, (self.string_ptr_loc.ptr, self.test_word.len() as u32));
for (slot, byte) in ptr.as_bytes().iter().zip(self.test_word.bytes()) {
slot.expect("should be valid pointer")
.write(byte)
@@ -87,6 +83,7 @@ impl HelloStringExercise {
let res = strings::hello_string(
&ctx,
&host_memory,
&bc,
self.string_ptr_loc.ptr as i32,
self.test_word.len() as i32,
self.return_ptr_loc.ptr as i32,
@@ -94,7 +91,7 @@ impl HelloStringExercise {
assert_eq!(res, types::Errno::Ok.into(), "hello string errno");
let given = host_memory
.ptr::<u32>(self.return_ptr_loc.ptr)
.ptr::<u32>(&bc, self.return_ptr_loc.ptr)
.read()
.expect("deref ptr to return value");
assert_eq!(self.test_word.len() as u32, given);
@@ -181,9 +178,10 @@ impl MultiStringExercise {
pub fn test(&self) {
let ctx = WasiCtx::new();
let host_memory = HostMemory::new();
let bc = BorrowChecker::new();
let write_string = |val: &str, loc: MemArea| {
let ptr = host_memory.ptr::<str>((loc.ptr, val.len() as u32));
let ptr = host_memory.ptr::<str>(&bc, (loc.ptr, val.len() as u32));
for (slot, byte) in ptr.as_bytes().iter().zip(val.bytes()) {
slot.expect("should be valid pointer")
.write(byte)
@@ -198,6 +196,7 @@ impl MultiStringExercise {
let res = strings::multi_string(
&ctx,
&host_memory,
&bc,
self.sa_ptr_loc.ptr as i32,
self.a.len() as i32,
self.sb_ptr_loc.ptr as i32,
@@ -209,7 +208,7 @@ impl MultiStringExercise {
assert_eq!(res, types::Errno::Ok.into(), "multi string errno");
let given = host_memory
.ptr::<u32>(self.return_ptr_loc.ptr)
.ptr::<u32>(&bc, self.return_ptr_loc.ptr)
.read()
.expect("deref ptr to return value");
assert_eq!((self.a.len() + self.b.len() + self.c.len()) as u32, given);