xref: /wasmtime-44.0.1/examples/multi.rs (revision 3b7cb6ee)
1 //! This is an example of working with mulit-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     // Configure our `Store`, but be sure to use a `Config` that enables the
15     // wasm multi-value feature since it's not stable yet.
16     println!("Initializing...");
17     let engine = Engine::new(Config::new().wasm_multi_value(true));
18     let store = Store::new(&engine);
19 
20     // Compile.
21     println!("Compiling module...");
22     let module = Module::from_file(&store, "examples/multi.wat")?;
23 
24     // Create external print functions.
25     println!("Creating callback...");
26     let callback_type = FuncType::new(
27         Box::new([ValType::I32, ValType::I64]),
28         Box::new([ValType::I64, ValType::I32]),
29     );
30     let callback_func = Func::new(&store, callback_type, |_, args, results| {
31         println!("Calling back...");
32         println!("> {} {}", args[0].unwrap_i32(), args[1].unwrap_i64());
33 
34         results[0] = Val::I64(args[1].unwrap_i64() + 1);
35         results[1] = Val::I32(args[0].unwrap_i32() + 1);
36         Ok(())
37     });
38 
39     // Instantiate.
40     println!("Instantiating module...");
41     let instance = Instance::new(&module, &[callback_func.into()])?;
42 
43     // Extract exports.
44     println!("Extracting export...");
45     let g = instance
46         .get_export("g")
47         .and_then(|e| e.func())
48         .ok_or(format_err!("failed to find export `g`"))?;
49 
50     // Call `$g`.
51     println!("Calling export \"g\"...");
52     let results = g.call(&[Val::I32(1), Val::I64(3)])?;
53 
54     println!("Printing result...");
55     println!("> {} {}", results[0].unwrap_i64(), results[1].unwrap_i32());
56 
57     assert_eq!(results[0].unwrap_i64(), 4);
58     assert_eq!(results[1].unwrap_i32(), 2);
59 
60     // Call `$round_trip_many`.
61     println!("Calling export \"round_trip_many\"...");
62     let round_trip_many = instance
63         .get_export("round_trip_many")
64         .and_then(|e| e.func())
65         .ok_or(format_err!("failed to find export `round_trip_many`"))?;
66     let args = vec![
67         Val::I64(0),
68         Val::I64(1),
69         Val::I64(2),
70         Val::I64(3),
71         Val::I64(4),
72         Val::I64(5),
73         Val::I64(6),
74         Val::I64(7),
75         Val::I64(8),
76         Val::I64(9),
77     ];
78     let results = round_trip_many.call(&args)?;
79 
80     println!("Printing result...");
81     print!(">");
82     for r in results.iter() {
83         print!(" {}", r.unwrap_i64());
84     }
85     println!();
86 
87     assert_eq!(results.len(), 10);
88     assert!(args
89         .iter()
90         .zip(results.iter())
91         .all(|(a, r)| a.i64() == r.i64()));
92 
93     Ok(())
94 }
95