1 //! Small example of how to use `externref`s. 2 3 // You can execute this example with `cargo run --example externref` 4 5 use wasmtime::*; 6 7 fn main() -> Result<()> { 8 println!("Initializing..."); 9 let mut config = Config::new(); 10 config.wasm_reference_types(true); 11 let engine = Engine::new(&config)?; 12 let mut store = Store::new(&engine, ()); 13 14 println!("Compiling module..."); 15 let module = Module::from_file(&engine, "examples/externref.wat")?; 16 17 println!("Instantiating module..."); 18 let instance = Instance::new(&mut store, &module, &[])?; 19 20 println!("Creating new `externref`..."); 21 let externref = match ExternRef::new(&mut store, "Hello, World!") { 22 Ok(x) => x, 23 Err(e) => match e.downcast::<GcHeapOutOfMemory<&str>>() { 24 Ok(oom) => { 25 let (inner, oom) = oom.take_inner(); 26 store.gc(Some(&oom))?; 27 ExternRef::new(&mut store, inner)? 28 } 29 Err(e) => return Err(e), 30 }, 31 }; 32 assert!( 33 externref 34 .data(&store)? 35 .expect("should have host data") 36 .is::<&'static str>() 37 ); 38 assert_eq!( 39 *externref 40 .data(&store)? 41 .expect("should have host data") 42 .downcast_ref::<&'static str>() 43 .unwrap(), 44 "Hello, World!" 45 ); 46 47 println!("Touching `externref` table..."); 48 let table = instance.get_table(&mut store, "table").unwrap(); 49 table.set(&mut store, 3, Some(externref).into())?; 50 let elem = table 51 .get(&mut store, 3) 52 .unwrap() // assert in bounds 53 .unwrap_extern() // assert it's an externref table 54 .copied() 55 .unwrap(); // assert the externref isn't null 56 assert!(Rooted::ref_eq(&store, &elem, &externref)?); 57 58 println!("Touching `externref` global..."); 59 let global = instance.get_global(&mut store, "global").unwrap(); 60 global.set(&mut store, Some(externref).into())?; 61 let global_val = global.get(&mut store).unwrap_externref().copied().unwrap(); 62 assert!(Rooted::ref_eq(&store, &global_val, &externref)?); 63 64 println!("Calling `externref` func..."); 65 let func = instance.get_typed_func::<Option<Rooted<ExternRef>>, Option<Rooted<ExternRef>>>( 66 &mut store, "func", 67 )?; 68 let ret = func.call(&mut store, Some(externref))?; 69 assert!(ret.is_some()); 70 assert!(Rooted::ref_eq(&store, &ret.unwrap(), &externref)?); 71 72 println!("GCing within the store..."); 73 store.gc(None)?; 74 75 println!("Done."); 76 Ok(()) 77 } 78