script_bindings/
realms.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::ptr::NonNull;
6
7use js::jsapi::{GetCurrentRealmOrNull, JSAutoRealm};
8use js::realm::{AutoRealm, CurrentRealm};
9
10use crate::DomTypes;
11use crate::interfaces::GlobalScopeHelpers;
12use crate::reflector::DomObject;
13use crate::script_runtime::JSContext;
14
15pub struct AlreadyInRealm(());
16
17impl AlreadyInRealm {
18    #![expect(unsafe_code)]
19    pub fn assert<D: DomTypes>() -> AlreadyInRealm {
20        unsafe {
21            assert!(!GetCurrentRealmOrNull(*D::GlobalScope::get_cx()).is_null());
22        }
23        AlreadyInRealm(())
24    }
25
26    pub fn assert_for_cx(cx: JSContext) -> AlreadyInRealm {
27        unsafe {
28            assert!(!GetCurrentRealmOrNull(*cx).is_null());
29        }
30        AlreadyInRealm(())
31    }
32}
33
34impl<'a, 'b> From<&'a mut CurrentRealm<'b>> for AlreadyInRealm {
35    fn from(_: &'a mut CurrentRealm<'b>) -> AlreadyInRealm {
36        AlreadyInRealm(())
37    }
38}
39
40#[derive(Clone, Copy)]
41pub enum InRealm<'a> {
42    Already(&'a AlreadyInRealm),
43    Entered(&'a JSAutoRealm),
44}
45
46impl<'a> From<&'a AlreadyInRealm> for InRealm<'a> {
47    fn from(token: &'a AlreadyInRealm) -> InRealm<'a> {
48        InRealm::already(token)
49    }
50}
51
52impl<'a> From<&'a JSAutoRealm> for InRealm<'a> {
53    fn from(token: &'a JSAutoRealm) -> InRealm<'a> {
54        InRealm::entered(token)
55    }
56}
57
58impl InRealm<'_> {
59    pub fn already(token: &AlreadyInRealm) -> InRealm<'_> {
60        InRealm::Already(token)
61    }
62
63    pub fn entered(token: &JSAutoRealm) -> InRealm<'_> {
64        InRealm::Entered(token)
65    }
66}
67
68pub fn enter_realm<D: DomTypes>(object: &impl DomObject) -> JSAutoRealm {
69    JSAutoRealm::new(
70        *D::GlobalScope::get_cx(),
71        object.reflector().get_jsobject().get(),
72    )
73}
74
75pub fn enter_auto_realm<'cx, D: DomTypes>(
76    cx: &'cx mut js::context::JSContext,
77    object: &impl DomObject,
78) -> AutoRealm<'cx> {
79    AutoRealm::new(
80        cx,
81        NonNull::new(object.reflector().get_jsobject().get()).unwrap(),
82    )
83}