1 #![cfg(not(miri))]
2 
3 use wasmtime::*;
4 
5 #[test]
test_import_calling_export()6 fn test_import_calling_export() {
7     const WAT: &str = r#"
8     (module
9       (type $t0 (func))
10       (import "" "imp" (func $.imp (type $t0)))
11       (func $run call $.imp)
12       (func $other)
13       (export "run" (func $run))
14       (export "other" (func $other))
15     )
16     "#;
17 
18     let mut store = Store::<Option<Func>>::default();
19     let module = Module::new(store.engine(), WAT).expect("failed to create module");
20 
21     let func_ty = FuncType::new(store.engine(), None, None);
22     let callback_func = Func::new(&mut store, func_ty, move |mut caller, _, _| {
23         caller
24             .data()
25             .unwrap()
26             .call(&mut caller, &[], &mut [])
27             .expect("expected function not to trap");
28         Ok(())
29     });
30 
31     let imports = vec![callback_func.into()];
32     let instance = Instance::new(&mut store, &module, imports.as_slice())
33         .expect("failed to instantiate module");
34 
35     let run_func = instance
36         .get_func(&mut store, "run")
37         .expect("expected a run func in the module");
38 
39     let other_func = instance
40         .get_func(&mut store, "other")
41         .expect("expected an other func in the module");
42     *store.data_mut() = Some(other_func);
43 
44     run_func
45         .call(&mut store, &[], &mut [])
46         .expect("expected function not to trap");
47 }
48 
49 #[test]
test_returns_incorrect_type() -> Result<()>50 fn test_returns_incorrect_type() -> Result<()> {
51     const WAT: &str = r#"
52     (module
53         (import "env" "evil" (func $evil (result i32)))
54         (func (export "run") (result i32)
55             (call $evil)
56         )
57     )
58     "#;
59 
60     let mut store = Store::<()>::default();
61     let module = Module::new(store.engine(), WAT)?;
62 
63     let func_ty = FuncType::new(store.engine(), None, Some(ValType::I32));
64     let callback_func = Func::new(&mut store, func_ty, |_, _, results| {
65         // Evil! Returns I64 here instead of promised in the signature I32.
66         results[0] = Val::I64(228);
67         Ok(())
68     });
69 
70     let imports = vec![callback_func.into()];
71     let instance = Instance::new(&mut store, &module, imports.as_slice())?;
72 
73     let run_func = instance
74         .get_func(&mut store, "run")
75         .expect("expected a run func in the module");
76 
77     let mut result = [Val::I32(0)];
78     let trap = run_func
79         .call(&mut store, &[], &mut result)
80         .expect_err("the execution should fail");
81     assert!(format!("{trap:?}").contains("function attempted to return an incompatible value"));
82     Ok(())
83 }
84