Commit Graph

8 Commits

Author SHA1 Message Date
Pat Hickey
cd484e4993 add a lifetime to the wiggle_runtime::GuestErrorType trait (#41)
* add a lifetime to the wiggle_runtime::GuestErrorType trait, wiggle_tests::WasiCtx struct

* wiggle-generate: make config parsing public so it can be reused in lucet
2020-03-10 14:48:57 -07:00
Pat Hickey
c78416912c Check safety of as_raw with a simplified borrow checker (#37)
* wiggle-runtime: add as_raw method for [T]

* add trivial borrow checker back in

* integrate runtime borrow checker with as_raw methods

* handle pointer arith overflow correctly in as_raw, create PtrOverflow error

* runtime: add validation back to GuestType

* generate: impl validate for enums, flags, handles, ints

* oops! make validate its own method on trait GuestTypeTransparent

* fix transparent impls for enum, flag, handle, int

* some structs are transparent. fix tests.

* tests: define byte_slice_strat and friends

* wiggle-tests: i believe my allocator is working now

* some type juggling around memset for ease of use

* make GuestTypeTransparent an unsafe trait

* delete redundant validation of pointer align

* fix doc

* wiggle_test: aha, you cant use sets to track memory areas

* add multi-string test

which exercises the runtime borrow checker against
HostMemory::byte_slice_strat

* oops left debug panic in

* remove redundant (& incorrect, since unchecked) length calc

* redesign validate again, and actually hook to as_raw

* makr all validate impls as inline

this should hopefully allow as_raw's check loop to be unrolled to a
no-op in most cases!

* code review fixes
2020-03-06 16:04:56 -08:00
Alex Crichton
ca9f33b6d9 Rewrite for recursive safety
This commit rewrites the runtime crate to provide safety in the face
of recursive calls to the guest. The basic principle is that
`GuestMemory` is now a trait which dynamically returns the
pointer/length pair. This also has an implicit contract (hence the
`unsafe` trait) that the pointer/length pair point to a valid list of
bytes in host memory "until something is reentrant".

After this changes the various suite of `Guest*` types were rewritten.
`GuestRef` and `GuestRefMut` were both removed since they cannot safely
exist. The `GuestPtrMut` type was removed for simplicity, and the final
`GuestPtr` type subsumes `GuestString` and `GuestArray`. This means
that there's only one guest pointer type, `GuestPtr<'a, T>`, where `'a`
is the borrow into host memory, basically borrowing the `GuestMemory`
trait object itself.

Some core utilities are exposed on `GuestPtr`, but they're all 100%
safe. Unsafety is now entirely contained within a few small locations:

* Implementations of the `GuestType` for primitive types (e.g. `i8`,
  `u8`, etc) use `unsafe` to read/write memory. The `unsafe` trait of
  `GuestMemory` though should prove that they're safe.

* `GuestPtr<'_, str>` has a method which validates utf-8 contents, and
  this requires `unsafe` internally to read all the bytes. This is
  guaranteed to be safe however given the contract of `GuestMemory`.

And that's it! Everything else is a bunch of safe combinators all built
up on the various utilities provided by `GuestPtr`. The general idioms
are roughly the same as before, with various tweaks here and there. A
summary of expected idioms are:

* For small values you'd `.read()` or `.write()` very quickly. You'd
  pass around the type itself.

* For strings, you'd pass `GuestPtr<'_, str>` down to the point where
  it's actually consumed. At that moment you'd either decide to copy it
  out (a safe operation) or you'd get a raw view to the string (an
  unsafe operation) and assert that you won't call back into wasm while
  you're holding that pointer.

* Arrays are similar to strings, passing around `GuestPtr<'_, [T]>`.
  Arrays also have a `iter()` method which yields an iterator of
  `GuestPtr<'_, T>` for convenience.

Overall there's still a lot of missing documentation on the runtime
crate specifically around the safety of the `GuestMemory` trait as well
as how the utilities/methods are expected to be used. Additionally
there's utilities which aren't currently implemented which would be easy
to implement. For example there's no method to copy out a string or a
slice, although that would be pretty easy to add.

In any case I'm curious to get feedback on this approach and see what
y'all think!
2020-03-04 10:26:47 -08:00
Jakub Konka
3764204250 Put context object behind a ref rather than mut ref
This commit puts context object, i.e., the implementor of the
WASI snapshot, behind a reference `&self` rather than a mutable
reference `&mut self`. As suggested by @alexcrichton, this gives
the implementor the possibility to determine how it handles its
interior mutability.
2020-03-03 17:50:32 +01:00
Pat Hickey
bb6995ceaf make wiggle-generate ordinary lib, and wiggle the proc-macro lib
this allows us to reuse the code in wiggle-generate elsewhere, because
a proc-macro=true lib can only export a #[proc_macro] and not ordinary
functions.

In lucet, I will depend on wiggle-generate to define a proc macro that
glues wiggle to the specifics of the runtime.
2020-02-28 11:43:43 -08:00
Jakub Konka
ec75f874ee Unify GuestType and GuestTypeClone, rename GuestTypeCopy to GuestTypeTransparent
This commit refactors trait system for guest types. Namely, as
discussed offline on zulip, `GuestType` now includes `GuestTypeClone`,
whereas `GuestTypeCopy` has been renamed to `GuestTypeTransparent`.
2020-02-27 21:53:52 +01:00
Pat Hickey
25a411d7fd rename the pointer read/write methods to read and write
these names were artifacts of some early confusion / bad design i made
in the traits. read and write are much simpler names!

also, change a ptr_mut to ptr where we just read the contents in the
argument marshalling for structs. this has no effect, but it is more
correct.
2020-02-26 19:51:35 +01:00
Pat Hickey
b7cd003b93 finish factoring tests (#17)
* atoms in one test unit

* factor out pointers test

* factor structs into separate test unit

* factor out arrays, flags

* finally, separate into strings and ints
2020-02-22 10:17:27 +01:00