diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index ad75d9006b..7fb800c420 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -181,7 +181,7 @@ jobs:
toolchain: nightly-2021-12-15
- run: cargo install cargo-fuzz --vers "^0.11"
# Install OCaml packages necessary for 'differential_spec' fuzz target.
- - run: sudo apt install -y ocaml-nox ocamlbuild
+ - run: sudo apt install -y ocaml-nox ocamlbuild ocaml-findlib libzarith-ocaml-dev
- run: cargo fetch
working-directory: ./fuzz
- run: cargo fuzz build --dev
diff --git a/crates/fuzzing/Cargo.toml b/crates/fuzzing/Cargo.toml
index 67663c70f8..b7b264bd4f 100644
--- a/crates/fuzzing/Cargo.toml
+++ b/crates/fuzzing/Cargo.toml
@@ -35,8 +35,7 @@ v8 = "0.33"
[dev-dependencies]
wat = "1.0.37"
-# FIXME(#3251) should re-enable once spec interpreter won't time out
# We only build the library containing the OCaml spec interpreter if the OCaml
# toolchain is available--which is assumed here to be the case when fuzzing.
-# [target.'cfg(fuzzing)'.dependencies]
-# wasm-spec-interpreter = { path = "./wasm-spec-interpreter", features = ["build-libinterpret"] }
+[target.'cfg(fuzzing)'.dependencies]
+wasm-spec-interpreter = { path = "./wasm-spec-interpreter", features = ["build-libinterpret"] }
diff --git a/crates/fuzzing/src/generators.rs b/crates/fuzzing/src/generators.rs
index 4d641a6b21..b84f2d1bb9 100644
--- a/crates/fuzzing/src/generators.rs
+++ b/crates/fuzzing/src/generators.rs
@@ -272,6 +272,9 @@ impl Config {
config.max_memory_pages = 1;
config.memory_max_size_required = true;
+ // While reference types are disabled below, only allow one table
+ config.max_tables = 1;
+
// Don't allow any imports
config.max_imports = 0;
diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs
index edb5d27e81..85c6b3c60e 100644
--- a/crates/fuzzing/src/oracles.rs
+++ b/crates/fuzzing/src/oracles.rs
@@ -793,9 +793,11 @@ pub fn differential_spec_execution(wasm: &[u8], config: &generators::Config) ->
// interfere, observable as an uncaught `SIGSEGV`--not even caught by
// libFuzzer. By running Wasmtime second, its signal handlers are registered
// most recently and they catch failures appropriately.
- let spec_vals = wasm_spec_interpreter::interpret(wasm, vec![]);
+ //
+ // For now, execute with dummy (zeroed) function arguments.
+ let spec_vals = wasm_spec_interpreter::interpret(wasm, None);
debug!("spec interpreter returned: {:?}", &spec_vals);
- let wasmtime_vals = run_in_wasmtime(wasm, config, &[]);
+ let wasmtime_vals = run_in_wasmtime(wasm, config);
debug!("Wasmtime returned: {:?}", wasmtime_vals);
// Match a spec interpreter value against a Wasmtime value. Eventually this
@@ -871,11 +873,7 @@ fn differential_store(
/// Helper for instantiating and running a Wasm module in Wasmtime and returning
/// its `Val` results.
-fn run_in_wasmtime(
- wasm: &[u8],
- config: &generators::Config,
- params: &[Val],
-) -> anyhow::Result