support SIMD fuzzing in reference interpreter (#3980)
* support SIMD fuzzing in reference interpreter * formatting
This commit is contained in:
@@ -16,6 +16,7 @@ use crate::generators;
|
||||
use arbitrary::Arbitrary;
|
||||
use log::debug;
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryInto;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
@@ -843,7 +844,14 @@ pub fn differential_spec_execution(wasm: &[u8], config: &generators::Config) ->
|
||||
(wasm_spec_interpreter::Value::F64(a), wasmtime::Val::F64(b)) => {
|
||||
f64_equal(*a as u64, *b)
|
||||
}
|
||||
(_, _) => unreachable!("fuzzing non-scalar value types is still TODO"),
|
||||
(wasm_spec_interpreter::Value::V128(a), wasmtime::Val::V128(b)) => {
|
||||
assert_eq!(a.len(), 16);
|
||||
let a_num = u128::from_le_bytes(a.as_slice().try_into().unwrap());
|
||||
a_num == *b
|
||||
}
|
||||
(_, _) => {
|
||||
unreachable!("TODO: only fuzzing of scalar and vector value types is supported")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const OCAML_DIR: &'static str = "ocaml";
|
||||
const SPEC_DIR: &'static str = "ocaml/spec";
|
||||
const SPEC_REPOSITORY: &'static str = "https://github.com/conrad-watt/spec";
|
||||
const SPEC_REPOSITORY_BRANCH: &'static str = "wasmtime_fuzzing";
|
||||
const SPEC_REPOSITORY_REV: &'static str = "7485eb0084b74871f96f261b9f916864596d8f1d";
|
||||
const SPEC_REPOSITORY_REV: &'static str = "52851c8394ee4099fb8bdeaec6d60d92e787052f";
|
||||
|
||||
fn main() {
|
||||
if cfg!(feature = "build-libinterpret") {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
This directory contains the necessary parts for building a library with FFI
|
||||
access to the Wasm spec interpreter. Its major parts:
|
||||
- `spec`: the Wasm spec code as a Git submodule (you may need to retrieve it:
|
||||
`git clone https://github.com/conrad-watt/spec/tree/wasmtime_fuzzing).
|
||||
`git clone -b wasmtime_fuzzing https://github.com/conrad-watt/spec`).
|
||||
- `interpret.ml`: a shim layer for calling the Wasm spec code and exposing it
|
||||
for FFI access
|
||||
- `Makefile`: the steps for gluing these pieces together into a static library
|
||||
|
||||
@@ -16,20 +16,23 @@ type ffi_value =
|
||||
| I64 of int64
|
||||
| F32 of int32
|
||||
| F64 of int64
|
||||
| V128 of Bytes.t
|
||||
|
||||
(** Helper for converting the FFI values to their spec interpreter type. *)
|
||||
let convert_to_wasm (v: ffi_value) : v = match v with
|
||||
| I32 n -> ConstInt32 (I32_impl_abs n)
|
||||
| I64 n -> ConstInt64 (I64_impl_abs n)
|
||||
| F32 n -> ConstFloat32 (F32.of_bits n)
|
||||
| F64 n -> ConstFloat64 (F64.of_bits n)
|
||||
| I32 n -> V_num (ConstInt32 (I32_impl_abs n))
|
||||
| I64 n -> V_num (ConstInt64 (I64_impl_abs n))
|
||||
| F32 n -> V_num (ConstFloat32 (F32.of_bits n))
|
||||
| F64 n -> V_num (ConstFloat64 (F64.of_bits n))
|
||||
| V128 n -> V_vec (ConstVec128 (V128.of_bits (Bytes.to_string n)))
|
||||
|
||||
(** Helper for converting the spec interpreter values to their FFI type. *)
|
||||
let convert_from_wasm (v: v) : ffi_value = match v with
|
||||
| (ConstInt32 (I32_impl_abs n)) -> I32 n
|
||||
| (ConstInt64 (I64_impl_abs n)) -> I64 n
|
||||
| (ConstFloat32 n) -> F32 (F32.to_bits n)
|
||||
| (ConstFloat64 n) -> F64 (F64.to_bits n)
|
||||
| V_num ((ConstInt32 (I32_impl_abs n))) -> I32 n
|
||||
| V_num ((ConstInt64 (I64_impl_abs n))) -> I64 n
|
||||
| V_num ((ConstFloat32 n)) -> F32 (F32.to_bits n)
|
||||
| V_num ((ConstFloat64 n)) -> F64 (F64.to_bits n)
|
||||
| V_vec ((ConstVec128 n)) -> V128 (Bytes.of_string (V128.to_bits n))
|
||||
| _ -> failwith "Unknown type"
|
||||
|
||||
(** Parse the given WebAssembly module binary into an Ast.module_. At some point in the future this
|
||||
|
||||
@@ -16,6 +16,7 @@ pub enum Value {
|
||||
I64(i64),
|
||||
F32(i32),
|
||||
F64(i64),
|
||||
V128(Vec<u8>),
|
||||
}
|
||||
|
||||
#[cfg(feature = "has-libinterpret")]
|
||||
|
||||
@@ -59,6 +59,7 @@ mod ocaml_bindings {
|
||||
Value::I64(i: OCamlInt64),
|
||||
Value::F32(i: OCamlInt32),
|
||||
Value::F64(i: OCamlInt64),
|
||||
Value::V128(i: OCamlBytes),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,4 +104,21 @@ mod tests {
|
||||
Err("Error(_, \"(Isabelle) trap: load\")".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simd_not() {
|
||||
let module = wat::parse_file("tests/simd_not.wat").unwrap();
|
||||
|
||||
let parameters = Some(vec![Value::V128(vec![
|
||||
0, 255, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
])]);
|
||||
let results = interpret(&module, parameters.clone()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
results,
|
||||
vec![Value::V128(vec![
|
||||
255, 0, 255, 255, 0, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255
|
||||
])]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
4
crates/fuzzing/wasm-spec-interpreter/tests/simd_not.wat
Normal file
4
crates/fuzzing/wasm-spec-interpreter/tests/simd_not.wat
Normal file
@@ -0,0 +1,4 @@
|
||||
(module
|
||||
(func (export "simd_not") (param $a v128) (result v128)
|
||||
local.get $a
|
||||
v128.not))
|
||||
@@ -23,6 +23,7 @@ fn run(data: &[u8]) -> Result<()> {
|
||||
|
||||
// Enable features that the spec interpreter has implemented
|
||||
config.module_config.config.multi_value_enabled = false;
|
||||
config.module_config.config.simd_enabled = true;
|
||||
|
||||
// TODO: this is a best-effort attempt to avoid errors caused by the
|
||||
// generated module exporting no functions.
|
||||
|
||||
Reference in New Issue
Block a user