1use {
2 crate::{
3 aliasable_box::AliasableBox,
4 data::DataEntity,
5 elem::ElemEntity,
6 engine::Engine,
7 extern_::ExternEntity,
8 func::{FuncEntity, FuncType},
9 global::GlobalEntity,
10 mem::MemEntity,
11 table::TableEntity,
12 },
13 std::{
14 collections::HashMap,
15 fmt,
16 hash::{Hash, Hasher},
17 ptr::NonNull,
18 },
19};
20
21#[derive(Debug)]
23pub struct Store {
24 engine: Engine,
25 id: StoreId,
26 types: FuncTypeInterner,
27 funcs: Vec<AliasableBox<FuncEntity>>,
28 tables: Vec<AliasableBox<TableEntity>>,
29 mems: Vec<AliasableBox<MemEntity>>,
30 globals: Vec<AliasableBox<GlobalEntity>>,
31 elems: Vec<AliasableBox<ElemEntity>>,
32 datas: Vec<AliasableBox<DataEntity>>,
33 externs: Vec<AliasableBox<ExternEntity>>,
34}
35
36impl Store {
37 pub fn new(engine: Engine) -> Self {
38 let id = StoreId::new();
39 Self {
40 engine,
41 id,
42 types: FuncTypeInterner::new(id),
43 funcs: Vec::new(),
44 tables: Vec::new(),
45 mems: Vec::new(),
46 globals: Vec::new(),
47 elems: Vec::new(),
48 datas: Vec::new(),
49 externs: Vec::new(),
50 }
51 }
52
53 pub fn engine(&self) -> &Engine {
54 &self.engine
55 }
56
57 pub(crate) fn id(&self) -> StoreId {
58 self.id
59 }
60
61 pub(crate) fn resolve_type(&self, type_: InternedFuncType) -> &FuncType {
62 self.types.resolve(type_)
63 }
64
65 pub(crate) fn get_or_intern_type(&mut self, type_: &FuncType) -> InternedFuncType {
66 self.types.get_or_intern(type_)
67 }
68
69 pub(crate) fn insert_func(&mut self, func: FuncEntity) -> Handle<FuncEntity> {
73 let func = AliasableBox::from_box(Box::new(func));
74 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&func), self.id) };
75 self.funcs.push(func);
76 handle
77 }
78
79 pub(crate) fn insert_table(&mut self, table: TableEntity) -> Handle<TableEntity> {
83 let table = AliasableBox::from_box(Box::new(table));
84 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&table), self.id) };
85 self.tables.push(table);
86 handle
87 }
88
89 pub(crate) fn insert_mem(&mut self, mem: MemEntity) -> Handle<MemEntity> {
93 let mem = AliasableBox::from_box(Box::new(mem));
94 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&mem), self.id) };
95 self.mems.push(mem);
96 handle
97 }
98
99 pub(crate) fn insert_global(&mut self, global: GlobalEntity) -> Handle<GlobalEntity> {
103 let global = AliasableBox::from_box(Box::new(global));
104 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&global), self.id) };
105 self.globals.push(global);
106 handle
107 }
108
109 pub(crate) fn insert_elem(&mut self, elem: ElemEntity) -> Handle<ElemEntity> {
113 let elem = AliasableBox::from_box(Box::new(elem));
114 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&elem), self.id) };
115 self.elems.push(elem);
116 handle
117 }
118
119 pub(crate) fn insert_data(&mut self, data: DataEntity) -> Handle<DataEntity> {
123 let data = AliasableBox::from_box(Box::new(data));
124 let handle = unsafe { Handle::from_unguarded(AliasableBox::as_raw(&data), self.id) };
125 self.datas.push(data);
126 handle
127 }
128
129 pub(crate) fn insert_extern(&mut self, extern_: ExternEntity) -> Handle<ExternEntity> {
133 let mut extern_ = AliasableBox::from_box(Box::new(extern_));
134 let handle =
135 unsafe { Handle::from_unguarded(NonNull::new_unchecked(&mut *extern_), self.id) };
136 self.externs.push(extern_);
137 handle
138 }
139}
140
141#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
143pub struct StoreId(usize);
144
145impl StoreId {
146 pub(crate) fn new() -> Self {
147 use std::sync::atomic::{AtomicUsize, Ordering};
148
149 static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
150
151 Self(
152 NEXT_ID
153 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |id| id.checked_add(1))
154 .unwrap(),
155 )
156 }
157}
158
159#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
160pub(crate) struct InternedFuncType {
161 type_: UnguardedInternedFuncType,
162 store_id: StoreId,
163}
164
165impl InternedFuncType {
166 pub(crate) unsafe fn from_unguarded(
167 type_: UnguardedInternedFuncType,
168 store_id: StoreId,
169 ) -> Self {
170 Self { type_, store_id }
171 }
172
173 pub(crate) fn to_unguarded(self, store_id: StoreId) -> UnguardedInternedFuncType {
174 assert_eq!(store_id, self.store_id);
175 self.type_
176 }
177}
178
179#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
180pub(crate) struct UnguardedInternedFuncType(usize);
181
182pub(crate) struct Handle<T> {
183 unguarded: UnguardedHandle<T>,
184 store_id: StoreId,
185}
186
187impl<T> Handle<T> {
188 pub(crate) fn as_ref(self, store: &Store) -> &T {
189 assert_eq!(store.id, self.store_id, "store mismatch");
190 unsafe { self.unguarded.as_ref() }
191 }
192
193 pub(crate) fn as_mut(mut self, store: &mut Store) -> &mut T {
194 assert_eq!(store.id, self.store_id, "store mismatch");
195 unsafe { self.unguarded.as_mut() }
196 }
197
198 pub(crate) unsafe fn from_unguarded(unguarded: UnguardedHandle<T>, store_id: StoreId) -> Self {
199 Self {
200 unguarded,
201 store_id,
202 }
203 }
204
205 pub(crate) fn to_unguarded(self, store_id: StoreId) -> UnguardedHandle<T> {
206 assert_eq!(store_id, self.store_id);
207 self.unguarded
208 }
209}
210
211impl<T> Clone for Handle<T> {
212 fn clone(&self) -> Self {
213 *self
214 }
215}
216
217impl<T> Copy for Handle<T> {}
218
219impl<T> fmt::Debug for Handle<T> {
220 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
221 f.debug_struct("Handle")
222 .field("handle", &self.unguarded)
223 .field("store_id", &self.store_id)
224 .finish()
225 }
226}
227
228impl<T> Eq for Handle<T> {}
229
230impl<T> Hash for Handle<T> {
231 fn hash<H>(&self, state: &mut H)
232 where
233 H: Hasher,
234 {
235 self.unguarded.hash(state);
236 self.store_id.hash(state);
237 }
238}
239
240impl<T> PartialEq for Handle<T> {
241 fn eq(&self, other: &Self) -> bool {
242 if self.unguarded != other.unguarded {
243 return false;
244 }
245 if self.store_id != other.store_id {
246 return false;
247 }
248 true
249 }
250}
251
252pub(crate) type UnguardedHandle<T> = NonNull<T>;
253
254#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
255pub(crate) struct HandlePair<T, U>(pub(crate) Handle<T>, pub(crate) Handle<U>);
256
257impl<T, U> HandlePair<T, U> {
258 pub(crate) fn as_mut_pair(mut self, store: &Store) -> (&mut T, &mut U) {
259 assert_eq!(store.id(), self.0.store_id, "store mismatch");
260 assert_eq!(store.id(), self.1.store_id, "store mismatch");
261 assert_ne!(
262 self.0.unguarded.as_ptr() as usize,
263 self.1.unguarded.as_ptr() as usize,
264 "overlapping handles"
265 );
266 unsafe { (self.0.unguarded.as_mut(), self.1.unguarded.as_mut()) }
267 }
268}
269
270#[derive(Debug)]
271struct FuncTypeInterner {
272 store_id: StoreId,
273 types: Vec<FuncType>,
274 interned_types: HashMap<FuncType, UnguardedInternedFuncType>,
275}
276
277impl FuncTypeInterner {
278 fn new(store_id: StoreId) -> Self {
279 Self {
280 store_id,
281 types: Vec::new(),
282 interned_types: HashMap::new(),
283 }
284 }
285
286 fn resolve(&self, type_: InternedFuncType) -> &FuncType {
287 unsafe { self.resolve_unguarded(type_.to_unguarded(self.store_id)) }
288 }
289
290 unsafe fn resolve_unguarded(&self, type_: UnguardedInternedFuncType) -> &FuncType {
292 &self.types[type_.0]
293 }
294
295 fn get_or_intern(&mut self, type_: &FuncType) -> InternedFuncType {
296 InternedFuncType {
297 type_: self.get_or_intern_unguarded(type_),
298 store_id: self.store_id,
299 }
300 }
301
302 fn get_or_intern_unguarded(&mut self, type_: &FuncType) -> UnguardedInternedFuncType {
304 match self.interned_types.get(type_).copied() {
305 Some(type_) => type_,
306 None => {
307 let interned_type = UnguardedInternedFuncType(self.types.len());
308 self.types.push(type_.clone());
309 self.interned_types.insert(type_.clone(), interned_type);
310 interned_type
311 }
312 }
313 }
314}