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.
12pub(crate) struct AtomicRefMutNoGC<'a, T> {
13    ref_mut: AtomicRefMut<'a, T>,
14    _anchor: &'a NoGC,
15}
16
17pub(crate) trait AtomicSafeBorrowMut {
18    type Target;
19
20    /// A version of [DomRefCell::safe_borrow_mut] for [AtomicRefCell].
21    /// The resulting borrowed mutable reference statically guarantees
22    /// that no garbage collection can occur while the borrow is live.
23    fn safe_borrow_mut<'a: 'b, 'b>(&'a self, no_gc: &'b NoGC)
24    -> AtomicRefMutNoGC<'b, Self::Target>;
25}
26
27impl<T> AtomicSafeBorrowMut for AtomicRefCell<T> {
28    type Target = T;
29    fn safe_borrow_mut<'a: 'b, 'b>(
30        &'a self,
31        no_gc: &'b NoGC,
32    ) -> AtomicRefMutNoGC<'b, Self::Target> {
33        AtomicRefMutNoGC {
34            ref_mut: self.borrow_mut(),
35            _anchor: no_gc,
36        }
37    }
38}
39
40impl<'a, T> Deref for AtomicRefMutNoGC<'a, T> {
41    type Target = T;
42    fn deref(&self) -> &Self::Target {
43        &self.ref_mut
44    }
45}
46
47impl<'a, T> DerefMut for AtomicRefMutNoGC<'a, T> {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        &mut self.ref_mut
50    }
51}