mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-21 05:02:11 -05:00
Add v8::Eternal<T>
(#1669)
Eternal handles are set-once handles that live for the lifetime of the isolate. https://v8.github.io/api/head/classv8_1_1Eternal.html
This commit is contained in:
parent
6b12ea15d0
commit
d72f9d3e6f
5 changed files with 124 additions and 0 deletions
|
@ -441,6 +441,28 @@ const v8::Data* v8__TracedReference__Get(v8::TracedReference<v8::Data>* self,
|
|||
return local_to_ptr(self->Get(isolate));
|
||||
}
|
||||
|
||||
void v8__Eternal__CONSTRUCT(uninit_t<v8::Eternal<v8::Data>>* buf) {
|
||||
construct_in_place<v8::Eternal<v8::Data>>(buf);
|
||||
}
|
||||
|
||||
void v8__Eternal__DESTRUCT(v8::Eternal<v8::Data>* self) { self->~Eternal(); }
|
||||
|
||||
void v8__Eternal__Clear(v8::Eternal<v8::Data>* self) { self->Clear(); }
|
||||
|
||||
bool v8__Eternal__IsEmpty(v8::Eternal<v8::Data>* self) {
|
||||
return self->IsEmpty();
|
||||
}
|
||||
|
||||
void v8__Eternal__Set(v8::Eternal<v8::Data>* self, v8::Isolate* isolate,
|
||||
const v8::Data* value) {
|
||||
self->Set(isolate, ptr_to_local(value));
|
||||
}
|
||||
|
||||
const v8::Data* v8__Eternal__Get(v8::Eternal<v8::Data>* self,
|
||||
v8::Isolate* isolate) {
|
||||
return local_to_ptr(self->Get(isolate));
|
||||
}
|
||||
|
||||
v8::Isolate* v8__WeakCallbackInfo__GetIsolate(
|
||||
const v8::WeakCallbackInfo<void>* self) {
|
||||
return self->GetIsolate();
|
||||
|
|
|
@ -18,6 +18,8 @@ static size_t cppgc__WeakMember_SIZE = sizeof(cppgc::WeakMember<RustObj>);
|
|||
|
||||
static size_t v8__TracedReference_SIZE = sizeof(v8::TracedReference<v8::Data>);
|
||||
|
||||
static size_t v8__Eternal_SIZE = sizeof(v8::Eternal<v8::Data>);
|
||||
|
||||
static size_t v8__String__ValueView_SIZE = sizeof(v8::String::ValueView);
|
||||
|
||||
static int v8__String__kMaxLength = v8::String::kMaxLength;
|
||||
|
|
|
@ -47,6 +47,20 @@ extern "C" {
|
|||
this: *const TracedReference<Data>,
|
||||
isolate: *mut Isolate,
|
||||
) -> *const Data;
|
||||
|
||||
fn v8__Eternal__CONSTRUCT(this: *mut Eternal<Data>);
|
||||
fn v8__Eternal__DESTRUCT(this: *mut Eternal<Data>);
|
||||
fn v8__Eternal__Clear(this: *mut Eternal<Data>);
|
||||
fn v8__Eternal__Get(
|
||||
this: *const Eternal<Data>,
|
||||
isolate: *mut Isolate,
|
||||
) -> *const Data;
|
||||
fn v8__Eternal__Set(
|
||||
this: *mut Eternal<Data>,
|
||||
isolate: *mut Isolate,
|
||||
data: *mut Data,
|
||||
);
|
||||
fn v8__Eternal__IsEmpty(this: *const Eternal<Data>) -> bool;
|
||||
}
|
||||
|
||||
/// An object reference managed by the v8 garbage collector.
|
||||
|
@ -1100,3 +1114,61 @@ impl<T> Drop for TracedReference<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Eternal handles are set-once handles that live for the lifetime of the isolate.
|
||||
#[repr(C)]
|
||||
pub struct Eternal<T> {
|
||||
data: [u8; crate::binding::v8__Eternal_SIZE],
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Eternal<T> {
|
||||
pub fn empty() -> Self {
|
||||
let mut this = std::mem::MaybeUninit::uninit();
|
||||
unsafe {
|
||||
v8__Eternal__CONSTRUCT(this.as_mut_ptr() as _);
|
||||
this.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
unsafe {
|
||||
v8__Eternal__Clear(self as *const Self as *mut Eternal<Data>);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&self, scope: &mut HandleScope<()>, data: Local<T>) {
|
||||
unsafe {
|
||||
v8__Eternal__Set(
|
||||
self as *const Self as *mut Eternal<Data>,
|
||||
scope.get_isolate_ptr(),
|
||||
data.as_non_null().as_ptr().cast(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<'s>(&self, scope: &mut HandleScope<'s, ()>) -> Local<'s, T> {
|
||||
unsafe {
|
||||
scope
|
||||
.cast_local(|sd| {
|
||||
v8__Eternal__Get(
|
||||
self as *const Self as *const Eternal<Data>,
|
||||
sd.get_isolate_ptr(),
|
||||
) as *const T
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
unsafe { v8__Eternal__IsEmpty(self as *const Self as *const Eternal<Data>) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for Eternal<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
v8__Eternal__DESTRUCT(self as *mut Self as *mut Eternal<Data>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ pub use external_references::ExternalReferences;
|
|||
pub use function::*;
|
||||
pub use gc::*;
|
||||
pub use get_property_names_args_builder::*;
|
||||
pub use handle::Eternal;
|
||||
pub use handle::Global;
|
||||
pub use handle::Handle;
|
||||
pub use handle::Local;
|
||||
|
|
|
@ -11977,3 +11977,30 @@ fn use_counter_callback() {
|
|||
|
||||
assert_eq!(COUNT.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eternals() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
let eternal1 = v8::Eternal::empty();
|
||||
|
||||
{
|
||||
let mut isolate = v8::Isolate::new(Default::default());
|
||||
let mut scope = v8::HandleScope::new(&mut isolate);
|
||||
|
||||
let str1 = v8::String::new(&mut scope, "hello").unwrap();
|
||||
|
||||
assert!(eternal1.is_empty());
|
||||
eternal1.set(&mut scope, str1);
|
||||
assert!(!eternal1.is_empty());
|
||||
|
||||
let str1_get = eternal1.get(&mut scope);
|
||||
assert_eq!(str1, str1_get);
|
||||
|
||||
eternal1.clear();
|
||||
assert!(eternal1.is_empty());
|
||||
}
|
||||
|
||||
// Try all 'standalone' methods after isolate has dropped.
|
||||
assert!(eternal1.is_empty());
|
||||
eternal1.clear();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue