14a349ee2SNick Fitzgerald //! Small example of how to use `externref`s.
24a349ee2SNick Fitzgerald
34a349ee2SNick Fitzgerald // You can execute this example with `cargo run --example externref`
44a349ee2SNick Fitzgerald
54a349ee2SNick Fitzgerald use wasmtime::*;
64a349ee2SNick Fitzgerald
main() -> Result<()>74a349ee2SNick Fitzgerald fn main() -> Result<()> {
84a349ee2SNick Fitzgerald println!("Initializing...");
94a349ee2SNick Fitzgerald let mut config = Config::new();
104a349ee2SNick Fitzgerald config.wasm_reference_types(true);
1154c07d8fSPeter Huene let engine = Engine::new(&config)?;
127a1b7cdfSAlex Crichton let mut store = Store::new(&engine, ());
134a349ee2SNick Fitzgerald
144a349ee2SNick Fitzgerald println!("Compiling module...");
154a349ee2SNick Fitzgerald let module = Module::from_file(&engine, "examples/externref.wat")?;
164a349ee2SNick Fitzgerald
174a349ee2SNick Fitzgerald println!("Instantiating module...");
187a1b7cdfSAlex Crichton let instance = Instance::new(&mut store, &module, &[])?;
194a349ee2SNick Fitzgerald
204a349ee2SNick Fitzgerald println!("Creating new `externref`...");
21c22b3cb9SNick Fitzgerald let externref = match ExternRef::new(&mut store, "Hello, World!") {
22c22b3cb9SNick Fitzgerald Ok(x) => x,
23c22b3cb9SNick Fitzgerald Err(e) => match e.downcast::<GcHeapOutOfMemory<&str>>() {
24c22b3cb9SNick Fitzgerald Ok(oom) => {
25c22b3cb9SNick Fitzgerald let (inner, oom) = oom.take_inner();
26*cc8d04f4SAlex Crichton store.gc(Some(&oom))?;
27c22b3cb9SNick Fitzgerald ExternRef::new(&mut store, inner)?
28c22b3cb9SNick Fitzgerald }
29c22b3cb9SNick Fitzgerald Err(e) => return Err(e),
30c22b3cb9SNick Fitzgerald },
31c22b3cb9SNick Fitzgerald };
3290ac295eSAlex Crichton assert!(
3390ac295eSAlex Crichton externref
3412c20b22SNick Fitzgerald .data(&store)?
3512c20b22SNick Fitzgerald .expect("should have host data")
3690ac295eSAlex Crichton .is::<&'static str>()
3790ac295eSAlex Crichton );
384a349ee2SNick Fitzgerald assert_eq!(
39bd2ea901SNick Fitzgerald *externref
40bd2ea901SNick Fitzgerald .data(&store)?
4112c20b22SNick Fitzgerald .expect("should have host data")
42bd2ea901SNick Fitzgerald .downcast_ref::<&'static str>()
43bd2ea901SNick Fitzgerald .unwrap(),
444a349ee2SNick Fitzgerald "Hello, World!"
454a349ee2SNick Fitzgerald );
464a349ee2SNick Fitzgerald
474a349ee2SNick Fitzgerald println!("Touching `externref` table...");
487a1b7cdfSAlex Crichton let table = instance.get_table(&mut store, "table").unwrap();
49a0442ea0SHamir Mahal table.set(&mut store, 3, Some(externref).into())?;
507a1b7cdfSAlex Crichton let elem = table
517a1b7cdfSAlex Crichton .get(&mut store, 3)
527a1b7cdfSAlex Crichton .unwrap() // assert in bounds
53ff93bce0SNick Fitzgerald .unwrap_extern() // assert it's an externref table
54bd2ea901SNick Fitzgerald .copied()
557a1b7cdfSAlex Crichton .unwrap(); // assert the externref isn't null
56bd2ea901SNick Fitzgerald assert!(Rooted::ref_eq(&store, &elem, &externref)?);
574a349ee2SNick Fitzgerald
584a349ee2SNick Fitzgerald println!("Touching `externref` global...");
597a1b7cdfSAlex Crichton let global = instance.get_global(&mut store, "global").unwrap();
60a0442ea0SHamir Mahal global.set(&mut store, Some(externref).into())?;
61bd2ea901SNick Fitzgerald let global_val = global.get(&mut store).unwrap_externref().copied().unwrap();
62bd2ea901SNick Fitzgerald assert!(Rooted::ref_eq(&store, &global_val, &externref)?);
634a349ee2SNick Fitzgerald
644a349ee2SNick Fitzgerald println!("Calling `externref` func...");
65bd2ea901SNick Fitzgerald let func = instance.get_typed_func::<Option<Rooted<ExternRef>>, Option<Rooted<ExternRef>>>(
66bd2ea901SNick Fitzgerald &mut store, "func",
67bd2ea901SNick Fitzgerald )?;
68bd2ea901SNick Fitzgerald let ret = func.call(&mut store, Some(externref))?;
694a349ee2SNick Fitzgerald assert!(ret.is_some());
70bd2ea901SNick Fitzgerald assert!(Rooted::ref_eq(&store, &ret.unwrap(), &externref)?);
714a349ee2SNick Fitzgerald
7217b99cc9SNick Fitzgerald println!("GCing within the store...");
73*cc8d04f4SAlex Crichton store.gc(None)?;
7417b99cc9SNick Fitzgerald
754a349ee2SNick Fitzgerald println!("Done.");
764a349ee2SNick Fitzgerald Ok(())
774a349ee2SNick Fitzgerald }
78