0
0
Fork 0
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:
Bert Belder 2019-12-20 16:01:45 +01:00
parent bbfaacfe56
commit 331582561b
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
16 changed files with 389 additions and 283 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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(),

View file

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

View file

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

View file

@ -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();

View file

@ -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();

View file

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