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