diff --git a/Cargo.lock b/Cargo.lock index cf4cf50389..8cbbe2a635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1254,9 +1254,9 @@ dependencies = [ [[package]] name = "deno_core" -version = "0.264.0" +version = "0.265.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c8dc01fe0c49caf5c784c50958db2d73eb03be62d2d95e3ec83541b64841d8c" +checksum = "f40a3dc5c31b35feedda9304ceff8b541dd5c8d7deeb69eb6036f8fa65bfdf08" dependencies = [ "anyhow", "bincode", @@ -1711,9 +1711,9 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.140.0" +version = "0.141.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d421b045e2220215b55676f8874246f6b08f9c5de9cdfdfefb6f9b10a3e0f4b3" +checksum = "86efc44027a9d370fa677988cb463fb8c9a48c5d8b53e91431a69a44540a6c11" dependencies = [ "proc-macro-rules", "proc-macro2", @@ -5597,9 +5597,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.173.0" +version = "0.174.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a4cbf3daa409a0affe0b6363364ff829fc3ef62c2a0f57c5e26f202f9845ef" +checksum = "1f15fc8c65ebdf37ec94b72dacad9622ad8e04a7cf7504060a709eb21ed02b88" dependencies = [ "bytes", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index 7e8988ce96..9949ad06c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ repository = "https://github.com/denoland/deno" [workspace.dependencies] deno_ast = { version = "0.34.0", features = ["transpiling"] } -deno_core = { version = "0.264.0", features = ["snapshot_data_bincode"] } +deno_core = { version = "0.265.0", features = ["snapshot_data_bincode"] } deno_bench_util = { version = "0.133.0", path = "./bench_util" } deno_lockfile = "0.19.0" diff --git a/cli/build.rs b/cli/build.rs index 1f941142c3..0a599b03b1 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -15,6 +15,7 @@ mod ts { use deno_runtime::deno_node::SUPPORTED_BUILTIN_NODE_MODULES; use serde::Serialize; use std::collections::HashMap; + use std::io::Write; use std::path::Path; use std::path::PathBuf; @@ -266,10 +267,6 @@ mod ts { ) .unwrap(); - let snapshot_to_file = SnapshotFileSerializer::new( - std::fs::File::create(snapshot_path).unwrap(), - ); - let output = create_snapshot( CreateSnapshotOptions { cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), @@ -279,33 +276,30 @@ mod ts { build_libs, path_dts, )], - // NOTE(bartlomieju): Compressing the TSC snapshot in debug build took - // ~45s on M1 MacBook Pro; without compression it took ~1s. - // Thus we're not not using compressed snapshot, trading off - // a lot of build time for some startup time in debug build. - #[cfg(debug_assertions)] - serializer: Box::new(snapshot_to_file), - - #[cfg(not(debug_assertions))] - serializer: Box::new(SnapshotBulkCompressingSerializer::new( - snapshot_to_file, - |snapshot| { - eprintln!("Compressing TSC snapshot..."); - let mut vec = Vec::with_capacity(snapshot.len()); - vec.extend((snapshot.len() as u32).to_le_bytes()); - vec.extend_from_slice( - &zstd::bulk::compress(&snapshot, 22) - .expect("snapshot compression failed"), - ); - Ok(vec) - }, - )), with_runtime_cb: None, skip_op_registration: false, }, None, ) .unwrap(); + + // NOTE(bartlomieju): Compressing the TSC snapshot in debug build took + // ~45s on M1 MacBook Pro; without compression it took ~1s. + // Thus we're not not using compressed snapshot, trading off + // a lot of build time for some startup time in debug build. + let mut file = std::fs::File::create(snapshot_path).unwrap(); + if cfg!(debug_assertions) { + file.write_all(&output.output).unwrap(); + } else { + let mut vec = Vec::with_capacity(output.output.len()); + vec.extend((output.output.len() as u32).to_le_bytes()); + vec.extend_from_slice( + &zstd::bulk::compress(&output.output, 22) + .expect("snapshot compression failed"), + ); + file.write_all(&vec).unwrap(); + } + for path in output.files_loaded_during_snapshot { println!("cargo:rerun-if-changed={}", path.display()); } diff --git a/cli/js.rs b/cli/js.rs index 4d75090d69..552f3842dc 100644 --- a/cli/js.rs +++ b/cli/js.rs @@ -1,17 +1,16 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_core::Snapshot; use log::debug; #[cfg(not(feature = "__runtime_js_sources"))] static CLI_SNAPSHOT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.bin")); -pub fn deno_isolate_init() -> Option { +pub fn deno_isolate_init() -> Option<&'static [u8]> { debug!("Deno isolate init with snapshots."); #[cfg(not(feature = "__runtime_js_sources"))] { - Some(Snapshot::Static(CLI_SNAPSHOT)) + Some(CLI_SNAPSHOT) } #[cfg(feature = "__runtime_js_sources")] { diff --git a/cli/tools/test/fmt.rs b/cli/tools/test/fmt.rs index fa2362ea1f..fe2007025c 100644 --- a/cli/tools/test/fmt.rs +++ b/cli/tools/test/fmt.rs @@ -2,6 +2,7 @@ use deno_core::stats::RuntimeActivity; use deno_core::stats::RuntimeActivityDiff; +use deno_core::stats::RuntimeActivityTrace; use deno_core::stats::RuntimeActivityType; use phf::phf_map; use std::borrow::Cow; @@ -165,16 +166,19 @@ fn format_sanitizer_accum( fn format_sanitizer_accum_item( activity: RuntimeActivity, -) -> (RuntimeActivityType, Cow<'static, str>, Option) { +) -> ( + RuntimeActivityType, + Cow<'static, str>, + Option, +) { let activity_type = activity.activity(); match activity { - // TODO(mmastrac): OpCallTrace needs to be Eq - RuntimeActivity::AsyncOp(_, name, trace) => { - (activity_type, name.into(), trace.map(|x| x.to_string())) + RuntimeActivity::AsyncOp(_, trace, name) => { + (activity_type, name.into(), trace) } - RuntimeActivity::Interval(_) => (activity_type, "".into(), None), - RuntimeActivity::Resource(_, name) => (activity_type, name.into(), None), - RuntimeActivity::Timer(_) => (activity_type, "".into(), None), + RuntimeActivity::Interval(..) => (activity_type, "".into(), None), + RuntimeActivity::Resource(.., name) => (activity_type, name.into(), None), + RuntimeActivity::Timer(..) => (activity_type, "".into(), None), } } @@ -354,7 +358,7 @@ mod tests { // https://github.com/denoland/deno/issues/13729 // https://github.com/denoland/deno/issues/13938 - leak_format_test!(op_unknown, true, [RuntimeActivity::AsyncOp(0, "op_unknown", None)], + leak_format_test!(op_unknown, true, [RuntimeActivity::AsyncOp(0, None, "op_unknown")], " - An async call to op_unknown was started in this test, but never completed.\n\ To get more details where ops were leaked, run again with --trace-ops flag.\n"); } diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs index e98df4671f..f7a7aed06d 100644 --- a/cli/tools/test/mod.rs +++ b/cli/tools/test/mod.rs @@ -518,7 +518,7 @@ async fn test_specifier_inner( if options.trace_ops { worker.execute_script_static( located_script_name!(), - "Deno[Deno.internal].core.setOpCallTracingEnabled(true);", + "Deno[Deno.internal].core.setLeakTracingEnabled(true);", )?; } @@ -740,7 +740,7 @@ fn preprocess_timer_activity(activities: &mut Vec) { // First, search for any timer resources which will indicate that we have an interval leak activities.retain(|activity| { - if let RuntimeActivity::Resource(_, name) = activity { + if let RuntimeActivity::Resource(.., name) = activity { if name == "timer" { timer_resource_leaked = true; return false; @@ -753,7 +753,7 @@ fn preprocess_timer_activity(activities: &mut Vec) { // them. if !timer_resource_leaked { activities.retain(|activity| { - if let RuntimeActivity::AsyncOp(_, op, _) = activity { + if let RuntimeActivity::AsyncOp(.., op) = activity { *op != "op_sleep_interval" } else { true @@ -775,7 +775,7 @@ async fn wait_for_activity_to_stabilize( let mut diff = RuntimeActivityStats::diff(&before, &after); preprocess_timer_activity(&mut diff.appeared); preprocess_timer_activity(&mut diff.disappeared); - if diff.appeared.is_empty() && diff.disappeared.is_empty() { + if diff.is_empty() { // No activity, so we return early return Ok(None); } @@ -792,7 +792,7 @@ async fn wait_for_activity_to_stabilize( diff = RuntimeActivityStats::diff(&before, &after); preprocess_timer_activity(&mut diff.appeared); preprocess_timer_activity(&mut diff.disappeared); - if diff.appeared.is_empty() && diff.disappeared.is_empty() { + if diff.is_empty() { return Ok(None); } } @@ -814,11 +814,7 @@ async fn wait_for_activity_to_stabilize( .retain(|activity| !matches!(activity, RuntimeActivity::Resource(..))); } - Ok(if diff.appeared.is_empty() && diff.disappeared.is_empty() { - None - } else { - Some(diff) - }) + Ok(if diff.is_empty() { None } else { Some(diff) }) } fn extract_files_from_regex_blocks( diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 56755b518c..e2e11e440e 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -26,7 +26,6 @@ use deno_core::JsRuntime; use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_core::RuntimeOptions; -use deno_core::Snapshot; use deno_graph::GraphKind; use deno_graph::Module; use deno_graph::ModuleGraph; @@ -140,8 +139,8 @@ fn get_asset_texts_from_new_runtime() -> Result, AnyError> { Ok(serde_v8::from_v8::>(scope, local)?) } -pub fn compiler_snapshot() -> Snapshot { - Snapshot::Static(&COMPILER_SNAPSHOT) +pub fn compiler_snapshot() -> &'static [u8] { + &COMPILER_SNAPSHOT } macro_rules! inc { diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 3a9d670863..e48af43ff7 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -10,6 +10,7 @@ use deno_core::snapshot::*; use deno_core::v8; use deno_core::Extension; use deno_http::DefaultHttpPropertyExtractor; +use std::io::Write; use std::path::Path; use std::path::PathBuf; use std::sync::Arc; @@ -270,9 +271,6 @@ pub fn create_runtime_snapshot( cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), startup_snapshot: None, extensions, - serializer: Box::new(SnapshotFileSerializer::new( - std::fs::File::create(snapshot_path).unwrap(), - )), with_runtime_cb: Some(Box::new(|rt| { let isolate = rt.v8_isolate(); let scope = &mut v8::HandleScope::new(isolate); @@ -285,6 +283,9 @@ pub fn create_runtime_snapshot( None, ) .unwrap(); + let mut snapshot = std::fs::File::create(snapshot_path).unwrap(); + snapshot.write_all(&output.output).unwrap(); + for path in output.files_loaded_during_snapshot { println!("cargo:rerun-if-changed={}", path.display()); } diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index a69c384abb..97b855c567 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -37,7 +37,6 @@ use deno_core::OpMetricsSummaryTracker; use deno_core::PollEventLoopOptions; use deno_core::RuntimeOptions; use deno_core::SharedArrayBufferStore; -use deno_core::Snapshot; use deno_core::SourceMapGetter; use deno_cron::local::LocalCronHandler; use deno_fs::FileSystem; @@ -336,7 +335,7 @@ pub struct WebWorker { pub struct WebWorkerOptions { pub bootstrap: BootstrapOptions, pub extensions: Vec, - pub startup_snapshot: Option, + pub startup_snapshot: Option<&'static [u8]>, pub unsafely_ignore_certificate_errors: Option>, pub root_cert_store_provider: Option>, pub seed: Option, diff --git a/runtime/worker.rs b/runtime/worker.rs index b6aff3c157..d19e520c9b 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -32,7 +32,6 @@ use deno_core::OpMetricsSummaryTracker; use deno_core::PollEventLoopOptions; use deno_core::RuntimeOptions; use deno_core::SharedArrayBufferStore; -use deno_core::Snapshot; use deno_core::SourceMapGetter; use deno_cron::local::LocalCronHandler; use deno_fs::FileSystem; @@ -128,7 +127,7 @@ pub struct WorkerOptions { pub extensions: Vec, /// V8 snapshot that should be loaded on startup. - pub startup_snapshot: Option, + pub startup_snapshot: Option<&'static [u8]>, /// Should op registration be skipped? pub skip_op_registration: bool, diff --git a/tests/integration/repl_tests.rs b/tests/integration/repl_tests.rs index 0e63f15891..7a09f904e8 100644 --- a/tests/integration/repl_tests.rs +++ b/tests/integration/repl_tests.rs @@ -1119,3 +1119,16 @@ fn pty_promise_was_collected_regression_test() { assert_contains!(out, "Uint8Array(67108864)"); assert!(err.is_empty()); } + +#[test] +fn eval_file_promise_error() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval-file=./repl/promise_rejection.ts"], + None, + None, + false, + ); + assert_contains!(out, "Uncaught undefined"); + assert!(err.is_empty()); +} diff --git a/tests/testdata/repl/promise_rejection.ts b/tests/testdata/repl/promise_rejection.ts new file mode 100644 index 0000000000..c6c3bcbd0b --- /dev/null +++ b/tests/testdata/repl/promise_rejection.ts @@ -0,0 +1,6 @@ +// Regression test for https://github.com/denoland/deno/issues/22592 +// deno-lint-ignore require-await +async function rejects() { + return Promise.reject(); +} +await rejects();