mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-22 06:09:47 -05:00
add v8::EscapableHandleScope (#113)
This commit is contained in:
parent
c107eb871f
commit
25c4f7f4d0
6 changed files with 146 additions and 8 deletions
|
@ -16,6 +16,9 @@ static_assert(sizeof(v8::ScriptOrigin) == sizeof(size_t) * 7,
|
|||
static_assert(sizeof(v8::HandleScope) == sizeof(size_t) * 3,
|
||||
"HandleScope size mismatch");
|
||||
|
||||
static_assert(sizeof(v8::EscapableHandleScope) == sizeof(size_t) * 4,
|
||||
"EscapableHandleScope size mismatch");
|
||||
|
||||
static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3,
|
||||
"PromiseRejectMessage size mismatch");
|
||||
|
||||
|
@ -111,6 +114,25 @@ v8::Isolate* v8__HandleScope__GetIsolate(const v8::HandleScope& self) {
|
|||
return self.GetIsolate();
|
||||
}
|
||||
|
||||
void v8__EscapableHandleScope__CONSTRUCT(
|
||||
uninit_t<v8::EscapableHandleScope>& buf, v8::Isolate* isolate) {
|
||||
construct_in_place<v8::EscapableHandleScope>(buf, isolate);
|
||||
}
|
||||
|
||||
void v8__EscapableHandleScope__DESTRUCT(v8::EscapableHandleScope& self) {
|
||||
self.~EscapableHandleScope();
|
||||
}
|
||||
|
||||
v8::Value* v8__EscapableHandleScope__Escape(v8::EscapableHandleScope& self,
|
||||
v8::Local<v8::Value> value) {
|
||||
return local_to_ptr(self.Escape(value));
|
||||
}
|
||||
|
||||
v8::Isolate* v8__EscapableHandleScope__GetIsolate(
|
||||
const v8::EscapableHandleScope& self) {
|
||||
return self.GetIsolate();
|
||||
}
|
||||
|
||||
void v8__Locker__CONSTRUCT(uninit_t<v8::Locker>& buf, v8::Isolate* isolate) {
|
||||
construct_in_place<v8::Locker>(buf, isolate);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ use std::marker::PhantomData;
|
|||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::isolate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__HandleScope__CONSTRUCT(
|
||||
|
@ -12,6 +14,19 @@ extern "C" {
|
|||
fn v8__HandleScope__GetIsolate<'sc>(
|
||||
this: &'sc HandleScope,
|
||||
) -> &'sc mut Isolate;
|
||||
|
||||
fn v8__EscapableHandleScope__CONSTRUCT(
|
||||
buf: &mut MaybeUninit<EscapableHandleScope>,
|
||||
isolate: &Isolate,
|
||||
);
|
||||
fn v8__EscapableHandleScope__DESTRUCT(this: &mut EscapableHandleScope);
|
||||
fn v8__EscapableHandleScope__Escape(
|
||||
this: &mut EscapableHandleScope,
|
||||
value: *mut Value,
|
||||
) -> *mut Value;
|
||||
fn v8__EscapableHandleScope__GetIsolate<'sc>(
|
||||
this: &'sc EscapableHandleScope,
|
||||
) -> &'sc mut Isolate;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -55,3 +70,61 @@ impl<'sc> AsMut<Isolate> for HandleScope<'sc> {
|
|||
unsafe { v8__HandleScope__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
/// A HandleScope which first allocates a handle in the current scope
|
||||
/// which will be later filled with the escape value.
|
||||
pub struct EscapableHandleScope<'sc>([usize; 4], PhantomData<&'sc mut ()>);
|
||||
|
||||
impl<'sc> EscapableHandleScope<'sc> {
|
||||
pub fn new(isolate: &mut impl AsMut<Isolate>) -> Self {
|
||||
let isolate = isolate.as_mut();
|
||||
let mut scope: MaybeUninit<Self> = MaybeUninit::uninit();
|
||||
unsafe {
|
||||
v8__EscapableHandleScope__CONSTRUCT(&mut scope, isolate);
|
||||
scope.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes the value into the previous scope and returns a handle to it.
|
||||
/// Cannot be called twice.
|
||||
pub fn escape<'parent>(
|
||||
&mut self,
|
||||
mut value: Local<'sc, Value>,
|
||||
) -> Local<'parent, Value> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__EscapableHandleScope__Escape(self, &mut *value))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> Drop for EscapableHandleScope<'sc> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__EscapableHandleScope__DESTRUCT(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> AsRef<EscapableHandleScope<'sc>> for EscapableHandleScope<'sc> {
|
||||
fn as_ref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> AsMut<EscapableHandleScope<'sc>> for EscapableHandleScope<'sc> {
|
||||
fn as_mut(&mut self) -> &mut Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> AsRef<Isolate> for EscapableHandleScope<'sc> {
|
||||
fn as_ref(&self) -> &Isolate {
|
||||
unsafe { v8__EscapableHandleScope__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> AsMut<Isolate> for EscapableHandleScope<'sc> {
|
||||
fn as_mut(&mut self) -> &mut Isolate {
|
||||
unsafe { v8__EscapableHandleScope__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ pub use function::{
|
|||
Function, FunctionCallbackInfo, FunctionTemplate, ReturnValue,
|
||||
};
|
||||
pub use global::Global;
|
||||
pub use handle_scope::HandleScope;
|
||||
pub use handle_scope::{EscapableHandleScope, HandleScope};
|
||||
pub use isolate::Isolate;
|
||||
pub use isolate::OwnedIsolate;
|
||||
pub use local::Local;
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::ops::Deref;
|
|||
use crate::isolate::Isolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::value::Value;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
|
||||
extern "C" {
|
||||
|
@ -23,7 +22,7 @@ pub struct Number(Opaque);
|
|||
|
||||
impl Number {
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
scope: &mut impl AsMut<Isolate>,
|
||||
value: f64,
|
||||
) -> Local<'sc, Number> {
|
||||
unsafe {
|
||||
|
@ -50,7 +49,7 @@ pub struct Integer(Opaque);
|
|||
|
||||
impl Integer {
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
scope: &mut impl AsMut<Isolate>,
|
||||
value: i32,
|
||||
) -> Local<'sc, Integer> {
|
||||
unsafe {
|
||||
|
@ -60,7 +59,7 @@ impl Integer {
|
|||
}
|
||||
|
||||
pub fn new_from_unsigned<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
scope: &mut impl AsMut<Isolate>,
|
||||
value: u32,
|
||||
) -> Local<'sc, Integer> {
|
||||
unsafe {
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::isolate::Isolate;
|
|||
use crate::support::char;
|
||||
use crate::support::int;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
|
@ -67,7 +66,7 @@ pub struct String(Opaque);
|
|||
|
||||
impl String {
|
||||
pub fn new_from_utf8<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
scope: &mut impl AsMut<Isolate>,
|
||||
buffer: &[u8],
|
||||
new_type: NewStringType,
|
||||
) -> Option<Local<'sc, String>> {
|
||||
|
@ -119,7 +118,7 @@ impl String {
|
|||
|
||||
// Convenience function not present in the original V8 API.
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
scope: &mut impl AsMut<Isolate>,
|
||||
value: &str,
|
||||
) -> Option<Local<'sc, String>> {
|
||||
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
||||
|
|
|
@ -135,6 +135,51 @@ fn test_string() {
|
|||
drop(locker);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn escapable_handle_scope() {
|
||||
let g = setup();
|
||||
let mut params = v8::Isolate::create_params();
|
||||
params.set_array_buffer_allocator(v8::Allocator::new_default_allocator());
|
||||
let mut isolate = v8::Isolate::new(params);
|
||||
let mut locker = v8::Locker::new(&isolate);
|
||||
isolate.enter();
|
||||
v8::HandleScope::enter(&mut locker, |scope1| {
|
||||
// After dropping EscapableHandleScope, we should be able to
|
||||
// read escaped values.
|
||||
let number_val = {
|
||||
let mut escapable_scope = v8::EscapableHandleScope::new(scope1);
|
||||
let number: Local<v8::Value> = cast(v8::Number::new(&mut escapable_scope, 78.9));
|
||||
escapable_scope.escape(number)
|
||||
};
|
||||
let number: Local<v8::Number> = cast(number_val);
|
||||
assert_eq!(number.value(), 78.9);
|
||||
|
||||
let str_val = {
|
||||
let mut escapable_scope = v8::EscapableHandleScope::new(scope1);
|
||||
let string = v8::String::new(&mut escapable_scope, "Hello 🦕 world!").unwrap();
|
||||
escapable_scope.escape(cast(string))
|
||||
};
|
||||
let string: Local<v8::String> = cast(str_val);
|
||||
assert_eq!("Hello 🦕 world!", string.to_rust_string_lossy(scope1));
|
||||
|
||||
let str_val = {
|
||||
let mut escapable_scope = v8::EscapableHandleScope::new(scope1);
|
||||
let nested_str_val = {
|
||||
let mut nested_escapable_scope = v8::EscapableHandleScope::new(&mut escapable_scope);
|
||||
let string = v8::String::new(&mut nested_escapable_scope, "Hello 🦕 world!").unwrap();
|
||||
nested_escapable_scope.escape(cast(string))
|
||||
};
|
||||
escapable_scope.escape(nested_str_val)
|
||||
};
|
||||
let string: Local<v8::String> = cast(str_val);
|
||||
assert_eq!("Hello 🦕 world!", string.to_rust_string_lossy(scope1));
|
||||
});
|
||||
drop(locker);
|
||||
isolate.exit();
|
||||
drop(g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_buffer() {
|
||||
setup();
|
||||
|
|
Loading…
Add table
Reference in a new issue