2019-12-27 09:12:16 -05:00
|
|
|
use crate::external_references::ExternalReferences;
|
2019-12-24 14:03:32 +01:00
|
|
|
use crate::support::int;
|
2019-12-27 09:12:16 -05:00
|
|
|
use crate::support::intptr_t;
|
2019-12-24 14:03:32 +01:00
|
|
|
use crate::Context;
|
|
|
|
use crate::Isolate;
|
|
|
|
use crate::Local;
|
2020-01-03 16:52:05 -05:00
|
|
|
use crate::OwnedIsolate;
|
|
|
|
use std::borrow::Borrow;
|
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::mem::MaybeUninit;
|
|
|
|
use std::ops::Deref;
|
|
|
|
use std::ops::DerefMut;
|
2019-12-24 14:03:32 +01:00
|
|
|
|
|
|
|
extern "C" {
|
2019-12-27 09:12:16 -05:00
|
|
|
fn v8__SnapshotCreator__CONSTRUCT(
|
2020-04-13 14:43:56 +02:00
|
|
|
buf: *mut MaybeUninit<SnapshotCreator>,
|
2019-12-27 09:12:16 -05:00
|
|
|
external_references: *const intptr_t,
|
|
|
|
);
|
2020-04-13 14:43:56 +02:00
|
|
|
fn v8__SnapshotCreator__DESTRUCT(this: *mut SnapshotCreator);
|
|
|
|
fn v8__SnapshotCreator__GetIsolate(
|
|
|
|
this: *mut SnapshotCreator,
|
|
|
|
) -> *mut Isolate;
|
2019-12-24 14:03:32 +01:00
|
|
|
fn v8__SnapshotCreator__CreateBlob(
|
|
|
|
this: *mut SnapshotCreator,
|
|
|
|
function_code_handling: FunctionCodeHandling,
|
2019-12-31 02:42:39 +01:00
|
|
|
) -> OwnedStartupData;
|
2019-12-24 14:03:32 +01:00
|
|
|
fn v8__SnapshotCreator__SetDefaultContext(
|
2020-04-13 14:43:56 +02:00
|
|
|
this: *mut SnapshotCreator,
|
|
|
|
context: *const Context,
|
2019-12-24 14:03:32 +01:00
|
|
|
);
|
2020-04-13 14:43:56 +02:00
|
|
|
fn v8__StartupData__DESTRUCT(this: *mut StartupData);
|
2019-12-24 14:03:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
2019-12-31 02:42:39 +01:00
|
|
|
pub struct StartupData<'a> {
|
|
|
|
data: *const u8,
|
2019-12-25 08:14:55 -05:00
|
|
|
raw_size: int,
|
2019-12-31 02:42:39 +01:00
|
|
|
_phantom: PhantomData<&'a [u8]>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> StartupData<'a> {
|
|
|
|
pub fn new<D>(data: &'a D) -> Self
|
|
|
|
where
|
2020-01-04 01:17:48 +01:00
|
|
|
D: Borrow<[u8]> + ?Sized,
|
2019-12-31 02:42:39 +01:00
|
|
|
{
|
|
|
|
let data = data.borrow();
|
|
|
|
Self {
|
|
|
|
data: data.as_ptr(),
|
|
|
|
raw_size: data.len() as int,
|
|
|
|
_phantom: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
2019-12-25 08:14:55 -05:00
|
|
|
}
|
|
|
|
|
2019-12-31 02:42:39 +01:00
|
|
|
impl<'a> Deref for StartupData<'a> {
|
2019-12-25 08:14:55 -05:00
|
|
|
type Target = [u8];
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
unsafe { std::slice::from_raw_parts(self.data, self.raw_size as usize) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-31 02:42:39 +01:00
|
|
|
#[repr(transparent)]
|
|
|
|
pub struct OwnedStartupData(StartupData<'static>);
|
|
|
|
|
|
|
|
impl Deref for OwnedStartupData {
|
|
|
|
type Target = StartupData<'static>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DerefMut for OwnedStartupData {
|
2019-12-25 08:14:55 -05:00
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2019-12-31 02:42:39 +01:00
|
|
|
&mut self.0
|
2019-12-25 08:14:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-31 02:42:39 +01:00
|
|
|
impl Drop for OwnedStartupData {
|
2019-12-25 08:14:55 -05:00
|
|
|
fn drop(&mut self) {
|
2019-12-31 02:42:39 +01:00
|
|
|
unsafe { v8__StartupData__DESTRUCT(&mut self.0) }
|
2019-12-25 08:14:55 -05:00
|
|
|
}
|
2019-12-24 14:03:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
pub enum FunctionCodeHandling {
|
|
|
|
Clear,
|
|
|
|
Keep,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper class to create a snapshot data blob.
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct SnapshotCreator([usize; 1]);
|
|
|
|
|
2019-12-27 09:12:16 -05:00
|
|
|
impl SnapshotCreator {
|
2019-12-24 14:03:32 +01:00
|
|
|
/// Create and enter an isolate, and set it up for serialization.
|
|
|
|
/// The isolate is created from scratch.
|
2019-12-27 09:12:16 -05:00
|
|
|
pub fn new(external_references: Option<&'static ExternalReferences>) -> Self {
|
2019-12-24 14:03:32 +01:00
|
|
|
let mut snapshot_creator: MaybeUninit<Self> = MaybeUninit::uninit();
|
2019-12-27 09:12:16 -05:00
|
|
|
let external_references_ptr = if let Some(er) = external_references {
|
|
|
|
er.as_ptr()
|
|
|
|
} else {
|
|
|
|
std::ptr::null()
|
|
|
|
};
|
2019-12-24 14:03:32 +01:00
|
|
|
unsafe {
|
2019-12-27 09:12:16 -05:00
|
|
|
v8__SnapshotCreator__CONSTRUCT(
|
|
|
|
&mut snapshot_creator,
|
|
|
|
external_references_ptr,
|
|
|
|
);
|
2019-12-24 14:03:32 +01:00
|
|
|
snapshot_creator.assume_init()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for SnapshotCreator {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe { v8__SnapshotCreator__DESTRUCT(self) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SnapshotCreator {
|
|
|
|
/// Set the default context to be included in the snapshot blob.
|
|
|
|
/// The snapshot will not contain the global proxy, and we expect one or a
|
|
|
|
/// global object template to create one, to be provided upon deserialization.
|
2020-04-13 14:43:56 +02:00
|
|
|
pub fn set_default_context<'sc>(&mut self, context: Local<'sc, Context>) {
|
|
|
|
unsafe { v8__SnapshotCreator__SetDefaultContext(self, &*context) };
|
2019-12-24 14:03:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a snapshot data blob.
|
|
|
|
/// This must not be called from within a handle scope.
|
|
|
|
pub fn create_blob(
|
|
|
|
&mut self,
|
|
|
|
function_code_handling: FunctionCodeHandling,
|
2019-12-31 02:42:39 +01:00
|
|
|
) -> Option<OwnedStartupData> {
|
2019-12-25 08:14:55 -05:00
|
|
|
let blob =
|
|
|
|
unsafe { v8__SnapshotCreator__CreateBlob(self, function_code_handling) };
|
|
|
|
if blob.data.is_null() {
|
|
|
|
debug_assert!(blob.raw_size == 0);
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
debug_assert!(blob.raw_size > 0);
|
|
|
|
Some(blob)
|
|
|
|
}
|
2019-12-24 14:03:32 +01:00
|
|
|
}
|
|
|
|
|
2020-01-03 16:52:05 -05:00
|
|
|
/// This is marked unsafe because it should be called at most once per snapshot
|
|
|
|
/// creator.
|
|
|
|
// TODO Because the SnapshotCreator creates its own isolate, we need a way to
|
|
|
|
// get an owned handle to it. This is a questionable design which ought to be
|
|
|
|
// 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)
|
|
|
|
}
|
2019-12-24 14:03:32 +01:00
|
|
|
}
|