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!(externref 33 .data(&store)? 34 .expect("should have host data") 35 .is::<&'static str>()); 36 assert_eq!( 37 *externref 38 .data(&store)? 39 .expect("should have host data") 40 .downcast_ref::<&'static str>() 41 .unwrap(), 42 "Hello, World!" 43 ); 44 45 println!("Touching `externref` table..."); 46 let table = instance.get_table(&mut store, "table").unwrap(); 47 table.set(&mut store, 3, Some(externref).into())?; 48 let elem = table 49 .get(&mut store, 3) 50 .unwrap() // assert in bounds 51 .unwrap_extern() // assert it's an externref table 52 .copied() 53 .unwrap(); // assert the externref isn't null 54 assert!(Rooted::ref_eq(&store, &elem, &externref)?); 55 56 println!("Touching `externref` global..."); 57 let global = instance.get_global(&mut store, "global").unwrap(); 58 global.set(&mut store, Some(externref).into())?; 59 let global_val = global.get(&mut store).unwrap_externref().copied().unwrap(); 60 assert!(Rooted::ref_eq(&store, &global_val, &externref)?); 61 62 println!("Calling `externref` func..."); 63 let func = instance.get_typed_func::<Option<Rooted<ExternRef>>, Option<Rooted<ExternRef>>>( 64 &mut store, "func", 65 )?; 66 let ret = func.call(&mut store, Some(externref))?; 67 assert!(ret.is_some()); 68 assert!(Rooted::ref_eq(&store, &ret.unwrap(), &externref)?); 69 70 println!("GCing within the store..."); 71 store.gc(None); 72 73 println!("Done."); 74 Ok(()) 75 } 76