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