xref: /wasmtime-44.0.1/tests/all/i31ref.rs (revision 43832481)
1 use wasmtime::*;
2 
3 #[test]
always_pop_i31ref_lifo_roots() -> Result<()>4 fn always_pop_i31ref_lifo_roots() -> Result<()> {
5     let mut config = Config::new();
6     config.wasm_function_references(true);
7     config.wasm_gc(true);
8 
9     let engine = Engine::new(&config)?;
10     let mut store = Store::new(&engine, ());
11 
12     let anyref = {
13         let mut scope = RootScope::new(&mut store);
14         AnyRef::from_i31(&mut scope, I31::wrapping_u32(42))
15     };
16 
17     // The anyref has left its rooting scope and been unrooted.
18     assert!(anyref.is_i31(&store).is_err());
19 
20     Ok(())
21 }
22 
23 #[test]
i31ref_to_raw_round_trip() -> Result<()>24 fn i31ref_to_raw_round_trip() -> Result<()> {
25     let mut config = Config::new();
26     config.wasm_function_references(true);
27     config.wasm_gc(true);
28 
29     let engine = Engine::new(&config)?;
30     let mut store = Store::new(&engine, ());
31 
32     // Should be able to round trip an `i31ref` to its raw representation and
33     // back again even though we have not forced the allocation of the `GcStore`
34     // yet.
35     let anyref = AnyRef::from_i31(&mut store, I31::wrapping_u32(42));
36     let raw = anyref.to_raw(&mut store)?;
37     let anyref = AnyRef::from_raw(&mut store, raw).expect("should be non-null");
38     assert!(anyref.is_i31(&store)?);
39     assert_eq!(anyref.as_i31(&store)?.unwrap().get_u32(), 42);
40 
41     Ok(())
42 }
43 
44 #[test]
45 #[cfg_attr(miri, ignore)]
owned_rooted_i31ref_through_typed_wasm_func() -> Result<()>46 fn owned_rooted_i31ref_through_typed_wasm_func() -> Result<()> {
47     // OwnedRooted<AnyRef>::wasm_ty_store should handle i31ref values without
48     // requiring a GC heap to be allocated.
49 
50     let mut config = Config::new();
51     config.wasm_function_references(true);
52     config.wasm_gc(true);
53 
54     let engine = Engine::new(&config)?;
55     let mut store = Store::new(&engine, ());
56 
57     let module = Module::new(
58         &engine,
59         r#"(module (func (export "f") (param (ref null any)) (result (ref null any)) local.get 0))"#,
60     )?;
61     let instance = Instance::new(&mut store, &module, &[])?;
62     let f = instance.get_typed_func::<Option<OwnedRooted<AnyRef>>, Option<OwnedRooted<AnyRef>>>(
63         &mut store, "f",
64     )?;
65 
66     // No GC heap objects created; the store has no GcStore allocated yet.
67     let anyref = AnyRef::from_i31(&mut store, I31::wrapping_u32(42));
68     let owned = anyref.to_owned_rooted(&mut store)?;
69     let result = f.call(&mut store, Some(owned))?.unwrap();
70     assert_eq!(
71         result
72             .to_rooted(&mut store)
73             .as_i31(&store)?
74             .unwrap()
75             .get_u32(),
76         42
77     );
78 
79     Ok(())
80 }
81