mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-11 08:34:01 -05:00
feat: v8::Global::from_raw, v8::Global::into_raw (#902)
Co-authored-by: Bert Belder <bertbelder@gmail.com>
This commit is contained in:
parent
4c0ee77600
commit
da7ef32ead
2 changed files with 23 additions and 5 deletions
|
@ -2,6 +2,7 @@ use std::borrow::Borrow;
|
|||
use std::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::forget;
|
||||
use std::mem::transmute;
|
||||
use std::ops::Deref;
|
||||
use std::ptr::NonNull;
|
||||
|
@ -130,12 +131,12 @@ impl<T> Global<T> {
|
|||
pub fn new(isolate: &mut Isolate, handle: impl Handle<Data = T>) -> Self {
|
||||
let HandleInfo { data, host } = handle.get_handle_info();
|
||||
host.assert_match_isolate(isolate);
|
||||
unsafe { Self::new_raw(isolate, data) }
|
||||
unsafe { Self::from_raw(isolate, data) }
|
||||
}
|
||||
|
||||
/// Implementation helper function that contains the code that can be shared
|
||||
/// between `Global::new()` and `Global::clone()`.
|
||||
unsafe fn new_raw(isolate: *mut Isolate, data: NonNull<T>) -> Self {
|
||||
/// Converts a raw pointer created with [`Global::into_raw()`] back to its
|
||||
/// original `Global`.
|
||||
pub unsafe fn from_raw(isolate: &mut Isolate, data: NonNull<T>) -> Self {
|
||||
let data = data.cast().as_ptr();
|
||||
let data = v8__Global__New(isolate, data) as *const T;
|
||||
let data = NonNull::new_unchecked(data as *mut _);
|
||||
|
@ -146,6 +147,18 @@ impl<T> Global<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Consume this `Global` and return the underlying raw pointer.
|
||||
///
|
||||
/// The returned raw pointer must be converted back into a `Global` by using
|
||||
/// [`Global::from_raw`], otherwise the V8 value referenced by this global
|
||||
/// handle will be pinned on the V8 heap permanently and never get garbage
|
||||
/// collected.
|
||||
pub fn into_raw(self) -> NonNull<T> {
|
||||
let data = self.data;
|
||||
forget(self);
|
||||
data
|
||||
}
|
||||
|
||||
pub fn open<'a>(&'a self, scope: &mut Isolate) -> &'a T {
|
||||
Handle::open(self, scope)
|
||||
}
|
||||
|
@ -159,7 +172,7 @@ impl<T> Global<T> {
|
|||
impl<T> Clone for Global<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let HandleInfo { data, host } = self.get_handle_info();
|
||||
unsafe { Self::new_raw(host.get_isolate().as_mut(), data) }
|
||||
unsafe { Self::from_raw(host.get_isolate().as_mut(), data) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,11 @@ fn global_handles() {
|
|||
assert!(g6 == g1);
|
||||
assert_eq!(g6.open(scope).to_rust_string_lossy(scope), "bla");
|
||||
}
|
||||
{
|
||||
let g1_ptr = g1.clone().into_raw();
|
||||
let g1_reconstructed = unsafe { v8::Global::from_raw(isolate, g1_ptr) };
|
||||
assert_eq!(g1, g1_reconstructed);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue