wasmtime/runtime/vm/gc/
host_data.rs1use crate::prelude::*;
17use core::any::Any;
18use wasmtime_slab::{Id, Slab};
19
20#[derive(Default)]
22pub struct ExternRefHostDataTable {
23 slab: Slab<Box<dyn Any + Send + Sync>>,
24}
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
28#[repr(transparent)]
29pub struct ExternRefHostDataId(Id);
30
31fn deref_box<T: ?Sized>(b: &Box<T>) -> &T {
32 &**b
33}
34
35fn deref_box_mut<T: ?Sized>(b: &mut Box<T>) -> &mut T {
36 &mut **b
37}
38
39impl ExternRefHostDataTable {
40 pub fn alloc(&mut self, value: Box<dyn Any + Send + Sync>) -> ExternRefHostDataId {
42 let id = self.slab.alloc(value);
43 let id = ExternRefHostDataId(id);
44 log::trace!("allocated new externref host data: {id:?}");
45 id
46 }
47
48 pub fn dealloc(&mut self, id: ExternRefHostDataId) -> Box<dyn Any + Send + Sync> {
50 log::trace!("deallocated externref host data: {id:?}");
51 self.slab.dealloc(id.0)
52 }
53
54 pub fn get(&self, id: ExternRefHostDataId) -> &(dyn Any + Send + Sync) {
56 let data: &Box<dyn Any + Send + Sync> = self.slab.get(id.0).unwrap();
57 deref_box(data)
58 }
59
60 pub fn get_mut(&mut self, id: ExternRefHostDataId) -> &mut (dyn Any + Send + Sync) {
62 let data: &mut Box<dyn Any + Send + Sync> = self.slab.get_mut(id.0).unwrap();
63 deref_box_mut(data)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn correct_dyn_object() {
73 let mut table = ExternRefHostDataTable::default();
74
75 let x = 42_u32;
76 let id = table.alloc(Box::new(x));
77 assert!(table.get(id).is::<u32>());
78 assert_eq!(*table.get(id).downcast_ref::<u32>().unwrap(), 42);
79 assert!(table.get_mut(id).is::<u32>());
80 assert_eq!(*table.get_mut(id).downcast_ref::<u32>().unwrap(), 42);
81 }
82}