fuzz: improve the spec interpreter (#4881)

* fuzz: improve the API of the `wasm-spec-interpreter` crate

This change addresses key parts of #4852 by improving the bindings to
the OCaml spec interpreter. The new API allows users to `instantiate` a
module, `interpret` named functions on that instance, and `export`
globals and memories from that instance. This currently leaves the
existing implementation ("instantiate and interpret the first function in
a module") present under a new name: `interpret_legacy`.

* fuzz: adapt the differential spec engine to the new API

This removes the legacy uses in the differential spec engine, replacing
them with the new `instantiate`-`interpret`-`export` API from the
`wasm-spec-interpreter` crate.

* fix: make instance access thread-safe

This changes the OCaml-side definition of the instance so that each
instance carries round a reference to a "global store" that's specific
to that instantiation. Because everything is updated by reference there
should be no visible behavioural change on the Rust side, apart from
everything suddenly being thread-safe (modulo the fact that access to
the OCaml runtime still needs to be locked). This fix will need to be
generalised slightly in future if we want to allow multiple modules to
be instantiated in the same store.

Co-authored-by: conrad-watt <cnrdwtt@gmail.com>
Co-authored-by: Alex Crichton <alex@alexcrichton.com>
This commit is contained in:
Andrew Brown
2022-09-12 14:23:03 -07:00
committed by GitHub
parent 024cad7e3d
commit c3f8415ac7
8 changed files with 443 additions and 147 deletions

View File

@@ -125,13 +125,6 @@ fn run(data: &[u8]) -> Result<()> {
// One side succeeded and one side failed, that means a bug happened!
(l, r) => {
// FIXME(#4852): the spec interpreter doesn't instantiate as part of
// the instantiate step so if wasmtime failed and the spec succeeded
// that's ok. This clause should be removed once that issue is
// fixed.
if l.is_ok() && lhs.name() == "spec" {
return Ok(());
}
panic!(
"failed to instantiate only one side: {:?} != {:?}",
l.err(),
@@ -172,15 +165,8 @@ fn run(data: &[u8]) -> Result<()> {
break 'outer;
}
// FIXME(#4852): the spec interpreter only supports one execution
// right now because each execution re-instantiates the module in
// its bindings. This should be removed once that issue is fixed.
if lhs.name() == "spec" {
break 'outer;
}
// We evaluate the same function with different arguments until we
// hit a predetermined limit or we run out of unstructured data--it
// Hit a predetermined limit or we run out of unstructured data--it
// does not make sense to re-evaluate the same arguments over and
// over.
if invocations > NUM_INVOCATIONS || u.is_empty() {