0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-26 17:19:09 -05:00

Make Isolate take ownership of CreateParams (#357)

This commit is contained in:
Bert Belder 2020-04-20 21:18:03 +02:00
parent fc582316db
commit 05782b846f
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
9 changed files with 534 additions and 380 deletions

View file

@ -126,10 +126,9 @@ impl Shared for Allocator {
} }
/// malloc/free based convenience allocator. /// malloc/free based convenience allocator.
pub fn new_default_allocator() -> SharedRef<Allocator> { pub fn new_default_allocator() -> UniqueRef<Allocator> {
unsafe { unsafe {
UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator()) UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
.make_shared()
} }
} }

View file

@ -100,12 +100,8 @@ bool v8__V8__Dispose() { return v8::V8::Dispose(); }
void v8__V8__ShutdownPlatform() { v8::V8::ShutdownPlatform(); } void v8__V8__ShutdownPlatform() { v8::V8::ShutdownPlatform(); }
// This function consumes the Isolate::CreateParams object. The Isolate takes v8::Isolate* v8__Isolate__New(const v8::Isolate::CreateParams& params) {
// ownership of the ArrayBuffer::Allocator referenced by the params object. return v8::Isolate::New(params);
v8::Isolate* v8__Isolate__New(v8::Isolate::CreateParams* params) {
auto isolate = v8::Isolate::New(*params);
delete params;
return isolate;
} }
void v8__Isolate__Dispose(v8::Isolate* isolate) { isolate->Dispose(); } void v8__Isolate__Dispose(v8::Isolate* isolate) { isolate->Dispose(); }
@ -194,36 +190,13 @@ void v8__Isolate__CancelTerminateExecution(v8::Isolate* isolate) {
isolate->CancelTerminateExecution(); isolate->CancelTerminateExecution();
} }
v8::Isolate::CreateParams* v8__Isolate__CreateParams__NEW() { void v8__Isolate__CreateParams__CONSTRUCT(
return new v8::Isolate::CreateParams(); uninit_t<v8::Isolate::CreateParams>* buf) {
construct_in_place<v8::Isolate::CreateParams>(buf);
} }
// This function is only called if the Isolate::CreateParams object is *not* size_t v8__Isolate__CreateParams__SIZEOF() {
// consumed by Isolate::New(). return sizeof(v8::Isolate::CreateParams);
void v8__Isolate__CreateParams__DELETE(v8::Isolate::CreateParams* self) {
assert(self->array_buffer_allocator ==
nullptr); // We only used the shared version.
delete self;
}
// This function takes ownership of the ArrayBuffer::Allocator.
void v8__Isolate__CreateParams__SET__array_buffer_allocator(
v8::Isolate::CreateParams* self,
const std::shared_ptr<v8::ArrayBuffer::Allocator>& allocator) {
self->array_buffer_allocator_shared = allocator;
}
// external_references should probably have static lifetime.
void v8__Isolate__CreateParams__SET__external_references(
v8::Isolate::CreateParams* self, const intptr_t* external_references) {
assert(self->external_references == nullptr);
self->external_references = external_references;
}
// This function does not take ownership of the StartupData.
void v8__Isolate__CreateParams__SET__snapshot_blob(
v8::Isolate::CreateParams* self, v8::StartupData* snapshot_blob) {
self->snapshot_blob = snapshot_blob;
} }
void v8__HandleScope__CONSTRUCT(uninit_t<v8::HandleScope>* buf, void v8__HandleScope__CONSTRUCT(uninit_t<v8::HandleScope>* buf,

View file

@ -12,23 +12,35 @@ pub union ExternalReference<'s> {
} }
pub struct ExternalReferences { pub struct ExternalReferences {
null_terminated: Vec<*const std::ffi::c_void>, null_terminated: Vec<intptr_t>,
} }
unsafe impl Sync for ExternalReferences {} unsafe impl Sync for ExternalReferences {}
impl ExternalReferences { impl ExternalReferences {
pub fn new(refs: &[ExternalReference]) -> Self { pub fn new(refs: &[ExternalReference]) -> Self {
let mut null_terminated = Vec::with_capacity(refs.len() + 1); let null_terminated = refs
for r in refs { .iter()
let ptr = unsafe { std::mem::transmute(*r) }; .map(|&r| unsafe { std::mem::transmute(r) })
null_terminated.push(ptr); .chain(std::iter::once(0)) // Add null terminator.
} .collect::<Vec<intptr_t>>();
null_terminated.push(std::ptr::null());
Self { null_terminated } Self { null_terminated }
} }
pub fn as_ptr(&self) -> *const intptr_t { pub fn as_ptr(&self) -> *const intptr_t {
self.null_terminated.as_ptr() as *const intptr_t self.null_terminated.as_ptr()
}
}
impl std::ops::Deref for ExternalReferences {
type Target = [intptr_t];
fn deref(&self) -> &Self::Target {
&*self.null_terminated
}
}
impl std::borrow::Borrow<[intptr_t]> for ExternalReferences {
fn borrow(&self) -> &[intptr_t] {
&**self
} }
} }

View file

