diff --git a/src/array_buffer.rs b/src/array_buffer.rs index 833bd32e..9334773a 100644 --- a/src/array_buffer.rs +++ b/src/array_buffer.rs @@ -126,10 +126,9 @@ impl Shared for Allocator { } /// malloc/free based convenience allocator. -pub fn new_default_allocator() -> SharedRef { +pub fn new_default_allocator() -> UniqueRef { unsafe { UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator()) - .make_shared() } } diff --git a/src/binding.cc b/src/binding.cc index 057e4e40..924c1b28 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -100,12 +100,8 @@ bool v8__V8__Dispose() { return v8::V8::Dispose(); } void v8__V8__ShutdownPlatform() { v8::V8::ShutdownPlatform(); } -// This function consumes the Isolate::CreateParams object. The Isolate takes -// ownership of the ArrayBuffer::Allocator referenced by the params object. -v8::Isolate* v8__Isolate__New(v8::Isolate::CreateParams* params) { - auto isolate = v8::Isolate::New(*params); - delete params; - return isolate; +v8::Isolate* v8__Isolate__New(const v8::Isolate::CreateParams& params) { + return v8::Isolate::New(params); } void v8__Isolate__Dispose(v8::Isolate* isolate) { isolate->Dispose(); } @@ -194,36 +190,13 @@ void v8__Isolate__CancelTerminateExecution(v8::Isolate* isolate) { isolate->CancelTerminateExecution(); } -v8::Isolate::CreateParams* v8__Isolate__CreateParams__NEW() { - return new v8::Isolate::CreateParams(); +void v8__Isolate__CreateParams__CONSTRUCT( + uninit_t* buf) { + construct_in_place(buf); } -// This function is only called if the Isolate::CreateParams object is *not* -// consumed by Isolate::New(). -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& 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; +size_t v8__Isolate__CreateParams__SIZEOF() { + return sizeof(v8::Isolate::CreateParams); } void v8__HandleScope__CONSTRUCT(uninit_t* buf, diff --git a/src/external_references.rs b/src/external_references.rs index a4998462..27ea44e4 100644 --- a/src/external_references.rs +++ b/src/external_references.rs @@ -12,23 +12,35 @@ pub union ExternalReference<'s> { } pub struct ExternalReferences { - null_terminated: Vec<*const std::ffi::c_void>, + null_terminated: Vec, } unsafe impl Sync for ExternalReferences {} impl ExternalReferences { pub fn new(refs: &[ExternalReference]) -> Self { - let mut null_terminated = Vec::with_capacity(refs.len() + 1); - for r in refs { - let ptr = unsafe { std::mem::transmute(*r) }; - null_terminated.push(ptr); - } - null_terminated.push(std::ptr::null()); + let null_terminated = refs + .iter() + .map(|&r| unsafe { std::mem::transmute(r) }) + .chain(std::iter::once(0)) // Add null terminator. + .collect::>(); Self { null_terminated } } 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 } } diff --git a/src/isolate.rs b/src/isolate.rs index 07153024..bd9c11cc 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -1,11 +1,8 @@ // Copyright 2019-2020 the Deno authors. All rights reserved. MIT license. -use crate::array_buffer::Allocator; -use crate::external_references::ExternalReferences; +use crate::isolate_create_params::raw; +use crate::isolate_create_params::CreateParams; use crate::promise::PromiseRejectMessage; -use crate::support::intptr_t; use crate::support::Opaque; -use crate::support::SharedRef; -use crate::support::UniqueRef; use crate::Context; use crate::Function; use crate::InIsolate; @@ -15,10 +12,10 @@ use crate::Module; use crate::Object; use crate::Promise; use crate::ScriptOrModule; -use crate::StartupData; use crate::String; use crate::Value; +use std::any::Any; use std::ffi::c_void; use std::mem::replace; use std::ops::Deref; @@ -71,7 +68,7 @@ pub type InterruptCallback = extern "C" fn(isolate: &mut Isolate, data: *mut c_void); 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__SetData(this: *mut Isolate, slot: u32, data: *mut c_void); fn v8__Isolate__GetData(this: *const Isolate, slot: u32) -> *mut c_void; @@ -117,20 +114,6 @@ extern "C" { 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, - ); - 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( isolate: *mut Isolate, 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. #[allow(clippy::new_ret_no_self)] - pub fn new(params: UniqueRef) -> OwnedIsolate { - // TODO: support CreateParams. + pub fn new(params: CreateParams) -> OwnedIsolate { 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. - pub fn create_params() -> UniqueRef { - CreateParams::new() + pub fn create_params() -> CreateParams { + CreateParams::default() } pub fn thread_safe_handle(&mut self) -> IsolateHandle { @@ -476,18 +460,24 @@ impl IsolateHandle { } } -/// Internal method for constructing an OwnedIsolate. -pub(crate) unsafe fn new_owned_isolate( - isolate_ptr: *mut Isolate, -) -> OwnedIsolate { - OwnedIsolate(NonNull::new(isolate_ptr).unwrap()) +/// Same as Isolate but gets disposed when it goes out of scope. +pub struct OwnedIsolate { + cxx_isolate: NonNull, + create_param_allocations: Box, } -/// Same as Isolate but gets disposed when it goes out of scope. -pub struct OwnedIsolate(NonNull); - -// TODO(ry) unsafe impl Send for OwnedIsolate {} -// TODO(ry) impl !Sync for OwnedIsolate {} +impl OwnedIsolate { + pub(crate) fn new( + cxx_isolate: *mut Isolate, + create_param_allocations: Box, + ) -> Self { + let cxx_isolate = NonNull::new(cxx_isolate).unwrap(); + Self { + cxx_isolate, + create_param_allocations, + } + } +} impl InIsolate for OwnedIsolate { fn isolate(&mut self) -> &mut Isolate { @@ -497,85 +487,19 @@ impl InIsolate for OwnedIsolate { impl Drop for OwnedIsolate { fn drop(&mut self) { - unsafe { self.0.as_mut().dispose() } + unsafe { self.cxx_isolate.as_mut().dispose() } } } impl Deref for OwnedIsolate { type Target = Isolate; fn deref(&self) -> &Self::Target { - unsafe { self.0.as_ref() } + unsafe { self.cxx_isolate.as_ref() } } } impl DerefMut for OwnedIsolate { fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { self.0.as_mut() } - } -} - -/// Initial configuration parameters for a new Isolate. -#[repr(C)] -pub struct CreateParams(Opaque); - -impl CreateParams { - pub fn new() -> UniqueRef { - 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) { - 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) } + unsafe { self.cxx_isolate.as_mut() } } } diff --git a/src/isolate_create_params.rs b/src/isolate_create_params.rs new file mode 100644 index 00000000..6f9e165f --- /dev/null +++ b/src/isolate_create_params.rs @@ -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>, + ) -> 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::>(); + 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) { + 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>, + // 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>, + external_references: Option>, +} + +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, + 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, + ); + fn v8__Isolate__CreateParams__SIZEOF() -> usize; + } + + impl Default for CreateParams { + fn default() -> Self { + let size = unsafe { v8__Isolate__CreateParams__SIZEOF() }; + assert_eq!(size_of::(), size); + let mut buf = MaybeUninit::::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 { + 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, + } +} diff --git a/src/lib.rs b/src/lib.rs index 94126e9f..0789300e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,9 +9,7 @@ //! v8::V8::initialize_platform(platform); //! v8::V8::initialize(); //! -//! let mut create_params = v8::Isolate::create_params(); -//! create_params.set_array_buffer_allocator(v8::new_default_allocator()); -//! let mut isolate = v8::Isolate::new(create_params); +//! let mut isolate = v8::Isolate::new(Default::default()); //! //! let mut handle_scope = v8::HandleScope::new(&mut isolate); //! let scope = handle_scope.enter(); @@ -85,6 +83,7 @@ mod function; mod global; mod handle_scope; mod isolate; +mod isolate_create_params; mod local; mod module; mod number; @@ -125,7 +124,6 @@ pub use function::*; pub use global::Global; pub use handle_scope::EscapableHandleScope; pub use handle_scope::HandleScope; -pub use isolate::CreateParams; pub use isolate::HostImportModuleDynamicallyCallback; pub use isolate::HostInitializeImportMetaObjectCallback; pub use isolate::Isolate; @@ -133,6 +131,7 @@ pub use isolate::IsolateHandle; pub use isolate::MessageCallback; pub use isolate::OwnedIsolate; pub use isolate::PromiseRejectCallback; +pub use isolate_create_params::CreateParams; pub use local::Local; pub use module::*; pub use object::*; @@ -154,7 +153,6 @@ pub use scope::Scope; pub use scope_traits::*; pub use script::ScriptOrigin; pub use snapshot::FunctionCodeHandling; -pub use snapshot::OwnedStartupData; pub use snapshot::SnapshotCreator; pub use snapshot::StartupData; pub use string::NewStringType; diff --git a/src/snapshot.rs b/src/snapshot.rs index 740b8b20..4c0967ba 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -1,15 +1,16 @@ use crate::external_references::ExternalReferences; +use crate::support::char; use crate::support::int; use crate::support::intptr_t; use crate::Context; use crate::Isolate; use crate::Local; use crate::OwnedIsolate; + use std::borrow::Borrow; -use std::marker::PhantomData; +use std::convert::TryFrom; use std::mem::MaybeUninit; use std::ops::Deref; -use std::ops::DerefMut; extern "C" { fn v8__SnapshotCreator__CONSTRUCT( @@ -23,7 +24,7 @@ extern "C" { fn v8__SnapshotCreator__CreateBlob( this: *mut SnapshotCreator, function_code_handling: FunctionCodeHandling, - ) -> OwnedStartupData; + ) -> StartupData; fn v8__SnapshotCreator__SetDefaultContext( this: *mut SnapshotCreator, context: *const Context, @@ -32,52 +33,35 @@ extern "C" { } #[repr(C)] -pub struct StartupData<'a> { - data: *const u8, +pub struct StartupData { + data: *const char, raw_size: int, - _phantom: PhantomData<&'a [u8]>, } -impl<'a> StartupData<'a> { - pub fn new(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> { +impl Deref for StartupData { type Target = [u8]; 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)] -pub struct OwnedStartupData(StartupData<'static>); - -impl Deref for OwnedStartupData { - type Target = StartupData<'static>; - fn deref(&self) -> &Self::Target { - &self.0 +impl AsRef<[u8]> for StartupData { + fn as_ref(&self) -> &[u8] { + &**self } } -impl DerefMut for OwnedStartupData { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 +impl Borrow<[u8]> for StartupData { + fn borrow(&self) -> &[u8] { + &**self } } -impl Drop for OwnedStartupData { +impl Drop for StartupData { 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( &mut self, function_code_handling: FunctionCodeHandling, - ) -> Option { + ) -> Option { let blob = unsafe { v8__SnapshotCreator__CreateBlob(self, function_code_handling) }; if blob.data.is_null() { @@ -149,6 +133,6 @@ impl SnapshotCreator { // revisited after the libdeno integration is complete. pub unsafe fn get_owned_isolate(&mut self) -> OwnedIsolate { let isolate_ptr = v8__SnapshotCreator__GetIsolate(self); - crate::isolate::new_owned_isolate(isolate_ptr) + OwnedIsolate::new(isolate_ptr, Box::new(())) } } diff --git a/src/support.rs b/src/support.rs index b694ff7e..8b98a556 100644 --- a/src/support.rs +++ b/src/support.rs @@ -1,5 +1,7 @@ +use std::any::Any; use std::borrow::Borrow; use std::borrow::BorrowMut; +use std::convert::identity; use std::convert::AsMut; use std::convert::AsRef; use std::marker::PhantomData; @@ -8,11 +10,14 @@ use std::mem::forget; use std::mem::needs_drop; use std::mem::size_of; use std::mem::take; +use std::mem::transmute_copy; use std::ops::Deref; use std::ops::DerefMut; use std::ptr::drop_in_place; use std::ptr::null_mut; use std::ptr::NonNull; +use std::rc::Rc; +use std::sync::Arc; // TODO use libc::intptr_t when stable. // https://doc.rust-lang.org/1.7.0/libc/type.intptr_t.html @@ -286,6 +291,98 @@ impl AsRef for SharedRef { } } +impl Borrow for SharedRef { + 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: + Deref + Borrow + 'static +{ +} +impl Allocated for A where + A: Deref + Borrow + 'static +{ +} + +pub(crate) enum Allocation { + Static(&'static T), + Arc(Arc), + Box(Box), + Rc(Rc), + UniqueRef(UniqueRef), + Other(Box + '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 Allocation { + unsafe fn transmute_wrap( + value: Abstract, + wrap: fn(Concrete) -> Self, + ) -> Self { + assert_eq!(size_of::(), size_of::()); + let wrapped = wrap(transmute_copy(&value)); + forget(value); + wrapped + } + + fn try_wrap( + value: Abstract, + wrap: fn(Concrete) -> Self, + ) -> Result { + if Any::is::(&value) { + Ok(unsafe { Self::transmute_wrap(value, wrap) }) + } else { + Err(value) + } + } + + pub fn of + Borrow + '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 Deref for Allocation { + 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 AsRef for Allocation { + fn as_ref(&self) -> &T { + &**self + } +} + +impl Borrow for Allocation { + fn borrow(&self) -> &T { + &**self + } +} + #[repr(C)] #[derive(Debug, PartialEq)] pub(crate) enum MaybeBool { @@ -524,3 +621,97 @@ where 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 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::>(); + 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)); + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index 2a4564e8..c9a04137 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -38,9 +38,7 @@ fn setup() -> SetupGuard { #[test] fn handle_scope_nested() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope1 = hs.enter(); @@ -55,9 +53,7 @@ fn handle_scope_nested() { #[allow(clippy::float_cmp)] fn handle_scope_numbers() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope1 = hs.enter(); @@ -79,9 +75,7 @@ fn handle_scope_numbers() { #[test] fn global_handles() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut g1 = v8::Global::::new(); let mut g2 = v8::Global::::new(); let mut g3 = v8::Global::::new(); @@ -134,9 +128,7 @@ fn global_handle_drop() { // Global 'g1' will be dropped _after_ the Isolate has been disposed. let mut g1 = v8::Global::::new(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -152,9 +144,7 @@ fn global_handle_drop() { #[test] fn test_string() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -187,9 +177,7 @@ fn test_string() { #[allow(clippy::float_cmp)] fn escapable_handle_scope() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope1 = hs.enter(); @@ -230,9 +218,7 @@ fn escapable_handle_scope() { #[test] fn context_scope() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -256,9 +242,7 @@ fn context_scope() { #[test] fn microtasks() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); isolate.run_microtasks(); @@ -340,9 +324,7 @@ fn get_isolate_from_handle() { } let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -374,9 +356,7 @@ fn get_isolate_from_handle() { #[test] fn array_buffer() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -415,11 +395,11 @@ fn array_buffer() { #[test] fn backing_store_segfault() { 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 = { assert_eq!(1, v8::SharedRef::use_count(&array_buffer_allocator)); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(array_buffer_allocator.clone()); + let params = v8::Isolate::create_params() + .array_buffer_allocator(array_buffer_allocator.clone()); assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator)); let mut isolate = v8::Isolate::new(params); assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator)); @@ -441,7 +421,7 @@ fn backing_store_segfault() { #[test] 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)); let alloc2 = alloc1.clone(); @@ -458,12 +438,11 @@ fn shared_array_buffer_allocator() { alloc2.take(); assert_eq!(0, v8::SharedPtr::use_count(&alloc2)); } + #[test] fn array_buffer_with_shared_backing_store() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -543,9 +522,7 @@ fn eval<'sc>( #[test] fn try_catch() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -600,9 +577,7 @@ fn try_catch() { #[test] fn throw_exception() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -626,9 +601,7 @@ fn throw_exception() { #[test] fn thread_safe_handle_drop_after_isolate() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let handle = isolate.thread_safe_handle(); // We can call it twice. let handle_ = isolate.thread_safe_handle(); @@ -659,9 +632,7 @@ fn thread_safe_handle_drop_after_isolate() { #[test] fn terminate_execution() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let (tx, rx) = std::sync::mpsc::channel::(); let handle = isolate.thread_safe_handle(); let t = std::thread::spawn(move || { @@ -697,9 +668,7 @@ fn terminate_execution() { #[test] fn request_interrupt_small_scripts() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let handle = isolate.thread_safe_handle(); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -725,9 +694,7 @@ fn request_interrupt_small_scripts() { #[test] fn add_message_listener() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 32); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -794,9 +761,7 @@ fn unexpected_module_resolve_callback<'a>( #[test] fn set_host_initialize_import_meta_object_callback() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -841,9 +806,7 @@ fn set_host_initialize_import_meta_object_callback() { #[test] fn script_compile_and_run() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -862,9 +825,7 @@ fn script_compile_and_run() { #[test] fn script_origin() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -953,9 +914,7 @@ fn inspector_string_buffer() { #[test] fn test_primitives() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -986,9 +945,7 @@ fn test_primitives() { #[test] fn exception() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); let context = v8::Context::new(scope); @@ -1013,9 +970,7 @@ fn exception() { #[test] fn create_message_argument_lifetimes() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); let context = v8::Context::new(scope); @@ -1050,9 +1005,7 @@ fn create_message_argument_lifetimes() { #[test] fn json() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1074,9 +1027,7 @@ fn json() { #[test] fn object_template() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1124,9 +1075,7 @@ fn object_template() { #[test] fn object_template_from_function_template() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1153,9 +1102,7 @@ fn object_template_from_function_template() { #[test] fn object() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1188,9 +1135,7 @@ fn object() { #[test] fn array() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1232,9 +1177,7 @@ fn array() { #[test] fn create_data_property() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1269,9 +1212,7 @@ fn create_data_property() { #[test] fn object_set_accessor() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); let context = v8::Context::new(scope); @@ -1327,9 +1268,7 @@ fn object_set_accessor() { #[test] fn promise_resolved() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1361,9 +1300,7 @@ fn promise_resolved() { #[test] fn promise_rejected() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1395,9 +1332,7 @@ fn promise_rejected() { #[test] fn proxy() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1471,9 +1406,7 @@ fn data_is_true_callback( #[test] fn function() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -1540,9 +1473,7 @@ extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) { #[test] fn set_promise_reject_callback() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); isolate.set_promise_reject_callback(promise_reject_callback); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -1595,9 +1526,7 @@ fn mock_source<'sc>( #[test] fn script_compiler_source() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); isolate.set_promise_reject_callback(promise_reject_callback); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -1619,9 +1548,7 @@ fn script_compiler_source() { #[test] fn module_instantiation_failures1() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1703,9 +1630,7 @@ fn compile_specifier_as_module_resolve_callback<'a>( #[test] fn module_evaluation() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1746,9 +1671,7 @@ fn module_evaluation() { #[test] fn primitive_array() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1781,9 +1704,7 @@ fn primitive_array() { #[test] fn equality() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -1802,9 +1723,7 @@ fn equality() { #[test] fn array_buffer_view() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); 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 // value. { - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - params.set_snapshot_blob(&startup_data); + let params = v8::Isolate::create_params().snapshot_blob(startup_data); let mut isolate = v8::Isolate::new(params); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -1882,9 +1799,6 @@ fn snapshot_creator() { let true_val = v8::Boolean::new(scope, true).into(); 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 // value. { - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - params.set_snapshot_blob(&startup_data); - params.set_external_references(&EXTERNAL_REFERENCES); + let params = v8::Isolate::create_params() + .snapshot_blob(startup_data) + .external_references(&**EXTERNAL_REFERENCES); let mut isolate = v8::Isolate::new(params); { let mut hs = v8::HandleScope::new(&mut isolate); @@ -1956,34 +1869,29 @@ fn external_references() { eval(scope, context, "if(F() != 'Hello callback!') throw 'boom2'"); 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] -fn startup_data() { - let data1 = b"abcd"; - let sd1 = v8::StartupData::new(data1); - assert_eq!(&*sd1, data1); +fn create_params_snapshot_blob() { + let static_data = b"abcd"; + let _ = v8::CreateParams::default().snapshot_blob(&static_data[..]); - let data2 = b"defg"; - let vec2 = Vec::from(&data2[..]); - let sd2 = v8::StartupData::new(&vec2); - assert_eq!(&*sd2, data2); + let vec_1 = Vec::from(&b"defg"[..]); + let _ = v8::CreateParams::default().snapshot_blob(vec_1); - let data3 = b"hijk"; - let sd3 = Box::new(v8::StartupData::new(data3)); - assert_eq!(&**sd3, data3); + let vec_2 = std::fs::read(file!()).unwrap(); + let _ = v8::CreateParams::default().snapshot_blob(vec_2); + + 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] fn uint8_array() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2013,9 +1921,7 @@ fn uint8_array() { #[test] fn dynamic_import() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -2057,9 +1963,7 @@ fn dynamic_import() { #[test] fn shared_array_buffer() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2115,9 +2019,7 @@ fn shared_array_buffer() { #[allow(clippy::eq_op)] fn value_checker() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2450,9 +2352,7 @@ fn value_checker() { #[test] fn try_from_local() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2681,9 +2581,7 @@ impl v8::inspector::ChannelImpl for ChannelCounter { #[test] fn inspector_dispatch_protocol_message() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); use v8::inspector::*; let mut default_client = ClientCounter::new(); @@ -2716,9 +2614,7 @@ fn inspector_dispatch_protocol_message() { #[test] fn inspector_schedule_pause_on_next_statement() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); use v8::inspector::*; let mut client = ClientCounter::new(); @@ -2780,9 +2676,7 @@ fn inspector_schedule_pause_on_next_statement() { #[test] fn inspector_console_api_message() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); use v8::inspector::*; @@ -2848,9 +2742,7 @@ fn inspector_console_api_message() { #[test] fn context_from_object_template() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2870,9 +2762,7 @@ fn context_from_object_template() { #[test] fn get_and_set_data() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); let nslots = isolate.get_number_of_data_slots(); assert!(nslots > 0); for slot in 0..nslots { @@ -2888,9 +2778,7 @@ fn get_and_set_data() { #[test] fn take_heap_snapshot() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2918,9 +2806,7 @@ fn take_heap_snapshot() { #[test] fn test_prototype_api() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); @@ -2976,9 +2862,7 @@ fn test_prototype_api() { #[test] fn test_map_api() { let _setup_guard = setup(); - let mut params = v8::Isolate::create_params(); - params.set_array_buffer_allocator(v8::new_default_allocator()); - let mut isolate = v8::Isolate::new(params); + let mut isolate = v8::Isolate::new(Default::default()); { let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter();