1 //! Garbage collection rooting APIs.
2 //!
3 //! Rooting prevents GC objects from being collected while they are actively
4 //! being used.
5 //!
6 //! ## Goals
7 //!
8 //! We have a few sometimes-conflicting goals with our GC rooting APIs:
9 //!
10 //! 1. Safety: It should never be possible to get a use-after-free bug because
11 //!    the user misused the rooting APIs, the collector "mistakenly" determined
12 //!    an object was unreachable and collected it, and then the user tried to
13 //!    access the object. This is our highest priority.
14 //!
15 //! 2. Moving GC: Our rooting APIs should moving collectors (such as
16 //!    generational and compacting collectors) where an object might get
17 //!    relocated after a collection and we need to update the GC root's pointer
18 //!    to the moved object. This means we either need cooperation and internal
19 //!    mutability from individual GC roots as well as the ability to enumerate
20 //!    all GC roots on the native Rust stack, or we need a level of indirection.
21 //!
22 //! 3. Performance: Our rooting APIs should generally be as low-overhead as
23 //!    possible. They definitely shouldn't require synchronization and locking
24 //!    to create, access, and drop GC roots.
25 //!
26 //! 4. Ergonomics: Our rooting APIs should be, if not a pleasure, then at least
27 //!    not a burden for users. Additionally, the API's types should be `Sync`
28 //!    and `Send` so that they work well with async Rust.
29 //!
30 //! For example, goals (3) and (4) are in conflict when we think about how to
31 //! support (2). Ideally, for ergonomics, a root would automatically unroot
32 //! itself when dropped. But in the general case that requires holding a
33 //! reference to the store's root set, and that root set needs to be held
34 //! simultaneously by all GC roots, and they each need to mutate the set to
35 //! unroot themselves. That implies `Rc<RefCell<...>>` or `Arc<Mutex<...>>`! The
36 //! former makes the store and GC root types not `Send` and not `Sync`. The
37 //! latter imposes synchronization and locking overhead. So we instead make GC
38 //! roots indirect and require passing in a store context explicitly to unroot
39 //! in the general case. This trades worse ergonomics for better performance and
40 //! support for moving GC.
41 //!
42 //! ## Two Flavors of Rooting API
43 //!
44 //! Okay, with that out of the way, this module provides two flavors of rooting
45 //! API. One for the common, scoped lifetime case, and another for the rare case
46 //! where we really need a GC root with an arbitrary, non-LIFO/non-scoped
47 //! lifetime:
48 //!
49 //! 1. `RootScope` and `Rooted<T>`: These are used for temporarily rooting GC
50 //!    objects for the duration of a scope. The internal implementation takes
51 //!    advantage of the LIFO property inherent in scopes, making creating and
52 //!    dropping `Rooted<T>`s and `RootScope`s super fast and roughly equivalent
53 //!    to bump allocation.
54 //!
55 //!    This type is vaguely similar to V8's [`HandleScope`].
56 //!
57 //!    [`HandleScope`]: https://v8.github.io/api/head/classv8_1_1HandleScope.html
58 //!
59 //!    Note that `Rooted<T>` can't be statically tied to its context scope via a
60 //!    lifetime parameter, unfortunately, as that would allow the creation of
61 //!    only one `Rooted<T>` at a time, since the `Rooted<T>` would take a borrow
62 //!    of the whole context.
63 //!
64 //!    This supports the common use case for rooting and provides good
65 //!    ergonomics.
66 //!
67 //! 2. `ManuallyRooted<T>`: This is the fully general rooting API used for
68 //!    holding onto non-LIFO GC roots with arbitrary lifetimes. However, users
69 //!    must manually unroot them. Failure to manually unroot a
70 //!    `ManuallyRooted<T>` before it is dropped will result in the GC object
71 //!    (and everything it transitively references) leaking for the duration of
72 //!    the `Store`'s lifetime.
73 //!
74 //!    This type is roughly similar to SpiderMonkey's [`PersistentRooted<T>`],
75 //!    although they avoid the manual-unrooting with internal mutation and
76 //!    shared references. (Our constraints mean we can't do those things, as
77 //!    mentioned explained above.)
78 //!
79 //!    [`PersistentRooted<T>`]: http://devdoc.net/web/developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::PersistentRooted.html
80 //!
81 //! At the end of the day, both `Rooted<T>` and `ManuallyRooted<T>` are just
82 //! tagged indices into the store's `RootSet`. This indirection allows working
83 //! with Rust's borrowing discipline (we use `&mut Store` to represent mutable
84 //! access to the GC heap) while still allowing rooted references to be moved
85 //! around without tying up the whole store in borrows. Additionally, and
86 //! crucially, this indirection allows us to update the *actual* GC pointers in
87 //! the `RootSet` and support moving GCs (again, as mentioned above).
88 //!
89 //! ## Unrooted References
90 //!
91 //! We generally don't expose *unrooted* GC references in the Wasmtime API at
92 //! this time -- and I expect it will be a very long time before we do, but in
93 //! the limit we may want to let users define their own GC-managed types that
94 //! participate in GC tracing and all that -- so we don't have to worry about
95 //! failure to root an object causing use-after-free bugs or failing to update a
96 //! GC root pointer after a moving GC as long as users stick to our safe rooting
97 //! APIs. (The one exception is `ValRaw`, which does hold raw GC references. But
98 //! with `ValRaw` all bets are off and safety is 100% up to the user.)
99 //!
100 //! We do, however, have to worry about these things internally. So first of
101 //! all, try to avoid ever working with unrooted GC references if you
102 //! can. However, if you really must, consider also using an `AutoAssertNoGc`
103 //! across the block of code that is manipulating raw GC references.
104 
105 use crate::prelude::*;
106 use crate::runtime::vm::{GcRootsList, GcStore, VMGcRef};
107 use crate::{
108     store::{AutoAssertNoGc, StoreId, StoreOpaque},
109     AsContext, AsContextMut, GcRef, Result, RootedGcRef,
110 };
111 use core::any;
112 use core::marker;
113 use core::mem;
114 use core::num::NonZeroU64;
115 use core::{
116     fmt::{self, Debug},
117     hash::{Hash, Hasher},
118     ops::{Deref, DerefMut},
119 };
120 use wasmtime_slab::{Id as SlabId, Slab};
121 
122 mod sealed {
123     use super::*;
124 
125     /// Sealed, `wasmtime`-internal trait for GC references.
126     ///
127     /// # Safety
128     ///
129     /// All types implementing this trait must:
130     ///
131     /// * Be a newtype of a `GcRootIndex`
132     ///
133     /// * Not implement `Copy` or `Clone`
134     ///
135     /// * Only have `&self` methods.
136     pub unsafe trait GcRefImpl: Sized {
137         /// Transmute a `&GcRootIndex` into an `&Self`.
138         fn transmute_ref(index: &GcRootIndex) -> &Self;
139     }
140 
141     /// Sealed, `wasmtime`-internal trait for the common methods on rooted GC
142     /// references.
143     pub trait RootedGcRefImpl<T: GcRef> {
144         /// Get this rooted GC reference's raw `VMGcRef` out of the store's GC
145         /// root set.
146         ///
147         /// Returns `None` for objects that have since been unrooted (eg because
148         /// its associated `RootedScope` was dropped).
149         ///
150         /// Panics if this root is not associated with the given store.
151         fn get_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Option<&'a VMGcRef>;
152 
153         /// Same as `get_gc_ref` but returns an error instead of `None` for
154         /// objects that have been unrooted.
155         fn try_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Result<&'a VMGcRef> {
156             self.get_gc_ref(store).ok_or_else(|| {
157                 anyhow!("attempted to use a garbage-collected object that has been unrooted")
158             })
159         }
160 
161         /// Get a clone of this rooted GC reference's raw `VMGcRef` out of the
162         /// store's GC root set.
163         ///
164         /// Returns `None` for objects that have since been unrooted (eg because
165         /// its associated `RootedScope` was dropped).
166         ///
167         /// Panics if this root is not associated with the given store.
168         fn clone_gc_ref(&self, store: &mut AutoAssertNoGc<'_>) -> Option<VMGcRef> {
169             let gc_ref = self.get_gc_ref(store)?.unchecked_copy();
170             Some(store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref))
171         }
172 
173         /// Same as `clone_gc_ref` but returns an error instead of `None` for
174         /// objects that have been unrooted.
175         fn try_clone_gc_ref(&self, store: &mut AutoAssertNoGc<'_>) -> Result<VMGcRef> {
176             let gc_ref = self.try_gc_ref(store)?.unchecked_copy();
177             Ok(store.gc_store_mut()?.clone_gc_ref(&gc_ref))
178         }
179     }
180 }
181 pub(crate) use sealed::*;
182 
183 /// The index of a GC root inside a particular store's GC root set.
184 ///
185 /// Can be either a LIFO- or manually-rooted object, depending on the
186 /// `PackedIndex`.
187 ///
188 /// Every `T` such that `T: GcRef` must be a newtype over this `GcRootIndex`.
189 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
190 // Just `pub` to avoid `warn(private_interfaces)` in public APIs, which we can't
191 // `allow(...)` on our MSRV yet.
192 #[doc(hidden)]
193 #[repr(C)] // NB: if this layout changes be sure to change the C API as well
194 pub struct GcRootIndex {
195     store_id: StoreId,
196     generation: u32,
197     index: PackedIndex,
198 }
199 
200 const _: () = {
201     // NB: these match the C API which should also be updated if this changes
202     assert!(mem::size_of::<GcRootIndex>() == 16);
203     assert!(mem::align_of::<GcRootIndex>() == 8);
204 };
205 
206 impl GcRootIndex {
207     #[inline]
208     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
209         self.store_id == store.id()
210     }
211 
212     /// Same as `RootedGcRefImpl::get_gc_ref` but doesn't check that the raw GC
213     /// ref is only used during the scope of an `AutoAssertNoGc`.
214     ///
215     /// It is up to callers to avoid triggering a GC while holding onto the
216     /// resulting raw `VMGcRef`. Failure to uphold this invariant is memory safe
217     /// but will lead to general incorrectness such as panics and wrong results.
218     pub(crate) fn unchecked_get_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Option<&'a VMGcRef> {
219         assert!(
220             self.comes_from_same_store(store),
221             "object used with wrong store"
222         );
223         if let Some(index) = self.index.as_lifo() {
224             let entry = store.gc_roots().lifo_roots.get(index)?;
225             if entry.generation == self.generation {
226                 Some(&entry.gc_ref)
227             } else {
228                 None
229             }
230         } else if let Some(id) = self.index.as_manual() {
231             let gc_ref = store.gc_roots().manually_rooted.get(id);
232             debug_assert!(gc_ref.is_some());
233             gc_ref
234         } else {
235             unreachable!()
236         }
237     }
238 
239     /// Same as `RootedGcRefImpl::get_gc_ref` but not associated with any
240     /// particular `T: GcRef`.
241     pub(crate) fn get_gc_ref<'a>(&self, store: &'a AutoAssertNoGc<'_>) -> Option<&'a VMGcRef> {
242         self.unchecked_get_gc_ref(store)
243     }
244 
245     /// Same as `unchecked_get_gc_ref` but returns an error instead of `None` if
246     /// the GC reference has been unrooted.
247     ///
248     /// # Panics
249     ///
250     /// Panics if `self` is not associated with the given store.
251     pub(crate) fn unchecked_try_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Result<&'a VMGcRef> {
252         self.unchecked_get_gc_ref(store).ok_or_else(|| {
253             anyhow!("attempted to use a garbage-collected object that has been unrooted")
254         })
255     }
256 
257     /// Same as `get_gc_ref` but returns an error instead of `None` if the GC
258     /// reference has been unrooted.
259     pub(crate) fn try_gc_ref<'a>(&self, store: &'a AutoAssertNoGc<'_>) -> Result<&'a VMGcRef> {
260         self.get_gc_ref(store).ok_or_else(|| {
261             anyhow!("attempted to use a garbage-collected object that has been unrooted")
262         })
263     }
264 
265     /// Same as `RootedGcRefImpl::clone_gc_ref` but not associated with any
266     /// particular `T: GcRef`.
267     pub(crate) fn try_clone_gc_ref(&self, store: &mut AutoAssertNoGc<'_>) -> Result<VMGcRef> {
268         let gc_ref = self.try_gc_ref(store)?.unchecked_copy();
269         Ok(store.gc_store_mut()?.clone_gc_ref(&gc_ref))
270     }
271 }
272 
273 /// This is a bit-packed version of
274 ///
275 /// ```ignore
276 /// enema {
277 ///     Lifo(usize),
278 ///     Manual(SlabId),
279 /// }
280 /// ```
281 ///
282 /// where the high bit is the discriminant and the lower 31 bits are the
283 /// payload.
284 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
285 #[repr(transparent)]
286 struct PackedIndex(u32);
287 
288 impl Debug for PackedIndex {
289     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290         if let Some(index) = self.as_lifo() {
291             f.debug_tuple("PackedIndex::Lifo").field(&index).finish()
292         } else if let Some(id) = self.as_manual() {
293             f.debug_tuple("PackedIndex::Manual").field(&id).finish()
294         } else {
295             unreachable!()
296         }
297     }
298 }
299 
300 impl PackedIndex {
301     const DISCRIMINANT_MASK: u32 = 0b1 << 31;
302     const LIFO_DISCRIMINANT: u32 = 0b0 << 31;
303     const MANUAL_DISCRIMINANT: u32 = 0b1 << 31;
304     const PAYLOAD_MASK: u32 = !Self::DISCRIMINANT_MASK;
305 
306     fn new_lifo(index: usize) -> PackedIndex {
307         let index32 = u32::try_from(index).unwrap();
308         assert_eq!(index32 & Self::DISCRIMINANT_MASK, 0);
309         let packed = PackedIndex(Self::LIFO_DISCRIMINANT | index32);
310         debug_assert!(packed.is_lifo());
311         debug_assert_eq!(packed.as_lifo(), Some(index));
312         debug_assert!(!packed.is_manual());
313         debug_assert!(packed.as_manual().is_none());
314         packed
315     }
316 
317     fn new_manual(id: SlabId) -> PackedIndex {
318         let raw = id.into_raw();
319         assert_eq!(raw & Self::DISCRIMINANT_MASK, 0);
320         let packed = PackedIndex(Self::MANUAL_DISCRIMINANT | raw);
321         debug_assert!(packed.is_manual());
322         debug_assert_eq!(packed.as_manual(), Some(id));
323         debug_assert!(!packed.is_lifo());
324         debug_assert!(packed.as_lifo().is_none());
325         packed
326     }
327 
328     fn discriminant(&self) -> u32 {
329         self.0 & Self::DISCRIMINANT_MASK
330     }
331 
332     fn is_lifo(&self) -> bool {
333         self.discriminant() == Self::LIFO_DISCRIMINANT
334     }
335 
336     fn is_manual(&self) -> bool {
337         self.discriminant() == Self::MANUAL_DISCRIMINANT
338     }
339 
340     fn payload(&self) -> u32 {
341         self.0 & Self::PAYLOAD_MASK
342     }
343 
344     fn as_lifo(&self) -> Option<usize> {
345         if self.is_lifo() {
346             Some(usize::try_from(self.payload()).unwrap())
347         } else {
348             None
349         }
350     }
351 
352     fn as_manual(&self) -> Option<SlabId> {
353         if self.is_manual() {
354             Some(SlabId::from_raw(self.payload()))
355         } else {
356             None
357         }
358     }
359 }
360 
361 /// The set of all embedder-API GC roots in a single store/heap.
362 #[derive(Debug, Default)]
363 pub(crate) struct RootSet {
364     /// GC roots with arbitrary lifetime that are manually rooted and unrooted,
365     /// for use with `ManuallyRooted<T>`.
366     manually_rooted: Slab<VMGcRef>,
367 
368     /// Strictly LIFO-ordered GC roots, for use with `RootScope` and
369     /// `Rooted<T>`.
370     lifo_roots: Vec<LifoRoot>,
371 
372     /// Generation counter for entries to prevent ABA bugs with `RootScope` and
373     /// `Rooted<T>`.
374     lifo_generation: u32,
375 }
376 
377 #[derive(Debug)]
378 struct LifoRoot {
379     generation: u32,
380     gc_ref: VMGcRef,
381 }
382 
383 impl RootSet {
384     pub(crate) fn trace_roots(&mut self, gc_roots_list: &mut GcRootsList) {
385         log::trace!("Begin trace user LIFO roots");
386         for root in &mut self.lifo_roots {
387             unsafe {
388                 gc_roots_list.add_root((&mut root.gc_ref).into());
389             }
390         }
391         log::trace!("End trace user LIFO roots");
392 
393         log::trace!("Begin trace user manual roots");
394         for (_id, root) in self.manually_rooted.iter_mut() {
395             unsafe {
396                 gc_roots_list.add_root(root.into());
397             }
398         }
399         log::trace!("End trace user manual roots");
400     }
401 
402     /// Enter a LIFO rooting scope.
403     ///
404     /// Returns an integer that should be passed unmodified to `exit_lifo_scope`
405     /// when the scope is finished.
406     ///
407     /// Calls to `{enter,exit}_lifo_scope` must happen in a strict LIFO order.
408     #[inline]
409     pub(crate) fn enter_lifo_scope(&self) -> usize {
410         self.lifo_roots.len()
411     }
412 
413     /// Exit a LIFO rooting scope.
414     ///
415     /// The `scope` argument must be the result of the corresponding
416     /// `enter_lifo_scope` call.
417     ///
418     /// Calls to `{enter,exit}_lifo_scope` must happen in a strict LIFO order.
419     #[inline]
420     pub(crate) fn exit_lifo_scope(&mut self, gc_store: Option<&mut GcStore>, scope: usize) {
421         debug_assert!(self.lifo_roots.len() >= scope);
422 
423         // If we actually have roots to unroot, call an out-of-line slow path.
424         if self.lifo_roots.len() > scope {
425             self.exit_lifo_scope_slow(gc_store, scope);
426         }
427     }
428 
429     #[inline(never)]
430     #[cold]
431     fn exit_lifo_scope_slow(&mut self, mut gc_store: Option<&mut GcStore>, scope: usize) {
432         self.lifo_generation += 1;
433 
434         // TODO: In the case where we have a tracing GC that doesn't need to
435         // drop barriers, this should really be:
436         //
437         //     self.lifo_roots.truncate(scope);
438 
439         let mut lifo_roots = mem::take(&mut self.lifo_roots);
440         for root in lifo_roots.drain(scope..) {
441             // Only drop the GC reference if we actually have a GC store. How
442             // can we have a GC reference but not a GC store? If we've only
443             // create `i31refs`, we never force a GC store's allocation. This is
444             // fine because `i31ref`s never need drop barriers.
445             if let Some(gc_store) = &mut gc_store {
446                 gc_store.drop_gc_ref(root.gc_ref);
447             }
448         }
449         self.lifo_roots = lifo_roots;
450     }
451 
452     pub(crate) fn with_lifo_scope<S, T>(store: &mut S, f: impl FnOnce(&mut S) -> T) -> T
453     where
454         S: DerefMut<Target = StoreOpaque>,
455     {
456         let scope = store.gc_roots().enter_lifo_scope();
457         let ret = f(store);
458         store.exit_gc_lifo_scope(scope);
459         ret
460     }
461 
462     pub(crate) fn push_lifo_root(&mut self, store_id: StoreId, gc_ref: VMGcRef) -> GcRootIndex {
463         let generation = self.lifo_generation;
464         let index = self.lifo_roots.len();
465         let index = PackedIndex::new_lifo(index);
466         self.lifo_roots.push(LifoRoot { generation, gc_ref });
467         GcRootIndex {
468             store_id,
469             generation,
470             index,
471         }
472     }
473 }
474 
475 /// A scoped, rooted reference to a garbage-collected `T`.
476 ///
477 /// A `Rooted<T>` is a strong handle to a garbage-collected `T`, preventing its
478 /// referent (and anything else transitively referenced) from being collected by
479 /// the GC during the scope within which this `Rooted<T>` was created.
480 ///
481 /// When the context exits this `Rooted<T>`'s scope, the underlying GC object is
482 /// automatically unrooted and any further attempts to use access the underlying
483 /// object will return errors or otherwise fail.
484 ///
485 /// `Rooted<T>` dereferences to its underlying `T`, allowing you to call `T`'s
486 /// methods.
487 ///
488 /// # Example
489 ///
490 /// ```
491 /// # use wasmtime::*;
492 /// # fn _foo() -> Result<()> {
493 /// let mut store = Store::<()>::default();
494 ///
495 /// // Allocating a GC object returns a `Rooted<T>`.
496 /// let hello: Rooted<ExternRef> = ExternRef::new(&mut store, "hello")?;
497 ///
498 /// // Because `Rooted<T>` derefs to `T`, we can call `T` methods on a
499 /// // `Rooted<T>`. For example, we can call the `ExternRef::data` method when we
500 /// // have a `Rooted<ExternRef>`.
501 /// let data = hello
502 ///     .data(&store)?
503 ///     .downcast_ref::<&str>()
504 ///     .ok_or_else(|| Error::msg("not a str"))?;
505 /// assert_eq!(*data, "hello");
506 ///
507 /// // A `Rooted<T>` roots its underlying GC object for the duration of the
508 /// // scope of the store/caller/context that was passed to the method that created
509 /// // it. If we only want to keep a GC reference rooted and alive temporarily, we
510 /// // can introduce new scopes with `RootScope`.
511 /// {
512 ///     let mut scope = RootScope::new(&mut store);
513 ///
514 ///     // This `Rooted<T>` is automatically unrooted after `scope` is dropped,
515 ///     // allowing the collector to reclaim its GC object in the next GC.
516 ///     let scoped_ref = ExternRef::new(&mut scope, "goodbye");
517 /// }
518 ///
519 /// let module = Module::new(store.engine(), r#"
520 ///     (module
521 ///         (global (export "global") (mut externref) (ref.null extern))
522 ///         (table (export "table") 10 externref)
523 ///         (func (export "func") (param externref) (result externref)
524 ///             local.get 0
525 ///         )
526 ///     )
527 /// "#)?;
528 /// let instance = Instance::new(&mut store, &module, &[])?;
529 ///
530 /// // GC references returned from calls into Wasm also return (optional, if the
531 /// // Wasm type is nullable) `Rooted<T>`s.
532 /// let result: Option<Rooted<_>> = instance
533 ///     .get_typed_func::<Option<Rooted<ExternRef>>, Option<Rooted<ExternRef>>>(&mut store, "func")?
534 ///     .call(&mut store, Some(hello))?;
535 ///
536 /// // Similarly, getting a GC reference from a Wasm instance's exported global
537 /// // or table yields a `Rooted<T>`.
538 ///
539 /// let global = instance
540 ///     .get_global(&mut store, "global")
541 ///     .ok_or_else(|| Error::msg("missing `global` export"))?;
542 /// let global_val = global.get(&mut store);
543 /// let global_ref: Option<&Rooted<_>> = global_val
544 ///     .externref()
545 ///     .ok_or_else(|| Error::msg("not an externref"))?;
546 ///
547 /// let table = instance.get_table(&mut store, "table").unwrap();
548 /// let table_elem = table
549 ///     .get(&mut store, 3)
550 ///     .ok_or_else(|| Error::msg("table out of bounds"))?;
551 /// let table_elem_ref: Option<&Rooted<_>> = table_elem
552 ///     .as_extern()
553 ///     .ok_or_else(|| Error::msg("not an externref"))?;
554 /// # Ok(())
555 /// # }
556 /// ```
557 ///
558 /// # Differences Between `Rooted<T>` and `ManuallyRooted<T>`
559 ///
560 /// While `Rooted<T>` is automatically unrooted when its scope is exited, this
561 /// means that `Rooted<T>` is only valid for strictly last-in-first-out (LIFO,
562 /// aka stack order) lifetimes. This is in contrast to
563 /// [`ManuallyRooted<T>`][crate::ManuallyRooted], which supports rooting GC
564 /// objects for arbitrary lifetimes, but requires manual unrooting.
565 ///
566 /// | Type                                         | Supported Lifetimes         | Unrooting |
567 /// |----------------------------------------------|-----------------------------|-----------|
568 /// | [`Rooted<T>`][crate::Rooted]                 | Strictly LIFO / stack order | Automatic |
569 /// | [`ManuallyRooted<T>`][crate::ManuallyRooted] | Arbitrary                   | Manual    |
570 ///
571 /// `Rooted<T>` should suffice for most use cases, and provides better
572 /// ergonomics, but `ManuallyRooted<T>` exists as a fully-general escape hatch.
573 ///
574 /// # Scopes
575 ///
576 /// Wasmtime automatically creates two kinds of scopes:
577 ///
578 /// 1. A [`Store`][crate::Store] is the outermost rooting scope. Creating a
579 ///    `Root<T>` directly inside a `Store` permanently roots the underlying
580 ///    object, similar to dropping a
581 ///    [`ManuallyRooted<T>`][crate::ManuallyRooted] without unrooting it.
582 ///
583 /// 2. A [`Caller`][crate::Caller] provides a rooting scope for the duration of
584 ///    a call from Wasm into a host function. Any objects rooted in a `Caller`
585 ///    will be unrooted after the host function returns. Note that there can be
586 ///    nested `Caller` scopes in the case where Wasm calls a host function,
587 ///    creating the first `Caller` and its rooting scope , and then the host
588 ///    function calls a Wasm function which then calls another host function,
589 ///    creating a second `Caller` and a second rooting scope. This nesting can
590 ///    be arbitrarily deep.
591 ///
592 /// Additionally, if you would like to define finer-grained rooting scopes,
593 /// Wasmtime provides the [`RootScope`][crate::RootScope] type.
594 ///
595 /// Scopes are always nested in a last-in-first-out (LIFO) order. An outer scope
596 /// is never exited (and the `Rooted<T>`s defined within it are never
597 /// automatically unrooted) while an inner scope is still active. All inner
598 /// scopes are exited before their outer scopes.
599 ///
600 /// The following diagram illustrates various rooting scopes over time, how they
601 /// nest, and when their `Rooted<T>`s are automatically unrooted:
602 ///
603 /// ```text
604 /// ----- new Store
605 ///   |
606 ///   |
607 ///   | let a: Rooted<T> = ...;
608 ///   |
609 ///   |
610 ///   | ----- call into Wasm
611 ///   |   |
612 ///   |   |
613 ///   |   | ----- Wasm calls host function F
614 ///   |   |   |
615 ///   |   |   |
616 ///   |   |   | let b: Rooted<T> = ...;
617 ///   |   |   |
618 ///   |   |   |
619 ///   |   |   | ----- F calls into Wasm
620 ///   |   |   |   |
621 ///   |   |   |   |
622 ///   |   |   |   | ----- Wasm call host function G
623 ///   |   |   |   |   |
624 ///   |   |   |   |   |
625 ///   |   |   |   |   | let c: Rooted<T> = ...;
626 ///   |   |   |   |   |
627 ///   |   |   |   |   |
628 ///   |   |   |   | ----- return to Wasm from host function G (unroots `c`)
629 ///   |   |   |   |
630 ///   |   |   |   |
631 ///   |   |   | ----- Wasm returns to F
632 ///   |   |   |
633 ///   |   |   |
634 ///   |   | ----- return from host function F (unroots `b`)
635 ///   |   |
636 ///   |   |
637 ///   | ----- return from Wasm
638 ///   |
639 ///   |
640 ///   | ----- let scope1 = RootScope::new(...);
641 ///   |   |
642 ///   |   |
643 ///   |   | let d: Rooted<T> = ...;
644 ///   |   |
645 ///   |   |
646 ///   |   | ----- let scope2 = RootScope::new(...);
647 ///   |   |   |
648 ///   |   |   |
649 ///   |   |   | let e: Rooted<T> = ...;
650 ///   |   |   |
651 ///   |   |   |
652 ///   |   | ----- drop `scope2` (unroots `e`)
653 ///   |   |
654 ///   |   |
655 ///   | ----- drop `scope1` (unroots `d`)
656 ///   |
657 ///   |
658 /// ----- drop Store (unroots `a`)
659 /// ```
660 ///
661 /// A `Rooted<T>` can be used successfully as long as it is still rooted so, in
662 /// the above diagram, `d` is valid inside `scope2` because `scope2` is wholly
663 /// contained within the scope `d` was rooted within (`scope1`).
664 ///
665 /// See also the documentation for [`RootScope`][crate::RootScope].
666 #[repr(transparent)]
667 pub struct Rooted<T: GcRef> {
668     inner: GcRootIndex,
669     _phantom: marker::PhantomData<T>,
670 }
671 
672 impl<T: GcRef> Clone for Rooted<T> {
673     fn clone(&self) -> Self {
674         Rooted {
675             inner: self.inner,
676             _phantom: marker::PhantomData,
677         }
678     }
679 }
680 
681 impl<T: GcRef> Copy for Rooted<T> {}
682 
683 impl<T: GcRef> Debug for Rooted<T> {
684     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
685         let name = format!("Rooted<{}>", any::type_name::<T>());
686         f.debug_struct(&name).field("inner", &self.inner).finish()
687     }
688 }
689 
690 impl<T: GcRef> RootedGcRefImpl<T> for Rooted<T> {
691     fn get_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Option<&'a VMGcRef> {
692         assert!(
693             self.comes_from_same_store(store),
694             "object used with wrong store"
695         );
696         let index = self.inner.index.as_lifo().unwrap();
697         let entry = store.gc_roots().lifo_roots.get(index)?;
698         if entry.generation == self.inner.generation {
699             Some(&entry.gc_ref)
700         } else {
701             None
702         }
703     }
704 }
705 
706 impl<T: GcRef> Deref for Rooted<T> {
707     type Target = T;
708 
709     fn deref(&self) -> &Self::Target {
710         T::transmute_ref(&self.inner)
711     }
712 }
713 
714 impl<T: GcRef> Rooted<T> {
715     /// Push the given `VMGcRef` onto our LIFO root set.
716     ///
717     /// `gc_ref` should belong to `store`'s heap; failure to uphold this is
718     /// memory safe but will result in general failures down the line such as
719     /// panics or incorrect results.
720     ///
721     /// `gc_ref` should be a GC reference pointing to an instance of the GC type
722     /// that `T` represents. Failure to uphold this invariant is memory safe but
723     /// will result in general incorrectness such as panics and wrong results.
724     pub(crate) fn new(store: &mut AutoAssertNoGc<'_>, gc_ref: VMGcRef) -> Rooted<T> {
725         let id = store.id();
726         let roots = store.gc_roots_mut();
727         let inner = roots.push_lifo_root(id, gc_ref);
728         Rooted {
729             inner,
730             _phantom: marker::PhantomData,
731         }
732     }
733 
734     /// Create a new `Rooted<T>` from a `GcRootIndex`.
735     ///
736     /// Note that `Rooted::from_gc_root_index(my_rooted.index)` is not
737     /// necessarily an identity funciton, as it allows changing the `T` type
738     /// parameter.
739     ///
740     /// The given index should be a LIFO index of a GC reference pointing to an
741     /// instance of the GC type that `T` represents. Failure to uphold this
742     /// invariant is memory safe but will result in general incorrectness such
743     /// as panics and wrong results.
744     pub(crate) fn from_gc_root_index(inner: GcRootIndex) -> Rooted<T> {
745         debug_assert!(inner.index.is_lifo());
746         Rooted {
747             inner,
748             _phantom: marker::PhantomData,
749         }
750     }
751 
752     #[inline]
753     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
754         debug_assert!(self.inner.index.is_lifo());
755         self.inner.comes_from_same_store(store)
756     }
757 
758     /// Create a [`ManuallyRooted<T>`][crate::ManuallyRooted] holding onto the
759     /// same GC object as `self`.
760     ///
761     /// Returns `None` if `self` is used outside of its scope and has therefore
762     /// been unrooted.
763     ///
764     /// This does not unroot `self`, and `self` remains valid until its
765     /// associated scope is exited.
766     ///
767     /// # Panics
768     ///
769     /// Panics if this object is not associate with the given store.
770     ///
771     /// # Example
772     ///
773     /// ```
774     /// # use wasmtime::*;
775     /// # fn _foo() -> Result<()> {
776     /// let mut store = Store::<()>::default();
777     ///
778     /// let y: ManuallyRooted<_> = {
779     ///     // Create a nested rooting scope.
780     ///     let mut scope = RootScope::new(&mut store);
781     ///
782     ///     // `x` is only rooted within this nested scope.
783     ///     let x: Rooted<_> = ExternRef::new(&mut scope, "hello!")?;
784     ///
785     ///     // Extend `x`'s rooting past its scope's lifetime by converting it
786     ///     // to a `ManuallyRooted`.
787     ///     x.to_manually_rooted(&mut scope)?
788     /// };
789     ///
790     /// // Now we can still access the reference outside the scope it was
791     /// // originally defined within.
792     /// let data = y.data(&store)?;
793     /// let data = data.downcast_ref::<&str>().unwrap();
794     /// assert_eq!(*data, "hello!");
795     ///
796     /// // But we have to manually unroot `y`.
797     /// y.unroot(&mut store);
798     /// # Ok(())
799     /// # }
800     /// ```
801     pub fn to_manually_rooted(&self, mut store: impl AsContextMut) -> Result<ManuallyRooted<T>> {
802         self._to_manually_rooted(store.as_context_mut().0)
803     }
804 
805     pub(crate) fn _to_manually_rooted(&self, store: &mut StoreOpaque) -> Result<ManuallyRooted<T>> {
806         let mut store = AutoAssertNoGc::new(store);
807         let gc_ref = self.try_clone_gc_ref(&mut store)?;
808         Ok(ManuallyRooted::new(&mut store, gc_ref))
809     }
810 
811     /// Are these two `Rooted<T>`s the same GC root?
812     ///
813     /// Note that this function can return `false` even when `a` and `b` are
814     /// rooting the same underlying GC object, but the object was rooted
815     /// multiple times (for example in different scopes). Use
816     /// [`Rooted::ref_eq`][crate::Rooted::ref_eq] to test whether these are
817     /// references to the same underlying GC object or not.
818     ///
819     /// # Example
820     ///
821     /// ```
822     /// # use wasmtime::*;
823     /// # fn foo() -> Result<()> {
824     /// let mut store = Store::<()>::default();
825     ///
826     /// let a = ExternRef::new(&mut store, "hello")?;
827     /// let b = a;
828     ///
829     /// // `a` and `b` are the same GC root.
830     /// assert!(Rooted::rooted_eq(a, b));
831     ///
832     /// {
833     ///     let mut scope = RootScope::new(&mut store);
834     ///
835     ///     // `c` is a different GC root, in a different scope, even though it
836     ///     // is rooting the same object.
837     ///     let c = a.to_manually_rooted(&mut scope)?.into_rooted(&mut scope);
838     ///     assert!(!Rooted::rooted_eq(a, c));
839     /// }
840     ///
841     /// let x = ExternRef::new(&mut store, "goodbye")?;
842     ///
843     /// // `a` and `x` are different GC roots, rooting different objects.
844     /// assert!(!Rooted::rooted_eq(a, x));
845     /// # Ok(())
846     /// # }
847     /// ```
848     pub fn rooted_eq(a: Self, b: Self) -> bool {
849         a.inner == b.inner
850     }
851 
852     /// Are these two GC roots referencing the same underlying GC object?
853     ///
854     /// This function will return `true` even when `a` and `b` are different GC
855     /// roots (for example because they were rooted in different scopes) if they
856     /// are rooting the same underlying GC object. To only test whether they are
857     /// the same GC root, and not whether they are rooting the same GC object,
858     /// use [`Rooted::rooted_eq`][crate::Rooted::rooted_eq].
859     ///
860     /// Returns an error if either `a` or `b` has been unrooted, for example
861     /// because the scope it was rooted within has been exited.
862     ///
863     /// Because this method takes any `impl RootedGcRef<T>` arguments, it can be
864     /// used to compare, for example, a `Rooted<T>` and a `ManuallyRooted<T>`.
865     ///
866     /// # Panics
867     ///
868     /// Panics if either `a` or `b` is not associated with the given `store`.
869     ///
870     /// # Example
871     ///
872     /// ```
873     /// # use wasmtime::*;
874     /// # fn foo() -> Result<()> {
875     /// let mut store = Store::<()>::default();
876     ///
877     /// let a = ExternRef::new(&mut store, "hello")?;
878     /// let b = a;
879     ///
880     /// // `a` and `b` are rooting the same object.
881     /// assert!(Rooted::ref_eq(&store, &a, &b)?);
882     ///
883     /// {
884     ///     let mut scope = RootScope::new(&mut store);
885     ///
886     ///     // `c` is a different GC root, in a different scope, but still
887     ///     // rooting the same object.
888     ///     let c = a.to_manually_rooted(&mut scope)?.into_rooted(&mut scope);
889     ///     assert!(!Rooted::ref_eq(&scope, &a, &c)?);
890     /// }
891     ///
892     /// let x = ExternRef::new(&mut store, "goodbye")?;
893     ///
894     /// // `a` and `x` are rooting different objects.
895     /// assert!(!Rooted::ref_eq(&store, &a, &x)?);
896     ///
897     /// // You can also compare `Rooted<T>`s and `ManuallyRooted<T>`s with this
898     /// // function.
899     /// let d = a.to_manually_rooted(&mut store)?;
900     /// assert!(Rooted::ref_eq(&store, &a, &d)?);
901     ///
902     /// d.unroot(&mut store);
903     /// # Ok(())
904     /// # }
905     /// ```
906     pub fn ref_eq(
907         store: impl AsContext,
908         a: &impl RootedGcRef<T>,
909         b: &impl RootedGcRef<T>,
910     ) -> Result<bool> {
911         let store = store.as_context().0;
912         let a = a.try_gc_ref(store)?;
913         let b = b.try_gc_ref(store)?;
914         Ok(a == b)
915     }
916 
917     /// Hash this root.
918     ///
919     /// Note that, similar to `Rooted::rooted_eq`, this only operates on the
920     /// root and *not* the underlying GC reference. That means that two
921     /// different rootings of the same object will hash to different values
922     /// (modulo hash collisions). If this is undesirable, use the
923     /// [`ref_hash`][crate::Rooted::ref_hash] method instead.
924     pub fn rooted_hash<H>(&self, state: &mut H)
925     where
926         H: Hasher,
927     {
928         self.inner.hash(state);
929     }
930 
931     /// Hash the underlying rooted object reference.
932     ///
933     /// Note that, similar to `Rooted::ref_eq`, and operates on the underlying
934     /// rooted GC object reference, not the root. That means that two
935     /// *different* rootings of the same object will hash to the *same*
936     /// value. If this is undesirable, use the
937     /// [`rooted_hash`][crate::Rooted::rooted_hash] method instead.
938     pub fn ref_hash<H>(&self, store: impl AsContext, state: &mut H) -> Result<()>
939     where
940         H: Hasher,
941     {
942         let gc_ref = self.try_gc_ref(store.as_context().0)?;
943         gc_ref.hash(state);
944         Ok(())
945     }
946 
947     /// Cast `self` to a `Rooted<U>`.
948     ///
949     /// It is the caller's responsibility to ensure that `self` is actually a
950     /// `U`. Failure to uphold this invariant will be memory safe but will
951     /// result in general incorrectness such as panics and wrong results.
952     pub(crate) fn unchecked_cast<U: GcRef>(self) -> Rooted<U> {
953         Rooted::from_gc_root_index(self.inner)
954     }
955 }
956 
957 /// Nested rooting scopes.
958 ///
959 /// `RootScope` allows the creation or nested rooting scopes for use with
960 /// [`Rooted<T>`][crate::Rooted]. This allows for fine-grained control over how
961 /// long a set of [`Rooted<T>`][crate::Rooted]s are strongly held alive, giving
962 /// gives you the tools necessary to avoid holding onto GC objects longer than
963 /// necessary. `Rooted<T>`s created within a `RootScope` are automatically
964 /// unrooted when the `RootScope` is dropped. For more details on
965 /// [`Rooted<T>`][crate::Rooted] lifetimes and their interaction with rooting
966 /// scopes, see [`Rooted<T>`][crate::Rooted]'s documentation.
967 ///
968 /// A `RootScope<C>` wraps a `C: AsContextMut` (that is, anything that
969 /// represents exclusive access to a [`Store`][crate::Store]) and in turn
970 /// implements [`AsContext`][crate::AsContext] and
971 /// [`AsContextMut`][crate::AsContextMut] in terms of its underlying
972 /// `C`. Therefore, `RootScope<C>` can be used anywhere you would use the
973 /// underlying `C`, for example in the [`Global::get`][crate::Global::get]
974 /// method. Any `Rooted<T>`s created by a method that a `RootScope<C>` was
975 /// passed as context to are tied to the `RootScope<C>`'s scope and
976 /// automatically unrooted when the scope is dropped.
977 ///
978 /// # Example
979 ///
980 /// ```
981 /// # use wasmtime::*;
982 /// # fn _foo() -> Result<()> {
983 /// let mut store = Store::<()>::default();
984 ///
985 /// let a: Rooted<_>;
986 /// let b: Rooted<_>;
987 /// let c: Rooted<_>;
988 ///
989 /// // Root `a` in the store's scope. It will be rooted for the duration of the
990 /// // store's lifetime.
991 /// a = ExternRef::new(&mut store, 42)?;
992 ///
993 /// // `a` is rooted, so we can access its data successfully.
994 /// assert!(a.data(&store).is_ok());
995 ///
996 /// {
997 ///     let mut scope1 = RootScope::new(&mut store);
998 ///
999 ///     // Root `b` in `scope1`.
1000 ///     b = ExternRef::new(&mut scope1, 36)?;
1001 ///
1002 ///     // Both `a` and `b` are rooted.
1003 ///     assert!(a.data(&scope1).is_ok());
1004 ///     assert!(b.data(&scope1).is_ok());
1005 ///
1006 ///     {
1007 ///         let mut scope2 = RootScope::new(&mut scope1);
1008 ///
1009 ///         // Root `c` in `scope2`.
1010 ///         c = ExternRef::new(&mut scope2, 36)?;
1011 ///
1012 ///         // All of `a`, `b`, and `c` are rooted.
1013 ///         assert!(a.data(&scope2).is_ok());
1014 ///         assert!(b.data(&scope2).is_ok());
1015 ///         assert!(c.data(&scope2).is_ok());
1016 ///
1017 ///         // Drop `scope2`.
1018 ///     }
1019 ///
1020 ///     // Now `a` and `b` are still rooted, but `c` was unrooted when we dropped
1021 ///     // `scope2`.
1022 ///     assert!(a.data(&scope1).is_ok());
1023 ///     assert!(b.data(&scope1).is_ok());
1024 ///     assert!(c.data(&scope1).is_err());
1025 ///
1026 ///     // Drop `scope1`.
1027 /// }
1028 ///
1029 /// // And now only `a` is still rooted. Both `b` and `c` were unrooted when we
1030 /// // dropped their respective rooting scopes.
1031 /// assert!(a.data(&store).is_ok());
1032 /// assert!(b.data(&store).is_err());
1033 /// assert!(c.data(&store).is_err());
1034 /// # Ok(())
1035 /// # }
1036 /// ```
1037 pub struct RootScope<C>
1038 where
1039     C: AsContextMut,
1040 {
1041     store: C,
1042     scope: usize,
1043 }
1044 
1045 impl<C> Drop for RootScope<C>
1046 where
1047     C: AsContextMut,
1048 {
1049     fn drop(&mut self) {
1050         self.store.as_context_mut().0.exit_gc_lifo_scope(self.scope);
1051     }
1052 }
1053 
1054 impl<C> RootScope<C>
1055 where
1056     C: AsContextMut,
1057 {
1058     // NB: we MUST NOT expose a method like
1059     //
1060     //     pub fn store(&mut self) -> &mut Store { ... }
1061     //
1062     // because callers could do treacherous things like
1063     //
1064     //     let scope1 = RootScope::new(&mut store1);
1065     //     let scope2 = RootScope::new(&mut store2);
1066     //     std::mem::swap(scope1.store(), scope2.store());
1067     //
1068     // and then we would start truncate the store's GC root set's LIFO roots to
1069     // the wrong lengths.
1070     //
1071     // Instead, we just implement `AsContext[Mut]` for `RootScope`.
1072 
1073     /// Construct a new scope for rooting GC objects.
1074     ///
1075     /// # Example
1076     ///
1077     /// ```
1078     /// # use wasmtime::*;
1079     /// let mut store = Store::<()>::default();
1080     ///
1081     /// {
1082     ///     let mut scope = RootScope::new(&mut store);
1083     ///
1084     ///     // Temporarily root GC objects in this nested rooting scope...
1085     /// }
1086     /// ```
1087     pub fn new(store: C) -> Self {
1088         let scope = store.as_context().0.gc_roots().enter_lifo_scope();
1089         RootScope { store, scope }
1090     }
1091 
1092     fn gc_roots(&mut self) -> &mut RootSet {
1093         self.store.as_context_mut().0.gc_roots_mut()
1094     }
1095 
1096     fn lifo_roots(&mut self) -> &mut Vec<LifoRoot> {
1097         &mut self.gc_roots().lifo_roots
1098     }
1099 
1100     /// Reserve enough capacity for `additional` GC roots in this scope.
1101     ///
1102     /// # Example
1103     ///
1104     /// ```
1105     /// # use wasmtime::*;
1106     /// let mut store = Store::<()>::default();
1107     ///
1108     /// {
1109     ///     let mut scope = RootScope::new(&mut store);
1110     ///
1111     ///     // Ensure we have enough storage pre-allocated to root five GC
1112     ///     // references inside this scope without any underlying reallocation.
1113     ///     scope.reserve(5);
1114     ///
1115     ///     // ...
1116     /// }
1117     /// ```
1118     pub fn reserve(&mut self, additional: usize) {
1119         self.lifo_roots().reserve(additional);
1120     }
1121 }
1122 
1123 impl<T> AsContext for RootScope<T>
1124 where
1125     T: AsContextMut,
1126 {
1127     type Data = T::Data;
1128 
1129     fn as_context(&self) -> crate::StoreContext<'_, Self::Data> {
1130         self.store.as_context()
1131     }
1132 }
1133 
1134 impl<T> AsContextMut for RootScope<T>
1135 where
1136     T: AsContextMut,
1137 {
1138     fn as_context_mut(&mut self) -> crate::StoreContextMut<'_, Self::Data> {
1139         self.store.as_context_mut()
1140     }
1141 }
1142 
1143 /// A rooted reference to a garbage-collected `T` with arbitrary lifetime.
1144 ///
1145 /// A `ManuallyRooted<T>` is a strong handle to a garbage-collected `T`,
1146 /// preventing its referent (and anything else transitively referenced) from
1147 /// being collected by the GC until [`unroot`][crate::ManuallyRooted::unroot] is
1148 /// explicitly called.
1149 ///
1150 /// The primary way to create a `ManuallyRooted<T>` is to promote a temporary
1151 /// `Rooted<T>` into a `ManuallyRooted<T>` via its
1152 /// [`to_manually_rooted`][crate::Rooted::to_manually_rooted] method.
1153 ///
1154 /// `ManuallyRooted<T>` dereferences to its underlying `T`, allowing you to call
1155 /// `T`'s methods.
1156 ///
1157 /// # Example
1158 ///
1159 /// ```
1160 /// # use wasmtime::*;
1161 /// # fn _foo() -> Result<()> {
1162 /// let mut store = Store::<Option<ManuallyRooted<ExternRef>>>::default();
1163 ///
1164 /// // Create our `ManuallyRooted` in a nested scope to avoid rooting it for
1165 /// // the duration of the store's lifetime.
1166 /// let x = {
1167 ///     let mut scope = RootScope::new(&mut store);
1168 ///     let x = ExternRef::new(&mut scope, 1234)?;
1169 ///     x.to_manually_rooted(&mut scope)?
1170 /// };
1171 ///
1172 /// // Place `x` into our store.
1173 /// *store.data_mut() = Some(x);
1174 ///
1175 /// // Do a bunch stuff that may or may not access, replace, or take `x`...
1176 ///
1177 /// // At any time, in any arbitrary scope, we can remove `x` from the store
1178 /// // and unroot it:
1179 /// if let Some(x) = store.data_mut().take() {
1180 ///     x.unroot(&mut store);
1181 /// }
1182 /// # Ok(())
1183 /// # }
1184 /// ```
1185 ///
1186 /// # Differences Between `ManuallyRooted<T>` and `Rooted<T>`
1187 ///
1188 /// While `ManuallyRooted<T>` can have arbitrary lifetimes, it requires manual
1189 /// unrooting. This is in contrast to [`Rooted<T>`][crate::Rooted] which is
1190 /// restricted to strictly last-in-first-out (LIFO, aka stack order) lifetimes,
1191 /// but comes with automatic unrooting.
1192 ///
1193 /// | Type                                         | Supported Lifetimes         | Unrooting |
1194 /// |----------------------------------------------|-----------------------------|-----------|
1195 /// | [`Rooted<T>`][crate::Rooted]                 | Strictly LIFO / stack order | Automatic |
1196 /// | [`ManuallyRooted<T>`][crate::ManuallyRooted] | Arbitrary                   | Manual    |
1197 ///
1198 /// `Rooted<T>` should suffice for most use cases, and provides better
1199 /// ergonomics, but `ManuallyRooted<T>` exists as a fully-general escape hatch.
1200 ///
1201 /// # Manual Unrooting
1202 ///
1203 /// Failure to explicitly call [`unroot`][crate::ManuallyRooted::unroot] (or
1204 /// another method that consumes `self` and unroots the reference, such as
1205 /// [`into_rooted`][crate::ManuallyRooted::into_rooted]) will leak the
1206 /// underlying GC object, preventing it from being garbage collected until its
1207 /// owning [`Store`][crate::Store] is dropped. That means all of the following
1208 /// will result in permanently rooting the underlying GC object:
1209 ///
1210 /// * Implicitly dropping a `ManuallyRooted<T>`:
1211 ///
1212 ///   ```no_run
1213 ///   # use wasmtime::*;
1214 ///   # let get_manually_rooted = || -> ManuallyRooted<ExternRef> { todo!() };
1215 ///   {
1216 ///       let perma_root: ManuallyRooted<_> = get_manually_rooted();
1217 ///
1218 ///       // `perma_root` is implicitly dropped at the end of its scope,
1219 ///       // permanently rooting/leaking its referent.
1220 ///   }
1221 ///   ```
1222 ///
1223 /// * Explicitly dropping a `ManuallyRooted<T>`: `drop(my_manually_rooted)`.
1224 ///
1225 /// * Forgetting a `ManuallyRooted<T>`: `std::mem::forget(my_manually_rooted)`.
1226 ///
1227 /// * Inserting a `ManuallyRooted<T>` into a `std::sync::Arc` or `std::rc::Rc`
1228 ///   cycle.
1229 ///
1230 /// * Etc...
1231 ///
1232 /// Wasmtime does *not* assert that a `ManuallyRooted<T>` is unrooted on `Drop`,
1233 /// or otherwise raise a panic, log a warning, or etc... on failure to manually
1234 /// unroot. Sometimes leaking is intentional and desirable, particularly when
1235 /// dealing with short-lived [`Store`][crate::Store]s where unrooting would just
1236 /// be busy work since the whole store is about to be dropped.
1237 #[repr(transparent)] // NB: the C API relies on this
1238 pub struct ManuallyRooted<T>
1239 where
1240     T: GcRef,
1241 {
1242     inner: GcRootIndex,
1243     _phantom: marker::PhantomData<T>,
1244 }
1245 
1246 const _: () = {
1247     use crate::{AnyRef, ExternRef};
1248 
1249     // NB: these match the C API which should also be updated if this changes
1250     assert!(mem::size_of::<ManuallyRooted<AnyRef>>() == 16);
1251     assert!(mem::align_of::<ManuallyRooted<AnyRef>>() == 8);
1252     assert!(mem::size_of::<ManuallyRooted<ExternRef>>() == 16);
1253     assert!(mem::align_of::<ManuallyRooted<ExternRef>>() == 8);
1254 };
1255 
1256 impl<T: GcRef> Debug for ManuallyRooted<T> {
1257     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1258         let name = format!("ManuallyRooted<{}>", any::type_name::<T>());
1259         f.debug_struct(&name).field("inner", &self.inner).finish()
1260     }
1261 }
1262 
1263 impl<T: GcRef> Deref for ManuallyRooted<T> {
1264     type Target = T;
1265 
1266     fn deref(&self) -> &Self::Target {
1267         T::transmute_ref(&self.inner)
1268     }
1269 }
1270 
1271 impl<T> ManuallyRooted<T>
1272 where
1273     T: GcRef,
1274 {
1275     /// Construct a new manually-rooted GC root.
1276     ///
1277     /// `gc_ref` should belong to `store`'s heap; failure to uphold this is
1278     /// memory safe but will result in general failures down the line such as
1279     /// panics or incorrect results.
1280     ///
1281     /// `gc_ref` should be a GC reference pointing to an instance of the GC type
1282     /// that `T` represents. Failure to uphold this invariant is memory safe but
1283     /// will result in general incorrectness such as panics and wrong results.
1284     pub(crate) fn new(store: &mut AutoAssertNoGc<'_>, gc_ref: VMGcRef) -> Self {
1285         let id = store.gc_roots_mut().manually_rooted.alloc(gc_ref);
1286         ManuallyRooted {
1287             inner: GcRootIndex {
1288                 store_id: store.id(),
1289                 generation: 0,
1290                 index: PackedIndex::new_manual(id),
1291             },
1292             _phantom: marker::PhantomData,
1293         }
1294     }
1295 
1296     #[inline]
1297     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
1298         debug_assert!(self.inner.index.is_manual());
1299         self.inner.comes_from_same_store(store)
1300     }
1301 
1302     /// Clone this `ManuallyRooted`.
1303     ///
1304     /// Does not consume or unroot `self`: both `self` and the new
1305     /// `ManuallyRooted` return value will need to be manually unrooted.
1306     ///
1307     /// # Panics
1308     ///
1309     /// Panics if `self` is not associated with the given `store`.
1310     ///
1311     /// # Example
1312     ///
1313     /// ```
1314     /// # use wasmtime::*;
1315     /// # fn _foo() -> Result<()> {
1316     /// let mut store = Store::<Vec<ManuallyRooted<ExternRef>>>::default();
1317     ///
1318     /// // Create our `ManuallyRooted` in a nested scope to avoid rooting it for
1319     /// // the duration of the store's lifetime.
1320     /// let x = {
1321     ///     let mut scope = RootScope::new(&mut store);
1322     ///     let x = ExternRef::new(&mut scope, 1234)?;
1323     ///     x.to_manually_rooted(&mut scope)?
1324     /// };
1325     ///
1326     /// // Push five clones of `x` into our store.
1327     /// for _ in 0..5 {
1328     ///     let x_clone = x.clone(&mut store);
1329     ///     store.data_mut().push(x_clone);
1330     /// }
1331     /// # Ok(())
1332     /// # }
1333     /// ```
1334     pub fn clone(&self, mut store: impl AsContextMut) -> Self {
1335         self._clone(store.as_context_mut().0)
1336     }
1337 
1338     pub(crate) fn _clone(&self, store: &mut StoreOpaque) -> Self {
1339         let mut store = AutoAssertNoGc::new(store);
1340         let gc_ref = self
1341             .clone_gc_ref(&mut store)
1342             .expect("ManuallyRooted always has a gc ref");
1343         Self::new(&mut store, gc_ref)
1344     }
1345 
1346     /// Unroot this GC object.
1347     ///
1348     /// Failure to call this method will result in the GC object, and anything
1349     /// it transitively references, being kept alive (aka "leaking") for the
1350     /// entirety of the store's lifetime.
1351     ///
1352     /// See the type-level docs for example usage.
1353     pub fn unroot(self, mut store: impl AsContextMut) {
1354         self._unroot(store.as_context_mut().0)
1355     }
1356 
1357     pub(crate) fn _unroot(self, store: &mut StoreOpaque) {
1358         assert!(
1359             self.comes_from_same_store(store),
1360             "object used with wrong store"
1361         );
1362 
1363         let mut store = AutoAssertNoGc::new(store);
1364         let id = self.inner.index.as_manual().unwrap();
1365         let roots = store.gc_roots_mut();
1366         let gc_ref = roots.manually_rooted.dealloc(id);
1367         store.unwrap_gc_store_mut().drop_gc_ref(gc_ref);
1368     }
1369 
1370     /// Clone this `ManuallyRooted<T>` into a `Rooted<T>`.
1371     ///
1372     /// This operation does not consume or unroot this `ManuallyRooted<T>`.
1373     ///
1374     /// The underlying GC object is re-rooted in the given context's scope. The
1375     /// resulting `Rooted<T>` is only valid during the given context's
1376     /// scope. See the [`Rooted<T>`][crate::Rooted] documentation for more
1377     /// details on rooting scopes.
1378     ///
1379     /// This operation does not consume or unroot this `ManuallyRooted<T>`.
1380     ///
1381     /// # Panics
1382     ///
1383     /// Panics if this object is not associated with the given context's store.
1384     ///
1385     /// # Example
1386     ///
1387     /// ```
1388     /// # use wasmtime::*;
1389     /// # fn _foo() -> Result<()> {
1390     /// let mut store = Store::<()>::default();
1391     ///
1392     /// let root1: Rooted<_>;
1393     ///
1394     /// let manual = {
1395     ///     let mut scope = RootScope::new(&mut store);
1396     ///     root1 = ExternRef::new(&mut scope, 1234)?;
1397     ///     root1.to_manually_rooted(&mut scope)?
1398     /// };
1399     ///
1400     /// // `root1` is no longer accessible because it was unrooted when `scope`
1401     /// // was dropped.
1402     /// assert!(root1.data(&store).is_err());
1403     ///
1404     /// // But we can re-root `manual` into this scope.
1405     /// let root2 = manual.to_rooted(&mut store);
1406     /// assert!(root2.data(&store).is_ok());
1407     ///
1408     /// // And we also still have access to `manual` and we still have to
1409     /// // manually unroot it.
1410     /// assert!(manual.data(&store).is_ok());
1411     /// manual.unroot(&mut store);
1412     /// # Ok(())
1413     /// # }
1414     /// ```
1415     pub fn to_rooted(&self, mut context: impl AsContextMut) -> Rooted<T> {
1416         self._to_rooted(context.as_context_mut().0)
1417     }
1418 
1419     pub(crate) fn _to_rooted(&self, store: &mut StoreOpaque) -> Rooted<T> {
1420         assert!(
1421             self.comes_from_same_store(store),
1422             "object used with wrong store"
1423         );
1424         let mut store = AutoAssertNoGc::new(store);
1425         let gc_ref = self.clone_gc_ref(&mut store).unwrap();
1426         Rooted::new(&mut store, gc_ref)
1427     }
1428 
1429     /// Convert this `ManuallyRooted<T>` into a `Rooted<T>`.
1430     ///
1431     /// The underlying GC object is re-rooted in the given context's scope. The
1432     /// resulting `Rooted<T>` is only valid during the given context's
1433     /// scope. See the [`Rooted<T>`][crate::Rooted] documentation for more
1434     /// details on rooting scopes.
1435     ///
1436     /// This operation consumes and unroots this `ManuallyRooted<T>`.
1437     ///
1438     /// # Panics
1439     ///
1440     /// Panics if this object is not associate with the given context's store.
1441     ///
1442     /// # Example
1443     ///
1444     /// ```
1445     /// # use wasmtime::*;
1446     /// # fn _foo() -> Result<()> {
1447     /// let mut store = Store::<()>::default();
1448     ///
1449     /// let root1: Rooted<_>;
1450     ///
1451     /// let manual = {
1452     ///     let mut scope = RootScope::new(&mut store);
1453     ///     root1 = ExternRef::new(&mut scope, 1234)?;
1454     ///     root1.to_manually_rooted(&mut scope)?
1455     /// };
1456     ///
1457     /// // `root1` is no longer accessible because it was unrooted when `scope`
1458     /// // was dropped.
1459     /// assert!(root1.data(&store).is_err());
1460     ///
1461     /// // But we can re-root `manual` into this scope.
1462     /// let root2 = manual.into_rooted(&mut store);
1463     /// assert!(root2.data(&store).is_ok());
1464     ///
1465     /// // `manual` was consumed by the `into_rooted` call, and we no longer
1466     /// // have access to it, nor need to manually unroot it.
1467     /// # Ok(())
1468     /// # }
1469     /// ```
1470     pub fn into_rooted(self, mut context: impl AsContextMut) -> Rooted<T> {
1471         self._into_rooted(context.as_context_mut().0)
1472     }
1473 
1474     pub(crate) fn _into_rooted(self, store: &mut StoreOpaque) -> Rooted<T> {
1475         assert!(
1476             self.comes_from_same_store(store),
1477             "object used with wrong store"
1478         );
1479         let rooted = self._to_rooted(store);
1480         self._unroot(store);
1481         rooted
1482     }
1483 
1484     /// Are these two GC roots referencing the same underlying GC object?
1485     ///
1486     /// This function will return `true` even when `a` and `b` are different GC
1487     /// roots (for example because they were rooted in different scopes) if they
1488     /// are rooting the same underlying GC object.
1489     ///
1490     /// Because this method takes any `impl RootedGcRef<T>` arguments, it can be
1491     /// used to compare, for example, a `Rooted<T>` and a `ManuallyRooted<T>`.
1492     ///
1493     /// # Panics
1494     ///
1495     /// Panics if either `a` or `b` is not associated with the given `store`.
1496     ///
1497     /// # Example
1498     ///
1499     /// ```
1500     /// # use wasmtime::*;
1501     /// # fn foo() -> Result<()> {
1502     /// let mut store = Store::<()>::default();
1503     ///
1504     /// let a = ExternRef::new_manually_rooted(&mut store, "hello")?;
1505     /// let b = a.clone(&mut store);
1506     ///
1507     /// // `a` and `b` are rooting the same object.
1508     /// assert!(ManuallyRooted::ref_eq(&store, &a, &b)?);
1509     ///
1510     /// {
1511     ///     let mut scope = RootScope::new(&mut store);
1512     ///
1513     ///     // `c` is a different GC root, is in a different scope, and is a
1514     ///     // `Rooted<T>` instead of a `ManuallyRooted<T>`, but is still rooting
1515     ///     // the same object.
1516     ///     let c = a.to_rooted(&mut scope);
1517     ///     assert!(ManuallyRooted::ref_eq(&scope, &a, &c)?);
1518     /// }
1519     ///
1520     /// let x = ExternRef::new_manually_rooted(&mut store, "goodbye")?;
1521     ///
1522     /// // `a` and `x` are rooting different objects.
1523     /// assert!(!ManuallyRooted::ref_eq(&store, &a, &x)?);
1524     ///
1525     /// a.unroot(&mut store);
1526     /// b.unroot(&mut store);
1527     /// x.unroot(&mut store);
1528     /// # Ok(())
1529     /// # }
1530     /// ```
1531     pub fn ref_eq(
1532         store: impl AsContext,
1533         a: &impl RootedGcRef<T>,
1534         b: &impl RootedGcRef<T>,
1535     ) -> Result<bool> {
1536         Rooted::ref_eq(store, a, b)
1537     }
1538 
1539     /// Hash this root.
1540     ///
1541     /// Note that, similar to `Rooted::rooted_eq`, this only operates on the
1542     /// root and *not* the underlying GC reference. That means that two
1543     /// different rootings of the same object will hash to different values
1544     /// (modulo hash collisions). If this is undesirable, use the
1545     /// [`ref_hash`][crate::ManuallyRooted::ref_hash] method instead.
1546     pub fn rooted_hash<H>(&self, state: &mut H)
1547     where
1548         H: Hasher,
1549     {
1550         self.inner.hash(state);
1551     }
1552 
1553     /// Hash the underlying rooted object reference.
1554     ///
1555     /// Note that, similar to `Rooted::ref_eq`, and operates on the underlying
1556     /// rooted GC object reference, not the root. That means that two
1557     /// *different* rootings of the same object will hash to the *same*
1558     /// value. If this is undesirable, use the
1559     /// [`rooted_hash`][crate::Rooted::rooted_hash] method instead.
1560     pub fn ref_hash<H>(&self, store: impl AsContext, state: &mut H)
1561     where
1562         H: Hasher,
1563     {
1564         let gc_ref = self
1565             .get_gc_ref(store.as_context().0)
1566             .expect("ManuallyRooted's get_gc_ref is infallible");
1567         gc_ref.hash(state);
1568     }
1569 
1570     #[doc(hidden)]
1571     pub fn into_parts_for_c_api(self) -> (NonZeroU64, u32, u32) {
1572         (
1573             self.inner.store_id.as_raw(),
1574             self.inner.generation,
1575             self.inner.index.0,
1576         )
1577     }
1578 
1579     #[doc(hidden)]
1580     pub unsafe fn from_raw_parts_for_c_api(a: NonZeroU64, b: u32, c: u32) -> ManuallyRooted<T> {
1581         ManuallyRooted {
1582             inner: GcRootIndex {
1583                 store_id: StoreId::from_raw(a),
1584                 generation: b,
1585                 index: PackedIndex(c),
1586             },
1587             _phantom: marker::PhantomData,
1588         }
1589     }
1590 
1591     /// Cast `self` to a `ManuallyRooted<U>`.
1592     ///
1593     /// It is the caller's responsibility to ensure that `self` is actually a
1594     /// `U`. Failure to uphold this invariant will be memory safe but will
1595     /// result in general incorrectness such as panics and wrong results.
1596     pub(crate) fn unchecked_cast<U: GcRef>(self) -> ManuallyRooted<U> {
1597         let u = ManuallyRooted {
1598             inner: self.inner,
1599             _phantom: core::marker::PhantomData,
1600         };
1601         core::mem::forget(self);
1602         u
1603     }
1604 }
1605 
1606 impl<T: GcRef> RootedGcRefImpl<T> for ManuallyRooted<T> {
1607     fn get_gc_ref<'a>(&self, store: &'a StoreOpaque) -> Option<&'a VMGcRef> {
1608         assert!(
1609             self.comes_from_same_store(store),
1610             "object used with wrong store"
1611         );
1612 
1613         let id = self.inner.index.as_manual().unwrap();
1614         store.gc_roots().manually_rooted.get(id)
1615     }
1616 }
1617 
1618 #[cfg(test)]
1619 mod tests {
1620     use crate::ExternRef;
1621 
1622     use super::*;
1623 
1624     #[test]
1625     fn sizes() {
1626         // Try to keep tabs on the size of these things. Don't want them growing
1627         // unintentionally.
1628         assert_eq!(std::mem::size_of::<Rooted<ExternRef>>(), 16);
1629         assert_eq!(std::mem::size_of::<ManuallyRooted<ExternRef>>(), 16);
1630     }
1631 }
1632