wasmtime_fuzzing/oracles/
gc_access.rs1use crate::generators;
4use wasmtime::*;
5
6pub fn gc_access(config: generators::Config, input: generators::GcAccess) {
11 let wasm = input.to_wasm();
12 crate::oracles::log_wasm(&wasm);
13
14 let mut wasmtime_config = config.to_wasmtime();
15 wasmtime_config.wasm_gc(true);
16 wasmtime_config.wasm_function_references(true);
17 wasmtime_config.wasm_reference_types(true);
18 wasmtime_config.wasm_bulk_memory(true);
19
20 let engine = match Engine::new(&wasmtime_config) {
21 Ok(e) => e,
22 Err(_) => return,
23 };
24
25 let module = match Module::new(&engine, &wasm) {
26 Ok(m) => m,
27 Err(_) => return,
28 };
29
30 let mut linker = Linker::new(&engine);
31 linker
32 .func_wrap(
33 "wasmtime",
34 "gc",
35 |mut caller: Caller<'_, crate::oracles::StoreLimits>| {
36 let _ = caller.gc(None);
37 },
38 )
39 .unwrap();
40
41 let limits = crate::oracles::StoreLimits::new();
42 let mut store = Store::new(&engine, limits);
43 store.limiter(|s| s as &mut dyn ResourceLimiter);
44 config.configure_store_epoch_and_fuel(&mut store);
45
46 let instance = match linker.instantiate(&mut store, &module) {
47 Ok(i) => i,
48 Err(_) => return,
49 };
50
51 let run = instance
52 .get_typed_func::<(), ()>(&mut store, "run")
53 .expect("should have `run` export");
54
55 if let Err(e) = run.call(&mut store, ()) {
56 let msg = format!("{e:?}");
57 assert!(
58 !msg.contains("wasm trap: wasm `unreachable` instruction executed"),
59 "GC access assertion failure: {e:?}"
60 );
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::generators::GcAccess;
68
69 #[test]
70 fn gc_access_oracle_passes() {
71 crate::test::test_n_times(128, |config: generators::Config, u| {
72 let input: GcAccess = u.arbitrary()?;
73 gc_access(config, input);
74 Ok(())
75 })
76 }
77}