1 //! Dummy implementations of things that a Wasm module can import.
2 
3 use anyhow::Context;
4 use wasmtime::*;
5 
6 /// Create a set of dummy functions/globals/etc for the given imports.
7 pub 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_ = import.ty().default_value(&mut *store).with_context(|| {
12             format!(
13                 "failed to create dummy value of `{}::{}` - {:?}",
14                 import.module(),
15                 import.name(),
16                 import.ty(),
17             )
18         })?;
19         linker
20             .define(&store, import.module(), import.name(), extern_)
21             .unwrap();
22     }
23     Ok(linker)
24 }
25 
26 #[cfg(test)]
27 mod tests {
28 
29     use super::*;
30 
31     fn store() -> Store<()> {
32         let mut config = Config::default();
33         config.wasm_multi_memory(true);
34         let engine = wasmtime::Engine::new(&config).unwrap();
35         Store::new(&engine, ())
36     }
37 
38     #[test]
39     fn dummy_table_import() {
40         let mut store = store();
41         let table_type = TableType::new(RefType::EXTERNREF, 10, None);
42         let table = table_type.default_value(&mut store).unwrap();
43         assert_eq!(table.size(&store), 10);
44         for i in 0..10 {
45             assert!(table.get(&mut store, i).unwrap().unwrap_extern().is_none());
46         }
47     }
48 
49     #[test]
50     fn dummy_global_import() {
51         let mut store = store();
52         let global_type = GlobalType::new(ValType::I32, Mutability::Const);
53         let global = global_type.default_value(&mut store).unwrap();
54         assert!(global.ty(&store).content().is_i32());
55         assert_eq!(global.ty(&store).mutability(), Mutability::Const);
56     }
57 
58     #[test]
59     fn dummy_memory_import() {
60         let mut store = store();
61         let memory_type = MemoryType::new(1, None);
62         let memory = memory_type
63             .default_value(&mut store)
64             .unwrap()
65             .into_memory()
66             .unwrap();
67         assert_eq!(memory.size(&store), 1);
68     }
69 
70     #[test]
71     fn dummy_function_import() {
72         let mut store = store();
73         let func_ty = FuncType::new(store.engine(), vec![ValType::I32], vec![ValType::I64]);
74         let func = func_ty.default_value(&mut store).unwrap();
75         let actual_ty = func.ty(&store);
76         assert!(FuncType::eq(&actual_ty, &func_ty));
77     }
78 }
79