@ -1,11 +1,8 @@
// Copyright 2019-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2019-2020 the Deno authors. All rights reserved. MIT license.
use crate::array_buffer::Allocator; use crate::isolate_create_params::raw;
use crate::external_references::ExternalReferences; use crate::isolate_create_params::CreateParams;
use crate::promise::PromiseRejectMessage; use crate::promise::PromiseRejectMessage;
use crate::support::intptr_t;
use crate::support::Opaque; use crate::support::Opaque;
use crate::support::SharedRef;
use crate::support::UniqueRef;
use crate::Context; use crate::Context;
use crate::Function; use crate::Function;
use crate::InIsolate; use crate::InIsolate;
@ -15,10 +12,10 @@ use crate::Module;
use crate::Object; use crate::Object;
use crate::Promise; use crate::Promise;
use crate::ScriptOrModule; use crate::ScriptOrModule;
use crate::StartupData;
use crate::String; use crate::String;
use crate::Value; use crate::Value;
use std::any::Any;
use std::ffi::c_void; use std::ffi::c_void;
use std::mem::replace; use std::mem::replace;
use std::ops::Deref; use std::ops::Deref;
@ -71,7 +68,7 @@ pub type InterruptCallback =
extern "C" fn(isolate: &mut Isolate, data: *mut c_void); extern "C" fn(isolate: &mut Isolate, data: *mut c_void);
extern "C" { extern "C" {
fn v8__Isolate__New(params: *mut CreateParams) -> *mut Isolate; fn v8__Isolate__New(params: *const raw::CreateParams) -> *mut Isolate;
fn v8__Isolate__Dispose(this: *mut Isolate); fn v8__Isolate__Dispose(this: *mut Isolate);
fn v8__Isolate__SetData(this: *mut Isolate, slot: u32, data: *mut c_void); 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__GetData(this: *const Isolate, slot: u32) -> *mut c_void;
@ -117,20 +114,6 @@ extern "C" {
function: *const Function, function: *const Function,
); );
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,
allocator: *const SharedRef<Allocator>,
);
fn v8__Isolate__CreateParams__SET__external_references(
this: *mut CreateParams,
value: *const intptr_t,
);
fn v8__Isolate__CreateParams__SET__snapshot_blob(
this: *mut CreateParams,
snapshot_blob: *mut StartupData,
);
fn v8__HeapProfiler__TakeHeapSnapshot( fn v8__HeapProfiler__TakeHeapSnapshot(
isolate: *mut Isolate, isolate: *mut Isolate,
callback: extern "C" fn(*mut c_void, *const u8, usize) -> bool, callback: extern "C" fn(*mut c_void, *const u8, usize) -> bool,
@ -156,15 +139,16 @@ impl Isolate {
/// ///
/// V8::initialize() must have run prior to this. /// V8::initialize() must have run prior to this.
#[allow(clippy::new_ret_no_self)] #[allow(clippy::new_ret_no_self)]
pub fn new(params: UniqueRef<CreateParams>) -> OwnedIsolate { pub fn new(params: CreateParams) -> OwnedIsolate {
// TODO: support CreateParams.
crate::V8::assert_initialized(); crate::V8::assert_initialized();
unsafe { new_owned_isolate(v8__Isolate__New(params.into_raw())) } let (raw_create_params, create_param_allocations) = params.finalize();
let cxx_isolate = unsafe { v8__Isolate__New(&raw_create_params) };
OwnedIsolate::new(cxx_isolate, create_param_allocations)
} }
/// Initial configuration parameters for a new Isolate. /// Initial configuration parameters for a new Isolate.
pub fn create_params() -> UniqueRef<CreateParams> { pub fn create_params() -> CreateParams {
CreateParams::new() CreateParams::default()
} }
pub fn thread_safe_handle(&mut self) -> IsolateHandle { pub fn thread_safe_handle(&mut self) -> IsolateHandle {
@ -476,18 +460,24 @@ impl IsolateHandle {
} }
} }
/// Internal method for constructing an OwnedIsolate. /// Same as Isolate but gets disposed when it goes out of scope.
pub(crate) unsafe fn new_owned_isolate( pub struct OwnedIsolate {
isolate_ptr: *mut Isolate, cxx_isolate: NonNull<Isolate>,
) -> OwnedIsolate { create_param_allocations: Box<dyn Any>,
OwnedIsolate(NonNull::new(isolate_ptr).unwrap())
} }
/// Same as Isolate but gets disposed when it goes out of scope. impl OwnedIsolate {
pub struct OwnedIsolate(NonNull<Isolate>); pub(crate) fn new(
cxx_isolate: *mut Isolate,
// TODO(ry) unsafe impl Send for OwnedIsolate {} create_param_allocations: Box<dyn Any>,
// TODO(ry) impl !Sync for OwnedIsolate {} ) -> Self {
let cxx_isolate = NonNull::new(cxx_isolate).unwrap();
Self {
cxx_isolate,
create_param_allocations,
}
}
}
impl InIsolate for OwnedIsolate { impl InIsolate for OwnedIsolate {
fn isolate(&mut self) -> &mut Isolate { fn isolate(&mut self) -> &mut Isolate {
@ -497,85 +487,19 @@ impl InIsolate for OwnedIsolate {
impl Drop for OwnedIsolate { impl Drop for OwnedIsolate {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { self.0.as_mut().dispose() } unsafe { self.cxx_isolate.as_mut().dispose() }
} }
} }
impl Deref for OwnedIsolate { impl Deref for OwnedIsolate {
type Target = Isolate; type Target = Isolate;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
unsafe { self.0.as_ref() } unsafe { self.cxx_isolate.as_ref() }
} }
} }
impl DerefMut for OwnedIsolate { impl DerefMut for OwnedIsolate {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.0.as_mut() } unsafe { self.cxx_isolate.as_mut() }
}
}
/// Initial configuration parameters for a new Isolate.
#[repr(C)]
pub struct CreateParams(Opaque);
impl CreateParams {
pub fn new() -> UniqueRef<CreateParams> {
unsafe { UniqueRef::from_raw(v8__Isolate__CreateParams__NEW()) }
}
/// The ArrayBuffer::Allocator to use for allocating and freeing the backing
/// store of ArrayBuffers.
///
/// The Isolate instance and every |BackingStore| allocated using this
/// allocator hold a SharedRef to the allocator, in order to facilitate
/// lifetime management for the allocator instance.
pub fn set_array_buffer_allocator(&mut self, value: SharedRef<Allocator>) {
unsafe {
v8__Isolate__CreateParams__SET__array_buffer_allocator(self, &value)
};
}
/// Specifies an optional nullptr-terminated array of raw addresses in the
/// embedder that V8 can match against during serialization and use for
/// deserialization. This array and its content must stay valid for the
/// entire lifetime of the isolate.
pub fn set_external_references(
&mut self,
external_references: &'static ExternalReferences,
) {
unsafe {
v8__Isolate__CreateParams__SET__external_references(
self,
external_references.as_ptr(),
)
};
}
/// 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: &StartupData) {
unsafe {
v8__Isolate__CreateParams__SET__snapshot_blob(
self,
snapshot_blob as *const _ as *mut StartupData,
)
};
}
}
impl Drop for CreateParams {
fn drop(&mut self) {
unsafe { v8__Isolate__CreateParams__DELETE(self) }
} }
} }

