wasmtime_fuzzing/oracles/
dummy.rs1use anyhow::ensure;
4use wasmtime::*;
5
6pub fn dummy_linker<T>(store: &mut Store<T>, module: &Module) -> Result<Linker<T>> {
8 let mut linker = Linker::new(store.engine());
9 linker.allow_shadowing(true);
10 for import in module.imports() {
11 let extern_ = dummy_extern(store, import.ty())?;
12 linker
13 .define(&store, import.module(), import.name(), extern_)
14 .unwrap();
15 }
16 Ok(linker)
17}
18
19pub fn dummy_extern<T>(store: &mut Store<T>, ty: ExternType) -> Result<Extern> {
21 Ok(match ty {
22 ExternType::Func(func_ty) => Extern::Func(dummy_func(store, func_ty)?),
23 ExternType::Global(global_ty) => Extern::Global(dummy_global(store, global_ty)?),
24 ExternType::Table(table_ty) => Extern::Table(dummy_table(store, table_ty)?),
25 ExternType::Memory(mem_ty) => Extern::Memory(dummy_memory(store, mem_ty)?),
26 ExternType::Tag(_tag_ty) => todo!(), })
28}
29
30pub fn dummy_func<T>(store: &mut Store<T>, ty: FuncType) -> Result<Func> {
32 let dummy_results = ty.results().map(dummy_value).collect::<Result<Vec<_>>>()?;
33 Ok(Func::new(store, ty.clone(), move |_, _, results| {
34 for (slot, dummy) in results.iter_mut().zip(&dummy_results) {
35 *slot = *dummy;
36 }
37 Ok(())
38 }))
39}
40
41pub fn dummy_value(val_ty: ValType) -> Result<Val> {
43 Ok(match val_ty {
44 ValType::I32 => Val::I32(0),
45 ValType::I64 => Val::I64(0),
46 ValType::F32 => Val::F32(0),
47 ValType::F64 => Val::F64(0),
48 ValType::V128 => Val::V128(0.into()),
49 ValType::Ref(r) => {
50 ensure!(
51 r.is_nullable(),
52 "cannot construct a dummy value of type `{r}`"
53 );
54 Val::null_ref(r.heap_type())
55 }
56 })
57}
58
59pub fn dummy_values(val_tys: impl IntoIterator<Item = ValType>) -> Result<Vec<Val>> {
61 val_tys.into_iter().map(dummy_value).collect()
62}
63
64pub fn dummy_global<T>(store: &mut Store<T>, ty: GlobalType) -> Result<Global> {
66 let val = dummy_value(ty.content().clone())?;
67 Global::new(store, ty, val)
68}
69
70pub fn dummy_table<T>(store: &mut Store<T>, ty: TableType) -> Result<Table> {
72 let init_val = dummy_value(ty.element().clone().into())?;
73 Table::new(store, ty, init_val.ref_().unwrap())
74}
75
76pub fn dummy_memory<T>(store: &mut Store<T>, ty: MemoryType) -> Result<Memory> {
78 Memory::new(store, ty)
79}
80
81#[cfg(test)]
82mod tests {
83
84 use super::*;
85
86 fn store() -> Store<()> {
87 let mut config = Config::default();
88 config.wasm_multi_memory(true);
89 let engine = wasmtime::Engine::new(&config).unwrap();
90 Store::new(&engine, ())
91 }
92
93 #[test]
94 fn dummy_table_import() {
95 let mut store = store();
96 let table = dummy_table(&mut store, TableType::new(RefType::EXTERNREF, 10, None)).unwrap();
97 assert_eq!(table.size(&store), 10);
98 for i in 0..10 {
99 assert!(table.get(&mut store, i).unwrap().unwrap_extern().is_none());
100 }
101 }
102
103 #[test]
104 fn dummy_global_import() {
105 let mut store = store();
106 let global =
107 dummy_global(&mut store, GlobalType::new(ValType::I32, Mutability::Const)).unwrap();
108 assert!(global.ty(&store).content().is_i32());
109 assert_eq!(global.ty(&store).mutability(), Mutability::Const);
110 }
111
112 #[test]
113 fn dummy_memory_import() {
114 let mut store = store();
115 let memory = dummy_memory(&mut store, MemoryType::new(1, None)).unwrap();
116 assert_eq!(memory.size(&store), 1);
117 }
118
119 #[test]
120 fn dummy_function_import() {
121 let mut store = store();
122 let func_ty = FuncType::new(store.engine(), vec![ValType::I32], vec![ValType::I64]);
123 let func = dummy_func(&mut store, func_ty.clone()).unwrap();
124 let actual_ty = func.ty(&store);
125 assert!(FuncType::eq(&actual_ty, &func_ty));
126 }
127}