/build/source/crates/checked/src/store.rs
Line | Count | Source |
1 | | use alloc::{string::String, vec::Vec}; |
2 | | use wasm::{ |
3 | | addrs::{FuncAddr, GlobalAddr, MemAddr, ModuleAddr, TableAddr}, |
4 | | config::Config, |
5 | | resumable::Resumable, |
6 | | FuncType, GlobalType, HaltExecutionError, MemType, RuntimeError, TableType, ValidationInfo, |
7 | | Value, |
8 | | }; |
9 | | |
10 | | use crate::{ |
11 | | stored_types::{Stored, StoredExternVal, StoredInstantiationOutcome, StoredRunState}, |
12 | | AbstractStored, StoreId, StoredRef, StoredValue, |
13 | | }; |
14 | | |
15 | | pub struct Store<'b, T: Config> { |
16 | | pub(crate) inner: wasm::Store<'b, T>, |
17 | | |
18 | | /// A unique identifier for this store. This is used to verify that stored |
19 | | /// objects belong to the current [`Store`](wasm::Store). |
20 | | pub(crate) id: StoreId, |
21 | | } |
22 | | |
23 | | impl<'b, T: Config> Store<'b, T> { |
24 | | /// Returns an immutable reference to the raw store. |
25 | 27 | pub fn inner(&self) -> &wasm::Store<'b, T> { |
26 | 27 | &self.inner |
27 | 27 | } |
28 | | |
29 | | /// Deconstructs this checked store and returns its inner representation. |
30 | 0 | pub fn into_inner(self) -> wasm::Store<'b, T> { |
31 | 0 | self.inner |
32 | 0 | } |
33 | | |
34 | | /// Returns the id of this store. |
35 | 0 | pub fn id(&self) -> StoreId { |
36 | 0 | self.id |
37 | 0 | } |
38 | | } |
39 | | |
40 | | // All functions in this impl block must occur in the same order as they are |
41 | | // defined in for the unchecked `Store` methods. Also all functions must follow |
42 | | // the same implementation scheme to make sure they are only light wrappers: |
43 | | // |
44 | | // 1. try unwrap [stored parameter objects] |
45 | | // 2. call [unchecked method] |
46 | | // 3. rewrap [results into stored objects] |
47 | | // 4. return [stored result objects] |
48 | | impl<'b, T: Config> Store<'b, T> { |
49 | 433 | pub fn new(user_data: T) -> Self { |
50 | 433 | Self { |
51 | 433 | inner: wasm::Store::new(user_data), |
52 | 433 | id: StoreId::new(), |
53 | 433 | } |
54 | 433 | } |
55 | | |
56 | | /// This is a safe variant of |
57 | | /// [`Store::module_instantiate`](wasm::Store::module_instantiate). |
58 | 288 | pub fn module_instantiate( |
59 | 288 | &mut self, |
60 | 288 | validation_info: &ValidationInfo<'b>, |
61 | 288 | extern_vals: Vec<StoredExternVal>, |
62 | 288 | maybe_fuel: Option<u64>, |
63 | 288 | ) -> Result<StoredInstantiationOutcome, RuntimeError> { |
64 | | // 1. try unwrap |
65 | 288 | let extern_vals = extern_vals.try_unwrap_into_bare(self.id); |
66 | | // 2. call |
67 | | // SAFETY: It was just checked that the `ExternVal`s came from the |
68 | | // current store through their store ids. |
69 | 286 | let instantiation_outcome = unsafe { |
70 | 288 | self.inner |
71 | 288 | .module_instantiate(validation_info, extern_vals, maybe_fuel) |
72 | 2 | }?; |
73 | | // 3. rewrap |
74 | | // SAFETY: The `InstantiationOutcome` just came from the current store. |
75 | 286 | let stored_instantiation_outcome = |
76 | 286 | unsafe { StoredInstantiationOutcome::from_bare(instantiation_outcome, self.id) }; |
77 | | // 4. return |
78 | 286 | Ok(stored_instantiation_outcome) |
79 | 288 | } |
80 | | |
81 | | /// This is a safe variant of |
82 | | /// [`Store::instance_export`](wasm::Store::instance_export). |
83 | 48.1k | pub fn instance_export( |
84 | 48.1k | &self, |
85 | 48.1k | module_addr: Stored<ModuleAddr>, |
86 | 48.1k | name: &str, |
87 | 48.1k | ) -> Result<StoredExternVal, RuntimeError> { |
88 | | // 1. try unwrap |
89 | 48.1k | let module_addr = module_addr.try_unwrap_into_bare(self.id); |
90 | | // 2. call |
91 | | // SAFETY: It was just checked that the `ModuleAddr` came from the |
92 | | // current store through its store id. |
93 | 48.1k | let extern_val = unsafe { self.inner.instance_export(module_addr, name) }?0 ; |
94 | | // 3. rewrap |
95 | | // SAFETY: The `ExternVal` just came from the current store. |
96 | 48.1k | let stored_extern_val = unsafe { StoredExternVal::from_bare(extern_val, self.id) }; |
97 | | // 4. return |
98 | 48.1k | Ok(stored_extern_val) |
99 | 48.1k | } |
100 | | |
101 | | /// This is a safer variant of |
102 | | /// [`Store::func_alloc`](wasm::Store::func_alloc). It is functionally |
103 | | /// equal, with the only difference being that this function returns a |
104 | | /// [`Stored<FuncAddr>`]. |
105 | | /// |
106 | | /// # Safety |
107 | | /// |
108 | | /// The caller has to guarantee that if the [`Value`]s returned from the |
109 | | /// given host function are references, their addresses came either from the |
110 | | /// host function arguments or from the current [`Store`] object. |
111 | | /// |
112 | | /// See [`Store::func_alloc`](wasm::Store::func_alloc) for more information. |
113 | | #[allow(clippy::let_and_return)] // reason = "to follow the 1234 structure" |
114 | 0 | pub unsafe fn func_alloc( |
115 | 0 | &mut self, |
116 | 0 | func_type: FuncType, |
117 | 0 | host_func: fn(&mut T, Vec<Value>) -> Result<Vec<Value>, HaltExecutionError>, |
118 | 0 | ) -> Stored<FuncAddr> { |
119 | | // 1. try unwrap |
120 | | // no stored parameters |
121 | | // 2. call |
122 | | // SAFETY: The caller ensures that if the host function returns |
123 | | // references, they originate either from the arguments or the current |
124 | | // store. |
125 | 0 | let func_addr = unsafe { self.inner.func_alloc(func_type, host_func) }; |
126 | | // 3. rewrap |
127 | | // 4. return |
128 | | // SAFETY: The function address just came from the current store. |
129 | 0 | unsafe { Stored::from_bare(func_addr, self.id) } |
130 | 0 | } |
131 | | |
132 | | /// This is a safe variant of [`Store::func_type`](wasm::Store::func_type). |
133 | 0 | pub fn func_type(&self, func_addr: Stored<FuncAddr>) -> FuncType { |
134 | | // 1. try unwrap |
135 | 0 | let func_addr = func_addr.try_unwrap_into_bare(self.id); |
136 | | // 2. call |
137 | | // 3. rewrap |
138 | | // `FuncType` does not have a stored variant. |
139 | | // 4. return |
140 | | // SAFETY: It was just checked that the `FuncAddr` came from the current |
141 | | // store through its store id. |
142 | 0 | unsafe { self.inner.func_type(func_addr) } |
143 | 0 | } |
144 | | |
145 | | /// This is a safe variant of [`Store::invoke`](wasm::Store::invoke). |
146 | 0 | pub fn invoke( |
147 | 0 | &mut self, |
148 | 0 | func_addr: Stored<FuncAddr>, |
149 | 0 | params: Vec<StoredValue>, |
150 | 0 | maybe_fuel: Option<u64>, |
151 | 0 | ) -> Result<StoredRunState<T>, RuntimeError> { |
152 | | // 1. try unwrap |
153 | 0 | let func_addr = func_addr.try_unwrap_into_bare(self.id); |
154 | 0 | let params = params.try_unwrap_into_bare(self.id); |
155 | | // 2. call |
156 | | // SAFETY: It was just checked that the `FuncAddr` and any addresses in |
157 | | // the parameters came from the current store through their store ids. |
158 | 0 | let run_state = unsafe { self.inner.invoke(func_addr, params, maybe_fuel) }?; |
159 | | // 3. rewrap |
160 | | // SAFETY: The `RunState` just came from the current store. |
161 | 0 | let stored_run_state = unsafe { StoredRunState::from_bare(run_state, self.id) }; |
162 | | // 4. return |
163 | 0 | Ok(stored_run_state) |
164 | 0 | } |
165 | | |
166 | | /// This is a safe variant of |
167 | | /// [`Store::table_alloc`](wasm::Store::table_alloc). |
168 | 146 | pub fn table_alloc( |
169 | 146 | &mut self, |
170 | 146 | table_type: TableType, |
171 | 146 | r#ref: StoredRef, |
172 | 146 | ) -> Result<Stored<TableAddr>, RuntimeError> { |
173 | | // 1. try unwrap |
174 | 146 | let r#ref = r#ref.try_unwrap_into_bare(self.id); |
175 | | // 2. call |
176 | | // SAFETY: It was just checked that any address in the reference came |
177 | | // from the current store through its store id. |
178 | 146 | let table_addr = unsafe { self.inner.table_alloc(table_type, r#ref) }?0 ; |
179 | | // 3. rewrap |
180 | | // SAFETY: The `TableAddr` just came from the current store. |
181 | 146 | let stored_table_addr = unsafe { Stored::from_bare(table_addr, self.id) }; |
182 | | // 4. return |
183 | 146 | Ok(stored_table_addr) |
184 | 146 | } |
185 | | |
186 | | /// This is a safe variant of |
187 | | /// [`Store::table_type`](wasm::Store::table_type). |
188 | 0 | pub fn table_type(&self, table_addr: Stored<TableAddr>) -> TableType { |
189 | | // 1. try unwrap |
190 | 0 | let table_addr = table_addr.try_unwrap_into_bare(self.id); |
191 | | // 2. call |
192 | | // 3. rewrap |
193 | | // `TableType` has no stored variant. |
194 | | // 4. return |
195 | | // SAFETY: It was just checked that the `TableAddr` came from the |
196 | | // current store through its store id. |
197 | 0 | unsafe { self.inner.table_type(table_addr) } |
198 | 0 | } |
199 | | |
200 | | /// This is a safe variant of |
201 | | /// [`Store::table_read`](wasm::Store::table_read). |
202 | 2 | pub fn table_read( |
203 | 2 | &self, |
204 | 2 | table_addr: Stored<TableAddr>, |
205 | 2 | i: u32, |
206 | 2 | ) -> Result<StoredRef, RuntimeError> { |
207 | | // 1. try unwrap |
208 | 2 | let table_addr = table_addr.try_unwrap_into_bare(self.id); |
209 | | // 2. call |
210 | | // SAFETY: It was just checked that the `TableAddr` came from the |
211 | | // current store through its store id. |
212 | 2 | let r#ref = unsafe { self.inner.table_read(table_addr, i) }?0 ; |
213 | | // 3. rewrap |
214 | | // SAFETY: The `Ref` ust came from the current store. |
215 | 2 | let stored_ref = unsafe { StoredRef::from_bare(r#ref, self.id) }; |
216 | | // 4. return |
217 | 2 | Ok(stored_ref) |
218 | 2 | } |
219 | | |
220 | | /// This is a safe variant of |
221 | | /// [`Store::table_write`](wasm::Store::table_write). |
222 | 0 | pub fn table_write( |
223 | 0 | &mut self, |
224 | 0 | table_addr: Stored<TableAddr>, |
225 | 0 | i: u32, |
226 | 0 | r#ref: StoredRef, |
227 | 0 | ) -> Result<(), RuntimeError> { |
228 | | // 1. try unwrap |
229 | 0 | let table_addr = table_addr.try_unwrap_into_bare(self.id); |
230 | 0 | let r#ref = r#ref.try_unwrap_into_bare(self.id); |
231 | | // 2. call |
232 | | // SAFETY: It was just checked that the `TableAddr` and any address in |
233 | | // the reference came from the current store through their store ids. |
234 | 0 | unsafe { self.inner.table_write(table_addr, i, r#ref) }?; |
235 | | // 3. rewrap |
236 | | // result is the unit type. |
237 | | // 4. return |
238 | 0 | Ok(()) |
239 | 0 | } |
240 | | |
241 | | /// This is a safe variant of |
242 | | /// [`Store::table_size`](wasm::Store::table_size). |
243 | 0 | pub fn table_size(&self, table_addr: Stored<TableAddr>) -> u32 { |
244 | | // 1. try unwrap |
245 | 0 | let table_addr = table_addr.try_unwrap_into_bare(self.id); |
246 | | // 2. call |
247 | | // 3. rewrap |
248 | | // table size has no stored variant. |
249 | | // 4. return |
250 | | // SAFETY: It was just checked that the `TableAddr` came from the |
251 | | // current store through its store id. |
252 | 0 | unsafe { self.inner.table_size(table_addr) } |
253 | 0 | } |
254 | | |
255 | | /// This is a variant of [`Store::mem_alloc`](wasm::Store::mem_alloc) that |
256 | | /// returns a stored object. |
257 | | #[allow(clippy::let_and_return)] // reason = "to follow the 1234 structure" |
258 | 148 | pub fn mem_alloc(&mut self, mem_type: MemType) -> Stored<MemAddr> { |
259 | | // 1. try unwrap |
260 | | // no stored parameters |
261 | | // 2. call |
262 | 148 | let mem_addr = self.inner.mem_alloc(mem_type); |
263 | | // 3. rewrap |
264 | | // 4. return |
265 | | // SAFETY: The `MemAddr` just came from the current store. |
266 | 148 | unsafe { Stored::from_bare(mem_addr, self.id) } |
267 | 148 | } |
268 | | |
269 | | /// This is a safe variant of [`Store::mem_type`](wasm::Store::mem_type). |
270 | 0 | pub fn mem_type(&self, mem_addr: Stored<MemAddr>) -> MemType { |
271 | | // 1. try unwrap |
272 | 0 | let mem_addr = mem_addr.try_unwrap_into_bare(self.id); |
273 | | // 2. call |
274 | | // 3. rewrap |
275 | | // `MemType` does not have a stored variant. |
276 | | // 4. return |
277 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
278 | | // store through its store id. |
279 | 0 | unsafe { self.inner.mem_type(mem_addr) } |
280 | 0 | } |
281 | | |
282 | | /// This is a safe variant of [`Store::mem_read`](wasm::Store::mem_read). |
283 | 105 | pub fn mem_read(&self, mem_addr: Stored<MemAddr>, i: u32) -> Result<u8, RuntimeError> { |
284 | | // 1. try unwrap |
285 | 105 | let mem_addr = mem_addr.try_unwrap_into_bare(self.id); |
286 | | // 2. call |
287 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
288 | | // store through its store id. |
289 | 105 | let byte = unsafe { self.inner.mem_read(mem_addr, i) }?0 ; |
290 | | // 3. rewrap |
291 | | // a single byte does not have a stored variant. |
292 | | // 4. return |
293 | 105 | Ok(byte) |
294 | 105 | } |
295 | | |
296 | | /// This is a safe variant of [`Store::mem_write`](wasm::Store::mem_write). |
297 | 0 | pub fn mem_write( |
298 | 0 | &mut self, |
299 | 0 | mem_addr: Stored<MemAddr>, |
300 | 0 | i: u32, |
301 | 0 | byte: u8, |
302 | 0 | ) -> Result<(), RuntimeError> { |
303 | | // 1. try unwrap |
304 | 0 | let mem_addr = mem_addr.try_unwrap_into_bare(self.id); |
305 | | // 2. call |
306 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
307 | | // store through its store id. |
308 | 0 | unsafe { self.inner.mem_write(mem_addr, i, byte) }?; |
309 | | // 3. rewrap |
310 | | // result is the unit type. |
311 | | // 4. return |
312 | 0 | Ok(()) |
313 | 0 | } |
314 | | |
315 | | /// This is a safe variant of [`Store::mem_size`](wasm::Store::mem_size). |
316 | 0 | pub fn mem_size(&self, mem_addr: Stored<MemAddr>) -> u32 { |
317 | | // 1. try unwrap |
318 | 0 | let mem_addr = mem_addr.try_unwrap_into_bare(self.id); |
319 | | // 2. call |
320 | | // 3. rewrap |
321 | | // mem size does not have a stored variant. |
322 | | // 4. return |
323 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
324 | | // store through its store id. |
325 | 0 | unsafe { self.inner.mem_size(mem_addr) } |
326 | 0 | } |
327 | | |
328 | | /// This is a safe variant of [`Store::mem_grow`](wasm::Store::mem_grow). |
329 | 0 | pub fn mem_grow(&mut self, mem_addr: Stored<MemAddr>, n: u32) -> Result<(), RuntimeError> { |
330 | | // 1. try unwrap |
331 | 0 | let mem_addr = mem_addr.try_unwrap_into_bare(self.id); |
332 | | // 2. call |
333 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
334 | | // store through its store id. |
335 | 0 | unsafe { self.inner.mem_grow(mem_addr, n) }?; |
336 | | // 3. rewrap |
337 | | // result is the unit type. |
338 | | // 4. return |
339 | 0 | Ok(()) |
340 | 0 | } |
341 | | |
342 | | /// This is a safe variant of |
343 | | /// [`Store::global_alloc`](wasm::Store::global_alloc). |
344 | 584 | pub fn global_alloc( |
345 | 584 | &mut self, |
346 | 584 | global_type: GlobalType, |
347 | 584 | val: StoredValue, |
348 | 584 | ) -> Result<Stored<GlobalAddr>, RuntimeError> { |
349 | | // 1. try unwrap |
350 | 584 | let val = val.try_unwrap_into_bare(self.id); |
351 | | // 2. call |
352 | | // SAFETY: It was just checked that any address the value came from the |
353 | | // current store through its store id. |
354 | 584 | let global_addr = unsafe { self.inner.global_alloc(global_type, val) }?0 ; |
355 | | // 3. rewrap |
356 | | // SAFETY: The `GlobalAddr` just came from the current store. |
357 | 584 | let stored_global_addr = unsafe { Stored::from_bare(global_addr, self.id) }; |
358 | | // 4. return |
359 | 584 | Ok(stored_global_addr) |
360 | 584 | } |
361 | | |
362 | | /// This is a safe variant of |
363 | | /// [`Store::global_type`](wasm::Store::global_type). |
364 | 2 | pub fn global_type(&self, global_addr: Stored<GlobalAddr>) -> Result<GlobalType, RuntimeError> { |
365 | | // 1. try unwrap |
366 | 2 | let global_addr = global_addr.try_unwrap_into_bare(self.id); |
367 | | // 2. call |
368 | | // SAFETY: It was just checked that the `GlobalAddr` came from the |
369 | | // current store through its store id. |
370 | 2 | let global_type = unsafe { self.inner.global_type(global_addr) }; |
371 | | // 3. rewrap |
372 | | // `GlobalType` does not have a stored variant. |
373 | | // 4. return |
374 | 2 | Ok(global_type) |
375 | 2 | } |
376 | | |
377 | | /// This is a safe variant of |
378 | | /// [`Store::global_read`](wasm::Store::global_read). |
379 | 99 | pub fn global_read(&self, global_addr: Stored<GlobalAddr>) -> StoredValue { |
380 | | // 1. try unwrap |
381 | 99 | let global_addr = global_addr.try_unwrap_into_bare(self.id); |
382 | | // 2. call |
383 | | // SAFETY: It was just checked that the `GlobalAddr` came from the |
384 | | // current store through its store id. |
385 | 99 | let value = unsafe { self.inner.global_read(global_addr) }; |
386 | | // 3. rewrap |
387 | | // 4. return |
388 | | // SAFETY: The `Value` just came from the current store. |
389 | 99 | unsafe { StoredValue::from_bare(value, self.id) } |
390 | 99 | } |
391 | | |
392 | | /// This is a safe variant of |
393 | | /// [`Store::global_write`](wasm::Store::global_write). |
394 | 1 | pub fn global_write( |
395 | 1 | &mut self, |
396 | 1 | global_addr: Stored<GlobalAddr>, |
397 | 1 | val: StoredValue, |
398 | 1 | ) -> Result<(), RuntimeError> { |
399 | | // 1. try unwrap |
400 | 1 | let global_addr = global_addr.try_unwrap_into_bare(self.id); |
401 | 1 | let val = val.try_unwrap_into_bare(self.id); |
402 | | // 2. call |
403 | | // SAFETY: It was just checked that the `GlobalAddr` any any address |
404 | | // contained in the value came from the current store through their |
405 | | // store ids. |
406 | 1 | unsafe { self.inner.global_write(global_addr, val) }?0 ; |
407 | | // 3. rewrap |
408 | | // result is the unit type. |
409 | | // 4. return |
410 | 1 | Ok(()) |
411 | 1 | } |
412 | | |
413 | | /// This is a safe variant of |
414 | | /// [`Store::create_resumable`](wasm::Store::create_resumable). |
415 | 6 | pub fn create_resumable( |
416 | 6 | &self, |
417 | 6 | func_addr: Stored<FuncAddr>, |
418 | 6 | params: Vec<StoredValue>, |
419 | 6 | maybe_fuel: Option<u64>, |
420 | 6 | ) -> Result<Stored<Resumable<T>>, RuntimeError> { |
421 | | // 1. try unwrap |
422 | 6 | let func_addr = func_addr.try_unwrap_into_bare(self.id); |
423 | 6 | let params = params.try_unwrap_into_bare(self.id); |
424 | | // 2. call |
425 | | // SAFETY: It was just checked that the `FuncAddr` any any addresses |
426 | | // contained in the parameters came from the current store through their |
427 | | // store ids. |
428 | 6 | let resumable = unsafe { self.inner.create_resumable(func_addr, params, maybe_fuel) }?0 ; |
429 | | // 3. rewrap |
430 | | // SAFETY: The `Resumable` just came from the current store. |
431 | 6 | let stored_resumable = unsafe { Stored::from_bare(resumable, self.id) }; |
432 | | // 4. return |
433 | 6 | Ok(stored_resumable) |
434 | 6 | } |
435 | | |
436 | | /// This is a safe variant of [`Store::resume`](wasm::Store::resume). |
437 | 49 | pub fn resume( |
438 | 49 | &mut self, |
439 | 49 | resumable: Stored<Resumable<T>>, |
440 | 49 | ) -> Result<StoredRunState<T>, RuntimeError> { |
441 | | // 1. try unwrap |
442 | 49 | let resumable = resumable.try_unwrap_into_bare(self.id); |
443 | | // 2. call |
444 | | // SAFETY: It was just checked that the `Resumable` came from the |
445 | | // current store through its store id. |
446 | 49 | let run_state = unsafe { self.inner.resume(resumable) }?0 ; |
447 | | // 3. rewrap |
448 | | // SAFETY: The `RunState` just came from the current store. |
449 | 49 | let stored_run_state = unsafe { StoredRunState::from_bare(run_state, self.id) }; |
450 | | // 4. return |
451 | 49 | Ok(stored_run_state) |
452 | 49 | } |
453 | | |
454 | | /// This is a safe variant of |
455 | | /// [`Store::invoke_without_fuel`](wasm::Store::invoke_without_fuel). |
456 | 47.8k | pub fn invoke_without_fuel( |
457 | 47.8k | &mut self, |
458 | 47.8k | func_addr: Stored<FuncAddr>, |
459 | 47.8k | params: Vec<StoredValue>, |
460 | 47.8k | ) -> Result<Vec<StoredValue>, RuntimeError> { |
461 | | // 1. try unwrap |
462 | 47.8k | let func_addr = func_addr.try_unwrap_into_bare(self.id); |
463 | 47.8k | let params = params.try_unwrap_into_bare(self.id); |
464 | | // 2. call |
465 | | // SAFETY: It was just checked that the `FuncAddr` and any addresses |
466 | | // contained in the parameters came from the current store through their |
467 | | // store ids. |
468 | 47.8k | let returns45.3k = unsafe { self.inner.invoke_without_fuel(func_addr, params) }?2.42k ; |
469 | | // 3. rewrap |
470 | | // SAFETY: All `Value`s just came from the current store. |
471 | 45.3k | let returns = unsafe { Vec::from_bare(returns, self.id) }; |
472 | | // 4. return |
473 | 45.3k | Ok(returns) |
474 | 47.8k | } |
475 | | |
476 | | /// This is a safe variant of |
477 | | /// [`Store::mem_access_mut_slice`](wasm::Store::mem_access_mut_slice). |
478 | 3 | pub fn mem_access_mut_slice<R>( |
479 | 3 | &self, |
480 | 3 | memory: Stored<MemAddr>, |
481 | 3 | accessor: impl FnOnce(&mut [u8]) -> R, |
482 | 3 | ) -> R { |
483 | | // 1. try unwrap |
484 | 3 | let memory = memory.try_unwrap_into_bare(self.id); |
485 | | // 2. call |
486 | | // 3. rewrap |
487 | | // result is generic |
488 | | // 4. return |
489 | | // SAFETY: It was just checked that the `MemAddr` came from the current |
490 | | // store through its store id. |
491 | 3 | unsafe { self.inner.mem_access_mut_slice(memory, accessor) } |
492 | 3 | } |
493 | | |
494 | | /// This is a safe variant of |
495 | | /// [`Store::instance_exports`](wasm::Store::instance_exports) |
496 | 0 | pub fn instance_exports( |
497 | 0 | &self, |
498 | 0 | module_addr: Stored<ModuleAddr>, |
499 | 0 | ) -> Vec<(String, StoredExternVal)> { |
500 | | // 1. try unwrap |
501 | 0 | let module_addr = module_addr.try_unwrap_into_bare(self.id); |
502 | | // 2. call |
503 | | // SAFETY: We just checked that this module address is valid in the |
504 | | // current store through its store id. |
505 | 0 | let exports = unsafe { self.inner.instance_exports(module_addr) }; |
506 | | // 3. rewrap |
507 | | // 4. return |
508 | 0 | exports |
509 | 0 | .into_iter() |
510 | 0 | .map(|(name, externval)| { |
511 | | // SAFETY: The `ExternVal`s just came from the current store. |
512 | 0 | let stored_externval = unsafe { StoredExternVal::from_bare(externval, self.id) }; |
513 | 0 | (name, stored_externval) |
514 | 0 | }) |
515 | 0 | .collect() |
516 | 0 | } |
517 | | } |