View file

@ -0,0 +1,189 @@
use crate::array_buffer;
use crate::array_buffer::Allocator as ArrayBufferAllocator;
use crate::support::char;
use crate::support::int;
use crate::support::intptr_t;
use crate::support::Allocated;
use crate::support::Allocation;
use crate::support::Opaque;
use crate::support::SharedPtr;
use std::any::Any;
use std::convert::TryFrom;
use std::iter::once;
use std::mem::size_of;
use std::mem::MaybeUninit;
use std::ptr::null;
/// Initial configuration parameters for a new Isolate.
#[must_use]
#[derive(Default)]
pub struct CreateParams {
raw: raw::CreateParams,
allocations: CreateParamAllocations,
}
impl CreateParams {
/// Explicitly specify a startup snapshot blob.
pub fn snapshot_blob(mut self, data: impl Allocated<[u8]>) -> Self {
let data = Allocation::of(data);
let header = Allocation::of(raw::StartupData::boxed_header(&data));
self.raw.snapshot_blob = &*header;
self.allocations.snapshot_blob_data = Some(data);
self.allocations.snapshot_blob_header = Some(header);
self
}
/// The ArrayBuffer::ArrayBufferAllocator to use for allocating and freeing the backing
/// store of ArrayBuffers.
pub fn array_buffer_allocator(
mut self,
array_buffer_allocator: impl Into<SharedPtr<ArrayBufferAllocator>>,
) -> Self {
self.raw.array_buffer_allocator_shared = array_buffer_allocator.into();
self
}
/// Specifies an optional nullptr-terminated array of raw addresses in the
/// embedder that V8 can match against during serialization and use for
/// deserialization. This array and its content must stay valid for the
/// entire lifetime of the isolate.
pub fn external_references(
mut self,
ext_refs: impl Allocated<[intptr_t]>,
) -> Self {
let last_non_null = ext_refs
.iter()
.cloned()
.enumerate()
.rev()
.find_map(|(idx, value)| if value != 0 { Some(idx) } else { None });
let first_null = ext_refs
.iter()
.cloned()
.enumerate()
.find_map(|(idx, value)| if value == 0 { Some(idx) } else { None });
match (last_non_null, first_null) {
(None, _) => {
// Empty list.
self.raw.external_references = null();
self.allocations.external_references = None;
}
(_, None) => {
// List does not have null terminator. Make a copy and add it.
let ext_refs =
ext_refs.iter().cloned().chain(once(0)).collect::<Vec<_>>();
let ext_refs = Allocation::of(ext_refs);
self.raw.external_references = &ext_refs[0];
self.allocations.external_references = Some(ext_refs);
}
(Some(idx1), Some(idx2)) if idx1 + 1 == idx2 => {
// List is properly null terminated, we'll use it as-is.
let ext_refs = Allocation::of(ext_refs);
self.raw.external_references = &ext_refs[0];
self.allocations.external_references = Some(ext_refs);
}
_ => panic!("unexpected null pointer in external references list"),
}
self
}
/// Whether calling Atomics.wait (a function that may block) is allowed in
/// this isolate. This can also be configured via SetAllowAtomicsWait.
pub fn allow_atomics_wait(mut self, value: bool) -> Self {
self.raw.allow_atomics_wait = value;
self
}
/// Termination is postponed when there is no active SafeForTerminationScope.
pub fn only_terminate_in_safe_scope(mut self, value: bool) -> Self {
self.raw.only_terminate_in_safe_scope = value;
self
}
fn set_fallback_defaults(mut self) -> Self {
if self.raw.array_buffer_allocator_shared.is_null() {
self = self.array_buffer_allocator(array_buffer::new_default_allocator());
}
self
}
pub(crate) fn finalize(mut self) -> (raw::CreateParams, Box<dyn Any>) {
self = self.set_fallback_defaults();
let Self { raw, allocations } = self;
(raw, Box::new(allocations))
}
}
#[derive(Default)]
struct CreateParamAllocations {
// Owner of the snapshot data buffer itself.
snapshot_blob_data: Option<Allocation<[u8]>>,
// Owns `struct StartupData` which contains just the (ptr, len) tuple in V8's
// preferred format. We have to heap allocate this because we need to put a
// stable pointer to it in `CreateParams`.
snapshot_blob_header: Option<Allocation<raw::StartupData>>,
external_references: Option<Allocation<[intptr_t]>>,
}
pub(crate) mod raw {
use super::*;
#[repr(C)]
pub(crate) struct CreateParams {
pub code_event_handler: *const Opaque, // JitCodeEventHandler
pub constraints: ResourceConstraints,
pub snapshot_blob: *const StartupData,
pub counter_lookup_callback: *const Opaque, // CounterLookupCallback
pub create_histogram_callback: *const Opaque, // CreateHistogramCallback
pub add_histogram_sample_callback: *const Opaque, // AddHistogramSampleCallback
pub array_buffer_allocator: *mut ArrayBufferAllocator,
pub array_buffer_allocator_shared: SharedPtr<ArrayBufferAllocator>,
pub external_references: *const intptr_t,
pub allow_atomics_wait: bool,
pub only_terminate_in_safe_scope: bool,
}
extern "C" {
fn v8__Isolate__CreateParams__CONSTRUCT(
buf: *mut MaybeUninit<CreateParams>,
);
fn v8__Isolate__CreateParams__SIZEOF() -> usize;
}
impl Default for CreateParams {
fn default() -> Self {
let size = unsafe { v8__Isolate__CreateParams__SIZEOF() };
assert_eq!(size_of::<Self>(), size);
let mut buf = MaybeUninit::<Self>::uninit();
unsafe { v8__Isolate__CreateParams__CONSTRUCT(&mut buf) };
unsafe { buf.assume_init() }
}
}
#[repr(C)]
pub(crate) struct StartupData {
pub data: *const char,
pub raw_size: int,
}
impl StartupData {
pub(super) fn boxed_header(data: &Allocation<[u8]>) -> Box<Self> {
Box::new(Self {
data: &data[0] as *const _ as *const char,
raw_size: int::try_from(data.len()).unwrap(),
})
}
}
#[repr(C)]
pub(crate) struct ResourceConstraints {
code_range_size_: usize,
max_old_generation_size_: usize,
max_young_generation_size_: usize,
max_zone_pool_size_: usize,
initial_old_generation_size_: usize,
initial_young_generation_size_: usize,
stack_limit_: *mut u32,
}
}

