xref: /wasmtime-44.0.1/examples/externref.rs (revision cc8d04f4)
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