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