()
| 555 | #[test] |
| 556 | #[cfg_attr(miri, ignore)] |
| 557 | fn host_sets_struct_in_table() -> Result<()> { |
| 558 | let mut store = gc_store()?; |
| 559 | |
| 560 | let module = Module::new( |
| 561 | store.engine(), |
| 562 | r#" |
| 563 | (module |
| 564 | (type (struct (field i8))) |
| 565 | (table $t (export "t") 1 1 (ref null 0) (ref.null 0)) |
| 566 | (func (export "f") (result (ref null 0)) |
| 567 | i32.const 0 |
| 568 | table.get $t |
| 569 | ) |
| 570 | ) |
| 571 | "#, |
| 572 | )?; |
| 573 | |
| 574 | let instance = Instance::new(&mut store, &module, &[])?; |
| 575 | let t = instance.get_table(&mut store, "t").unwrap(); |
| 576 | |
| 577 | let struct_ty = StructType::new( |
| 578 | store.engine(), |
| 579 | [FieldType::new(Mutability::Const, StorageType::I8)], |
| 580 | )?; |
| 581 | let pre = StructRefPre::new(&mut store, struct_ty.clone()); |
| 582 | let s0 = StructRef::new(&mut store, &pre, &[Val::I32(42)])?; |
| 583 | t.set(&mut store, 0, s0.into())?; |
| 584 | |
| 585 | // Get the global from the host. |
| 586 | let val = t.get(&mut store, 0).expect("in bounds"); |
| 587 | let anyref = val.unwrap_any().expect("non-null"); |
| 588 | let s1 = anyref.unwrap_struct(&store)?; |
| 589 | assert_eq!(s1.field(&mut store, 0)?.unwrap_i32(), 42); |
| 590 | assert!(Rooted::ref_eq(&store, &s0, &s1)?); |
| 591 | |
| 592 | // Get the global from the guest. |
| 593 | let f = instance.get_typed_func::<(), Option<Rooted<StructRef>>>(&mut store, "f")?; |
| 594 | let s2 = f.call(&mut store, ())?.expect("non-null"); |
| 595 | assert_eq!(s2.field(&mut store, 0)?.unwrap_i32(), 42); |
| 596 | assert!(Rooted::ref_eq(&store, &s0, &s2)?); |
| 597 | |
| 598 | Ok(()) |
| 599 | } |
| 600 | |
| 601 | #[test] |
| 602 | #[cfg_attr(miri, ignore)] |
nothing calls this directly
no test coverage detected