View file

@ -9,9 +9,7 @@
//! v8::V8::initialize_platform(platform); //! v8::V8::initialize_platform(platform);
//! v8::V8::initialize(); //! v8::V8::initialize();
//! //!
//! let mut create_params = v8::Isolate::create_params(); //! let mut isolate = v8::Isolate::new(Default::default());
//! create_params.set_array_buffer_allocator(v8::new_default_allocator());
//! let mut isolate = v8::Isolate::new(create_params);
//! //!
//! let mut handle_scope = v8::HandleScope::new(&mut isolate); //! let mut handle_scope = v8::HandleScope::new(&mut isolate);
//! let scope = handle_scope.enter(); //! let scope = handle_scope.enter();
@ -85,6 +83,7 @@ mod function;
mod global; mod global;
mod handle_scope; mod handle_scope;
mod isolate; mod isolate;
mod isolate_create_params;
mod local; mod local;
mod module; mod module;
mod number; mod number;
@ -125,7 +124,6 @@ pub use function::*;
pub use global::Global; pub use global::Global;
pub use handle_scope::EscapableHandleScope; pub use handle_scope::EscapableHandleScope;
pub use handle_scope::HandleScope; pub use handle_scope::HandleScope;
pub use isolate::CreateParams;
pub use isolate::HostImportModuleDynamicallyCallback; pub use isolate::HostImportModuleDynamicallyCallback;
pub use isolate::HostInitializeImportMetaObjectCallback; pub use isolate::HostInitializeImportMetaObjectCallback;
pub use isolate::Isolate; pub use isolate::Isolate;
@ -133,6 +131,7 @@ pub use isolate::IsolateHandle;
pub use isolate::MessageCallback; pub use isolate::MessageCallback;
pub use isolate::OwnedIsolate; pub use isolate::OwnedIsolate;
pub use isolate::PromiseRejectCallback; pub use isolate::PromiseRejectCallback;
pub use isolate_create_params::CreateParams;
pub use local::Local; pub use local::Local;
pub use module::*; pub use module::*;
pub use object::*; pub use object::*;
@ -154,7 +153,6 @@ pub use scope::Scope;
pub use scope_traits::*; pub use scope_traits::*;
pub use script::ScriptOrigin; pub use script::ScriptOrigin;
pub use snapshot::FunctionCodeHandling; pub use snapshot::FunctionCodeHandling;
pub use snapshot::OwnedStartupData;
pub use snapshot::SnapshotCreator; pub use snapshot::SnapshotCreator;
pub use snapshot::StartupData; pub use snapshot::StartupData;
pub use string::NewStringType; pub use string::NewStringType;

View file

