Add AsHandleValue trait to Heap<Value> and make Heap values rooted (#38024)

Encapsulates the unsafe conversion from Heap<Value> to HandleValue<'a>,
and reducing repetitive unsafe code at call.

fix #37258
This commit is contained in:
Taym Haddadi 2025-08-04 18:42:53 +02:00 committed by GitHub
parent 9416251cab
commit 04ec710e60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 204 additions and 146 deletions

View file

@ -30,7 +30,8 @@ use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::{mem, ptr};
use js::jsapi::{JSObject, JSTracer};
use js::jsapi::{Heap, JSObject, JSTracer, Value};
use js::rust::HandleValue;
use layout_api::TrustedNodeAddress;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
pub(crate) use script_bindings::root::*;
@ -409,3 +410,21 @@ where
&*(slice as *const [Dom<T>] as *const [LayoutDom<T>])
}
}
/// Converts a rooted `Heap<Value>` into a `HandleValue`.
///
/// This is only safe if the `Heap` is rooted (e.g., held inside a `Dom`-managed struct),
/// and the `#[must_root]` crown lint is active to enforce rooting at compile time.
/// Avoids repeating unsafe `from_raw` calls at each usage site.
pub trait AsHandleValue<'a> {
fn as_handle_value(&'a self) -> HandleValue<'a>;
}
impl<'a> AsHandleValue<'a> for Heap<Value> {
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
fn as_handle_value(&'a self) -> HandleValue<'a> {
// SAFETY: `self` is assumed to be rooted, and `handle()` ties
// the lifetime to `&self`, which the compiler can enforce.
unsafe { HandleValue::from_marked_location(self.ptr.get() as *const _) }
}
}