forked from wasmerio/wasmer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwast.rs
98 lines (92 loc) · 3.83 KB
/
wast.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#![cfg(all(feature = "compiler", feature = "engine"))]
use crate::utils::get_compiler;
use std::path::Path;
use wasmer::{Features, Store};
#[cfg(feature = "test-jit")]
use wasmer_engine_jit::JIT;
#[cfg(feature = "test-native")]
use wasmer_engine_native::Native;
use wasmer_wast::Wast;
// The generated tests (from build.rs) look like:
// #[cfg(test)]
// mod singlepass {
// mod spec {
// #[test]
// fn address() -> anyhow::Result<()> {
// crate::run_wast("tests/spectests/address.wast", "singlepass")
// }
// }
// }
include!(concat!(env!("OUT_DIR"), "/generated_spectests.rs"));
// This prefixer returns the hash of the module to prefix each of
// the functions in the shared object generated by the `NativeEngine`.
fn _native_prefixer(bytes: &[u8]) -> String {
let hash = blake3::hash(bytes);
format!("{}", hash.to_hex())
}
#[cfg(feature = "test-jit")]
fn get_store(features: Features, try_nan_canonicalization: bool) -> Store {
let compiler_config = get_compiler(try_nan_canonicalization);
Store::new(&JIT::new(compiler_config).features(features).engine())
}
#[cfg(feature = "test-native")]
fn get_store(features: Features, try_nan_canonicalization: bool) -> Store {
let compiler_config = get_compiler(try_nan_canonicalization);
Store::new(&Native::new(compiler_config).features(features).engine())
}
pub fn run_wast(wast_path: &str, compiler: &str) -> anyhow::Result<()> {
println!(
"Running wast `{}` with the {} compiler",
wast_path, compiler
);
let try_nan_canonicalization = wast_path.contains("nan-canonicalization");
let mut features = Features::default();
let is_bulkmemory = wast_path.contains("bulk-memory");
let is_simd = wast_path.contains("simd");
if is_bulkmemory {
features.bulk_memory(true);
}
if is_simd {
features.simd(true);
}
if cfg!(feature = "test-singlepass") {
features.multi_value(false);
}
let store = get_store(features, try_nan_canonicalization);
let mut wast = Wast::new_with_spectest(store);
// `bulk-memory-operations/bulk.wast` checks for a message that
// specifies which element is uninitialized, but our traps don't
// shepherd that information out.
wast.allow_trap_message("uninitialized element 2", "uninitialized element");
if compiler == "cranelift" && cfg!(feature = "test-native") {
wast.allow_trap_message("call stack exhausted", "out of bounds memory access");
wast.allow_trap_message("indirect call type mismatch", "call stack exhausted");
wast.allow_trap_message("integer divide by zero", "call stack exhausted");
wast.allow_trap_message("integer overflow", "call stack exhausted");
wast.allow_trap_message("invalid conversion to integer", "call stack exhausted");
wast.allow_trap_message("undefined element", "call stack exhausted");
wast.allow_trap_message("uninitialized element", "call stack exhausted");
wast.allow_trap_message("unreachable", "call stack exhausted");
}
if cfg!(feature = "coverage") {
wast.disable_assert_and_exhaustion();
}
if is_simd {
// We allow this, so tests can be run properly for `simd_const` test.
wast.allow_instantiation_failures(&[
"Validation error: multiple tables",
"Validation error: unknown memory 0",
"Validation error: Invalid var_u32",
]);
}
if compiler == "singlepass" {
// We don't support multivalue yet in singlepass
wast.allow_instantiation_failures(&[
"Validation error: invalid result arity: func type returns multiple values",
"Validation error: blocks, loops, and ifs accept no parameters when multi-value is not enabled",
]);
}
wast.fail_fast = false;
let path = Path::new(wast_path);
wast.run_file(path)
}