@ -1,15 +1,16 @@
use crate::external_references::ExternalReferences; use crate::external_references::ExternalReferences;
use crate::support::char;
use crate::support::int; use crate::support::int;
use crate::support::intptr_t; use crate::support::intptr_t;
use crate::Context; use crate::Context;
use crate::Isolate; use crate::Isolate;
use crate::Local; use crate::Local;
use crate::OwnedIsolate; use crate::OwnedIsolate;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::marker::PhantomData; use std::convert::TryFrom;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ops::Deref; use std::ops::Deref;
use std::ops::DerefMut;
extern "C" { extern "C" {
fn v8__SnapshotCreator__CONSTRUCT( fn v8__SnapshotCreator__CONSTRUCT(
@ -23,7 +24,7 @@ extern "C" {
fn v8__SnapshotCreator__CreateBlob( fn v8__SnapshotCreator__CreateBlob(
this: *mut SnapshotCreator, this: *mut SnapshotCreator,
function_code_handling: FunctionCodeHandling, function_code_handling: FunctionCodeHandling,
) -> OwnedStartupData; ) -> StartupData;
fn v8__SnapshotCreator__SetDefaultContext( fn v8__SnapshotCreator__SetDefaultContext(
this: *mut SnapshotCreator, this: *mut SnapshotCreator,
context: *const Context, context: *const Context,
@ -32,52 +33,35 @@ extern "C" {
} }
#[repr(C)] #[repr(C)]
pub struct StartupData<'a> { pub struct StartupData {
data: *const u8, data: *const char,
raw_size: int, raw_size: int,
_phantom: PhantomData<&'a [u8]>,
} }
impl<'a> StartupData<'a> { impl Deref for StartupData {
pub fn new<D>(data: &'a D) -> Self
where
D: Borrow<[u8]> + ?Sized,
{
let data = data.borrow();
Self {
data: data.as_ptr(),
raw_size: data.len() as int,
_phantom: PhantomData,
}
}
}
impl<'a> Deref for StartupData<'a> {
type Target = [u8]; type Target = [u8];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
unsafe { std::slice::from_raw_parts(self.data, self.raw_size as usize) } let data = self.data as *const u8;
let len = usize::try_from(self.raw_size).unwrap();
unsafe { std::slice::from_raw_parts(data, len) }
} }
} }
#[repr(transparent)] impl AsRef<[u8]> for StartupData {
pub struct OwnedStartupData(StartupData<'static>); fn as_ref(&self) -> &[u8] {
&**self
impl Deref for OwnedStartupData {
type Target = StartupData<'static>;
fn deref(&self) -> &Self::Target {
&self.0
} }
} }
impl DerefMut for OwnedStartupData { impl Borrow<[u8]> for StartupData {
fn deref_mut(&mut self) -> &mut Self::Target { fn borrow(&self) -> &[u8] {
&mut self.0 &**self
} }
} }
impl Drop for OwnedStartupData { impl Drop for StartupData {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { v8__StartupData__DESTRUCT(&mut self.0) } unsafe { v8__StartupData__DESTRUCT(self) }
} }
} }
@ -130,7 +114,7 @@ impl SnapshotCreator {
pub fn create_blob( pub fn create_blob(
&mut self, &mut self,
function_code_handling: FunctionCodeHandling, function_code_handling: FunctionCodeHandling,
) -> Option<OwnedStartupData> { ) -> Option<StartupData> {
let blob = let blob =
unsafe { v8__SnapshotCreator__CreateBlob(self, function_code_handling) }; unsafe { v8__SnapshotCreator__CreateBlob(self, function_code_handling) };
if blob.data.is_null() { if blob.data.is_null() {
@ -149,6 +133,6 @@ impl SnapshotCreator {
// revisited after the libdeno integration is complete. // revisited after the libdeno integration is complete.
pub unsafe fn get_owned_isolate(&mut self) -> OwnedIsolate { pub unsafe fn get_owned_isolate(&mut self) -> OwnedIsolate {
let isolate_ptr = v8__SnapshotCreator__GetIsolate(self); let isolate_ptr = v8__SnapshotCreator__GetIsolate(self);
crate::isolate::new_owned_isolate(isolate_ptr) OwnedIsolate::new(isolate_ptr, Box::new(()))
} }
} }

View file

@ -1,5 +1,7 @@
use std::any::Any;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::convert::identity;
use std::convert::AsMut; use std::convert::AsMut;
use std::convert::AsRef; use std::convert::AsRef;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -8,11 +10,14 @@ use std::mem::forget;
use std::mem::needs_drop; use std::mem::needs_drop;
use std::mem::size_of; use std::mem::size_of;
use std::mem::take; use std::mem::take;
use std::mem::transmute_copy;
use std::ops::Deref; use std::ops::Deref;
use std::ops::DerefMut; use std::ops::DerefMut;
use std::ptr::drop_in_place; use std::ptr::drop_in_place;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use std::sync::Arc;
// TODO use libc::intptr_t when stable. // TODO use libc::intptr_t when stable.
// https://doc.rust-lang.org/1.7.0/libc/type.intptr_t.html // https://doc.rust-lang.org/1.7.0/libc/type.intptr_t.html
@ -286,6 +291,98 @@ impl<T: Shared> AsRef<T> for SharedRef<T> {
} }
} }
impl<T: Shared> Borrow<T> for SharedRef<T> {
fn borrow(&self) -> &T {
&**self
}
}
/// A trait for values with static lifetimes that are allocated at a fixed
/// address in memory. Practically speaking, that means they're either a
/// `&'static` reference, or they're heap-allocated in a `Arc`, `Box`, `Rc`,
/// `UniqueRef`, `SharedRef` or `Vec`.
pub trait Allocated<T: ?Sized>:
Deref<Target = T> + Borrow<T> + 'static
{
}
impl<A, T: ?Sized> Allocated<T> for A where
A: Deref<Target = T> + Borrow<T> + 'static
{
}
pub(crate) enum Allocation<T: ?Sized + 'static> {
Static(&'static T),
Arc(Arc<T>),
Box(Box<T>),
Rc(Rc<T>),
UniqueRef(UniqueRef<T>),
Other(Box<dyn Borrow<T> + 'static>),
// Note: it would be nice to add `SharedRef` to this list, but it requires the
// `T: Shared` bound, and it's unfortunately not possible to set bounds on
// individual enum variants.
}
impl<T: ?Sized + 'static> Allocation<T> {
unsafe fn transmute_wrap<Abstract, Concrete>(
value: Abstract,
wrap: fn(Concrete) -> Self,
) -> Self {
assert_eq!(size_of::<Abstract>(), size_of::<Concrete>());
let wrapped = wrap(transmute_copy(&value));
forget(value);
wrapped
}
fn try_wrap<Abstract: 'static, Concrete: 'static>(
value: Abstract,
wrap: fn(Concrete) -> Self,
) -> Result<Self, Abstract> {
if Any::is::<Concrete>(&value) {
Ok(unsafe { Self::transmute_wrap(value, wrap) })
} else {
Err(value)
}
}
pub fn of<Abstract: Deref<Target = T> + Borrow<T> + 'static>(
a: Abstract,
) -> Self {
Self::try_wrap(a, identity)
.or_else(|a| Self::try_wrap(a, Self::Static))
.or_else(|a| Self::try_wrap(a, Self::Arc))
.or_else(|a| Self::try_wrap(a, Self::Box))
.or_else(|a| Self::try_wrap(a, Self::Rc))
.or_else(|a| Self::try_wrap(a, Self::UniqueRef))
.unwrap_or_else(|a| Self::Other(Box::from(a)))
}
}
impl<T: ?Sized> Deref for Allocation<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Self::Static(v) => v.borrow(),
Self::Arc(v) => v.borrow(),
Self::Box(v) => v.borrow(),
Self::Rc(v) => v.borrow(),
Self::UniqueRef(v) => v.borrow(),
Self::Other(v) => (&**v).borrow(),
}
}
}
impl<T: ?Sized> AsRef<T> for Allocation<T> {
fn as_ref(&self) -> &T {
&**self
}
}
impl<T: ?Sized> Borrow<T> for Allocation<T> {
fn borrow(&self) -> &T {
&**self
}
}
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub(crate) enum MaybeBool { pub(crate) enum MaybeBool {
@ -524,3 +621,97 @@ where
T::c_fn_from(F::get()) T::c_fn_from(F::get())
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
static TEST_OBJ_DROPPED: AtomicBool = AtomicBool::new(false);
struct TestObj {
pub id: u32,
}
impl Drop for TestObj {
fn drop(&mut self) {
assert!(!TEST_OBJ_DROPPED.swap(true, Ordering::SeqCst));
}
}
struct TestObjRef(TestObj);
impl Deref for TestObjRef {
type Target = TestObj;
fn deref(&self) -> &TestObj {
&self.0
}
}
impl Borrow<TestObj> for TestObjRef {
fn borrow(&self) -> &TestObj {
&**self
}
}
#[test]
fn allocation() {
// Static.
static STATIC_OBJ: TestObj = TestObj { id: 1 };
let owner = Allocation::of(&STATIC_OBJ);
match owner {
Allocation::Static(_) => assert_eq!(owner.id, 1),
_ => panic!(),
}
drop(owner);
assert!(!TEST_OBJ_DROPPED.load(Ordering::SeqCst));
// Arc.
let owner = Allocation::of(Arc::new(TestObj { id: 2 }));
match owner {
Allocation::Arc(_) => assert_eq!(owner.id, 2),
_ => panic!(),
}
drop(owner);
assert!(TEST_OBJ_DROPPED.swap(false, Ordering::SeqCst));
// Box.
let owner = Allocation::of(Box::new(TestObj { id: 3 }));
match owner {
Allocation::Box(_) => assert_eq!(owner.id, 3),
_ => panic!(),
}
drop(owner);
assert!(TEST_OBJ_DROPPED.swap(false, Ordering::SeqCst));
// Rc.
let owner = Allocation::of(Rc::new(TestObj { id: 4 }));
match owner {
Allocation::Rc(_) => assert_eq!(owner.id, 4),
_ => panic!(),
}
drop(owner);
assert!(TEST_OBJ_DROPPED.swap(false, Ordering::SeqCst));
// Other.
let owner = Allocation::of(TestObjRef(TestObj { id: 5 }));
match owner {
Allocation::Other(_) => assert_eq!(owner.id, 5),
_ => panic!(),
}
drop(owner);
assert!(TEST_OBJ_DROPPED.swap(false, Ordering::SeqCst));
// Contents of Vec should not be moved.
let vec = vec![1u8, 2, 3, 5, 8, 13, 21];
let vec_element_ptrs =
vec.iter().map(|i| i as *const u8).collect::<Vec<_>>();
let owner = Allocation::of(vec);
match owner {
Allocation::Other(_) => {}
_ => panic!(),
}
owner
.iter()
.map(|i| i as *const u8)
.zip(vec_element_ptrs)
.for_each(|(p1, p2)| assert_eq!(p1, p2));
}
}

View file

@ -38,9 +38,7 @@ fn setup() -> SetupGuard {
#[test] #[test]
fn handle_scope_nested() { fn handle_scope_nested() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope1 = hs.enter(); let scope1 = hs.enter();
@ -55,9 +53,7 @@ fn handle_scope_nested() {
#[allow(clippy::float_cmp)] #[allow(clippy::float_cmp)]
fn handle_scope_numbers() { fn handle_scope_numbers() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope1 = hs.enter(); let scope1 = hs.enter();
@ -79,9 +75,7 @@ fn handle_scope_numbers() {
#[test] #[test]
fn global_handles() { fn global_handles() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut g1 = v8::Global::<v8::String>::new(); let mut g1 = v8::Global::<v8::String>::new();
let mut g2 = v8::Global::<v8::Integer>::new(); let mut g2 = v8::Global::<v8::Integer>::new();
let mut g3 = v8::Global::<v8::Integer>::new(); let mut g3 = v8::Global::<v8::Integer>::new();
@ -134,9 +128,7 @@ fn global_handle_drop() {
// Global 'g1' will be dropped _after_ the Isolate has been disposed. // Global 'g1' will be dropped _after_ the Isolate has been disposed.
let mut g1 = v8::Global::<v8::String>::new(); let mut g1 = v8::Global::<v8::String>::new();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -152,9 +144,7 @@ fn global_handle_drop() {
#[test] #[test]
fn test_string() { fn test_string() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -187,9 +177,7 @@ fn test_string() {
#[allow(clippy::float_cmp)] #[allow(clippy::float_cmp)]
fn escapable_handle_scope() { fn escapable_handle_scope() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope1 = hs.enter(); let scope1 = hs.enter();
@ -230,9 +218,7 @@ fn escapable_handle_scope() {
#[test] #[test]
fn context_scope() { fn context_scope() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -256,9 +242,7 @@ fn context_scope() {
#[test] #[test]
fn microtasks() { fn microtasks() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
isolate.run_microtasks(); isolate.run_microtasks();
@ -340,9 +324,7 @@ fn get_isolate_from_handle() {
} }
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -374,9 +356,7 @@ fn get_isolate_from_handle() {
#[test] #[test]
fn array_buffer() { fn array_buffer() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -415,11 +395,11 @@ fn array_buffer() {
#[test] #[test]
fn backing_store_segfault() { fn backing_store_segfault() {
let _setup_guard = setup(); let _setup_guard = setup();
let array_buffer_allocator = v8::new_default_allocator(); let array_buffer_allocator = v8::new_default_allocator().make_shared();
let shared_bs = { let shared_bs = {
assert_eq!(1, v8::SharedRef::use_count(&array_buffer_allocator)); assert_eq!(1, v8::SharedRef::use_count(&array_buffer_allocator));
let mut params = v8::Isolate::create_params(); let params = v8::Isolate::create_params()
params.set_array_buffer_allocator(array_buffer_allocator.clone()); .array_buffer_allocator(array_buffer_allocator.clone());
assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator)); assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator));
let mut isolate = v8::Isolate::new(params); let mut isolate = v8::Isolate::new(params);
assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator)); assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator));
@ -441,7 +421,7 @@ fn backing_store_segfault() {
#[test] #[test]
fn shared_array_buffer_allocator() { fn shared_array_buffer_allocator() {
let alloc1 = v8::new_default_allocator(); let alloc1 = v8::new_default_allocator().make_shared();
assert_eq!(1, v8::SharedRef::use_count(&alloc1)); assert_eq!(1, v8::SharedRef::use_count(&alloc1));
let alloc2 = alloc1.clone(); let alloc2 = alloc1.clone();
@ -458,12 +438,11 @@ fn shared_array_buffer_allocator() {
alloc2.take(); alloc2.take();
assert_eq!(0, v8::SharedPtr::use_count(&alloc2)); assert_eq!(0, v8::SharedPtr::use_count(&alloc2));
} }
#[test] #[test]
fn array_buffer_with_shared_backing_store() { fn array_buffer_with_shared_backing_store() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -543,9 +522,7 @@ fn eval<'sc>(
#[test] #[test]
fn try_catch() { fn try_catch() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -600,9 +577,7 @@ fn try_catch() {
#[test] #[test]
fn throw_exception() { fn throw_exception() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -626,9 +601,7 @@ fn throw_exception() {
#[test] #[test]
fn thread_safe_handle_drop_after_isolate() { fn thread_safe_handle_drop_after_isolate() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let handle = isolate.thread_safe_handle(); let handle = isolate.thread_safe_handle();
// We can call it twice. // We can call it twice.
let handle_ = isolate.thread_safe_handle(); let handle_ = isolate.thread_safe_handle();
@ -659,9 +632,7 @@ fn thread_safe_handle_drop_after_isolate() {
#[test] #[test]
fn terminate_execution() { fn terminate_execution() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let (tx, rx) = std::sync::mpsc::channel::<bool>(); let (tx, rx) = std::sync::mpsc::channel::<bool>();
let handle = isolate.thread_safe_handle(); let handle = isolate.thread_safe_handle();
let t = std::thread::spawn(move || { let t = std::thread::spawn(move || {
@ -697,9 +668,7 @@ fn terminate_execution() {
#[test] #[test]
fn request_interrupt_small_scripts() { fn request_interrupt_small_scripts() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let handle = isolate.thread_safe_handle(); let handle = isolate.thread_safe_handle();
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -725,9 +694,7 @@ fn request_interrupt_small_scripts() {
#[test] #[test]
fn add_message_listener() { fn add_message_listener() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 32); isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 32);
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
@ -794,9 +761,7 @@ fn unexpected_module_resolve_callback<'a>(
#[test] #[test]
fn set_host_initialize_import_meta_object_callback() { fn set_host_initialize_import_meta_object_callback() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
@ -841,9 +806,7 @@ fn set_host_initialize_import_meta_object_callback() {
#[test] #[test]
fn script_compile_and_run() { fn script_compile_and_run() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -862,9 +825,7 @@ fn script_compile_and_run() {
#[test] #[test]
fn script_origin() { fn script_origin() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -953,9 +914,7 @@ fn inspector_string_buffer() {
#[test] #[test]
fn test_primitives() { fn test_primitives() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -986,9 +945,7 @@ fn test_primitives() {
#[test] #[test]
fn exception() { fn exception() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
let context = v8::Context::new(scope); let context = v8::Context::new(scope);
@ -1013,9 +970,7 @@ fn exception() {
#[test] #[test]
fn create_message_argument_lifetimes() { fn create_message_argument_lifetimes() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
let context = v8::Context::new(scope); let context = v8::Context::new(scope);
@ -1050,9 +1005,7 @@ fn create_message_argument_lifetimes() {
#[test] #[test]
fn json() { fn json() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1074,9 +1027,7 @@ fn json() {
#[test] #[test]
fn object_template() { fn object_template() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1124,9 +1075,7 @@ fn object_template() {
#[test] #[test]
fn object_template_from_function_template() { fn object_template_from_function_template() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1153,9 +1102,7 @@ fn object_template_from_function_template() {
#[test] #[test]
fn object() { fn object() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1188,9 +1135,7 @@ fn object() {
#[test] #[test]
fn array() { fn array() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1232,9 +1177,7 @@ fn array() {
#[test] #[test]
fn create_data_property() { fn create_data_property() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1269,9 +1212,7 @@ fn create_data_property() {
#[test] #[test]
fn object_set_accessor() { fn object_set_accessor() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
let context = v8::Context::new(scope); let context = v8::Context::new(scope);
@ -1327,9 +1268,7 @@ fn object_set_accessor() {
#[test] #[test]
fn promise_resolved() { fn promise_resolved() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1361,9 +1300,7 @@ fn promise_resolved() {
#[test] #[test]
fn promise_rejected() { fn promise_rejected() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1395,9 +1332,7 @@ fn promise_rejected() {
#[test] #[test]
fn proxy() { fn proxy() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1471,9 +1406,7 @@ fn data_is_true_callback(
#[test] #[test]
fn function() { fn function() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -1540,9 +1473,7 @@ extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
#[test] #[test]
fn set_promise_reject_callback() { fn set_promise_reject_callback() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
isolate.set_promise_reject_callback(promise_reject_callback); isolate.set_promise_reject_callback(promise_reject_callback);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -1595,9 +1526,7 @@ fn mock_source<'sc>(
#[test] #[test]
fn script_compiler_source() { fn script_compiler_source() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
isolate.set_promise_reject_callback(promise_reject_callback); isolate.set_promise_reject_callback(promise_reject_callback);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -1619,9 +1548,7 @@ fn script_compiler_source() {
#[test] #[test]
fn module_instantiation_failures1() { fn module_instantiation_failures1() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1703,9 +1630,7 @@ fn compile_specifier_as_module_resolve_callback<'a>(
#[test] #[test]
fn module_evaluation() { fn module_evaluation() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1746,9 +1671,7 @@ fn module_evaluation() {
#[test] #[test]
fn primitive_array() { fn primitive_array() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1781,9 +1704,7 @@ fn primitive_array() {
#[test] #[test]
fn equality() { fn equality() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1802,9 +1723,7 @@ fn equality() {
#[test] #[test]
fn array_buffer_view() { fn array_buffer_view() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -1865,9 +1784,7 @@ fn snapshot_creator() {
// Now we try to load up the snapshot and check that 'a' has the correct // Now we try to load up the snapshot and check that 'a' has the correct
// value. // value.
{ {
let mut params = v8::Isolate::create_params(); let params = v8::Isolate::create_params().snapshot_blob(startup_data);
params.set_array_buffer_allocator(v8::new_default_allocator());
params.set_snapshot_blob(&startup_data);
let mut isolate = v8::Isolate::new(params); let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -1882,9 +1799,6 @@ fn snapshot_creator() {
let true_val = v8::Boolean::new(scope, true).into(); let true_val = v8::Boolean::new(scope, true).into();
assert!(result.same_value(true_val)); assert!(result.same_value(true_val));
} }
// TODO(ry) WARNING! startup_data needs to be kept alive as long the isolate
// using it. See note in CreateParams::set_snapshot_blob
drop(startup_data);
} }
} }
@ -1936,10 +1850,9 @@ fn external_references() {
// Now we try to load up the snapshot and check that 'a' has the correct // Now we try to load up the snapshot and check that 'a' has the correct
// value. // value.
{ {
let mut params = v8::Isolate::create_params(); let params = v8::Isolate::create_params()
params.set_array_buffer_allocator(v8::new_default_allocator()); .snapshot_blob(startup_data)
params.set_snapshot_blob(&startup_data); .external_references(&**EXTERNAL_REFERENCES);
params.set_external_references(&EXTERNAL_REFERENCES);
let mut isolate = v8::Isolate::new(params); let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
@ -1956,34 +1869,29 @@ fn external_references() {
eval(scope, context, "if(F() != 'Hello callback!') throw 'boom2'"); eval(scope, context, "if(F() != 'Hello callback!') throw 'boom2'");
assert!(result.is_some()); assert!(result.is_some());
} }
// TODO(ry) WARNING! startup_data needs to be kept alive as long the isolate
// using it. See note in CreateParams::set_snapshot_blob
drop(startup_data);
} }
} }
#[test] #[test]
fn startup_data() { fn create_params_snapshot_blob() {
let data1 = b"abcd"; let static_data = b"abcd";
let sd1 = v8::StartupData::new(data1); let _ = v8::CreateParams::default().snapshot_blob(&static_data[..]);
assert_eq!(&*sd1, data1);
let data2 = b"defg"; let vec_1 = Vec::from(&b"defg"[..]);
let vec2 = Vec::from(&data2[..]); let _ = v8::CreateParams::default().snapshot_blob(vec_1);
let sd2 = v8::StartupData::new(&vec2);
assert_eq!(&*sd2, data2);
let data3 = b"hijk"; let vec_2 = std::fs::read(file!()).unwrap();
let sd3 = Box::new(v8::StartupData::new(data3)); let _ = v8::CreateParams::default().snapshot_blob(vec_2);
assert_eq!(&**sd3, data3);
let arc_slice: std::sync::Arc<[u8]> = std::fs::read(file!()).unwrap().into();
let _ = v8::CreateParams::default().snapshot_blob(arc_slice.clone());
let _ = v8::CreateParams::default().snapshot_blob(arc_slice);
} }
#[test] #[test]
fn uint8_array() { fn uint8_array() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2013,9 +1921,7 @@ fn uint8_array() {
#[test] #[test]
fn dynamic_import() { fn dynamic_import() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
@ -2057,9 +1963,7 @@ fn dynamic_import() {
#[test] #[test]
fn shared_array_buffer() { fn shared_array_buffer() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2115,9 +2019,7 @@ fn shared_array_buffer() {
#[allow(clippy::eq_op)] #[allow(clippy::eq_op)]
fn value_checker() { fn value_checker() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2450,9 +2352,7 @@ fn value_checker() {
#[test] #[test]
fn try_from_local() { fn try_from_local() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2681,9 +2581,7 @@ impl v8::inspector::ChannelImpl for ChannelCounter {
#[test] #[test]
fn inspector_dispatch_protocol_message() { fn inspector_dispatch_protocol_message() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
use v8::inspector::*; use v8::inspector::*;
let mut default_client = ClientCounter::new(); let mut default_client = ClientCounter::new();
@ -2716,9 +2614,7 @@ fn inspector_dispatch_protocol_message() {
#[test] #[test]
fn inspector_schedule_pause_on_next_statement() { fn inspector_schedule_pause_on_next_statement() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
use v8::inspector::*; use v8::inspector::*;
let mut client = ClientCounter::new(); let mut client = ClientCounter::new();
@ -2780,9 +2676,7 @@ fn inspector_schedule_pause_on_next_statement() {
#[test] #[test]
fn inspector_console_api_message() { fn inspector_console_api_message() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
use v8::inspector::*; use v8::inspector::*;
@ -2848,9 +2742,7 @@ fn inspector_console_api_message() {
#[test] #[test]
fn context_from_object_template() { fn context_from_object_template() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2870,9 +2762,7 @@ fn context_from_object_template() {
#[test] #[test]
fn get_and_set_data() { fn get_and_set_data() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let nslots = isolate.get_number_of_data_slots(); let nslots = isolate.get_number_of_data_slots();
assert!(nslots > 0); assert!(nslots > 0);
for slot in 0..nslots { for slot in 0..nslots {
@ -2888,9 +2778,7 @@ fn get_and_set_data() {
#[test] #[test]
fn take_heap_snapshot() { fn take_heap_snapshot() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2918,9 +2806,7 @@ fn take_heap_snapshot() {
#[test] #[test]
fn test_prototype_api() { fn test_prototype_api() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();
@ -2976,9 +2862,7 @@ fn test_prototype_api() {
#[test] #[test]
fn test_map_api() { fn test_map_api() {
let _setup_guard = setup(); let _setup_guard = setup();
let mut params = v8::Isolate::create_params(); let mut isolate = v8::Isolate::new(Default::default());
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
{ {
let mut hs = v8::HandleScope::new(&mut isolate); let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter(); let scope = hs.enter();