Skip to main content

wry_bindgen_runtime/wire/
js_ref.rs

1use super::encode::{BinaryDecode, BinaryEncode, EncodeTypeDef, JsRefEncode, TypeDef};
2use super::ipc::{DecodeError, DecodedData, EncodedData};
3
4#[repr(transparent)]
5#[derive(Clone, Copy, PartialEq, Eq, Hash)]
6pub struct JsRef(u64);
7
8impl JsRef {
9    /// The `null` JS value constant.
10    pub const NULL: Self = Self(129);
11
12    /// The `undefined` JS value constant.
13    pub const UNDEFINED: Self = Self(128);
14
15    /// The `true` JS value constant.
16    pub const TRUE: Self = Self(130);
17
18    /// The `false` JS value constant.
19    pub const FALSE: Self = Self(131);
20
21    #[inline]
22    pub const fn is_special_value(self) -> bool {
23        self.0 >= Self::UNDEFINED.0 && self.0 <= Self::FALSE.0
24    }
25
26    #[inline]
27    pub const fn is_owned_heap_ref(self) -> bool {
28        self.0 > Self::FALSE.0
29    }
30
31    #[inline]
32    pub const fn into_abi(self) -> u32 {
33        self.0 as u32
34    }
35
36    #[inline]
37    pub const fn from_abi(abi: u32) -> Self {
38        Self(abi as u64)
39    }
40
41    /// Reserve a handle to the next borrowed JS reference.
42    ///
43    /// Borrowed references occupy the borrow stack (indices 1-127) rather than a
44    /// heap slot; JS puts the value on its borrow stack without sending an id, so
45    /// Rust syncs by reserving the matching handle here.
46    #[inline]
47    pub fn next_borrowed_ref() -> Self {
48        crate::batch::with_runtime(|rt| rt.next_borrowed_ref())
49    }
50
51    /// Release this JS heap object.
52    #[inline]
53    pub fn drop_js_object(self) {
54        crate::batch::drop_js_object(self);
55    }
56
57    /// Dispose the JS wrapper for the Rust callback behind this reference.
58    #[inline]
59    pub fn dispose_js_rust_function(self) {
60        crate::batch::dispose_js_rust_function(self);
61    }
62
63    /// Mark the JS wrapper for the Rust callback behind this reference as
64    /// unusable.
65    #[inline]
66    pub fn invalidate_js_rust_function(self) {
67        crate::batch::dispose_js_rust_function(self);
68    }
69
70    #[inline]
71    pub(crate) const fn from_raw(raw: u64) -> Self {
72        Self(raw)
73    }
74
75    #[inline]
76    pub(crate) const fn raw(self) -> u64 {
77        self.0
78    }
79}
80
81impl EncodeTypeDef for JsRef {
82    fn encode_type_def(type_def: &mut TypeDef) {
83        type_def.heap_ref();
84    }
85}
86
87impl BinaryEncode for JsRef {
88    fn encode(self, encoder: &mut EncodedData) {
89        self.0.encode(encoder);
90    }
91}
92
93impl BinaryDecode for JsRef {
94    fn decode(_decoder: &mut DecodedData) -> Result<Self, DecodeError> {
95        // JS heap references are sent out-of-band in the deferred heap-ref
96        // batch. Decoding reserves the next Rust-side ID for that value.
97        Ok(crate::batch::with_runtime(|rt| {
98            rt.get_next_inbound_js_ref()
99        }))
100    }
101}
102
103impl JsRefEncode for JsRef {
104    fn js_ref(&self) -> JsRef {
105        *self
106    }
107}