xref: /wasmtime-44.0.1/examples/multi.rs (revision a277cf5e)
1 //! This is an example of working with multi-value modules and dealing with
2 //! multi-value functions.
3 //!
4 //! Note that the `Func::wrap*` interfaces cannot be used to return multiple
5 //! values just yet, so we need to use the more dynamic `Func::new` and
6 //! `Func::call` methods.
7 
8 // You can execute this example with `cargo run --example multi`
9 
10 use anyhow::{format_err, Result};
11 use wasmtime::*;
12 
13 fn main() -> Result<()> {
14     println!("Initializing...");
15     let engine = Engine::default();
16     let store = Store::new(&engine);
17 
18     // Compile.
19     println!("Compiling module...");
20     let module = Module::from_file(&engine, "examples/multi.wat")?;
21 
22     // Create external print functions.
23     println!("Creating callback...");
24     let callback_type = FuncType::new(
25         [ValType::I32, ValType::I64].iter().cloned(),
26         [ValType::I64, ValType::I32].iter().cloned(),
27     );
28     let callback_func = Func::new(&store, callback_type, |_, args, results| {
29         println!("Calling back...");
30         println!("> {} {}", args[0].unwrap_i32(), args[1].unwrap_i64());
31 
32         results[0] = Val::I64(args[1].unwrap_i64() + 1);
33         results[1] = Val::I32(args[0].unwrap_i32() + 1);
34         Ok(())
35     });
36 
37     // Instantiate.
38     println!("Instantiating module...");
39     let instance = Instance::new(&store, &module, &[callback_func.into()])?;
40 
41     // Extract exports.
42     println!("Extracting export...");
43     let g = instance
44         .get_func("g")
45         .ok_or(format_err!("failed to find export `g`"))?;
46 
47     // Call `$g`.
48     println!("Calling export \"g\"...");
49     let results = g.call(&[Val::I32(1), Val::I64(3)])?;
50 
51     println!("Printing result...");
52     println!("> {} {}", results[0].unwrap_i64(), results[1].unwrap_i32());
53 
54     assert_eq!(results[0].unwrap_i64(), 4);
55     assert_eq!(results[1].unwrap_i32(), 2);
56 
57     // Call `$round_trip_many`.
58     println!("Calling export \"round_trip_many\"...");
59     let round_trip_many = instance
60         .get_func("round_trip_many")
61         .ok_or(format_err!("failed to find export `round_trip_many`"))?;
62     let args = vec![
63         Val::I64(0),
64         Val::I64(1),
65         Val::I64(2),
66         Val::I64(3),
67         Val::I64(4),
68         Val::I64(5),
69         Val::I64(6),
70         Val::I64(7),
71         Val::I64(8),
72         Val::I64(9),
73     ];
74     let results = round_trip_many.call(&args)?;
75 
76     println!("Printing result...");
77     print!(">");
78     for r in results.iter() {
79         print!(" {}", r.unwrap_i64());
80     }
81     println!();
82 
83     assert_eq!(results.len(), 10);
84     assert!(args
85         .iter()
86         .zip(results.iter())
87         .all(|(a, r)| a.i64() == r.i64()));
88 
89     Ok(())
90 }
91