script_bindings/
realms.rs1use 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}