diff --git a/mozjs/src/gc/root.rs b/mozjs/src/gc/root.rs index d9ee964b33..8a1520534b 100644 --- a/mozjs/src/gc/root.rs +++ b/mozjs/src/gc/root.rs @@ -4,6 +4,7 @@ use std::ops::Deref; use std::ptr; use crate::jsapi::{jsid, JSContext, JSFunction, JSObject, JSScript, JSString, Symbol, Value, JS}; +use mozjs_sys::jsapi::JS::Heap; use mozjs_sys::jsgc::{RootKind, Rooted}; use crate::jsapi::Handle as RawHandle; @@ -197,6 +198,23 @@ impl<'a, T> Deref for Handle<'a, T> { } } +/// Allows safe and ergonomic conversion of a rooted `Heap` into a `HandleValue`. +/// +/// This avoids repeating unsafe `from_raw` conversions at call sites, +/// and ensures the lifetime is tied to the borrow of the `Heap`. +pub trait AsHandleValue<'a> { + fn as_handle_value(&'a self) -> HandleValue<'a>; +} + +impl<'a> AsHandleValue<'a> for Heap { + #[allow(unsafe_code)] + fn as_handle_value(&'a self) -> HandleValue<'a> { + // SAFETY: The value is rooted and kept alive by the `Heap`, + // making it safe to convert to a `HandleValue` and pass to SpiderMonkey. + unsafe { HandleValue::from_raw(self.handle()) } + } +} + impl<'a, T> MutableHandle<'a, T> { pub unsafe fn from_marked_location(ptr: *mut T) -> Self { MutableHandle::new(&mut *ptr)