mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 00:29:09 -05:00
chore(core): Split JsRuntimeForSnapshot from JsRuntime (#19308)
This cleans up `JsRuntime` a bit more: * We no longer print cargo's rerun-if-changed messages in `JsRuntime` -- those are printed elsewhere * We no longer special case the OwnedIsolate for snapshots. Instead we make use of an inner object that has the `Drop` impl and allows us to `std::mem::forget` it if we need to extract the isolate for a snapshot * The `snapshot` method is only available on `JsRuntimeForSnapshot`, not `JsRuntime`. * `OpState` construction is slightly cleaner, though I'd still like to extract more --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
parent
f89b2c5ca6
commit
782db80629
13 changed files with 697 additions and 432 deletions
13
cli/build.rs
13
cli/build.rs
|
@ -262,7 +262,7 @@ mod ts {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
create_snapshot(CreateSnapshotOptions {
|
let output = create_snapshot(CreateSnapshotOptions {
|
||||||
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
snapshot_path,
|
snapshot_path,
|
||||||
startup_snapshot: None,
|
startup_snapshot: None,
|
||||||
|
@ -289,6 +289,9 @@ mod ts {
|
||||||
})),
|
})),
|
||||||
snapshot_module_load_cb: None,
|
snapshot_module_load_cb: None,
|
||||||
});
|
});
|
||||||
|
for path in output.files_loaded_during_snapshot {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn version() -> String {
|
pub(crate) fn version() -> String {
|
||||||
|
@ -326,7 +329,8 @@ deno_core::extension!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
fn create_cli_snapshot(snapshot_path: PathBuf) {
|
#[must_use = "The files listed by create_cli_snapshot should be printed as 'cargo:rerun-if-changed' lines"]
|
||||||
|
fn create_cli_snapshot(snapshot_path: PathBuf) -> CreateSnapshotOutput {
|
||||||
// NOTE(bartlomieju): ordering is important here, keep it in sync with
|
// NOTE(bartlomieju): ordering is important here, keep it in sync with
|
||||||
// `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`!
|
// `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`!
|
||||||
let fs = Arc::new(deno_fs::RealFs);
|
let fs = Arc::new(deno_fs::RealFs);
|
||||||
|
@ -481,7 +485,10 @@ fn main() {
|
||||||
ts::create_compiler_snapshot(compiler_snapshot_path, &c);
|
ts::create_compiler_snapshot(compiler_snapshot_path, &c);
|
||||||
|
|
||||||
let cli_snapshot_path = o.join("CLI_SNAPSHOT.bin");
|
let cli_snapshot_path = o.join("CLI_SNAPSHOT.bin");
|
||||||
create_cli_snapshot(cli_snapshot_path);
|
let output = create_cli_snapshot(cli_snapshot_path);
|
||||||
|
for path in output.files_loaded_during_snapshot {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,10 +15,19 @@ use crate::modules::ImportAssertionsKind;
|
||||||
use crate::modules::ModuleMap;
|
use crate::modules::ModuleMap;
|
||||||
use crate::modules::ResolutionKind;
|
use crate::modules::ResolutionKind;
|
||||||
use crate::ops::OpCtx;
|
use crate::ops::OpCtx;
|
||||||
use crate::snapshot_util::SnapshotOptions;
|
|
||||||
use crate::JsRealm;
|
use crate::JsRealm;
|
||||||
use crate::JsRuntime;
|
use crate::JsRuntime;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub(crate) enum BindingsMode {
|
||||||
|
/// We have no snapshot -- this is a pristine context.
|
||||||
|
New,
|
||||||
|
/// We have initialized before, are reloading a snapshot, and will snapshot.
|
||||||
|
Loaded,
|
||||||
|
/// We have initialized before, are reloading a snapshot, and will not snapshot again.
|
||||||
|
LoadedFinal,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn external_references(ops: &[OpCtx]) -> v8::ExternalReferences {
|
pub(crate) fn external_references(ops: &[OpCtx]) -> v8::ExternalReferences {
|
||||||
// Overallocate a bit, it's better than having to resize the vector.
|
// Overallocate a bit, it's better than having to resize the vector.
|
||||||
let mut references = Vec::with_capacity(4 + ops.len() * 4);
|
let mut references = Vec::with_capacity(4 + ops.len() * 4);
|
||||||
|
@ -118,7 +127,7 @@ pub(crate) fn initialize_context<'s>(
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
context: v8::Local<'s, v8::Context>,
|
context: v8::Local<'s, v8::Context>,
|
||||||
op_ctxs: &[OpCtx],
|
op_ctxs: &[OpCtx],
|
||||||
snapshot_options: SnapshotOptions,
|
bindings_mode: BindingsMode,
|
||||||
) -> v8::Local<'s, v8::Context> {
|
) -> v8::Local<'s, v8::Context> {
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
|
@ -128,13 +137,13 @@ pub(crate) fn initialize_context<'s>(
|
||||||
codegen,
|
codegen,
|
||||||
"Deno.__op__ = function(opFns, callConsole, console) {{"
|
"Deno.__op__ = function(opFns, callConsole, console) {{"
|
||||||
);
|
);
|
||||||
if !snapshot_options.loaded() {
|
if bindings_mode == BindingsMode::New {
|
||||||
_ = writeln!(codegen, "Deno.__op__console(callConsole, console);");
|
_ = writeln!(codegen, "Deno.__op__console(callConsole, console);");
|
||||||
}
|
}
|
||||||
for op_ctx in op_ctxs {
|
for op_ctx in op_ctxs {
|
||||||
if op_ctx.decl.enabled {
|
if op_ctx.decl.enabled {
|
||||||
// If we're loading from a snapshot, we can skip registration for most ops
|
// If we're loading from a snapshot, we can skip registration for most ops
|
||||||
if matches!(snapshot_options, SnapshotOptions::Load)
|
if bindings_mode == BindingsMode::LoadedFinal
|
||||||
&& !op_ctx.decl.force_registration
|
&& !op_ctx.decl.force_registration
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -173,7 +182,7 @@ pub(crate) fn initialize_context<'s>(
|
||||||
let op_fn = op_ctx_function(scope, op_ctx);
|
let op_fn = op_ctx_function(scope, op_ctx);
|
||||||
op_fns.set_index(scope, op_ctx.id as u32, op_fn.into());
|
op_fns.set_index(scope, op_ctx.id as u32, op_fn.into());
|
||||||
}
|
}
|
||||||
if snapshot_options.loaded() {
|
if bindings_mode != BindingsMode::New {
|
||||||
op_fn.call(scope, recv.into(), &[op_fns.into()]);
|
op_fn.call(scope, recv.into(), &[op_fns.into()]);
|
||||||
} else {
|
} else {
|
||||||
// Bind functions to Deno.core.*
|
// Bind functions to Deno.core.*
|
||||||
|
@ -284,7 +293,7 @@ pub fn host_import_module_dynamically_callback<'s>(
|
||||||
|
|
||||||
let resolver_handle = v8::Global::new(scope, resolver);
|
let resolver_handle = v8::Global::new(scope, resolver);
|
||||||
{
|
{
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let module_map_rc = JsRuntime::module_map_from(scope);
|
let module_map_rc = JsRuntime::module_map_from(scope);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -484,7 +493,7 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if has_unhandled_rejection_handler {
|
if has_unhandled_rejection_handler {
|
||||||
let state_rc = JsRuntime::state(tc_scope);
|
let state_rc = JsRuntime::state_from(tc_scope);
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
if let Some(pending_mod_evaluate) = state.pending_mod_evaluate.as_mut() {
|
if let Some(pending_mod_evaluate) = state.pending_mod_evaluate.as_mut() {
|
||||||
if !pending_mod_evaluate.has_evaluated {
|
if !pending_mod_evaluate.has_evaluated {
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl JsStackFrame {
|
||||||
let l = message.get_line_number(scope)? as i64;
|
let l = message.get_line_number(scope)? as i64;
|
||||||
// V8's column numbers are 0-based, we want 1-based.
|
// V8's column numbers are 0-based, we want 1-based.
|
||||||
let c = message.get_start_column() as i64 + 1;
|
let c = message.get_start_column() as i64 + 1;
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let (getter, cache) = {
|
let (getter, cache) = {
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
(
|
(
|
||||||
|
@ -282,7 +282,7 @@ impl JsError {
|
||||||
frames = vec![stack_frame];
|
frames = vec![stack_frame];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let (getter, cache) = {
|
let (getter, cache) = {
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
(
|
(
|
||||||
|
@ -414,7 +414,7 @@ impl JsError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let (getter, cache) = {
|
let (getter, cache) = {
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
(
|
(
|
||||||
|
|
|
@ -3,7 +3,7 @@ use deno_core::anyhow::Error;
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::AsyncRefCell;
|
use deno_core::AsyncRefCell;
|
||||||
use deno_core::AsyncResult;
|
use deno_core::AsyncResult;
|
||||||
use deno_core::JsRuntime;
|
use deno_core::JsRuntimeForSnapshot;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
|
@ -93,7 +93,7 @@ impl From<tokio::net::TcpStream> for TcpStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_js_runtime() -> JsRuntime {
|
fn create_js_runtime() -> JsRuntimeForSnapshot {
|
||||||
let ext = deno_core::Extension::builder("my_ext")
|
let ext = deno_core::Extension::builder("my_ext")
|
||||||
.ops(vec![
|
.ops(vec![
|
||||||
op_listen::decl(),
|
op_listen::decl(),
|
||||||
|
@ -103,11 +103,13 @@ fn create_js_runtime() -> JsRuntime {
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
JsRuntime::new(deno_core::RuntimeOptions {
|
JsRuntimeForSnapshot::new(
|
||||||
extensions: vec![ext],
|
deno_core::RuntimeOptions {
|
||||||
will_snapshot: false,
|
extensions: vec![ext],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
},
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
|
|
|
@ -349,6 +349,7 @@ macro_rules! extension {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Extension {
|
pub struct Extension {
|
||||||
|
pub(crate) name: &'static str,
|
||||||
js_files: Option<Vec<ExtensionFileSource>>,
|
js_files: Option<Vec<ExtensionFileSource>>,
|
||||||
esm_files: Option<Vec<ExtensionFileSource>>,
|
esm_files: Option<Vec<ExtensionFileSource>>,
|
||||||
esm_entry_point: Option<&'static str>,
|
esm_entry_point: Option<&'static str>,
|
||||||
|
@ -358,7 +359,6 @@ pub struct Extension {
|
||||||
event_loop_middleware: Option<Box<OpEventLoopFn>>,
|
event_loop_middleware: Option<Box<OpEventLoopFn>>,
|
||||||
initialized: bool,
|
initialized: bool,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
name: &'static str,
|
|
||||||
deps: Option<&'static [&'static str]>,
|
deps: Option<&'static [&'static str]>,
|
||||||
force_op_registration: bool,
|
force_op_registration: bool,
|
||||||
pub(crate) is_core: bool,
|
pub(crate) is_core: bool,
|
||||||
|
|
|
@ -113,6 +113,7 @@ pub use crate::runtime::CrossIsolateStore;
|
||||||
pub use crate::runtime::GetErrorClassFn;
|
pub use crate::runtime::GetErrorClassFn;
|
||||||
pub use crate::runtime::JsErrorCreateFn;
|
pub use crate::runtime::JsErrorCreateFn;
|
||||||
pub use crate::runtime::JsRuntime;
|
pub use crate::runtime::JsRuntime;
|
||||||
|
pub use crate::runtime::JsRuntimeForSnapshot;
|
||||||
pub use crate::runtime::RuntimeOptions;
|
pub use crate::runtime::RuntimeOptions;
|
||||||
pub use crate::runtime::SharedArrayBufferStore;
|
pub use crate::runtime::SharedArrayBufferStore;
|
||||||
pub use crate::runtime::Snapshot;
|
pub use crate::runtime::Snapshot;
|
||||||
|
|
|
@ -1719,6 +1719,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ascii_str;
|
use crate::ascii_str;
|
||||||
use crate::JsRuntime;
|
use crate::JsRuntime;
|
||||||
|
use crate::JsRuntimeForSnapshot;
|
||||||
use crate::RuntimeOptions;
|
use crate::RuntimeOptions;
|
||||||
use crate::Snapshot;
|
use crate::Snapshot;
|
||||||
use deno_ops::op;
|
use deno_ops::op;
|
||||||
|
@ -2889,11 +2890,13 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error();
|
||||||
);
|
);
|
||||||
|
|
||||||
let loader = MockLoader::new();
|
let loader = MockLoader::new();
|
||||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
let mut runtime = JsRuntimeForSnapshot::new(
|
||||||
module_loader: Some(loader),
|
RuntimeOptions {
|
||||||
will_snapshot: true,
|
module_loader: Some(loader),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
},
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
// In default resolution code should be empty.
|
// In default resolution code should be empty.
|
||||||
// Instead we explicitly pass in our own code.
|
// Instead we explicitly pass in our own code.
|
||||||
// The behavior should be very similar to /a.js.
|
// The behavior should be very similar to /a.js.
|
||||||
|
@ -2931,11 +2934,13 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error();
|
||||||
);
|
);
|
||||||
|
|
||||||
let loader = MockLoader::new();
|
let loader = MockLoader::new();
|
||||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
let mut runtime = JsRuntimeForSnapshot::new(
|
||||||
module_loader: Some(loader),
|
RuntimeOptions {
|
||||||
will_snapshot: true,
|
module_loader: Some(loader),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
},
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
// In default resolution code should be empty.
|
// In default resolution code should be empty.
|
||||||
// Instead we explicitly pass in our own code.
|
// Instead we explicitly pass in our own code.
|
||||||
// The behavior should be very similar to /a.js.
|
// The behavior should be very similar to /a.js.
|
||||||
|
|
|
@ -183,7 +183,7 @@ pub struct OpState {
|
||||||
pub get_error_class_fn: GetErrorClassFn,
|
pub get_error_class_fn: GetErrorClassFn,
|
||||||
pub tracker: OpsTracker,
|
pub tracker: OpsTracker,
|
||||||
pub last_fast_op_error: Option<AnyError>,
|
pub last_fast_op_error: Option<AnyError>,
|
||||||
gotham_state: GothamState,
|
pub(crate) gotham_state: GothamState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpState {
|
impl OpState {
|
||||||
|
@ -196,6 +196,12 @@ impl OpState {
|
||||||
tracker: OpsTracker::new(ops_count),
|
tracker: OpsTracker::new(ops_count),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear all user-provided resources and state.
|
||||||
|
pub(crate) fn clear(&mut self) {
|
||||||
|
std::mem::take(&mut self.gotham_state);
|
||||||
|
std::mem::take(&mut self.resource_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for OpState {
|
impl Deref for OpState {
|
||||||
|
|
|
@ -72,14 +72,14 @@ fn op_run_microtasks(scope: &mut v8::HandleScope) {
|
||||||
|
|
||||||
#[op(v8)]
|
#[op(v8)]
|
||||||
fn op_has_tick_scheduled(scope: &mut v8::HandleScope) -> bool {
|
fn op_has_tick_scheduled(scope: &mut v8::HandleScope) -> bool {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
state.has_tick_scheduled
|
state.has_tick_scheduled
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op(v8)]
|
#[op(v8)]
|
||||||
fn op_set_has_tick_scheduled(scope: &mut v8::HandleScope, v: bool) {
|
fn op_set_has_tick_scheduled(scope: &mut v8::HandleScope, v: bool) {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
state_rc.borrow_mut().has_tick_scheduled = v;
|
state_rc.borrow_mut().has_tick_scheduled = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> {
|
||||||
if self.for_storage {
|
if self.for_storage {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
||||||
let backing_store = shared_array_buffer.get_backing_store();
|
let backing_store = shared_array_buffer.get_backing_store();
|
||||||
|
@ -263,7 +263,7 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> {
|
||||||
self.throw_data_clone_error(scope, message);
|
self.throw_data_clone_error(scope, message);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
if let Some(compiled_wasm_module_store) = &state.compiled_wasm_module_store
|
if let Some(compiled_wasm_module_store) = &state.compiled_wasm_module_store
|
||||||
{
|
{
|
||||||
|
@ -305,7 +305,7 @@ impl<'a> v8::ValueDeserializerImpl for SerializeDeserialize<'a> {
|
||||||
if self.for_storage {
|
if self.for_storage {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
||||||
let backing_store = shared_array_buffer_store.take(transfer_id)?;
|
let backing_store = shared_array_buffer_store.take(transfer_id)?;
|
||||||
|
@ -325,7 +325,7 @@ impl<'a> v8::ValueDeserializerImpl for SerializeDeserialize<'a> {
|
||||||
if self.for_storage {
|
if self.for_storage {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
if let Some(compiled_wasm_module_store) = &state.compiled_wasm_module_store
|
if let Some(compiled_wasm_module_store) = &state.compiled_wasm_module_store
|
||||||
{
|
{
|
||||||
|
@ -409,7 +409,7 @@ fn op_serialize(
|
||||||
value_serializer.write_header();
|
value_serializer.write_header();
|
||||||
|
|
||||||
if let Some(transferred_array_buffers) = transferred_array_buffers {
|
if let Some(transferred_array_buffers) = transferred_array_buffers {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
for index in 0..transferred_array_buffers.length() {
|
for index in 0..transferred_array_buffers.length() {
|
||||||
let i = v8::Number::new(scope, index as f64).into();
|
let i = v8::Number::new(scope, index as f64).into();
|
||||||
|
@ -494,7 +494,7 @@ fn op_deserialize<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(transferred_array_buffers) = transferred_array_buffers {
|
if let Some(transferred_array_buffers) = transferred_array_buffers {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow_mut();
|
let state = state_rc.borrow_mut();
|
||||||
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store {
|
||||||
for i in 0..transferred_array_buffers.length() {
|
for i in 0..transferred_array_buffers.length() {
|
||||||
|
@ -724,7 +724,7 @@ fn op_set_wasm_streaming_callback(
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let streaming_rid = state_rc
|
let streaming_rid = state_rc
|
||||||
.borrow()
|
.borrow()
|
||||||
.op_state
|
.op_state
|
||||||
|
@ -751,7 +751,7 @@ fn op_abort_wasm_streaming(
|
||||||
error: serde_v8::Value,
|
error: serde_v8::Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let wasm_streaming = {
|
let wasm_streaming = {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
let wsr = state
|
let wsr = state
|
||||||
.op_state
|
.op_state
|
||||||
|
@ -790,7 +790,7 @@ fn op_dispatch_exception(
|
||||||
scope: &mut v8::HandleScope,
|
scope: &mut v8::HandleScope,
|
||||||
exception: serde_v8::Value,
|
exception: serde_v8::Value,
|
||||||
) {
|
) {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
if let Some(inspector) = &state.inspector {
|
if let Some(inspector) = &state.inspector {
|
||||||
let inspector = inspector.borrow();
|
let inspector = inspector.borrow();
|
||||||
|
@ -828,7 +828,7 @@ fn op_apply_source_map(
|
||||||
scope: &mut v8::HandleScope,
|
scope: &mut v8::HandleScope,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> Result<Location, Error> {
|
) -> Result<Location, Error> {
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let (getter, cache) = {
|
let (getter, cache) = {
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
(
|
(
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl JsRealmInner {
|
||||||
};
|
};
|
||||||
|
|
||||||
let exception = v8::Local::new(scope, handle);
|
let exception = v8::Local::new(scope, handle);
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state_from(scope);
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
if let Some(inspector) = &state.inspector {
|
if let Some(inspector) = &state.inspector {
|
||||||
let inspector = inspector.borrow();
|
let inspector = inspector.borrow();
|
||||||
|
|
921
core/runtime.rs
921
core/runtime.rs
File diff suppressed because it is too large
Load diff
|
@ -4,9 +4,10 @@ use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use crate::runtime::RuntimeSnapshotOptions;
|
||||||
use crate::ExtModuleLoaderCb;
|
use crate::ExtModuleLoaderCb;
|
||||||
use crate::Extension;
|
use crate::Extension;
|
||||||
use crate::JsRuntime;
|
use crate::JsRuntimeForSnapshot;
|
||||||
use crate::RuntimeOptions;
|
use crate::RuntimeOptions;
|
||||||
use crate::Snapshot;
|
use crate::Snapshot;
|
||||||
|
|
||||||
|
@ -21,16 +22,28 @@ pub struct CreateSnapshotOptions {
|
||||||
pub snapshot_module_load_cb: Option<ExtModuleLoaderCb>,
|
pub snapshot_module_load_cb: Option<ExtModuleLoaderCb>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) {
|
pub struct CreateSnapshotOutput {
|
||||||
|
/// Any files marked as LoadedFromFsDuringSnapshot are collected here and should be
|
||||||
|
/// printed as 'cargo:rerun-if-changed' lines from your build script.
|
||||||
|
pub files_loaded_during_snapshot: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use = "The files listed by create_snapshot should be printed as 'cargo:rerun-if-changed' lines"]
|
||||||
|
pub fn create_snapshot(
|
||||||
|
create_snapshot_options: CreateSnapshotOptions,
|
||||||
|
) -> CreateSnapshotOutput {
|
||||||
let mut mark = Instant::now();
|
let mut mark = Instant::now();
|
||||||
|
|
||||||
let js_runtime = JsRuntime::new(RuntimeOptions {
|
let js_runtime = JsRuntimeForSnapshot::new(
|
||||||
will_snapshot: true,
|
RuntimeOptions {
|
||||||
startup_snapshot: create_snapshot_options.startup_snapshot,
|
startup_snapshot: create_snapshot_options.startup_snapshot,
|
||||||
extensions: create_snapshot_options.extensions,
|
extensions: create_snapshot_options.extensions,
|
||||||
snapshot_module_load_cb: create_snapshot_options.snapshot_module_load_cb,
|
..Default::default()
|
||||||
..Default::default()
|
},
|
||||||
});
|
RuntimeSnapshotOptions {
|
||||||
|
snapshot_module_load_cb: create_snapshot_options.snapshot_module_load_cb,
|
||||||
|
},
|
||||||
|
);
|
||||||
println!(
|
println!(
|
||||||
"JsRuntime for snapshot prepared, took {:#?} ({})",
|
"JsRuntime for snapshot prepared, took {:#?} ({})",
|
||||||
Instant::now().saturating_duration_since(mark),
|
Instant::now().saturating_duration_since(mark),
|
||||||
|
@ -38,6 +51,22 @@ pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) {
|
||||||
);
|
);
|
||||||
mark = Instant::now();
|
mark = Instant::now();
|
||||||
|
|
||||||
|
let mut files_loaded_during_snapshot = vec![];
|
||||||
|
for source in js_runtime
|
||||||
|
.extensions()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|e| vec![e.get_esm_sources(), e.get_js_sources()])
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
{
|
||||||
|
use crate::ExtensionFileSourceCode;
|
||||||
|
if let ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(path) =
|
||||||
|
&source.code
|
||||||
|
{
|
||||||
|
files_loaded_during_snapshot.push(path.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let snapshot = js_runtime.snapshot();
|
let snapshot = js_runtime.snapshot();
|
||||||
let snapshot_slice: &[u8] = &snapshot;
|
let snapshot_slice: &[u8] = &snapshot;
|
||||||
println!(
|
println!(
|
||||||
|
@ -83,6 +112,9 @@ pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) {
|
||||||
Instant::now().saturating_duration_since(mark),
|
Instant::now().saturating_duration_since(mark),
|
||||||
create_snapshot_options.snapshot_path.display(),
|
create_snapshot_options.snapshot_path.display(),
|
||||||
);
|
);
|
||||||
|
CreateSnapshotOutput {
|
||||||
|
files_loaded_during_snapshot,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FilterFn = Box<dyn Fn(&PathBuf) -> bool>;
|
pub type FilterFn = Box<dyn Fn(&PathBuf) -> bool>;
|
||||||
|
@ -121,29 +153,36 @@ fn data_error_to_panic(err: v8::DataError) -> ! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub(crate) enum SnapshotOptions {
|
pub(crate) enum SnapshotOptions {
|
||||||
Load,
|
Load(Snapshot),
|
||||||
CreateFromExisting,
|
CreateFromExisting(Snapshot),
|
||||||
Create,
|
Create,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SnapshotOptions {
|
impl SnapshotOptions {
|
||||||
|
pub fn new_from(snapshot: Option<Snapshot>, will_snapshot: bool) -> Self {
|
||||||
|
match (snapshot, will_snapshot) {
|
||||||
|
(Some(snapshot), true) => Self::CreateFromExisting(snapshot),
|
||||||
|
(None, true) => Self::Create,
|
||||||
|
(Some(snapshot), false) => Self::Load(snapshot),
|
||||||
|
(None, false) => Self::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn loaded(&self) -> bool {
|
pub fn loaded(&self) -> bool {
|
||||||
matches!(self, Self::Load | Self::CreateFromExisting)
|
matches!(self, Self::Load(_) | Self::CreateFromExisting(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn will_snapshot(&self) -> bool {
|
pub fn will_snapshot(&self) -> bool {
|
||||||
matches!(self, Self::Create | Self::CreateFromExisting)
|
matches!(self, Self::Create | Self::CreateFromExisting(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bools(snapshot_loaded: bool, will_snapshot: bool) -> Self {
|
pub fn snapshot(self) -> Option<Snapshot> {
|
||||||
match (snapshot_loaded, will_snapshot) {
|
match self {
|
||||||
(true, true) => Self::CreateFromExisting,
|
Self::CreateFromExisting(snapshot) => Some(snapshot),
|
||||||
(false, true) => Self::Create,
|
Self::Load(snapshot) => Some(snapshot),
|
||||||
(true, false) => Self::Load,
|
_ => None,
|
||||||
(false, false) => Self::None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,9 +257,9 @@ pub(crate) fn set_snapshotted_data(
|
||||||
/// Returns an isolate set up for snapshotting.
|
/// Returns an isolate set up for snapshotting.
|
||||||
pub(crate) fn create_snapshot_creator(
|
pub(crate) fn create_snapshot_creator(
|
||||||
external_refs: &'static v8::ExternalReferences,
|
external_refs: &'static v8::ExternalReferences,
|
||||||
maybe_startup_snapshot: Option<Snapshot>,
|
maybe_startup_snapshot: SnapshotOptions,
|
||||||
) -> v8::OwnedIsolate {
|
) -> v8::OwnedIsolate {
|
||||||
if let Some(snapshot) = maybe_startup_snapshot {
|
if let Some(snapshot) = maybe_startup_snapshot.snapshot() {
|
||||||
match snapshot {
|
match snapshot {
|
||||||
Snapshot::Static(data) => {
|
Snapshot::Static(data) => {
|
||||||
v8::Isolate::snapshot_creator_from_existing_snapshot(
|
v8::Isolate::snapshot_creator_from_existing_snapshot(
|
||||||
|
|
|
@ -337,7 +337,7 @@ mod startup_snapshot {
|
||||||
runtime_main::init_ops_and_esm(),
|
runtime_main::init_ops_and_esm(),
|
||||||
];
|
];
|
||||||
|
|
||||||
create_snapshot(CreateSnapshotOptions {
|
let output = create_snapshot(CreateSnapshotOptions {
|
||||||
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
snapshot_path,
|
snapshot_path,
|
||||||
startup_snapshot: None,
|
startup_snapshot: None,
|
||||||
|
@ -345,6 +345,9 @@ mod startup_snapshot {
|
||||||
compression_cb: None,
|
compression_cb: None,
|
||||||
snapshot_module_load_cb: Some(Box::new(transpile_ts_for_snapshotting)),
|
snapshot_module_load_cb: Some(Box::new(transpile_ts_for_snapshotting)),
|
||||||
});
|
});
|
||||||
|
for path in output.files_loaded_during_snapshot {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue