2019-12-20 08:47:20 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2019-11-20 13:34:32 -08:00
|
|
|
use crate::array_buffer::Allocator;
|
2019-12-19 14:13:33 +01:00
|
|
|
use crate::promise::PromiseRejectMessage;
|
2019-11-20 13:34:32 -08:00
|
|
|
use crate::support::Delete;
|
2019-11-15 16:21:34 -08:00
|
|
|
use crate::support::Opaque;
|
2019-11-20 13:34:32 -08:00
|
|
|
use crate::support::UniqueRef;
|
2019-12-24 16:40:41 -05:00
|
|
|
use crate::Context;
|
2019-12-19 21:34:07 -05:00
|
|
|
use crate::Local;
|
2019-12-20 08:47:20 -05:00
|
|
|
use crate::Message;
|
2019-12-24 16:40:41 -05:00
|
|
|
use crate::Module;
|
|
|
|
use crate::Object;
|
2019-12-24 14:03:32 +01:00
|
|
|
use crate::StartupData;
|
2019-12-19 21:34:07 -05:00
|
|
|
use crate::Value;
|
2019-12-25 10:56:27 -05:00
|
|
|
use std::ffi::c_void;
|
2019-12-20 08:47:20 -05:00
|
|
|
use std::ops::Deref;
|
|
|
|
use std::ops::DerefMut;
|
|
|
|
use std::ptr::NonNull;
|
2019-12-19 21:34:07 -05:00
|
|
|
|
2019-12-19 23:36:29 -05:00
|
|
|
type MessageCallback = extern "C" fn(Local<Message>, Local<Value>);
|
2019-11-15 16:21:34 -08:00
|
|
|
|
2019-12-19 14:13:33 +01:00
|
|
|
type PromiseRejectCallback = extern "C" fn(PromiseRejectMessage);
|
|
|
|
|
2019-12-24 16:40:41 -05:00
|
|
|
type HostInitializeImportMetaObjectCallback =
|
|
|
|
extern "C" fn(Local<Context>, Local<Module>, Local<Object>);
|
|
|
|
|
2019-11-15 16:21:34 -08:00
|
|
|
extern "C" {
|
2019-12-19 19:15:52 -05:00
|
|
|
fn v8__Isolate__New(params: *mut CreateParams) -> *mut Isolate;
|
|
|
|
fn v8__Isolate__Dispose(this: *mut Isolate);
|
2019-12-25 10:56:27 -05:00
|
|
|
fn v8__Isolate__SetData(this: *mut Isolate, slot: u32, data: *mut c_void);
|
|
|
|
fn v8__Isolate__GetData(this: *const Isolate, slot: u32) -> *mut c_void;
|
|
|
|
fn v8__Isolate__GetNumberOfDataSlots(this: *const Isolate) -> u32;
|
2019-12-19 19:15:52 -05:00
|
|
|
fn v8__Isolate__Enter(this: *mut Isolate);
|
|
|
|
fn v8__Isolate__Exit(this: *mut Isolate);
|
2019-12-18 17:17:38 -05:00
|
|
|
fn v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
|
2019-12-19 19:15:52 -05:00
|
|
|
this: *mut Isolate,
|
2019-12-18 17:17:38 -05:00
|
|
|
caputre: bool,
|
|
|
|
frame_limit: i32,
|
|
|
|
);
|
2019-12-19 21:34:07 -05:00
|
|
|
fn v8__Isolate__AddMessageListener(
|
|
|
|
this: &mut Isolate,
|
|
|
|
callback: MessageCallback,
|
|
|
|
) -> bool;
|
2019-12-19 14:13:33 +01:00
|
|
|
fn v8__Isolate__SetPromiseRejectCallback(
|
2019-12-19 19:15:52 -05:00
|
|
|
isolate: *mut Isolate,
|
2019-12-19 14:13:33 +01:00
|
|
|
callback: PromiseRejectCallback,
|
2019-12-19 19:15:52 -05:00
|
|
|
);
|
2019-12-24 16:40:41 -05:00
|
|
|
fn v8__Isolate__SetHostInitializeImportMetaObjectCallback(
|
|
|
|
isolate: *mut Isolate,
|
|
|
|
callback: HostInitializeImportMetaObjectCallback,
|
|
|
|
);
|
2019-12-23 08:16:01 -05:00
|
|
|
fn v8__Isolate__ThrowException(
|
|
|
|
isolate: &Isolate,
|
|
|
|
exception: &Value,
|
|
|
|
) -> *mut Value;
|
2019-11-20 13:34:32 -08:00
|
|
|
|
|
|
|
fn v8__Isolate__CreateParams__NEW() -> *mut CreateParams;
|
|
|
|
fn v8__Isolate__CreateParams__DELETE(this: &mut CreateParams);
|
|
|
|
fn v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
|
|
|
this: &mut CreateParams,
|
|
|
|
value: *mut Allocator,
|
|
|
|
);
|
2019-12-24 14:03:32 +01:00
|
|
|
fn v8__Isolate__CreateParams__SET__snapshot_blob(
|
|
|
|
this: &mut CreateParams,
|
|
|
|
snapshot_blob: *mut StartupData,
|
|
|
|
);
|
2019-11-15 16:21:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
2019-12-20 08:47:20 -05:00
|
|
|
/// Isolate represents an isolated instance of the V8 engine. V8 isolates have
|
|
|
|
/// completely separate states. Objects from one isolate must not be used in
|
|
|
|
/// other isolates. The embedder can create multiple isolates and use them in
|
|
|
|
/// parallel in multiple threads. An isolate can be entered by at most one
|
|
|
|
/// thread at any given time. The Locker/Unlocker API must be used to
|
|
|
|
/// synchronize.
|
2019-12-19 19:15:52 -05:00
|
|
|
pub struct Isolate(Opaque);
|
2019-11-27 07:14:39 -08:00
|
|
|
|
2019-11-15 16:21:34 -08:00
|
|
|
impl Isolate {
|
2019-12-04 00:57:06 -05:00
|
|
|
/// Creates a new isolate. Does not change the currently entered
|
|
|
|
/// isolate.
|
|
|
|
///
|
|
|
|
/// When an isolate is no longer used its resources should be freed
|
|
|
|
/// by calling V8::dispose(). Using the delete operator is not allowed.
|
|
|
|
///
|
|
|
|
/// V8::initialize() must have run prior to this.
|
2019-12-19 19:15:52 -05:00
|
|
|
#[allow(clippy::new_ret_no_self)]
|
|
|
|
pub fn new(params: UniqueRef<CreateParams>) -> OwnedIsolate {
|
2019-11-15 16:21:34 -08:00
|
|
|
// TODO: support CreateParams.
|
2019-11-30 09:16:25 -08:00
|
|
|
crate::V8::assert_initialized();
|
2019-12-19 19:15:52 -05:00
|
|
|
let isolate_ptr = unsafe { v8__Isolate__New(params.into_raw()) };
|
|
|
|
OwnedIsolate(NonNull::new(isolate_ptr).unwrap())
|
2019-11-15 16:21:34 -08:00
|
|
|
}
|
2019-12-04 00:57:06 -05:00
|
|
|
|
|
|
|
/// Initial configuration parameters for a new Isolate.
|
|
|
|
pub fn create_params() -> UniqueRef<CreateParams> {
|
|
|
|
CreateParams::new()
|
|
|
|
}
|
2019-12-09 02:26:58 +01:00
|
|
|
|
2019-12-25 10:56:27 -05:00
|
|
|
/// Associate embedder-specific data with the isolate. |slot| has to be
|
|
|
|
/// between 0 and GetNumberOfDataSlots() - 1.
|
|
|
|
pub unsafe fn set_data(&mut self, slot: u32, ptr: *mut c_void) {
|
|
|
|
v8__Isolate__SetData(self, slot, ptr)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieve embedder-specific data from the isolate.
|
|
|
|
/// Returns NULL if SetData has never been called for the given |slot|.
|
|
|
|
pub fn get_data(&self, slot: u32) -> *mut c_void {
|
|
|
|
unsafe { v8__Isolate__GetData(self, slot) }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the maximum number of available embedder data slots. Valid slots
|
|
|
|
/// are in the range of 0 - GetNumberOfDataSlots() - 1.
|
|
|
|
pub fn get_number_of_data_slots(&self) -> u32 {
|
|
|
|
unsafe { v8__Isolate__GetNumberOfDataSlots(self) }
|
|
|
|
}
|
|
|
|
|
2019-12-09 02:26:58 +01:00
|
|
|
/// Sets this isolate as the entered one for the current thread.
|
|
|
|
/// Saves the previously entered one (if any), so that it can be
|
|
|
|
/// restored when exiting. Re-entering an isolate is allowed.
|
|
|
|
pub fn enter(&mut self) {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { v8__Isolate__Enter(self) }
|
2019-12-09 02:26:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Exits this isolate by restoring the previously entered one in the
|
|
|
|
/// current thread. The isolate may still stay the same, if it was
|
|
|
|
/// entered more than once.
|
|
|
|
///
|
|
|
|
/// Requires: self == Isolate::GetCurrent().
|
|
|
|
pub fn exit(&mut self) {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { v8__Isolate__Exit(self) }
|
2019-12-09 02:26:58 +01:00
|
|
|
}
|
2019-12-18 17:17:38 -05:00
|
|
|
|
|
|
|
/// Tells V8 to capture current stack trace when uncaught exception occurs
|
|
|
|
/// and report it to the message listeners. The option is off by default.
|
|
|
|
pub fn set_capture_stack_trace_for_uncaught_exceptions(
|
|
|
|
&mut self,
|
|
|
|
capture: bool,
|
|
|
|
frame_limit: i32,
|
|
|
|
) {
|
|
|
|
unsafe {
|
|
|
|
v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
|
2019-12-19 19:15:52 -05:00
|
|
|
self,
|
2019-12-18 17:17:38 -05:00
|
|
|
capture,
|
|
|
|
frame_limit,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2019-12-19 14:13:33 +01:00
|
|
|
|
2019-12-19 21:34:07 -05:00
|
|
|
/// Adds a message listener (errors only).
|
|
|
|
///
|
|
|
|
/// The same message listener can be added more than once and in that
|
|
|
|
/// case it will be called more than once for each message.
|
|
|
|
///
|
|
|
|
/// The exception object will be passed to the callback.
|
|
|
|
pub fn add_message_listener(&mut self, callback: MessageCallback) -> bool {
|
|
|
|
unsafe { v8__Isolate__AddMessageListener(self, callback) }
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:13:33 +01:00
|
|
|
/// Set callback to notify about promise reject with no handler, or
|
|
|
|
/// revocation of such a previous notification once the handler is added.
|
|
|
|
pub fn set_promise_reject_callback(
|
|
|
|
&mut self,
|
|
|
|
callback: PromiseRejectCallback,
|
|
|
|
) {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { v8__Isolate__SetPromiseRejectCallback(self, callback) }
|
|
|
|
}
|
2019-12-24 16:40:41 -05:00
|
|
|
/// This specifies the callback called by the upcoming importa.meta
|
|
|
|
/// language feature to retrieve host-defined meta data for a module.
|
|
|
|
pub fn set_host_initialize_import_meta_object_callback(
|
|
|
|
&mut self,
|
|
|
|
callback: HostInitializeImportMetaObjectCallback,
|
|
|
|
) {
|
|
|
|
unsafe {
|
|
|
|
v8__Isolate__SetHostInitializeImportMetaObjectCallback(self, callback)
|
|
|
|
}
|
|
|
|
}
|
2019-12-19 19:15:52 -05:00
|
|
|
|
2019-12-23 08:16:01 -05:00
|
|
|
/// Schedules an exception to be thrown when returning to JavaScript. When an
|
|
|
|
/// exception has been scheduled it is illegal to invoke any JavaScript
|
|
|
|
/// operation; the caller must return immediately and only after the exception
|
|
|
|
/// has been handled does it become legal to invoke JavaScript operations.
|
|
|
|
pub fn throw_exception<'sc>(
|
|
|
|
&self,
|
|
|
|
exception: Local<'_, Value>,
|
|
|
|
) -> Local<'sc, Value> {
|
|
|
|
unsafe {
|
|
|
|
let ptr = v8__Isolate__ThrowException(self, &exception);
|
2019-12-25 12:39:42 +01:00
|
|
|
Local::from_raw(ptr).unwrap()
|
2019-12-23 08:16:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 19:15:52 -05:00
|
|
|
/// Disposes the isolate. The isolate must not be entered by any
|
|
|
|
/// thread to be disposable.
|
|
|
|
pub unsafe fn dispose(&mut self) {
|
|
|
|
v8__Isolate__Dispose(self)
|
2019-12-19 14:13:33 +01:00
|
|
|
}
|
2019-11-15 16:21:34 -08:00
|
|
|
}
|
|
|
|
|
2019-12-19 19:15:52 -05:00
|
|
|
/// Same as Isolate but gets disposed when it goes out of scope.
|
|
|
|
pub struct OwnedIsolate(NonNull<Isolate>);
|
|
|
|
|
|
|
|
impl Drop for OwnedIsolate {
|
2019-11-15 16:21:34 -08:00
|
|
|
fn drop(&mut self) {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { self.0.as_mut().dispose() }
|
2019-11-15 16:21:34 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 19:15:52 -05:00
|
|
|
impl Deref for OwnedIsolate {
|
|
|
|
type Target = Isolate;
|
2019-11-30 16:31:51 +01:00
|
|
|
fn deref(&self) -> &Self::Target {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { self.0.as_ref() }
|
2019-11-15 16:21:34 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 19:15:52 -05:00
|
|
|
impl DerefMut for OwnedIsolate {
|
2019-11-30 16:31:51 +01:00
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2019-12-19 19:15:52 -05:00
|
|
|
unsafe { self.0.as_mut() }
|
2019-11-30 16:31:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-25 00:31:36 +01:00
|
|
|
/// Trait for retrieving the current isolate from a scope object.
|
|
|
|
pub trait InIsolate {
|
|
|
|
// Do not implement this trait on unscoped Isolate references
|
|
|
|
// (e.g. OwnedIsolate).
|
|
|
|
fn isolate(&mut self) -> &mut Isolate;
|
|
|
|
}
|
|
|
|
|
2019-11-20 13:34:32 -08:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct CreateParams(Opaque);
|
|
|
|
|
|
|
|
impl CreateParams {
|
|
|
|
pub fn new() -> UniqueRef<CreateParams> {
|
|
|
|
unsafe { UniqueRef::from_raw(v8__Isolate__CreateParams__NEW()) }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_array_buffer_allocator(&mut self, value: UniqueRef<Allocator>) {
|
|
|
|
unsafe {
|
|
|
|
v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
|
|
|
self,
|
|
|
|
value.into_raw(),
|
|
|
|
)
|
|
|
|
};
|
|
|
|
}
|
2019-12-24 14:03:32 +01:00
|
|
|
|
|
|
|
/// Hand startup data to V8, in case the embedder has chosen to build
|
|
|
|
/// V8 with external startup data.
|
|
|
|
///
|
|
|
|
/// Note:
|
|
|
|
/// - By default the startup data is linked into the V8 library, in which
|
|
|
|
/// case this function is not meaningful.
|
|
|
|
/// - If this needs to be called, it needs to be called before V8
|
|
|
|
/// tries to make use of its built-ins.
|
|
|
|
/// - To avoid unnecessary copies of data, V8 will point directly into the
|
|
|
|
/// given data blob, so pretty please keep it around until V8 exit.
|
|
|
|
/// - Compression of the startup blob might be useful, but needs to
|
|
|
|
/// handled entirely on the embedders' side.
|
|
|
|
/// - The call will abort if the data is invalid.
|
|
|
|
pub fn set_snapshot_blob(&mut self, snapshot_blob: &mut StartupData) {
|
|
|
|
unsafe {
|
|
|
|
v8__Isolate__CreateParams__SET__snapshot_blob(self, &mut *snapshot_blob)
|
|
|
|
};
|
|
|
|
}
|
2019-11-20 13:34:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Delete for CreateParams {
|
|
|
|
fn delete(&'static mut self) {
|
|
|
|
unsafe { v8__Isolate__CreateParams__DELETE(self) }
|
|
|
|
}
|
|
|
|
}
|