Files
wasmtime/crates/runtime/src/region.rs
Jakub Konka 2ad77538f5 Add array generation to wiggle-generate crate (#9)
* Add array generation to wiggle-generate crate

This commit:
* adds array generation to `wiggle-generate` crate which implies
  that we can now generate arrays from `witx` files
* introduces two test interface functions `foo::reduce_excuses` and
  `foo::populate_excuses`, and adds matching prop-tests
* adds an out-of-boundary check to `HostMemory::mem_area_strat` since
  now, given we're generating arrays for testing with an arbitrary
  but bounded number of elements, it is possible to violate the boundary
* refactors `Region::extend` to a new signature `extend(times: u32)`
  which multiplies the current pointer `len` by `times`
* fixes bug in `GuestArray::as_ref` and `GuestArrayMut::as_ref_mut` methods
  where we were not validating the first element (we always started the
  validation from the second element)

* Fix generation of arrays in witx

This commit fixes how `arrays` are auto-generated from `witx` files.
In particular, the changes include:
* Since by design every `array` in `witx` represents an immutable
  slab of memory, we will only ever operate on `GuestArray` in which
  case I've gone ahead and removed `GuestArrayMut` so as to unclutter
  the code somewhat. If we find ourselves in need for it in the future,
  I reckon it will be better to write it from scratch (since the codebase
  will inevitably evolve by then considerably) rather than maintaining an
  unused implementation.
* I've rewritten `GuestArrayRef<T>` to be a wrapper for `Vec<GuestRef<T>>`.
  Also, `GuestArray::as_ref` now borrows each underlying "element" of the
  array one-by-one rather than borrowing the entire chunk of memory at once.
  This change is motivated by the inability to coerce type parameter `T` in
  `GuestArray<T>` in more complicated cases such as arrays of guest pointers
  `GuestPtr<T>` to `*const T` for reuse in `std::slice::from_raw_parts` call.
  (In general, the size of Wasm32 pointer is 4 bytes, while

```
std::mem::size_of::<T>() == std::mem::size_of::<GuestPtr<S>>() == 16
```

  which is problematic; i.e., I can't see how I could properly extract guest
  pointers from slices of 4 bytes and at the same time not allocate.)
* I've augmented fuzz tests by (re-)defining two `array` types:

```
(typename $const_excuse_array (array (@witx const_pointer $excuse)))
(typename $excuse_array (array (@witx pointer $excuse)))
```

  This should hopefully emulate and test the `iovec` and `ciovec` arrays
  present in WASI spec.
2020-02-19 10:58:55 +01:00

72 lines
1.7 KiB
Rust

/// Represents a contiguous region in memory.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Region {
pub start: u32,
pub len: u32,
}
impl Region {
pub fn new(start: u32, len: u32) -> Self {
assert!(len > 0, "Region cannot have 0 length");
Self { start, len }
}
/// Checks if this `Region` overlaps with `rhs` `Region`.
pub fn overlaps(&self, rhs: Region) -> bool {
let self_start = self.start as u64;
let self_end = self_start + (self.len - 1) as u64;
let rhs_start = rhs.start as u64;
let rhs_end = rhs_start + (rhs.len - 1) as u64;
if self_start <= rhs_start {
self_end >= rhs_start
} else {
rhs_end >= self_start
}
}
pub fn extend(&self, times: u32) -> Self {
let len = self.len * times;
Self {
start: self.start,
len,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn nonoverlapping() {
let r1 = Region::new(0, 10);
let r2 = Region::new(10, 10);
assert!(!r1.overlaps(r2));
let r1 = Region::new(10, 10);
let r2 = Region::new(0, 10);
assert!(!r1.overlaps(r2));
}
#[test]
fn overlapping() {
let r1 = Region::new(0, 10);
let r2 = Region::new(9, 10);
assert!(r1.overlaps(r2));
let r1 = Region::new(0, 10);
let r2 = Region::new(2, 5);
assert!(r1.overlaps(r2));
let r1 = Region::new(9, 10);
let r2 = Region::new(0, 10);
assert!(r1.overlaps(r2));
let r1 = Region::new(2, 5);
let r2 = Region::new(0, 10);
assert!(r1.overlaps(r2));
}
}