mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-23 15:50:11 -05:00
Add Local lifetimes back (#95)
This commit is contained in:
parent
bbfaacfe56
commit
331582561b
16 changed files with 389 additions and 283 deletions
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::isolate::Isolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Object;
|
||||
|
||||
|
@ -18,9 +19,9 @@ extern "C" {
|
|||
pub struct Context(Opaque);
|
||||
|
||||
impl Context {
|
||||
pub fn new(isolate: &Isolate) -> Local<Context> {
|
||||
pub fn new<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Context> {
|
||||
// TODO: optional arguments;
|
||||
unsafe { Local::from_raw(v8__Context__New(isolate)).unwrap() }
|
||||
unsafe { Local::from_raw(v8__Context__New(scope.as_mut())).unwrap() }
|
||||
}
|
||||
|
||||
/// Returns the global proxy object.
|
||||
|
@ -33,7 +34,7 @@ impl Context {
|
|||
/// Please note that changes to global proxy object prototype most probably
|
||||
/// would break VM---v8 expects only global object as a prototype of global
|
||||
/// proxy object.
|
||||
pub fn global(&mut self) -> Local<Object> {
|
||||
pub fn global<'sc>(&mut self) -> Local<'sc, Object> {
|
||||
unsafe { Local::from_raw(v8__Context__Global(&mut *self)).unwrap() }
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use crate::isolate::Isolate;
|
||||
use crate::support::int;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::String;
|
||||
use crate::Value;
|
||||
|
@ -45,11 +46,12 @@ impl StackTrace {
|
|||
pub struct Message(Opaque);
|
||||
|
||||
impl Message {
|
||||
pub fn get(&self) -> Local<String> {
|
||||
pub fn get<'sc>(&self, _scope: &mut HandleScope<'sc>) -> Local<'sc, String> {
|
||||
unsafe { Local::from_raw(v8__Message__Get(self)) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn get_isolate(&self) -> &Isolate {
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
pub fn get_isolate(&self) -> &mut Isolate {
|
||||
unsafe { v8__Message__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
@ -57,41 +59,60 @@ impl Message {
|
|||
/// Creates an error message for the given exception.
|
||||
/// Will try to reconstruct the original stack trace from the exception value,
|
||||
/// or capture the current stack trace if not available.
|
||||
pub fn create_message(
|
||||
isolate: &Isolate,
|
||||
mut exception: Local<Value>,
|
||||
) -> Local<Message> {
|
||||
pub fn create_message<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
mut exception: Local<'sc, Value>,
|
||||
) -> Local<'sc, Message> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__Exception__CreateMessage(isolate, &mut *exception))
|
||||
Local::from_raw(v8__Exception__CreateMessage(
|
||||
scope.as_mut(),
|
||||
&mut *exception,
|
||||
))
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns the original stack trace that was captured at the creation time
|
||||
/// of a given exception, or an empty handle if not available.
|
||||
pub fn get_stack_trace(
|
||||
pub fn get_stack_trace<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut exception: Local<Value>,
|
||||
) -> Option<Local<StackTrace>> {
|
||||
) -> Option<Local<'sc, StackTrace>> {
|
||||
unsafe { Local::from_raw(v8__Exception__GetStackTrace(&mut *exception)) }
|
||||
}
|
||||
|
||||
pub fn range_error(mut message: Local<String>) -> Local<Value> {
|
||||
pub fn range_error<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut message: Local<String>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Exception__RangeError(&mut *message)) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn reference_error(mut message: Local<String>) -> Local<Value> {
|
||||
pub fn reference_error<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut message: Local<String>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Exception__ReferenceError(&mut *message)) }
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn syntax_error(mut message: Local<String>) -> Local<Value> {
|
||||
pub fn syntax_error<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut message: Local<String>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Exception__SyntaxError(&mut *message)) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn type_error(mut message: Local<String>) -> Local<Value> {
|
||||
pub fn type_error<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut message: Local<String>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Exception__TypeError(&mut *message)) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn error(mut message: Local<String>) -> Local<Value> {
|
||||
pub fn error<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut message: Local<String>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Exception__Error(&mut *message)) }.unwrap()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::support::{int, Opaque};
|
||||
use crate::Context;
|
||||
use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
@ -63,7 +64,10 @@ impl ReturnValue {
|
|||
/// Getter. Creates a new Local<> so it comes with a certain performance
|
||||
/// hit. If the ReturnValue was not yet set, this will return the undefined
|
||||
/// value.
|
||||
pub fn get(&mut self) -> Local<Value> {
|
||||
pub fn get<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__ReturnValue__Get(&mut *self)).unwrap() }
|
||||
}
|
||||
}
|
||||
|
@ -122,20 +126,22 @@ pub struct FunctionTemplate(Opaque);
|
|||
|
||||
impl FunctionTemplate {
|
||||
/// Creates a function template.
|
||||
pub fn new(
|
||||
isolate: &Isolate,
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
callback: extern "C" fn(&FunctionCallbackInfo),
|
||||
) -> Local<FunctionTemplate> {
|
||||
) -> Local<'sc, FunctionTemplate> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__FunctionTemplate__New(isolate, callback)).unwrap()
|
||||
Local::from_raw(v8__FunctionTemplate__New(scope.as_mut(), callback))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the unique function instance in the current execution context.
|
||||
pub fn get_function(
|
||||
pub fn get_function<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<Context>,
|
||||
) -> Option<Local<Function>> {
|
||||
) -> Option<Local<'sc, Function>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__FunctionTemplate__GetFunction(
|
||||
&mut *self,
|
||||
|
@ -153,20 +159,22 @@ impl Function {
|
|||
// TODO: add remaining arguments from C++
|
||||
/// Create a function in the current execution context
|
||||
/// for a given FunctionCallback.
|
||||
pub fn new(
|
||||
pub fn new<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<Context>,
|
||||
callback: extern "C" fn(&FunctionCallbackInfo),
|
||||
) -> Option<Local<Function>> {
|
||||
) -> Option<Local<'sc, Function>> {
|
||||
unsafe { Local::from_raw(v8__Function__New(&mut *context, callback)) }
|
||||
}
|
||||
|
||||
pub fn call(
|
||||
pub fn call<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<Context>,
|
||||
mut recv: Local<Value>,
|
||||
arc: i32,
|
||||
argv: Vec<Local<Value>>,
|
||||
) -> Option<Local<Value>> {
|
||||
) -> Option<Local<'sc, Value>> {
|
||||
let mut argv_: Vec<*mut Value> = vec![];
|
||||
for mut arg in argv {
|
||||
argv_.push(&mut *arg);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::isolate::Isolate;
|
||||
|
@ -8,22 +9,36 @@ extern "C" {
|
|||
isolate: &Isolate,
|
||||
);
|
||||
fn v8__HandleScope__DESTRUCT(this: &mut HandleScope);
|
||||
fn v8__HandleScope__GetIsolate(this: &HandleScope) -> &mut Isolate;
|
||||
fn v8__HandleScope__GetIsolate<'sc>(
|
||||
this: &'sc HandleScope,
|
||||
) -> &'sc mut Isolate;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct HandleScope([usize; 3]);
|
||||
pub struct HandleScope<'sc>([usize; 3], PhantomData<&'sc mut ()>);
|
||||
|
||||
impl HandleScope {
|
||||
pub fn enter(isolate: &Isolate, mut f: impl FnMut(&mut HandleScope) -> ()) {
|
||||
impl<'sc> HandleScope<'sc> {
|
||||
pub fn enter(
|
||||
isolate: &Isolate,
|
||||
mut f: impl FnMut(&mut HandleScope<'_>) -> (),
|
||||
) {
|
||||
let mut scope: MaybeUninit<Self> = MaybeUninit::uninit();
|
||||
unsafe { v8__HandleScope__CONSTRUCT(&mut scope, isolate) };
|
||||
let scope = unsafe { &mut *(scope.as_mut_ptr()) };
|
||||
f(scope);
|
||||
|
||||
unsafe { v8__HandleScope__DESTRUCT(scope) };
|
||||
}
|
||||
}
|
||||
|
||||
fn get_isolate(&self) -> &Isolate {
|
||||
impl<'sc> AsRef<Isolate> for HandleScope<'sc> {
|
||||
fn as_ref(&self) -> &Isolate {
|
||||
unsafe { v8__HandleScope__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sc> AsMut<Isolate> for HandleScope<'sc> {
|
||||
fn as_mut(&mut self) -> &mut Isolate {
|
||||
unsafe { v8__HandleScope__GetIsolate(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,18 @@ impl Isolate {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<Isolate> for Isolate {
|
||||
fn as_ref(&self) -> &Isolate {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<Isolate> for Isolate {
|
||||
fn as_mut(&mut self) -> &mut Isolate {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as Isolate but gets disposed when it goes out of scope.
|
||||
pub struct OwnedIsolate(NonNull<Isolate>);
|
||||
|
||||
|
|
16
src/json.rs
16
src/json.rs
|
@ -18,19 +18,19 @@ extern "C" {
|
|||
|
||||
/// Tries to parse the string `json_string` and returns it as value if
|
||||
/// successful.
|
||||
pub fn parse(
|
||||
mut context: Local<Context>,
|
||||
mut json_string: Local<String>,
|
||||
) -> Option<Local<Value>> {
|
||||
pub fn parse<'sc>(
|
||||
mut context: Local<'sc, Context>,
|
||||
mut json_string: Local<'sc, String>,
|
||||
) -> Option<Local<'sc, Value>> {
|
||||
unsafe { Local::from_raw(v8__JSON__Parse(&mut *context, &mut *json_string)) }
|
||||
}
|
||||
|
||||
/// Tries to stringify the JSON-serializable object `json_object` and returns
|
||||
/// it as string if successful.
|
||||
pub fn stringify(
|
||||
mut context: Local<Context>,
|
||||
mut json_object: Local<Value>,
|
||||
) -> Option<Local<String>> {
|
||||
pub fn stringify<'sc>(
|
||||
mut context: Local<'sc, Context>,
|
||||
mut json_object: Local<'sc, Value>,
|
||||
) -> Option<Local<'sc, String>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__JSON__Stringify(&mut *context, &mut *json_object))
|
||||
}
|
||||
|
|
21
src/local.rs
21
src/local.rs
|
@ -1,4 +1,5 @@
|
|||
use crate::value::Value;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::ptr::NonNull;
|
||||
|
@ -37,30 +38,30 @@ use std::ptr::NonNull;
|
|||
/// Note: Local handles in Rusty V8 differ from the V8 C++ API in that they are
|
||||
/// never empty. In situations where empty handles are needed, use
|
||||
/// Option<Local>.
|
||||
pub struct Local<T>(NonNull<T>);
|
||||
pub struct Local<'sc, T>(NonNull<T>, PhantomData<&'sc ()>);
|
||||
|
||||
impl<T> Copy for Local<T> {}
|
||||
impl<'sc, T> Copy for Local<'sc, T> {}
|
||||
|
||||
impl<T> Clone for Local<T> {
|
||||
impl<'sc, T> Clone for Local<'sc, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0)
|
||||
Self(self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Local<T> {
|
||||
impl<'sc, T> Local<'sc, T> {
|
||||
pub unsafe fn from_raw(ptr: *mut T) -> Option<Self> {
|
||||
Some(Self(NonNull::new(ptr)?))
|
||||
Some(Self(NonNull::new(ptr)?, PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Local<T> {
|
||||
impl<'sc, T> Deref for Local<'sc, T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { self.0.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for Local<T> {
|
||||
impl<'sc, T> DerefMut for Local<'sc, T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
unsafe { self.0.as_mut() }
|
||||
}
|
||||
|
@ -68,11 +69,11 @@ impl<T> DerefMut for Local<T> {
|
|||
|
||||
// TODO make it possible for targets other than Local<Value>. For example
|
||||
// Local<String> should be able to be down cast to Local<Name>.
|
||||
impl<T> From<Local<T>> for Local<Value>
|
||||
impl<'sc, T> From<Local<'sc, T>> for Local<'sc, Value>
|
||||
where
|
||||
T: Deref<Target = Value>,
|
||||
{
|
||||
fn from(v: Local<T>) -> Local<Value> {
|
||||
fn from(v: Local<'sc, T>) -> Local<'sc, Value> {
|
||||
unsafe { std::mem::transmute(v) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::isolate::Isolate;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
extern "C" {
|
||||
|
@ -12,9 +13,9 @@ extern "C" {
|
|||
/// construction and destruction, the current thread is allowed to use the locked
|
||||
/// isolate. V8 guarantees that an isolate can be locked by at most one thread at
|
||||
/// any time. In other words, the scope of a v8::Locker is a critical section.
|
||||
pub struct Locker([usize; 2]);
|
||||
pub struct Locker<'sc>([usize; 2], PhantomData<&'sc mut ()>);
|
||||
|
||||
impl Locker {
|
||||
impl<'a> Locker<'a> {
|
||||
/// Initialize Locker for a given Isolate.
|
||||
pub fn new(isolate: &Isolate) -> Self {
|
||||
let mut buf = MaybeUninit::<Self>::uninit();
|
||||
|
@ -25,7 +26,7 @@ impl Locker {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for Locker {
|
||||
impl<'a> Drop for Locker<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__Locker__DESTRUCT(self) }
|
||||
}
|
||||
|
|
|
@ -79,5 +79,8 @@ impl Module {
|
|||
}
|
||||
}
|
||||
|
||||
type ResolveCallback =
|
||||
dyn Fn(Local<Context>, Local<String>, Local<Module>) -> Option<Local<Module>>;
|
||||
type ResolveCallback<'sc> = dyn Fn(
|
||||
Local<'sc, Context>,
|
||||
Local<'sc, String>,
|
||||
Local<'sc, Module>,
|
||||
) -> Option<Local<'sc, Module>>;
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crate::isolate::Isolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::Isolate;
|
||||
use crate::value::Value;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__Number__New(isolate: &Isolate, value: f64) -> *mut Number;
|
||||
fn v8__Number__New(isolate: *mut Isolate, value: f64) -> *mut Number;
|
||||
fn v8__Number__Value(this: &Number) -> f64;
|
||||
fn v8__Integer__New(isolate: &Isolate, value: i32) -> *mut Integer;
|
||||
fn v8__Integer__New(isolate: *mut Isolate, value: i32) -> *mut Integer;
|
||||
fn v8__Integer__NewFromUnsigned(
|
||||
isolate: &Isolate,
|
||||
isolate: *mut Isolate,
|
||||
value: u32,
|
||||
) -> *mut Integer;
|
||||
fn v8__Integer__Value(this: &Integer) -> i64;
|
||||
fn v8__Integer__Value(this: *const Integer) -> i64;
|
||||
}
|
||||
|
||||
/// A JavaScript number value (ECMA-262, 4.3.20)
|
||||
|
@ -21,9 +22,12 @@ extern "C" {
|
|||
pub struct Number(Opaque);
|
||||
|
||||
impl Number {
|
||||
pub fn new(isolate: &Isolate, value: f64) -> Local<Number> {
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
value: f64,
|
||||
) -> Local<'sc, Number> {
|
||||
unsafe {
|
||||
let local = v8__Number__New(isolate, value);
|
||||
let local = v8__Number__New(scope.as_mut(), value);
|
||||
Local::from_raw(local).unwrap()
|
||||
}
|
||||
}
|
||||
|
@ -45,16 +49,22 @@ impl Deref for Number {
|
|||
pub struct Integer(Opaque);
|
||||
|
||||
impl Integer {
|
||||
pub fn new(isolate: &Isolate, value: i32) -> Local<Integer> {
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
value: i32,
|
||||
) -> Local<'sc, Integer> {
|
||||
unsafe {
|
||||
let local = v8__Integer__New(isolate, value);
|
||||
let local = v8__Integer__New(scope.as_mut(), value);
|
||||
Local::from_raw(local).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_unsigned(isolate: &Isolate, value: u32) -> Local<Integer> {
|
||||
pub fn new_from_unsigned<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
value: u32,
|
||||
) -> Local<'sc, Integer> {
|
||||
unsafe {
|
||||
let local = v8__Integer__NewFromUnsigned(isolate, value);
|
||||
let local = v8__Integer__NewFromUnsigned(scope.as_mut(), value);
|
||||
Local::from_raw(local).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use crate::isolate::Isolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Name;
|
||||
use crate::Value;
|
||||
|
@ -12,7 +13,7 @@ pub struct Object(Opaque);
|
|||
|
||||
extern "C" {
|
||||
fn v8__Object__New(
|
||||
isolate: &Isolate,
|
||||
isolate: *mut Isolate,
|
||||
prototype_or_null: *mut Value,
|
||||
names: *mut *mut Name,
|
||||
values: *mut *mut Value,
|
||||
|
@ -28,13 +29,13 @@ impl Object {
|
|||
/// a prototype at all). This is similar to Object.create().
|
||||
/// All properties will be created as enumerable, configurable
|
||||
/// and writable properties.
|
||||
pub fn new(
|
||||
isolate: &Isolate,
|
||||
mut prototype_or_null: Local<Value>,
|
||||
names: Vec<Local<Name>>,
|
||||
values: Vec<Local<Value>>,
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
mut prototype_or_null: Local<'sc, Value>,
|
||||
names: Vec<Local<'sc, Name>>,
|
||||
values: Vec<Local<'sc, Value>>,
|
||||
length: usize,
|
||||
) -> Local<Object> {
|
||||
) -> Local<'sc, Object> {
|
||||
let mut names_: Vec<*mut Name> = vec![];
|
||||
for mut name in names {
|
||||
let n = &mut *name;
|
||||
|
@ -48,7 +49,7 @@ impl Object {
|
|||
}
|
||||
unsafe {
|
||||
Local::from_raw(v8__Object__New(
|
||||
isolate,
|
||||
scope.as_mut(),
|
||||
&mut *prototype_or_null,
|
||||
names_.as_mut_ptr(),
|
||||
values_.as_mut_ptr(),
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use crate::isolate::Isolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
|
@ -19,29 +20,31 @@ pub struct Boolean(Opaque);
|
|||
pub struct Name(Opaque);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Null(isolate: &Isolate) -> *mut Primitive;
|
||||
fn v8__Null(isolate: *mut Isolate) -> *mut Primitive;
|
||||
|
||||
fn v8__Undefined(isolate: &Isolate) -> *mut Primitive;
|
||||
fn v8__Undefined(isolate: *mut Isolate) -> *mut Primitive;
|
||||
|
||||
fn v8__True(isolate: &Isolate) -> *mut Boolean;
|
||||
fn v8__True(isolate: *mut Isolate) -> *mut Boolean;
|
||||
|
||||
fn v8__False(isolate: &Isolate) -> *mut Boolean;
|
||||
fn v8__False(isolate: *mut Isolate) -> *mut Boolean;
|
||||
}
|
||||
|
||||
pub fn new_null(isolate: &Isolate) -> Local<Primitive> {
|
||||
unsafe { Local::from_raw(v8__Null(isolate)) }.unwrap()
|
||||
pub fn new_null<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Primitive> {
|
||||
unsafe { Local::from_raw(v8__Null(scope.as_mut())) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn new_undefined(isolate: &Isolate) -> Local<Primitive> {
|
||||
unsafe { Local::from_raw(v8__Undefined(isolate)) }.unwrap()
|
||||
pub fn new_undefined<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
) -> Local<'sc, Primitive> {
|
||||
unsafe { Local::from_raw(v8__Undefined(scope.as_mut())) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn new_true(isolate: &Isolate) -> Local<Boolean> {
|
||||
unsafe { Local::from_raw(v8__True(isolate)) }.unwrap()
|
||||
pub fn new_true<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Boolean> {
|
||||
unsafe { Local::from_raw(v8__True(scope.as_mut())) }.unwrap()
|
||||
}
|
||||
|
||||
pub fn new_false(isolate: &Isolate) -> Local<Boolean> {
|
||||
unsafe { Local::from_raw(v8__False(isolate)) }.unwrap()
|
||||
pub fn new_false<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Boolean> {
|
||||
unsafe { Local::from_raw(v8__False(scope.as_mut())) }.unwrap()
|
||||
}
|
||||
|
||||
impl Deref for Primitive {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::support::MaybeBool;
|
||||
use crate::support::Opaque;
|
||||
use crate::Context;
|
||||
use crate::Function;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
|
@ -77,18 +80,21 @@ impl Promise {
|
|||
|
||||
/// Returns the content of the [[PromiseResult]] field. The Promise must not
|
||||
/// be pending.
|
||||
pub fn result(&mut self) -> Local<Value> {
|
||||
pub fn result<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
) -> Local<'sc, Value> {
|
||||
unsafe { Local::from_raw(v8__Promise__Result(&mut *self)).unwrap() }
|
||||
}
|
||||
|
||||
/// Register a rejection handler with a promise.
|
||||
///
|
||||
/// See `Self::then2`.
|
||||
pub fn catch(
|
||||
pub fn catch<'sc>(
|
||||
&mut self,
|
||||
mut context: Local<Context>,
|
||||
mut handler: Local<Function>,
|
||||
) -> Option<Local<Promise>> {
|
||||
mut context: Local<'sc, Context>,
|
||||
mut handler: Local<'sc, Function>,
|
||||
) -> Option<Local<'sc, Promise>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__Promise__Catch(
|
||||
&mut *self,
|
||||
|
@ -101,11 +107,11 @@ impl Promise {
|
|||
/// Register a resolution handler with a promise.
|
||||
///
|
||||
/// See `Self::then2`.
|
||||
pub fn then(
|
||||
pub fn then<'sc>(
|
||||
&mut self,
|
||||
mut context: Local<Context>,
|
||||
mut handler: Local<Function>,
|
||||
) -> Option<Local<Promise>> {
|
||||
mut context: Local<'sc, Context>,
|
||||
mut handler: Local<'sc, Function>,
|
||||
) -> Option<Local<'sc, Promise>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__Promise__Then(
|
||||
&mut *self,
|
||||
|
@ -119,12 +125,12 @@ impl Promise {
|
|||
/// The handler is given the respective resolution/rejection value as
|
||||
/// an argument. If the promise is already resolved/rejected, the handler is
|
||||
/// invoked at the end of turn.
|
||||
pub fn then2(
|
||||
pub fn then2<'sc>(
|
||||
&mut self,
|
||||
mut context: Local<Context>,
|
||||
mut on_fulfilled: Local<Function>,
|
||||
mut on_rejected: Local<Function>,
|
||||
) -> Option<Local<Promise>> {
|
||||
mut context: Local<'sc, Context>,
|
||||
mut on_fulfilled: Local<'sc, Function>,
|
||||
mut on_rejected: Local<'sc, Function>,
|
||||
) -> Option<Local<'sc, Promise>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__Promise__Then2(
|
||||
&mut *self,
|
||||
|
@ -141,12 +147,18 @@ pub struct PromiseResolver(Opaque);
|
|||
|
||||
impl PromiseResolver {
|
||||
/// Create a new resolver, along with an associated promise in pending state.
|
||||
pub fn new(mut context: Local<Context>) -> Option<Local<PromiseResolver>> {
|
||||
pub fn new<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<'sc, Context>,
|
||||
) -> Option<Local<'sc, PromiseResolver>> {
|
||||
unsafe { Local::from_raw(v8__Promise__Resolver__New(&mut *context)) }
|
||||
}
|
||||
|
||||
/// Extract the associated promise.
|
||||
pub fn get_promise(&mut self) -> Local<Promise> {
|
||||
pub fn get_promise<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
) -> Local<'sc, Promise> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__Promise__Resolver__GetPromise(&mut *self)).unwrap()
|
||||
}
|
||||
|
@ -154,10 +166,10 @@ impl PromiseResolver {
|
|||
|
||||
/// Resolve the associated promise with a given value.
|
||||
/// Ignored if the promise is no longer pending.
|
||||
pub fn resolve(
|
||||
pub fn resolve<'sc>(
|
||||
&mut self,
|
||||
mut context: Local<Context>,
|
||||
mut value: Local<Value>,
|
||||
mut context: Local<'sc, Context>,
|
||||
mut value: Local<'sc, Value>,
|
||||
) -> Option<bool> {
|
||||
unsafe {
|
||||
v8__Promise__Resolver__Resolve(&mut *self, &mut *context, &mut *value)
|
||||
|
@ -167,10 +179,10 @@ impl PromiseResolver {
|
|||
|
||||
/// Reject the associated promise with a given value.
|
||||
/// Ignored if the promise is no longer pending.
|
||||
pub fn reject(
|
||||
pub fn reject<'sc>(
|
||||
&mut self,
|
||||
mut context: Local<Context>,
|
||||
mut value: Local<Value>,
|
||||
mut context: Local<'sc, Context>,
|
||||
mut value: Local<'sc, Value>,
|
||||
) -> Option<bool> {
|
||||
unsafe {
|
||||
v8__Promise__Resolver__Reject(&mut *self, &mut *context, &mut *value)
|
||||
|
@ -189,10 +201,10 @@ pub enum PromiseRejectEvent {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PromiseRejectMessage([usize; 3]);
|
||||
pub struct PromiseRejectMessage<'msg>([usize; 3], PhantomData<&'msg ()>);
|
||||
|
||||
impl PromiseRejectMessage {
|
||||
pub fn get_promise(&self) -> Local<Promise> {
|
||||
impl<'msg> PromiseRejectMessage<'msg> {
|
||||
pub fn get_promise(&self) -> Local<'msg, Promise> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__PromiseRejectMessage__GetPromise(self)).unwrap()
|
||||
}
|
||||
|
@ -202,7 +214,7 @@ impl PromiseRejectMessage {
|
|||
unsafe { v8__PromiseRejectMessage__GetEvent(self) }
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> Local<Value> {
|
||||
pub fn get_value(&self) -> Local<'msg, Value> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__PromiseRejectMessage__GetValue(self)).unwrap()
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::null;
|
||||
|
||||
use crate::support::Opaque;
|
||||
use crate::Boolean;
|
||||
use crate::Context;
|
||||
use crate::HandleScope;
|
||||
use crate::Integer;
|
||||
use crate::Local;
|
||||
use crate::String;
|
||||
|
@ -11,7 +13,7 @@ use crate::Value;
|
|||
|
||||
/// The origin, within a file, of a script.
|
||||
#[repr(C)]
|
||||
pub struct ScriptOrigin([usize; 7]);
|
||||
pub struct ScriptOrigin<'sc>([usize; 7], PhantomData<&'sc ()>);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Script__Compile(
|
||||
|
@ -42,11 +44,12 @@ pub struct Script(Opaque);
|
|||
|
||||
impl Script {
|
||||
/// A shorthand for ScriptCompiler::Compile().
|
||||
pub fn compile(
|
||||
pub fn compile<'sc>(
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<Context>,
|
||||
mut source: Local<String>,
|
||||
origin: Option<&'_ ScriptOrigin>,
|
||||
) -> Option<Local<Script>> {
|
||||
origin: Option<&ScriptOrigin>,
|
||||
) -> Option<Local<'sc, Script>> {
|
||||
// TODO: use the type system to enforce that a Context has been entered.
|
||||
// TODO: `context` and `source` probably shouldn't be mut.
|
||||
unsafe {
|
||||
|
@ -61,24 +64,28 @@ impl Script {
|
|||
/// Runs the script returning the resulting value. It will be run in the
|
||||
/// context in which it was created (ScriptCompiler::CompileBound or
|
||||
/// UnboundScript::BindToCurrentContext()).
|
||||
pub fn run(&mut self, mut context: Local<Context>) -> Option<Local<Value>> {
|
||||
pub fn run<'sc>(
|
||||
&mut self,
|
||||
_scope: &mut HandleScope<'sc>,
|
||||
mut context: Local<Context>,
|
||||
) -> Option<Local<'sc, Value>> {
|
||||
unsafe { Local::from_raw(v8__Script__Run(self, &mut *context)) }
|
||||
}
|
||||
}
|
||||
|
||||
/// The origin, within a file, of a script.
|
||||
impl ScriptOrigin {
|
||||
impl<'sc> ScriptOrigin<'sc> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
mut resource_name: Local<Value>,
|
||||
mut resource_line_offset: Local<Integer>,
|
||||
mut resource_column_offset: Local<Integer>,
|
||||
mut resource_is_shared_cross_origin: Local<Boolean>,
|
||||
mut script_id: Local<Integer>,
|
||||
mut source_map_url: Local<Value>,
|
||||
mut resource_is_opaque: Local<Boolean>,
|
||||
mut is_wasm: Local<Boolean>,
|
||||
mut is_module: Local<Boolean>,
|
||||
mut resource_name: Local<'sc, Value>,
|
||||
mut resource_line_offset: Local<'sc, Integer>,
|
||||
mut resource_column_offset: Local<'sc, Integer>,
|
||||
mut resource_is_shared_cross_origin: Local<'sc, Boolean>,
|
||||
mut script_id: Local<'sc, Integer>,
|
||||
mut source_map_url: Local<'sc, Value>,
|
||||
mut resource_is_opaque: Local<'sc, Boolean>,
|
||||
mut is_wasm: Local<'sc, Boolean>,
|
||||
mut is_module: Local<'sc, Boolean>,
|
||||
) -> Self {
|
||||
unsafe {
|
||||
let mut buf = std::mem::MaybeUninit::<ScriptOrigin>::uninit();
|
||||
|
|
|
@ -8,12 +8,13 @@ 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;
|
||||
|
||||
extern "C" {
|
||||
fn v8__String__NewFromUtf8(
|
||||
isolate: &Isolate,
|
||||
isolate: *mut Isolate,
|
||||
data: *const char,
|
||||
new_type: NewStringType,
|
||||
length: int,
|
||||
|
@ -21,11 +22,11 @@ extern "C" {
|
|||
|
||||
fn v8__String__Length(this: &String) -> int;
|
||||
|
||||
fn v8__String__Utf8Length(this: &String, isolate: &Isolate) -> int;
|
||||
fn v8__String__Utf8Length(this: &String, isolate: *mut Isolate) -> int;
|
||||
|
||||
fn v8__String__WriteUtf8(
|
||||
this: &String,
|
||||
isolate: &Isolate,
|
||||
isolate: *mut Isolate,
|
||||
buffer: *mut char,
|
||||
length: int,
|
||||
nchars_ref: *mut int,
|
||||
|
@ -65,14 +66,14 @@ bitflags! {
|
|||
pub struct String(Opaque);
|
||||
|
||||
impl String {
|
||||
pub fn new_from_utf8(
|
||||
isolate: &Isolate,
|
||||
pub fn new_from_utf8<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
buffer: &[u8],
|
||||
new_type: NewStringType,
|
||||
) -> Option<Local<String>> {
|
||||
) -> Option<Local<'sc, String>> {
|
||||
unsafe {
|
||||
let ptr = v8__String__NewFromUtf8(
|
||||
isolate,
|
||||
scope.as_mut(),
|
||||
buffer.as_ptr() as *const char,
|
||||
new_type,
|
||||
buffer.len().try_into().ok()?,
|
||||
|
@ -88,13 +89,13 @@ impl String {
|
|||
|
||||
/// Returns the number of bytes in the UTF-8 encoded representation of this
|
||||
/// string.
|
||||
pub fn utf8_length(&self, isolate: &Isolate) -> usize {
|
||||
unsafe { v8__String__Utf8Length(self, isolate) as usize }
|
||||
pub fn utf8_length(&self, isolate: &mut impl AsMut<Isolate>) -> usize {
|
||||
unsafe { v8__String__Utf8Length(self, isolate.as_mut()) as usize }
|
||||
}
|
||||
|
||||
pub fn write_utf8(
|
||||
&self,
|
||||
isolate: &Isolate,
|
||||
isolate: &mut Isolate,
|
||||
buffer: &mut [u8],
|
||||
nchars_ref: Option<&mut usize>,
|
||||
options: WriteOptions,
|
||||
|
@ -117,16 +118,20 @@ impl String {
|
|||
}
|
||||
|
||||
// Convenience function not present in the original V8 API.
|
||||
pub fn new(
|
||||
isolate: &Isolate,
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
value: &str,
|
||||
new_type: NewStringType,
|
||||
) -> Option<Local<String>> {
|
||||
Self::new_from_utf8(isolate, value.as_ref(), new_type)
|
||||
) -> Option<Local<'sc, String>> {
|
||||
Self::new_from_utf8(scope, value.as_ref(), new_type)
|
||||
}
|
||||
|
||||
// Convenience function not present in the original V8 API.
|
||||
pub fn to_rust_string_lossy(&self, isolate: &Isolate) -> std::string::String {
|
||||
pub fn to_rust_string_lossy(
|
||||
&self,
|
||||
isolate: &mut impl AsMut<Isolate>,
|
||||
) -> std::string::String {
|
||||
let isolate = isolate.as_mut();
|
||||
let capacity = self.utf8_length(isolate);
|
||||
let mut string = std::string::String::with_capacity(capacity);
|
||||
let data = string.as_mut_ptr();
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
extern crate lazy_static;
|
||||
|
||||
use rusty_v8 as v8;
|
||||
use rusty_v8::{new_null, FunctionCallbackInfo, Local};
|
||||
use rusty_v8::{new_null, FunctionCallbackInfo, HandleScope, Local};
|
||||
use std::default::Default;
|
||||
use std::sync::Mutex;
|
||||
|
||||
lazy_static! {
|
||||
|
@ -64,11 +65,11 @@ fn handle_scope_numbers() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let l1 = v8::Integer::new(&isolate, -123);
|
||||
let l2 = v8::Integer::new_from_unsigned(&isolate, 456);
|
||||
v8::HandleScope::enter(&isolate, |_scope2| {
|
||||
let l3 = v8::Number::new(&isolate, 78.9);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let l1 = v8::Integer::new(scope, -123);
|
||||
let l2 = v8::Integer::new_from_unsigned(scope, 456);
|
||||
v8::HandleScope::enter(&isolate, |scope2| {
|
||||
let l3 = v8::Number::new(scope2, 78.9);
|
||||
assert_eq!(l1.value(), -123);
|
||||
assert_eq!(l2.value(), 456);
|
||||
assert_eq!(l3.value(), 78.9);
|
||||
|
@ -89,18 +90,22 @@ fn test_string() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let reference = "Hello 🦕 world!";
|
||||
let local = v8_str(&isolate, reference);
|
||||
let local =
|
||||
v8::String::new(scope, reference, v8::NewStringType::Normal).unwrap();
|
||||
assert_eq!(15, local.length());
|
||||
assert_eq!(17, local.utf8_length(&isolate));
|
||||
assert_eq!(reference, local.to_rust_string_lossy(&isolate));
|
||||
assert_eq!(17, local.utf8_length(scope));
|
||||
assert_eq!(reference, local.to_rust_string_lossy(scope));
|
||||
});
|
||||
drop(locker);
|
||||
}
|
||||
|
||||
fn v8_str(isolate: &v8::Isolate, s: &str) -> v8::Local<v8::String> {
|
||||
v8::String::new(&isolate, s, v8::NewStringType::Normal).unwrap()
|
||||
fn v8_str<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
s: &str,
|
||||
) -> v8::Local<'sc, v8::String> {
|
||||
v8::String::new(scope, s, v8::NewStringType::Normal).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -122,18 +127,20 @@ fn isolate_add_message_listener() {
|
|||
) {
|
||||
CALL_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
let isolate = message.get_isolate();
|
||||
let message_str = message.get();
|
||||
assert_eq!(message_str.to_rust_string_lossy(&isolate), "Uncaught foo");
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let message_str = message.get(scope);
|
||||
assert_eq!(message_str.to_rust_string_lossy(scope), "Uncaught foo");
|
||||
});
|
||||
}
|
||||
isolate.add_message_listener(check_message_0);
|
||||
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_s| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |s| {
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
let source = v8_str(&isolate, "throw 'foo'");
|
||||
let mut script = v8::Script::compile(context, source, None).unwrap();
|
||||
assert!(script.run(context).is_none());
|
||||
let source = v8::String::new(s, "throw 'foo'", Default::default()).unwrap();
|
||||
let mut script = v8::Script::compile(s, context, source, None).unwrap();
|
||||
assert!(script.run(s, context).is_none());
|
||||
assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
|
||||
context.exit();
|
||||
});
|
||||
|
@ -151,17 +158,19 @@ fn script_compile_and_run() {
|
|||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
|
||||
v8::HandleScope::enter(&isolate, |_s| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |s| {
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
let source = v8_str(&isolate, "'Hello ' + 13 + 'th planet'");
|
||||
let mut script = v8::Script::compile(context, source, None).unwrap();
|
||||
source.to_rust_string_lossy(&isolate);
|
||||
let result = script.run(context).unwrap();
|
||||
let source =
|
||||
v8::String::new(s, "'Hello ' + 13 + 'th planet'", Default::default())
|
||||
.unwrap();
|
||||
let mut script = v8::Script::compile(s, context, source, None).unwrap();
|
||||
source.to_rust_string_lossy(s);
|
||||
let result = script.run(s, context).unwrap();
|
||||
// TODO: safer casts.
|
||||
let result: v8::Local<v8::String> =
|
||||
unsafe { std::mem::transmute_copy(&result) };
|
||||
assert_eq!(result.to_rust_string_lossy(&isolate), "Hello 13th planet");
|
||||
assert_eq!(result.to_rust_string_lossy(s), "Hello 13th planet");
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -177,19 +186,21 @@ fn script_origin() {
|
|||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
|
||||
v8::HandleScope::enter(&isolate, |_s| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |s| {
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
|
||||
let resource_name = v8_str(&isolate, "foo.js");
|
||||
let resource_line_offset = v8::Integer::new(&isolate, 4);
|
||||
let resource_column_offset = v8::Integer::new(&isolate, 5);
|
||||
let resource_is_shared_cross_origin = v8::new_true(&isolate);
|
||||
let script_id = v8::Integer::new(&isolate, 123);
|
||||
let source_map_url = v8_str(&isolate, "source_map_url");
|
||||
let resource_is_opaque = v8::new_true(&isolate);
|
||||
let is_wasm = v8::new_false(&isolate);
|
||||
let is_module = v8::new_false(&isolate);
|
||||
let resource_name =
|
||||
v8::String::new(s, "foo.js", Default::default()).unwrap();
|
||||
let resource_line_offset = v8::Integer::new(s, 4);
|
||||
let resource_column_offset = v8::Integer::new(s, 5);
|
||||
let resource_is_shared_cross_origin = v8::new_true(s);
|
||||
let script_id = v8::Integer::new(s, 123);
|
||||
let source_map_url =
|
||||
v8::String::new(s, "source_map_url", Default::default()).unwrap();
|
||||
let resource_is_opaque = v8::new_true(s);
|
||||
let is_wasm = v8::new_false(s);
|
||||
let is_module = v8::new_false(s);
|
||||
|
||||
let script_origin = v8::ScriptOrigin::new(
|
||||
resource_name.into(),
|
||||
|
@ -203,11 +214,11 @@ fn script_origin() {
|
|||
is_module,
|
||||
);
|
||||
|
||||
let source = v8_str(&isolate, "1+2");
|
||||
let source = v8::String::new(s, "1+2", Default::default()).unwrap();
|
||||
let mut script =
|
||||
v8::Script::compile(context, source, Some(&script_origin)).unwrap();
|
||||
source.to_rust_string_lossy(&isolate);
|
||||
let _result = script.run(context).unwrap();
|
||||
v8::Script::compile(s, context, source, Some(&script_origin)).unwrap();
|
||||
source.to_rust_string_lossy(s);
|
||||
let _result = script.run(s, context).unwrap();
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -268,23 +279,23 @@ fn test_primitives() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let null = v8::new_null(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let null = v8::new_null(scope);
|
||||
assert!(!null.is_undefined());
|
||||
assert!(null.is_null());
|
||||
assert!(null.is_null_or_undefined());
|
||||
|
||||
let undefined = v8::new_undefined(&isolate);
|
||||
let undefined = v8::new_undefined(scope);
|
||||
assert!(undefined.is_undefined());
|
||||
assert!(!undefined.is_null());
|
||||
assert!(undefined.is_null_or_undefined());
|
||||
|
||||
let true_ = v8::new_true(&isolate);
|
||||
let true_ = v8::new_true(scope);
|
||||
assert!(!true_.is_undefined());
|
||||
assert!(!true_.is_null());
|
||||
assert!(!true_.is_null_or_undefined());
|
||||
|
||||
let false_ = v8::new_false(&isolate);
|
||||
let false_ = v8::new_false(scope);
|
||||
assert!(!false_.is_undefined());
|
||||
assert!(!false_.is_null());
|
||||
assert!(!false_.is_null_or_undefined());
|
||||
|
@ -302,24 +313,25 @@ fn exception() {
|
|||
let mut isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
isolate.enter();
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let reference = "This is a test error";
|
||||
let local = v8_str(&isolate, reference);
|
||||
v8::range_error(local);
|
||||
v8::reference_error(local);
|
||||
v8::syntax_error(local);
|
||||
v8::type_error(local);
|
||||
let exception = v8::error(local);
|
||||
let msg = v8::create_message(&isolate, exception);
|
||||
let msg_string = msg.get();
|
||||
let rust_msg_string = msg_string.to_rust_string_lossy(&isolate);
|
||||
let local =
|
||||
v8::String::new(scope, reference, v8::NewStringType::Normal).unwrap();
|
||||
v8::range_error(scope, local);
|
||||
v8::reference_error(scope, local);
|
||||
v8::syntax_error(scope, local);
|
||||
v8::type_error(scope, local);
|
||||
let exception = v8::error(scope, local);
|
||||
let msg = v8::create_message(scope, exception);
|
||||
let msg_string = msg.get(scope);
|
||||
let rust_msg_string = msg_string.to_rust_string_lossy(scope);
|
||||
assert_eq!(
|
||||
"Uncaught Error: This is a test error".to_string(),
|
||||
rust_msg_string
|
||||
);
|
||||
assert!(v8::get_stack_trace(exception).is_none());
|
||||
assert!(v8::get_stack_trace(scope, exception).is_none());
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -335,17 +347,17 @@ fn json() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_s| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |s| {
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
let json_string = v8_str(&isolate, "{\"a\": 1, \"b\": 2}");
|
||||
let json_string = v8_str(s, "{\"a\": 1, \"b\": 2}");
|
||||
let maybe_value = v8::json::parse(context, json_string);
|
||||
assert!(maybe_value.is_some());
|
||||
let value = maybe_value.unwrap();
|
||||
let maybe_stringified = v8::json::stringify(context, value);
|
||||
assert!(maybe_stringified.is_some());
|
||||
let stringified = maybe_stringified.unwrap();
|
||||
let rust_str = stringified.to_rust_string_lossy(&isolate);
|
||||
let rust_str = stringified.to_rust_string_lossy(s);
|
||||
assert_eq!("{\"a\":1,\"b\":2}".to_string(), rust_str);
|
||||
context.exit();
|
||||
});
|
||||
|
@ -367,19 +379,19 @@ fn object() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let null: v8::Local<v8::Value> = new_null(&isolate).into();
|
||||
let s1 = v8_str(&isolate, "a");
|
||||
let s2 = v8_str(&isolate, "b");
|
||||
let null: v8::Local<v8::Value> = new_null(scope).into();
|
||||
let s1 = v8::String::new(scope, "a", v8::NewStringType::Normal).unwrap();
|
||||
let s2 = v8::String::new(scope, "b", v8::NewStringType::Normal).unwrap();
|
||||
let name1: Local<v8::Name> = cast(s1);
|
||||
let name2: Local<v8::Name> = cast(s2);
|
||||
let names = vec![name1, name2];
|
||||
let v1: v8::Local<v8::Value> = v8::Number::new(&isolate, 1.0).into();
|
||||
let v2: v8::Local<v8::Value> = v8::Number::new(&isolate, 2.0).into();
|
||||
let v1: v8::Local<v8::Value> = v8::Number::new(scope, 1.0).into();
|
||||
let v2: v8::Local<v8::Value> = v8::Number::new(scope, 2.0).into();
|
||||
let values = vec![v1, v2];
|
||||
let object = v8::Object::new(&isolate, null, names, values, 2);
|
||||
let object = v8::Object::new(scope, null, names, values, 2);
|
||||
assert!(!object.is_null_or_undefined());
|
||||
context.exit();
|
||||
});
|
||||
|
@ -395,36 +407,32 @@ fn promise_resolved() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let maybe_resolver = v8::PromiseResolver::new(context);
|
||||
let maybe_resolver = v8::PromiseResolver::new(scope, context);
|
||||
assert!(maybe_resolver.is_some());
|
||||
let mut resolver = maybe_resolver.unwrap();
|
||||
let mut promise = resolver.get_promise();
|
||||
let mut promise = resolver.get_promise(scope);
|
||||
assert!(!promise.has_handler());
|
||||
assert_eq!(promise.state(), v8::PromiseState::Pending);
|
||||
let str = v8_str(&isolate, "test");
|
||||
let str =
|
||||
v8::String::new(scope, "test", v8::NewStringType::Normal).unwrap();
|
||||
let value: Local<v8::Value> = cast(str);
|
||||
resolver.resolve(context, value);
|
||||
assert_eq!(promise.state(), v8::PromiseState::Fulfilled);
|
||||
let result = promise.result();
|
||||
let result = promise.result(scope);
|
||||
let result_str: v8::Local<v8::String> = cast(result);
|
||||
assert_eq!(
|
||||
result_str.to_rust_string_lossy(&isolate),
|
||||
"test".to_string()
|
||||
);
|
||||
assert_eq!(result_str.to_rust_string_lossy(scope), "test".to_string());
|
||||
// Resolve again with different value, since promise is already in `Fulfilled` state
|
||||
// it should be ignored.
|
||||
let str = v8_str(&isolate, "test2");
|
||||
let str =
|
||||
v8::String::new(scope, "test2", v8::NewStringType::Normal).unwrap();
|
||||
let value: Local<v8::Value> = cast(str);
|
||||
resolver.resolve(context, value);
|
||||
let result = promise.result();
|
||||
let result = promise.result(scope);
|
||||
let result_str: v8::Local<v8::String> = cast(result);
|
||||
assert_eq!(
|
||||
result_str.to_rust_string_lossy(&isolate),
|
||||
"test".to_string()
|
||||
);
|
||||
assert_eq!(result_str.to_rust_string_lossy(scope), "test".to_string());
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -439,37 +447,33 @@ fn promise_rejected() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let maybe_resolver = v8::PromiseResolver::new(context);
|
||||
let maybe_resolver = v8::PromiseResolver::new(scope, context);
|
||||
assert!(maybe_resolver.is_some());
|
||||
let mut resolver = maybe_resolver.unwrap();
|
||||
let mut promise = resolver.get_promise();
|
||||
let mut promise = resolver.get_promise(scope);
|
||||
assert!(!promise.has_handler());
|
||||
assert_eq!(promise.state(), v8::PromiseState::Pending);
|
||||
let str = v8_str(&isolate, "test");
|
||||
let str =
|
||||
v8::String::new(scope, "test", v8::NewStringType::Normal).unwrap();
|
||||
let value: Local<v8::Value> = cast(str);
|
||||
let rejected = resolver.reject(context, value);
|
||||
assert!(rejected.unwrap());
|
||||
assert_eq!(promise.state(), v8::PromiseState::Rejected);
|
||||
let result = promise.result();
|
||||
let result = promise.result(scope);
|
||||
let result_str: v8::Local<v8::String> = cast(result);
|
||||
assert_eq!(
|
||||
result_str.to_rust_string_lossy(&isolate),
|
||||
"test".to_string()
|
||||
);
|
||||
assert_eq!(result_str.to_rust_string_lossy(scope), "test".to_string());
|
||||
// Reject again with different value, since promise is already in `Rejected` state
|
||||
// it should be ignored.
|
||||
let str = v8_str(&isolate, "test2");
|
||||
let str =
|
||||
v8::String::new(scope, "test2", v8::NewStringType::Normal).unwrap();
|
||||
let value: Local<v8::Value> = cast(str);
|
||||
resolver.reject(context, value);
|
||||
let result = promise.result();
|
||||
let result = promise.result(scope);
|
||||
let result_str: v8::Local<v8::String> = cast(result);
|
||||
assert_eq!(
|
||||
result_str.to_rust_string_lossy(&isolate),
|
||||
"test".to_string()
|
||||
);
|
||||
assert_eq!(result_str.to_rust_string_lossy(scope), "test".to_string());
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -478,16 +482,15 @@ fn promise_rejected() {
|
|||
extern "C" fn fn_callback(info: &FunctionCallbackInfo) {
|
||||
assert_eq!(info.length(), 0);
|
||||
let isolate = info.get_isolate();
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
context.enter();
|
||||
let s = v8_str(&isolate, "Hello callback!");
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let s =
|
||||
v8::String::new(scope, "Hello callback!", v8::NewStringType::Normal)
|
||||
.unwrap();
|
||||
let value: Local<v8::Value> = s.into();
|
||||
let rv = &mut info.get_return_value();
|
||||
let rv_value = rv.get();
|
||||
let rv_value = rv.get(scope);
|
||||
assert!(rv_value.is_undefined());
|
||||
rv.set(value);
|
||||
context.exit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -500,25 +503,26 @@ fn function() {
|
|||
);
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let global = context.global();
|
||||
let recv: Local<v8::Value> = global.into();
|
||||
// create function using template
|
||||
let mut fn_template = v8::FunctionTemplate::new(&isolate, fn_callback);
|
||||
let mut fn_template = v8::FunctionTemplate::new(scope, fn_callback);
|
||||
let mut function = fn_template
|
||||
.get_function(context)
|
||||
.get_function(scope, context)
|
||||
.expect("Unable to create function");
|
||||
let _value = v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
||||
let _value =
|
||||
v8::Function::call(&mut *function, scope, context, recv, 0, vec![]);
|
||||
// create function without a template
|
||||
let mut function = v8::Function::new(context, fn_callback)
|
||||
let mut function = v8::Function::new(scope, context, fn_callback)
|
||||
.expect("Unable to create function");
|
||||
let maybe_value =
|
||||
v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
||||
v8::Function::call(&mut *function, scope, context, recv, 0, vec![]);
|
||||
let value = maybe_value.unwrap();
|
||||
let value_str: v8::Local<v8::String> = cast(value);
|
||||
let rust_str = value_str.to_rust_string_lossy(&isolate);
|
||||
let rust_str = value_str.to_rust_string_lossy(scope);
|
||||
assert_eq!(rust_str, "Hello callback!".to_string());
|
||||
context.exit();
|
||||
});
|
||||
|
@ -534,9 +538,9 @@ extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
|
|||
let isolate = promise_obj.get_isolate();
|
||||
let value = msg.get_value();
|
||||
let locker = v8::Locker::new(isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let value_str: v8::Local<v8::String> = cast(value);
|
||||
let rust_str = value_str.to_rust_string_lossy(&isolate);
|
||||
let rust_str = value_str.to_rust_string_lossy(scope);
|
||||
assert_eq!(rust_str, "promise rejected".to_string());
|
||||
});
|
||||
drop(locker);
|
||||
|
@ -553,11 +557,13 @@ fn set_promise_reject_callback() {
|
|||
isolate.set_promise_reject_callback(promise_reject_callback);
|
||||
isolate.enter();
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let mut resolver = v8::PromiseResolver::new(context).unwrap();
|
||||
let str_ = v8_str(&isolate, "promise rejected");
|
||||
let mut resolver = v8::PromiseResolver::new(scope, context).unwrap();
|
||||
let str_ =
|
||||
v8::String::new(scope, "promise rejected", v8::NewStringType::Normal)
|
||||
.unwrap();
|
||||
let value: Local<v8::Value> = cast(str_);
|
||||
resolver.reject(context, value);
|
||||
context.exit();
|
||||
|
@ -566,16 +572,18 @@ fn set_promise_reject_callback() {
|
|||
isolate.exit();
|
||||
}
|
||||
|
||||
fn mock_script_origin(isolate: &v8::Isolate) -> v8::ScriptOrigin {
|
||||
let resource_name = v8_str(&isolate, "foo.js");
|
||||
let resource_line_offset = v8::Integer::new(&isolate, 4);
|
||||
let resource_column_offset = v8::Integer::new(&isolate, 5);
|
||||
let resource_is_shared_cross_origin = v8::new_true(&isolate);
|
||||
let script_id = v8::Integer::new(&isolate, 123);
|
||||
let source_map_url = v8_str(&isolate, "source_map_url");
|
||||
let resource_is_opaque = v8::new_true(&isolate);
|
||||
let is_wasm = v8::new_false(&isolate);
|
||||
let is_module = v8::new_true(&isolate);
|
||||
fn mock_script_origin<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
) -> v8::ScriptOrigin<'sc> {
|
||||
let resource_name = v8_str(scope, "foo.js");
|
||||
let resource_line_offset = v8::Integer::new(scope, 4);
|
||||
let resource_column_offset = v8::Integer::new(scope, 5);
|
||||
let resource_is_shared_cross_origin = v8::new_true(scope);
|
||||
let script_id = v8::Integer::new(scope, 123);
|
||||
let source_map_url = v8_str(scope, "source_map_url");
|
||||
let resource_is_opaque = v8::new_true(scope);
|
||||
let is_wasm = v8::new_false(scope);
|
||||
let is_module = v8::new_true(scope);
|
||||
v8::ScriptOrigin::new(
|
||||
resource_name.into(),
|
||||
resource_line_offset,
|
||||
|
@ -600,16 +608,14 @@ fn script_compiler_source() {
|
|||
isolate.set_promise_reject_callback(promise_reject_callback);
|
||||
isolate.enter();
|
||||
let locker = v8::Locker::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |_scope| {
|
||||
let mut context = v8::Context::new(&isolate);
|
||||
v8::HandleScope::enter(&isolate, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
|
||||
let source = "1+2";
|
||||
let script_origin = mock_script_origin(&isolate);
|
||||
let source = v8::script_compiler::Source::new(
|
||||
v8_str(&isolate, source),
|
||||
&script_origin,
|
||||
);
|
||||
let script_origin = mock_script_origin(scope);
|
||||
let source =
|
||||
v8::script_compiler::Source::new(v8_str(scope, source), &script_origin);
|
||||
|
||||
let result = v8::script_compiler::compile_module(
|
||||
&isolate,
|
||||
|
|
Loading…
Reference in a new issue