Draft out IntDatatype in wiggle-generate (#15)

* Draft out IntDatatype in wiggle-generate

This commit drafts out basic layout for `IntDatatype` structure in
`wiggle`. As it currently stands, an `Int` type is represented as
a one-element tuple struct much like `FlagDatatype`, however, with
this difference that we do not perform any checks on the input
underlying representation since any value for the prescribed type
is legal.

* Finish drafting IntDatatype support in wiggle

This commit adds necessary marshal stubs to properly pass `IntDatatype`
in and out of interface functions. It also adds a basic proptest.
This commit is contained in:
Jakub Konka
2020-02-21 22:53:10 +01:00
committed by GitHub
parent 6ab3ff71d2
commit f48474b247
5 changed files with 175 additions and 2 deletions

View File

@@ -143,6 +143,15 @@ impl foo::Foo for WasiCtx {
println!("a_string='{}'", as_str);
Ok(as_str.len() as u32)
}
fn cookie_cutter(&mut self, init_cookie: types::Cookie) -> Result<types::Bool, types::Errno> {
let res = if init_cookie == types::Cookie::START {
types::Bool::True
} else {
types::Bool::False
};
Ok(res)
}
}
// Errno is used as a first return value in the functions above, therefore
// it must implement GuestErrorType with type Context = WasiCtx.
@@ -958,3 +967,62 @@ proptest! {
e.test()
}
}
fn cookie_strat() -> impl Strategy<Value = types::Cookie> {
(0..std::u64::MAX)
.prop_map(|x| types::Cookie::try_from(x).expect("within range of cookie"))
.boxed()
}
#[derive(Debug)]
struct CookieCutterExercise {
cookie: types::Cookie,
return_ptr_loc: MemArea,
}
impl CookieCutterExercise {
pub fn strat() -> BoxedStrategy<Self> {
(cookie_strat(), HostMemory::mem_area_strat(4))
.prop_map(|(cookie, return_ptr_loc)| Self {
cookie,
return_ptr_loc,
})
.boxed()
}
pub fn test(&self) {
let mut ctx = WasiCtx::new();
let mut host_memory = HostMemory::new();
let mut guest_memory = GuestMemory::new(host_memory.as_mut_ptr(), host_memory.len() as u32);
let res = foo::cookie_cutter(
&mut ctx,
&mut guest_memory,
self.cookie.into(),
self.return_ptr_loc.ptr as i32,
);
assert_eq!(res, types::Errno::Ok.into(), "cookie cutter errno");
let is_cookie_start = *guest_memory
.ptr::<types::Bool>(self.return_ptr_loc.ptr)
.expect("ptr to returned Bool")
.as_ref()
.expect("deref to Bool value");
assert_eq!(
if is_cookie_start == types::Bool::True {
true
} else {
false
},
self.cookie == types::Cookie::START,
"returned Bool should test if input was Cookie::START",
);
}
}
proptest! {
#[test]
fn cookie_cutter(e in CookieCutterExercise::strat()) {
e.test()
}
}

View File

@@ -18,6 +18,15 @@
$awd
$suv))
(typename $cookie
(int u64
(const $start 0)))
(typename $bool
(enum u8
$false
$true))
(typename $pair_ints
(struct
(field $first s32)
@@ -77,4 +86,9 @@
(result $error $errno)
(result $total_bytes u32)
)
(@interface func (export "cookie_cutter")
(param $init_cookie $cookie)
(result $error $errno)
(result $is_start $bool)
)
)