Skip to main content

script/dom/bindings/
cell.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::ops::{Deref, DerefMut};
6
7use atomic_refcell::{AtomicRefCell, AtomicRefMut};
8use js::context::NoGC;
9
10/// A borrowed mutable reference to the contents of an AtomicRefCell,
11/// anchored to the lifetime of a [NoGC] token.
12#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
13pub(crate) struct AtomicRefMutNoGC<'a, T> {
14    ref_mut: AtomicRefMut<'a, T>,
15    _anchor: &'a NoGC,
16}
17
18pub(crate) trait AtomicSafeBorrowMut {
19    type Target;
20
21    /// A version of [DomRefCell::safe_borrow_mut] for [AtomicRefCell].
22    /// The resulting borrowed mutable reference statically guarantees
23    /// that no garbage collection can occur while the borrow is live.
24    fn safe_borrow_mut<'a: 'b, 'b>(&'a self, no_gc: &'b NoGC)
25    -> AtomicRefMutNoGC<'b, Self::Target>;
26}
27
28impl<T> AtomicSafeBorrowMut for AtomicRefCell<T> {
29    type Target = T;
30    fn safe_borrow_mut<'a: 'b, 'b>(
31        &'a self,
32        no_gc: &'b NoGC,
33    ) -> AtomicRefMutNoGC<'b, Self::Target> {
34        AtomicRefMutNoGC {
35            ref_mut: self.borrow_mut(),
36            _anchor: no_gc,
37        }
38    }
39}
40
41impl<'a, T> Deref for AtomicRefMutNoGC<'a, T> {
42    type Target = T;
43    fn deref(&self) -> &Self::Target {
44        &self.ref_mut
45    }
46}
47
48impl<'a, T> DerefMut for AtomicRefMutNoGC<'a, T> {
49    fn deref_mut(&mut self) -> &mut Self::Target {
50        &mut self.ref_mut
51    }
52}