0
0
Fork 0
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:
Bartek Iwańczuk 2022-02-18 01:26:00 +01:00 committed by GitHub
parent 4c0ee77600
commit da7ef32ead
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 5 deletions

View file

@ -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) }
}
}

View file

@ -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]