mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-03-09 13:38:51 -04: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,
|
static_assert(sizeof(v8::HandleScope) == sizeof(size_t) * 3,
|
||||||
"HandleScope size mismatch");
|
"HandleScope size mismatch");
|
||||||
|
|
||||||
|
static_assert(sizeof(v8::EscapableHandleScope) == sizeof(size_t) * 4,
|
||||||
|
"EscapableHandleScope size mismatch");
|
||||||
|
|
||||||
static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3,
|
static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3,
|
||||||
"PromiseRejectMessage size mismatch");
|
"PromiseRejectMessage size mismatch");
|
||||||
|
|
||||||
|
@ -111,6 +114,25 @@ v8::Isolate* v8__HandleScope__GetIsolate(const v8::HandleScope& self) {
|
||||||
return self.GetIsolate();
|
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) {
|
void v8__Locker__CONSTRUCT(uninit_t<v8::Locker>& buf, v8::Isolate* isolate) {
|
||||||
construct_in_place<v8::Locker>(buf, isolate);
|
construct_in_place<v8::Locker>(buf, isolate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ use std::marker::PhantomData;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
use crate::isolate::Isolate;
|
use crate::isolate::Isolate;
|
||||||
|
use crate::Local;
|
||||||
|
use crate::Value;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn v8__HandleScope__CONSTRUCT(
|
fn v8__HandleScope__CONSTRUCT(
|
||||||
|
@ -12,6 +14,19 @@ extern "C" {
|
||||||
fn v8__HandleScope__GetIsolate<'sc>(
|
fn v8__HandleScope__GetIsolate<'sc>(
|
||||||
this: &'sc HandleScope,
|
this: &'sc HandleScope,
|
||||||
) -> &'sc mut Isolate;
|
) -> &'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)]
|
#[repr(C)]
|
||||||
|
@ -55,3 +70,61 @@ impl<'sc> AsMut<Isolate> for HandleScope<'sc> {
|
||||||
unsafe { v8__HandleScope__GetIsolate(self) }
|
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,
|
Function, FunctionCallbackInfo, FunctionTemplate, ReturnValue,
|
||||||
};
|
};
|
||||||
pub use global::Global;
|
pub use global::Global;
|
||||||
pub use handle_scope::HandleScope;
|
pub use handle_scope::{EscapableHandleScope, HandleScope};
|
||||||
pub use isolate::Isolate;
|
pub use isolate::Isolate;
|
||||||
pub use isolate::OwnedIsolate;
|
pub use isolate::OwnedIsolate;
|
||||||
pub use local::Local;
|
pub use local::Local;
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::ops::Deref;
|
||||||
use crate::isolate::Isolate;
|
use crate::isolate::Isolate;
|
||||||
use crate::support::Opaque;
|
use crate::support::Opaque;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::HandleScope;
|
|
||||||
use crate::Local;
|
use crate::Local;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -23,7 +22,7 @@ pub struct Number(Opaque);
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
pub fn new<'sc>(
|
pub fn new<'sc>(
|
||||||
scope: &mut HandleScope<'sc>,
|
scope: &mut impl AsMut<Isolate>,
|
||||||
value: f64,
|
value: f64,
|
||||||
) -> Local<'sc, Number> {
|
) -> Local<'sc, Number> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -50,7 +49,7 @@ pub struct Integer(Opaque);
|
||||||
|
|
||||||
impl Integer {
|
impl Integer {
|
||||||
pub fn new<'sc>(
|
pub fn new<'sc>(
|
||||||
scope: &mut HandleScope<'sc>,
|
scope: &mut impl AsMut<Isolate>,
|
||||||
value: i32,
|
value: i32,
|
||||||
) -> Local<'sc, Integer> {
|
) -> Local<'sc, Integer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -60,7 +59,7 @@ impl Integer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_unsigned<'sc>(
|
pub fn new_from_unsigned<'sc>(
|
||||||
scope: &mut HandleScope<'sc>,
|
scope: &mut impl AsMut<Isolate>,
|
||||||
value: u32,
|
value: u32,
|
||||||
) -> Local<'sc, Integer> {
|
) -> Local<'sc, Integer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::isolate::Isolate;
|
||||||
use crate::support::char;
|
use crate::support::char;
|
||||||
use crate::support::int;
|
use crate::support::int;
|
||||||
use crate::support::Opaque;
|
use crate::support::Opaque;
|
||||||
use crate::HandleScope;
|
|
||||||
use crate::Local;
|
use crate::Local;
|
||||||
use crate::Value;
|
use crate::Value;
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ pub struct String(Opaque);
|
||||||
|
|
||||||
impl String {
|
impl String {
|
||||||
pub fn new_from_utf8<'sc>(
|
pub fn new_from_utf8<'sc>(
|
||||||
scope: &mut HandleScope<'sc>,
|
scope: &mut impl AsMut<Isolate>,
|
||||||
buffer: &[u8],
|
buffer: &[u8],
|
||||||
new_type: NewStringType,
|
new_type: NewStringType,
|
||||||
) -> Option<Local<'sc, String>> {
|
) -> Option<Local<'sc, String>> {
|
||||||
|
@ -119,7 +118,7 @@ impl String {
|
||||||
|
|
||||||
// Convenience function not present in the original V8 API.
|
// Convenience function not present in the original V8 API.
|
||||||
pub fn new<'sc>(
|
pub fn new<'sc>(
|
||||||
scope: &mut HandleScope<'sc>,
|
scope: &mut impl AsMut<Isolate>,
|
||||||
value: &str,
|
value: &str,
|
||||||
) -> Option<Local<'sc, String>> {
|
) -> Option<Local<'sc, String>> {
|
||||||
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
||||||
|
|
|
@ -135,6 +135,51 @@ fn test_string() {
|
||||||
drop(locker);
|
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]
|
#[test]
|
||||||
fn array_buffer() {
|
fn array_buffer() {
|
||||||
setup();
|
setup();
|
||||||
|
|
Loading…
Add table
Reference in a new issue