From 60bf79c18410fd332b6b9b7c222e6d3d62bfe3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Jun 2023 00:36:16 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"refactor(core):=20cleanup=20feature?= =?UTF-8?q?=20flags=20for=20js=20source=20inclusion=E2=80=A6=20(#19490)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … (#19463)" This reverts commit ceb03cfb037cf7024a5048b17b508ddda59cfa05. This is being reverted because it causes 3.5Mb increase in the binary size, due to runtime JS code being included in the binary, even though it's already snapshotted. CC @nayeemrmn --- Cargo.lock | 1 - bench_util/benches/op_baseline.rs | 2 +- bench_util/benches/utf8.rs | 5 +- cli/Cargo.toml | 8 +- cli/build.rs | 64 +++++---- cli/lsp/tsc.rs | 2 +- cli/ops/mod.rs | 2 +- cli/tools/bench.rs | 2 +- cli/tools/test.rs | 2 +- cli/tsc/mod.rs | 4 +- core/00_primordials.js | 3 - core/01_core.js | 3 - core/02_error.js | 3 - core/Cargo.toml | 6 +- core/extensions.rs | 145 +++++++++++++------- core/inspector.rs | 3 - core/lib.rs | 1 + core/modules.rs | 27 +++- core/runtime.rs | 80 +++++------ core/snapshot_util.rs | 30 +++- ext/fs/lib.rs | 1 + ext/net/ops.rs | 2 +- ext/url/benches/url_ops.rs | 9 +- ext/web/benches/encoding.rs | 16 ++- ext/web/benches/timers_ops.rs | 15 +- ext/webidl/benches/dict.rs | 7 +- runtime/Cargo.toml | 11 +- runtime/build.rs | 59 ++++---- runtime/examples/extension_with_esm/main.rs | 2 +- runtime/examples/extension_with_ops/main.rs | 2 +- runtime/js.rs | 7 + runtime/web_worker.rs | 60 ++++---- runtime/worker.rs | 58 ++++---- 33 files changed, 386 insertions(+), 256 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72b0011483..edb0a6e124 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -949,7 +949,6 @@ dependencies = [ "anyhow", "bytes", "deno_ast", - "deno_core", "deno_ops", "futures", "indexmap", diff --git a/bench_util/benches/op_baseline.rs b/bench_util/benches/op_baseline.rs index a8aadda013..4b3bc0203c 100644 --- a/bench_util/benches/op_baseline.rs +++ b/bench_util/benches/op_baseline.rs @@ -19,7 +19,7 @@ deno_core::extension!( ); fn setup() -> Vec { - vec![bench_setup::init()] + vec![bench_setup::init_ops()] } #[op] diff --git a/bench_util/benches/utf8.rs b/bench_util/benches/utf8.rs index 6d0a5977e8..9bc7cdaee4 100644 --- a/bench_util/benches/utf8.rs +++ b/bench_util/benches/utf8.rs @@ -7,12 +7,14 @@ use deno_bench_util::bencher::Bencher; use deno_bench_util::BenchOptions; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; fn setup() -> Vec { vec![Extension::builder("bench_setup") .js(vec![ExtensionFileSource { specifier: "ext:bench_setup/setup.js", - code: r#" + code: ExtensionFileSourceCode::IncludedInBinary( + r#" const hello = "hello world\n"; const hello1k = hello.repeat(1e3); const hello1m = hello.repeat(1e6); @@ -20,6 +22,7 @@ fn setup() -> Vec { const hello1kEncoded = Deno.core.encode(hello1k); const hello1mEncoded = Deno.core.encode(hello1m); "#, + ), }]) .build()] } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 41194bfcde..fe9f358445 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,8 +27,8 @@ harness = false path = "./bench/lsp_bench_standalone.rs" [build-dependencies] -deno_runtime = { workspace = true, features = ["exclude_js_main_from_snapshot"] } -deno_core.workspace = true +deno_runtime = { workspace = true, features = ["snapshot_from_snapshot", "include_js_files_for_snapshotting"] } +deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } lazy-regex.workspace = true serde.workspace = true serde_json.workspace = true @@ -41,14 +41,14 @@ winres.workspace = true [dependencies] deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] } -deno_core = { workspace = true, features = ["exclude_js_sources"] } +deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_doc = "=0.63.1" deno_emit = "=0.24.0" deno_graph = "=0.49.0" deno_lint = { version = "=0.47.0", features = ["docs"] } deno_lockfile.workspace = true deno_npm.workspace = true -deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot"] } +deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "include_js_files_for_snapshotting"] } deno_semver.workspace = true deno_task_shell = "=0.12.0" eszip = "=0.44.0" diff --git a/cli/build.rs b/cli/build.rs index 77e0ee1de8..5ff86fa20c 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use deno_core::snapshot_util::*; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; use deno_runtime::deno_cache::SqliteBackedCache; use deno_runtime::deno_http::DefaultHttpPropertyExtractor; use deno_runtime::deno_kv::sqlite::SqliteDbHandler; @@ -261,11 +262,15 @@ mod ts { ) .unwrap(); - create_snapshot(CreateSnapshotOptions { + let output = create_snapshot(CreateSnapshotOptions { cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), snapshot_path, startup_snapshot: None, - extensions: vec![deno_tsc::init(op_crate_libs, build_libs, path_dts)], + extensions: vec![deno_tsc::init_ops_and_esm( + op_crate_libs, + build_libs, + path_dts, + )], // NOTE(bartlomieju): Compressing the TSC snapshot in debug build took // ~45s on M1 MacBook Pro; without compression it took ~1s. @@ -284,6 +289,9 @@ mod ts { })), 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 { @@ -314,52 +322,55 @@ deno_core::extension!( customizer = |ext: &mut deno_core::ExtensionBuilder| { ext.esm(vec![ExtensionFileSource { specifier: "ext:cli/runtime/js/99_main.js", - code: include_str!("../runtime/js/99_main.js"), + code: ExtensionFileSourceCode::LoadedFromFsDuringSnapshot( + std::path::PathBuf::from(deno_runtime::js::PATH_FOR_99_MAIN_JS), + ), }]); } ); -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 // `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`! let fs = Arc::new(deno_fs::RealFs); let extensions: Vec = vec![ - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::( deno_web::BlobStore::default(), Default::default(), ), - deno_fetch::deno_fetch::init::(Default::default()), - deno_cache::deno_cache::init::(None), - deno_websocket::deno_websocket::init::( + deno_fetch::deno_fetch::init_ops::(Default::default()), + deno_cache::deno_cache::init_ops::(None), + deno_websocket::deno_websocket::init_ops::( "".to_owned(), None, None, ), - deno_webstorage::deno_webstorage::init(None), - deno_crypto::deno_crypto::init(None), - deno_broadcast_channel::deno_broadcast_channel::init( + deno_webstorage::deno_webstorage::init_ops(None), + deno_crypto::deno_crypto::init_ops(None), + deno_broadcast_channel::deno_broadcast_channel::init_ops( deno_broadcast_channel::InMemoryBroadcastChannel::default(), false, // No --unstable. ), - deno_ffi::deno_ffi::init::(false), - deno_net::deno_net::init::( + deno_ffi::deno_ffi::init_ops::(false), + deno_net::deno_net::init_ops::( None, false, // No --unstable. None, ), - deno_tls::deno_tls::init(), - deno_kv::deno_kv::init( + deno_tls::deno_tls::init_ops(), + deno_kv::deno_kv::init_ops( SqliteDbHandler::::new(None), false, // No --unstable. ), - deno_napi::deno_napi::init::(), - deno_http::deno_http::init::(), - deno_io::deno_io::init(Default::default()), - deno_fs::deno_fs::init::(false, fs.clone()), - deno_node::deno_node::init::(None, fs), - cli::init(), + deno_napi::deno_napi::init_ops::(), + deno_http::deno_http::init_ops::(), + deno_io::deno_io::init_ops(Default::default()), + deno_fs::deno_fs::init_ops::(false, fs.clone()), + deno_node::deno_node::init_ops::(None, fs), + cli::init_ops_and_esm(), // NOTE: This needs to be init_ops_and_esm! ]; create_snapshot(CreateSnapshotOptions { @@ -474,7 +485,10 @@ fn main() { ts::create_compiler_snapshot(compiler_snapshot_path, &c); 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")] { diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 4c26abdc11..66687789bf 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -3236,7 +3236,7 @@ fn op_script_version( /// server. fn js_runtime(performance: Arc) -> JsRuntime { JsRuntime::new(RuntimeOptions { - extensions: vec![deno_tsc::init(performance)], + extensions: vec![deno_tsc::init_ops(performance)], startup_snapshot: Some(tsc::compiler_snapshot()), ..Default::default() }) diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index d0d668bfb7..5066c44b9f 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -12,7 +12,7 @@ pub mod bench; pub mod testing; pub fn cli_exts(npm_resolver: Arc) -> Vec { - vec![deno_cli::init(npm_resolver)] + vec![deno_cli::init_ops(npm_resolver)] } deno_core::extension!(deno_cli, diff --git a/cli/tools/bench.rs b/cli/tools/bench.rs index 4e7e90ba79..a7b75d8be8 100644 --- a/cli/tools/bench.rs +++ b/cli/tools/bench.rs @@ -447,7 +447,7 @@ async fn bench_specifier( .create_custom_worker( specifier.clone(), PermissionsContainer::new(permissions), - vec![ops::bench::deno_bench::init(sender.clone())], + vec![ops::bench::deno_bench::init_ops(sender.clone())], Default::default(), ) .await?; diff --git a/cli/tools/test.rs b/cli/tools/test.rs index 6181ebac0a..6f32d69e49 100644 --- a/cli/tools/test.rs +++ b/cli/tools/test.rs @@ -935,7 +935,7 @@ pub async fn test_specifier( .create_custom_worker( specifier.clone(), PermissionsContainer::new(permissions), - vec![ops::testing::deno_test::init(sender.clone())], + vec![ops::testing::deno_test::init_ops(sender.clone())], Stdio { stdin: StdioPipe::Inherit, stdout, diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index edc64e8ef3..a4d6640f7c 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -122,7 +122,7 @@ fn get_asset_texts_from_new_runtime() -> Result, AnyError> { // the assets are stored within the typescript isolate, so take them out of there let mut runtime = JsRuntime::new(RuntimeOptions { startup_snapshot: Some(compiler_snapshot()), - extensions: vec![deno_cli_tsc::init()], + extensions: vec![deno_cli_tsc::init_ops()], ..Default::default() }); let global = runtime @@ -787,7 +787,7 @@ pub fn exec(request: Request) -> Result { let mut runtime = JsRuntime::new(RuntimeOptions { startup_snapshot: Some(compiler_snapshot()), - extensions: vec![deno_cli_tsc::init( + extensions: vec![deno_cli_tsc::init_ops( request, root_map, remapped_specifiers, diff --git a/core/00_primordials.js b/core/00_primordials.js index b85aa6673b..60474e649d 100644 --- a/core/00_primordials.js +++ b/core/00_primordials.js @@ -34,9 +34,6 @@ "use strict"; (() => { - if (globalThis.__bootstrap) { - return; - } const primordials = {}; const { diff --git a/core/01_core.js b/core/01_core.js index 8b5a4ff667..13aa17c7ed 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -2,9 +2,6 @@ "use strict"; ((window) => { - if (globalThis.__bootstrap.core) { - return; - } const { Array, ArrayPrototypeFill, diff --git a/core/02_error.js b/core/02_error.js index ffca10a321..b29dc9b4ee 100644 --- a/core/02_error.js +++ b/core/02_error.js @@ -2,9 +2,6 @@ "use strict"; ((window) => { - if (globalThis.__bootstrap.core.prepareStackTrace) { - return; - } const core = Deno.core; const ops = core.ops; const { diff --git a/core/Cargo.toml b/core/Cargo.toml index 251f15429e..b9cb265e88 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -16,10 +16,7 @@ path = "lib.rs" [features] default = ["v8_use_custom_libcxx"] v8_use_custom_libcxx = ["v8/use_custom_libcxx"] -# Enable to exclude JS sources from the binary (e.g. if they are already snapshotted). -exclude_js_sources = [] -# Enable to override `exclude_js_sources` (e.g. for snapshot creation in `build.rs`). -force_include_js_sources = ["exclude_js_sources"] +include_js_files_for_snapshotting = [] [dependencies] anyhow.workspace = true @@ -50,4 +47,3 @@ path = "examples/http_bench_json_ops/main.rs" # These dependencies are only used for the 'http_bench_*_ops' examples. [dev-dependencies] deno_ast.workspace = true -deno_core = { workspace = true, features = ["force_include_js_sources"] } diff --git a/core/extensions.rs b/core/extensions.rs index ab05781064..fa6d7851e7 100644 --- a/core/extensions.rs +++ b/core/extensions.rs @@ -1,15 +1,32 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use crate::modules::ModuleCode; use crate::OpState; +use anyhow::Context as _; +use anyhow::Error; use std::cell::RefCell; +use std::path::PathBuf; use std::rc::Rc; use std::task::Context; use v8::fast_api::FastFunction; +#[derive(Clone, Debug)] +pub enum ExtensionFileSourceCode { + /// Source code is included in the binary produced. Either by being defined + /// inline, or included using `include_str!()`. If you are snapshotting, this + /// will result in two copies of the source code being included - one in the + /// snapshot, the other the static string in the `Extension`. + IncludedInBinary(&'static str), + + // Source code is loaded from a file on disk. It's meant to be used if the + // embedder is creating snapshots. Files will be loaded from the filesystem + // during the build time and they will only be present in the V8 snapshot. + LoadedFromFsDuringSnapshot(PathBuf), +} + #[derive(Clone, Debug)] pub struct ExtensionFileSource { pub specifier: &'static str, - pub code: &'static str, + pub code: ExtensionFileSourceCode, } impl ExtensionFileSource { @@ -17,14 +34,29 @@ impl ExtensionFileSource { s.chars().filter(|c| !c.is_ascii()).collect::() } - pub fn load(&self) -> ModuleCode { - debug_assert!( - self.code.is_ascii(), - "Extension code must be 7-bit ASCII: {} (found {})", - self.specifier, - Self::find_non_ascii(self.code) - ); - ModuleCode::from_static(self.code) + pub fn load(&self) -> Result { + match &self.code { + ExtensionFileSourceCode::IncludedInBinary(code) => { + debug_assert!( + code.is_ascii(), + "Extension code must be 7-bit ASCII: {} (found {})", + self.specifier, + Self::find_non_ascii(code) + ); + Ok(ModuleCode::from_static(code)) + } + ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(path) => { + let msg = || format!("Failed to read \"{}\"", path.display()); + let s = std::fs::read_to_string(path).with_context(msg)?; + debug_assert!( + s.is_ascii(), + "Extension code must be 7-bit ASCII: {} (found {})", + self.specifier, + Self::find_non_ascii(&s) + ); + Ok(s.into()) + } + } } } @@ -155,7 +187,6 @@ macro_rules! extension { $(, esm = [ $( dir $dir_esm:literal , )? $( $esm:literal ),* $(,)? ] )? $(, esm_setup_script = $esm_setup_script:expr )? $(, js = [ $( dir $dir_js:literal , )? $( $js:literal ),* $(,)? ] )? - $(, force_include_js_sources $($force_include_js_sources:block)? )? // dummy variable $(, options = { $( $options_id:ident : $options_type:ty ),* $(,)? } )? $(, middleware = $middleware_fn:expr )? $(, state = $state_fn:expr )? @@ -180,9 +211,9 @@ macro_rules! extension { #[inline(always)] #[allow(unused_variables)] fn with_js(ext: &mut $crate::ExtensionBuilder) { - ext.esm( - $crate::include_js_files!( $name $( force_include_js_sources $($force_include_js_sources)?, )? $( $( dir $dir_esm , )? $( $esm , )* )? ) - ); + $( ext.esm( + $crate::include_js_files!( $name $( dir $dir_esm , )? $( $esm , )* ) + ); )? $( ext.esm(vec![ExtensionFileSource { specifier: "ext:setup", @@ -192,9 +223,9 @@ macro_rules! extension { $( ext.esm_entry_point($esm_entry_point); )? - ext.js( - $crate::include_js_files!( $name $( force_include_js_sources $($force_include_js_sources)?, )? $( $( dir $dir_js , )? $( $js , )* )? ) - ); + $( ext.js( + $crate::include_js_files!( $name $( dir $dir_js , )? $( $js , )* ) + ); )? } // If ops were specified, add those ops to the extension. @@ -254,7 +285,7 @@ macro_rules! extension { } #[allow(dead_code)] - pub fn init $( < $( $param : $type + 'static ),+ > )? ( $( $( $options_id : $options_type ),* )? ) -> $crate::Extension + pub fn init_ops_and_esm $( < $( $param : $type + 'static ),+ > )? ( $( $( $options_id : $options_type ),* )? ) -> $crate::Extension $( where $( $bound : $bound_type ),+ )? { let mut ext = Self::ext(); @@ -265,6 +296,17 @@ macro_rules! extension { Self::with_customizer(&mut ext); ext.take() } + + #[allow(dead_code)] + pub fn init_ops $( < $( $param : $type + 'static ),+ > )? ( $( $( $options_id : $options_type ),* )? ) -> $crate::Extension + $( where $( $bound : $bound_type ),+ )? + { + let mut ext = Self::ext(); + Self::with_ops $( ::< $( $param ),+ > )?(&mut ext); + Self::with_state_and_middleware $( ::< $( $param ),+ > )?(&mut ext, $( $( $options_id , )* )? ); + Self::with_customizer(&mut ext); + ext.take() + } } }; @@ -566,49 +608,54 @@ impl ExtensionBuilder { /// - "ext:my_extension/js/01_hello.js" /// - "ext:my_extension/js/02_goodbye.js" /// ``` -#[cfg(not(all( - feature = "exclude_js_sources", - not(feature = "force_include_js_sources") -)))] +#[cfg(not(feature = "include_js_files_for_snapshotting"))] #[macro_export] macro_rules! include_js_files { - ($name:ident $(force_include_js_sources $($dummy:block)?,)? $(dir $dir:literal,)? $($file:literal,)*) => { - $crate::force_include_js_files!($name $(dir $dir,)? $($file,)*) - }; -} - -#[cfg(all( - feature = "exclude_js_sources", - not(feature = "force_include_js_sources") -))] -#[macro_export] -macro_rules! include_js_files { - ($name:ident force_include_js_sources $($dummy:block)?, $(dir $dir:literal,)? $($file:literal,)*) => { - $crate::force_include_js_files!($name $(dir $dir,)? $($file,)*) - }; - - ($name:ident $(dir $dir:literal,)? $($file:literal,)*) => { - vec![] - }; -} - -#[macro_export] -macro_rules! force_include_js_files { - ($name:ident dir $dir:literal, $($file:literal,)*) => { + ($name:ident dir $dir:literal, $($file:literal,)+) => { vec![ $($crate::ExtensionFileSource { specifier: concat!("ext:", stringify!($name), "/", $file), - code: include_str!(concat!($dir, "/", $file)), - },)* + code: $crate::ExtensionFileSourceCode::IncludedInBinary( + include_str!(concat!($dir, "/", $file) + )), + },)+ ] }; - ($name:ident $($file:literal,)*) => { + ($name:ident $($file:literal,)+) => { vec![ $($crate::ExtensionFileSource { specifier: concat!("ext:", stringify!($name), "/", $file), - code: include_str!($file), - },)* + code: $crate::ExtensionFileSourceCode::IncludedInBinary( + include_str!($file) + ), + },)+ + ] + }; +} + +#[cfg(feature = "include_js_files_for_snapshotting")] +#[macro_export] +macro_rules! include_js_files { + ($name:ident dir $dir:literal, $($file:literal,)+) => { + vec![ + $($crate::ExtensionFileSource { + specifier: concat!("ext:", stringify!($name), "/", $file), + code: $crate::ExtensionFileSourceCode::LoadedFromFsDuringSnapshot( + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join($dir).join($file) + ), + },)+ + ] + }; + + ($name:ident $($file:literal,)+) => { + vec![ + $($crate::ExtensionFileSource { + specifier: concat!("ext:", stringify!($name), "/", $file), + code: $crate::ExtensionFileSourceCode::LoadedFromFsDuringSnapshot( + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join($file) + ), + },)+ ] }; } diff --git a/core/inspector.rs b/core/inspector.rs index d7592fbe45..d7c84608f5 100644 --- a/core/inspector.rs +++ b/core/inspector.rs @@ -365,9 +365,6 @@ impl JsRuntimeInspector { w.poll_state = PollState::Parked; w.parked_thread.replace(thread::current()); } - PollState::Parked => { - w.parked_thread.replace(thread::current()); - } _ => unreachable!(), }; w.poll_state diff --git a/core/lib.rs b/core/lib.rs index 729182a4f0..336d9c2b98 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -60,6 +60,7 @@ pub use crate::async_cell::RcRef; pub use crate::extensions::Extension; pub use crate::extensions::ExtensionBuilder; pub use crate::extensions::ExtensionFileSource; +pub use crate::extensions::ExtensionFileSourceCode; pub use crate::extensions::OpDecl; pub use crate::extensions::OpMiddlewareFn; pub use crate::fast_string::FastString; diff --git a/core/modules.rs b/core/modules.rs index 5d9fe2fc45..4f1875ae59 100644 --- a/core/modules.rs +++ b/core/modules.rs @@ -438,7 +438,7 @@ impl ModuleLoader for ExtModuleLoader { let result = if let Some(load_callback) = &self.maybe_load_callback { load_callback(source) } else { - Ok(source.load()) + source.load() }; match result { Ok(code) => { @@ -459,6 +459,29 @@ impl ModuleLoader for ExtModuleLoader { } } +impl Drop for ExtModuleLoader { + fn drop(&mut self) { + let sources = self.sources.get_mut(); + let used_specifiers = self.used_specifiers.get_mut(); + let unused_modules: Vec<_> = sources + .iter() + .filter(|(k, _)| !used_specifiers.contains(k.as_str())) + .collect(); + + if !unused_modules.is_empty() { + let mut msg = + "Following modules were passed to ExtModuleLoader but never used:\n" + .to_string(); + for m in unused_modules { + msg.push_str(" - "); + msg.push_str(m.0); + msg.push('\n'); + } + panic!("{}", msg); + } + } +} + /// Basic file system module loader. /// /// Note that this loader will **block** event loop @@ -2021,7 +2044,7 @@ import "/a.js"; deno_core::extension!(test_ext, ops = [op_test]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], module_loader: Some(loader), ..Default::default() }); diff --git a/core/runtime.rs b/core/runtime.rs index 29064df635..ecfd0bd571 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -510,7 +510,7 @@ impl JsRuntime { maybe_load_callback: Option, ) -> JsRuntime { let init_mode = InitMode::from_options(&options); - let (op_state, ops) = Self::create_opstate(&mut options); + let (op_state, ops) = Self::create_opstate(&mut options, init_mode); let op_state = Rc::new(RefCell::new(op_state)); // Collect event-loop middleware @@ -860,7 +860,7 @@ impl JsRuntime { realm.execute_script( self.v8_isolate(), file_source.specifier, - file_source.load(), + file_source.load()?, )?; } } @@ -963,11 +963,20 @@ impl JsRuntime { } /// Initializes ops of provided Extensions - fn create_opstate(options: &mut RuntimeOptions) -> (OpState, Vec) { + fn create_opstate( + options: &mut RuntimeOptions, + init_mode: InitMode, + ) -> (OpState, Vec) { // Add built-in extension - options - .extensions - .insert(0, crate::ops_builtin::core::init()); + if init_mode == InitMode::FromSnapshot { + options + .extensions + .insert(0, crate::ops_builtin::core::init_ops()); + } else { + options + .extensions + .insert(0, crate::ops_builtin::core::init_ops_and_esm()); + } let ops = Self::collect_ops(&mut options.extensions); @@ -1849,19 +1858,6 @@ impl JsRuntime { .map(|handle| v8::Local::new(tc_scope, handle)) .expect("ModuleInfo not found"); let mut status = module.get_status(); - if status == v8::ModuleStatus::Evaluated { - let (sender, receiver) = oneshot::channel(); - sender.send(Ok(())).unwrap(); - return receiver; - } - if status == v8::ModuleStatus::Errored { - let (sender, receiver) = oneshot::channel(); - let exception = module.get_exception(); - sender - .send(exception_to_err_result(tc_scope, exception, false)) - .unwrap(); - return receiver; - } assert_eq!( status, v8::ModuleStatus::Instantiated, @@ -2707,7 +2703,7 @@ pub mod tests { } ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init(mode, dispatch_count.clone())], + extensions: vec![test_ext::init_ops(mode, dispatch_count.clone())], get_error_class_fn: Some(&|error| { crate::error::get_custom_error_class(error).unwrap() }), @@ -3122,7 +3118,7 @@ pub mod tests { deno_core::extension!(test_ext, ops = [op_err]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], get_error_class_fn: Some(&get_error_class_name), ..Default::default() }); @@ -3728,7 +3724,7 @@ main(); deno_core::extension!(test_ext, ops = [op_err_sync, op_err_async]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -3890,7 +3886,7 @@ assertEquals(1, notify_return_value); state = |state| state.put(InnerState(42)) ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -3921,7 +3917,7 @@ assertEquals(1, notify_return_value); ops = [op_sync_serialize_object_with_numbers_as_keys] ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -3963,7 +3959,7 @@ Deno.core.ops.op_sync_serialize_object_with_numbers_as_keys({ ops = [op_async_serialize_object_with_numbers_as_keys] ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -3999,7 +3995,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_async_sleep]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4054,7 +4050,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_macrotask, op_next_tick]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4195,7 +4191,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_promise_reject]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4338,7 +4334,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { } let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], module_loader: Some(Rc::new(ModsLoader)), ..Default::default() }); @@ -4363,7 +4359,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_err]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); assert!(runtime @@ -4388,7 +4384,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_add_4]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); let r = runtime @@ -4411,7 +4407,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops_fn = ops); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); let err = runtime @@ -4440,7 +4436,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_sum_take, op_boomerang]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4509,7 +4505,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { middleware = |op| if op.is_unstable { op.disable() } else { op } ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); runtime @@ -4557,7 +4553,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_test]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); let realm = runtime.create_realm().unwrap(); @@ -4590,7 +4586,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_test]); let mut runtime = JsRuntime::new(RuntimeOptions { startup_snapshot: Some(Snapshot::Boxed(snapshot)), - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); let realm = runtime.create_realm().unwrap(); @@ -4624,7 +4620,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_test]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], get_error_class_fn: Some(&|error| { crate::error::get_custom_error_class(error).unwrap() }), @@ -4672,7 +4668,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_test]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], get_error_class_fn: Some(&|error| { crate::error::get_custom_error_class(error).unwrap() }), @@ -4749,7 +4745,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_pending]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4796,7 +4792,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_pending]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); @@ -4896,7 +4892,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [a::op_test, op_test]); JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); } @@ -4915,7 +4911,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { deno_core::extension!(test_ext, ops = [op_test_sync, op_test_async]); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); diff --git a/core/snapshot_util.rs b/core/snapshot_util.rs index 200a81d150..88c2731477 100644 --- a/core/snapshot_util.rs +++ b/core/snapshot_util.rs @@ -22,7 +22,16 @@ pub struct CreateSnapshotOptions { pub snapshot_module_load_cb: Option, } -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, +} + +#[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 js_runtime = JsRuntimeForSnapshot::new( @@ -42,6 +51,22 @@ pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) { ); 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_slice: &[u8] = &snapshot; println!( @@ -87,6 +112,9 @@ pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) { Instant::now().saturating_duration_since(mark), create_snapshot_options.snapshot_path.display(), ); + CreateSnapshotOutput { + files_loaded_during_snapshot, + } } pub type FilterFn = Box bool>; diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index d277129271..7ba6cd7cac 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -19,6 +19,7 @@ use crate::ops::*; use deno_core::error::AnyError; use deno_core::OpState; use std::cell::RefCell; +use std::convert::From; use std::path::Path; use std::rc::Rc; diff --git a/ext/net/ops.rs b/ext/net/ops.rs index 354acb3bdf..05aa416b4b 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -1034,7 +1034,7 @@ mod tests { ); let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![test_ext::init()], + extensions: vec![test_ext::init_ops()], ..Default::default() }); diff --git a/ext/url/benches/url_ops.rs b/ext/url/benches/url_ops.rs index 1e3d201f62..835dfea2ec 100644 --- a/ext/url/benches/url_ops.rs +++ b/ext/url/benches/url_ops.rs @@ -7,17 +7,20 @@ use deno_bench_util::bencher::Bencher; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; fn setup() -> Vec { vec![ - deno_webidl::deno_webidl::init(), - deno_url::deno_url::init(), + deno_webidl::deno_webidl::init_ops_and_esm(), + deno_url::deno_url::init_ops_and_esm(), Extension::builder("bench_setup") .esm(vec![ExtensionFileSource { specifier: "ext:bench_setup/setup", - code: r#"import { URL } from "ext:deno_url/00_url.js"; + code: ExtensionFileSourceCode::IncludedInBinary( + r#"import { URL } from "ext:deno_url/00_url.js"; globalThis.URL = URL; "#, + ), }]) .esm_entry_point("ext:bench_setup/setup") .build(), diff --git a/ext/web/benches/encoding.rs b/ext/web/benches/encoding.rs index 9d12d9c2c9..5b147f00c8 100644 --- a/ext/web/benches/encoding.rs +++ b/ext/web/benches/encoding.rs @@ -6,6 +6,7 @@ use deno_bench_util::bencher::benchmark_group; use deno_bench_util::bencher::Bencher; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; use deno_core::OpState; use deno_web::BlobStore; @@ -23,18 +24,23 @@ impl deno_web::TimersPermission for Permissions { fn setup() -> Vec { vec![ - deno_webidl::deno_webidl::init(), - deno_url::deno_url::init(), - deno_console::deno_console::init(), - deno_web::deno_web::init::(BlobStore::default(), None), + deno_webidl::deno_webidl::init_ops_and_esm(), + deno_url::deno_url::init_ops_and_esm(), + deno_console::deno_console::init_ops_and_esm(), + deno_web::deno_web::init_ops_and_esm::( + BlobStore::default(), + None, + ), Extension::builder("bench_setup") .esm(vec![ExtensionFileSource { specifier: "ext:bench_setup/setup", - code: r#" + code: ExtensionFileSourceCode::IncludedInBinary( + r#" import { TextDecoder } from "ext:deno_web/08_text_encoding.js"; globalThis.TextDecoder = TextDecoder; globalThis.hello12k = Deno.core.encode("hello world\n".repeat(1e3)); "#, + ), }]) .state(|state| { state.put(Permissions {}); diff --git a/ext/web/benches/timers_ops.rs b/ext/web/benches/timers_ops.rs index c6afea9c1f..084fac98ba 100644 --- a/ext/web/benches/timers_ops.rs +++ b/ext/web/benches/timers_ops.rs @@ -6,6 +6,7 @@ use deno_bench_util::bencher::benchmark_group; use deno_bench_util::bencher::Bencher; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; use deno_core::OpState; use deno_web::BlobStore; @@ -21,19 +22,19 @@ impl deno_web::TimersPermission for Permissions { fn setup() -> Vec { vec![ - deno_webidl::deno_webidl::init(), - deno_url::deno_url::init(), - deno_console::deno_console::init(), - deno_web::deno_web::init::(BlobStore::default(), None), + deno_webidl::deno_webidl::init_ops_and_esm(), + deno_url::deno_url::init_ops_and_esm(), + deno_console::deno_console::init_ops_and_esm(), + deno_web::deno_web::init_ops_and_esm::(BlobStore::default(), None), Extension::builder("bench_setup") .esm(vec![ ExtensionFileSource { - specifier: "ext:bench_setup/setup", - code: r#" + specifier: "ext:bench_setup/setup", + code: ExtensionFileSourceCode::IncludedInBinary(r#" import { setTimeout, handleTimerMacrotask } from "ext:deno_web/02_timers.js"; globalThis.setTimeout = setTimeout; Deno.core.setMacrotaskCallback(handleTimerMacrotask); - "# + "#) }, ]) .state(|state| { diff --git a/ext/webidl/benches/dict.rs b/ext/webidl/benches/dict.rs index bf5c0554b7..b3d95c8a32 100644 --- a/ext/webidl/benches/dict.rs +++ b/ext/webidl/benches/dict.rs @@ -7,14 +7,17 @@ use deno_bench_util::bencher::Bencher; use deno_core::Extension; use deno_core::ExtensionFileSource; +use deno_core::ExtensionFileSourceCode; fn setup() -> Vec { vec![ - deno_webidl::deno_webidl::init(), + deno_webidl::deno_webidl::init_ops_and_esm(), Extension::builder("deno_webidl_bench") .esm(vec![ExtensionFileSource { specifier: "ext:deno_webidl_bench/setup.js", - code: include_str!("dict.js"), + code: ExtensionFileSourceCode::IncludedInBinary(include_str!( + "dict.js" + )), }]) .esm_entry_point("ext:deno_webidl_bench/setup.js") .build(), diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index e66698a019..77571b2102 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -14,8 +14,15 @@ description = "Provides the deno runtime library" docsrs = [] # A feature that disables creation of startup snapshot during in the build script. dont_create_runtime_snapshot = [] -# Enable to exclude `js/99_main.js` from the generated snapshot. -exclude_js_main_from_snapshot = [] +# A feature that changes how startup snapshot is generated, that allows +# extending it in embedder crates. +snapshot_from_snapshot = [] +# A feature that disables embedding of the JavaScript source files in the binary. +# With this feature enabled, the sources must be consumed during build time, +# by creating a startup snapshot. +include_js_files_for_snapshotting = [ + "deno_core/include_js_files_for_snapshotting", +] [lib] name = "deno_runtime" diff --git a/runtime/build.rs b/runtime/build.rs index d7b4018fb3..f656682a1d 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -35,7 +35,7 @@ mod startup_snapshot { file_source.specifier ), }; - let code = file_source.load(); + let code = file_source.load()?; if !should_transpile { return Ok(code); @@ -264,20 +264,22 @@ mod startup_snapshot { ], ); - #[cfg(not(feature = "exclude_js_main_from_snapshot"))] + #[cfg(not(feature = "snapshot_from_snapshot"))] deno_core::extension!( runtime_main, deps = [runtime], customizer = |ext: &mut deno_core::ExtensionBuilder| { ext.esm(vec![ExtensionFileSource { specifier: "ext:runtime_main/js/99_main.js", - code: include_str!("js/99_main.js"), + code: deno_core::ExtensionFileSourceCode::IncludedInBinary( + include_str!("js/99_main.js"), + ), }]); ext.esm_entry_point("ext:runtime_main/js/99_main.js"); } ); - #[cfg(feature = "exclude_js_main_from_snapshot")] + #[cfg(feature = "snapshot_from_snapshot")] deno_core::extension!( runtime_main, deps = [runtime], @@ -292,48 +294,50 @@ mod startup_snapshot { // `runtime/worker.rs`, `runtime/web_worker.rs` and `cli/build.rs`! let fs = std::sync::Arc::new(deno_fs::RealFs); let extensions: Vec = vec![ - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::( + deno_webidl::deno_webidl::init_ops_and_esm(), + deno_console::deno_console::init_ops_and_esm(), + deno_url::deno_url::init_ops_and_esm(), + deno_web::deno_web::init_ops_and_esm::( deno_web::BlobStore::default(), Default::default(), ), - deno_fetch::deno_fetch::init::(Default::default()), - deno_cache::deno_cache::init::(None), - deno_websocket::deno_websocket::init::( + deno_fetch::deno_fetch::init_ops_and_esm::( + Default::default(), + ), + deno_cache::deno_cache::init_ops_and_esm::(None), + deno_websocket::deno_websocket::init_ops_and_esm::( "".to_owned(), None, None, ), - deno_webstorage::deno_webstorage::init(None), - deno_crypto::deno_crypto::init(None), - deno_broadcast_channel::deno_broadcast_channel::init( + deno_webstorage::deno_webstorage::init_ops_and_esm(None), + deno_crypto::deno_crypto::init_ops_and_esm(None), + deno_broadcast_channel::deno_broadcast_channel::init_ops_and_esm( deno_broadcast_channel::InMemoryBroadcastChannel::default(), false, // No --unstable. ), - deno_ffi::deno_ffi::init::(false), - deno_net::deno_net::init::( + deno_ffi::deno_ffi::init_ops_and_esm::(false), + deno_net::deno_net::init_ops_and_esm::( None, false, // No --unstable. None, ), - deno_tls::deno_tls::init(), - deno_kv::deno_kv::init( + deno_tls::deno_tls::init_ops_and_esm(), + deno_kv::deno_kv::init_ops_and_esm( deno_kv::sqlite::SqliteDbHandler::::new(None), false, // No --unstable ), - deno_napi::deno_napi::init::(), - deno_http::deno_http::init::(), - deno_io::deno_io::init(Default::default()), - deno_fs::deno_fs::init::(false, fs.clone()), - runtime::init(), + deno_napi::deno_napi::init_ops_and_esm::(), + deno_http::deno_http::init_ops_and_esm::(), + deno_io::deno_io::init_ops_and_esm(Default::default()), + deno_fs::deno_fs::init_ops_and_esm::(false, fs.clone()), + runtime::init_ops_and_esm(), // FIXME(bartlomieju): these extensions are specified last, because they // depend on `runtime`, even though it should be other way around - deno_node::deno_node::init::(None, fs), - runtime_main::init(), + deno_node::deno_node::init_ops_and_esm::(None, fs), + runtime_main::init_ops_and_esm(), ]; - create_snapshot(CreateSnapshotOptions { + let output = create_snapshot(CreateSnapshotOptions { cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), snapshot_path, startup_snapshot: None, @@ -341,6 +345,9 @@ mod startup_snapshot { compression_cb: None, 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()); + } } } diff --git a/runtime/examples/extension_with_esm/main.rs b/runtime/examples/extension_with_esm/main.rs index e2b7fccd1e..6b21460a3f 100644 --- a/runtime/examples/extension_with_esm/main.rs +++ b/runtime/examples/extension_with_esm/main.rs @@ -26,7 +26,7 @@ async fn main() -> Result<(), AnyError> { PermissionsContainer::allow_all(), WorkerOptions { module_loader: Rc::new(FsModuleLoader), - extensions: vec![hello_runtime::init()], + extensions: vec![hello_runtime::init_ops_and_esm()], ..Default::default() }, ); diff --git a/runtime/examples/extension_with_ops/main.rs b/runtime/examples/extension_with_ops/main.rs index 53b6ca4fca..1feb4ba279 100644 --- a/runtime/examples/extension_with_ops/main.rs +++ b/runtime/examples/extension_with_ops/main.rs @@ -28,7 +28,7 @@ async fn main() -> Result<(), AnyError> { PermissionsContainer::allow_all(), WorkerOptions { module_loader: Rc::new(FsModuleLoader), - extensions: vec![hello_runtime::init()], + extensions: vec![hello_runtime::init_ops()], ..Default::default() }, ); diff --git a/runtime/js.rs b/runtime/js.rs index 6aaa32f5f1..def2724ce3 100644 --- a/runtime/js.rs +++ b/runtime/js.rs @@ -13,3 +13,10 @@ pub fn deno_isolate_init() -> Snapshot { debug!("Deno isolate init with snapshots."); Snapshot::Static(RUNTIME_SNAPSHOT) } + +#[cfg(not(feature = "include_js_files_for_snapshotting"))] +pub static SOURCE_CODE_FOR_99_MAIN_JS: &str = include_str!("js/99_main.js"); + +#[cfg(feature = "include_js_files_for_snapshotting")] +pub static PATH_FOR_99_MAIN_JS: &str = + concat!(env!("CARGO_MANIFEST_DIR"), "/js/99_main.js"); diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 796e23c3c8..36f9718b51 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -399,14 +399,14 @@ impl WebWorker { // `runtime/build.rs`, `runtime/worker.rs` and `cli/build.rs`! let mut extensions: Vec = vec![ // Web APIs - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::( options.blob_store.clone(), Some(main_module.clone()), ), - deno_fetch::deno_fetch::init::( + deno_fetch::deno_fetch::init_ops::( deno_fetch::Options { user_agent: options.bootstrap.user_agent.clone(), root_cert_store_provider: options.root_cert_store_provider.clone(), @@ -417,57 +417,57 @@ impl WebWorker { ..Default::default() }, ), - deno_cache::deno_cache::init::(create_cache), - deno_websocket::deno_websocket::init::( + deno_cache::deno_cache::init_ops::(create_cache), + deno_websocket::deno_websocket::init_ops::( options.bootstrap.user_agent.clone(), options.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), ), - deno_webstorage::deno_webstorage::init(None).disable(), - deno_crypto::deno_crypto::init(options.seed), - deno_broadcast_channel::deno_broadcast_channel::init( + deno_webstorage::deno_webstorage::init_ops(None).disable(), + deno_crypto::deno_crypto::init_ops(options.seed), + deno_broadcast_channel::deno_broadcast_channel::init_ops( options.broadcast_channel.clone(), unstable, ), - deno_ffi::deno_ffi::init::(unstable), - deno_net::deno_net::init::( + deno_ffi::deno_ffi::init_ops::(unstable), + deno_net::deno_net::init_ops::( options.root_cert_store_provider.clone(), unstable, options.unsafely_ignore_certificate_errors.clone(), ), - deno_tls::deno_tls::init(), - deno_kv::deno_kv::init( + deno_tls::deno_tls::init_ops(), + deno_kv::deno_kv::init_ops( SqliteDbHandler::::new(None), unstable, ), - deno_napi::deno_napi::init::(), - deno_http::deno_http::init::(), - deno_io::deno_io::init(Some(options.stdio)), - deno_fs::deno_fs::init::( + deno_napi::deno_napi::init_ops::(), + deno_http::deno_http::init_ops::(), + deno_io::deno_io::init_ops(Some(options.stdio)), + deno_fs::deno_fs::init_ops::( unstable, options.fs.clone(), ), - deno_node::deno_node::init::( + deno_node::deno_node::init_ops::( options.npm_resolver, options.fs, ), // Runtime ops that are always initialized for WebWorkers - ops::web_worker::deno_web_worker::init(), - ops::runtime::deno_runtime::init(main_module.clone()), - ops::worker_host::deno_worker_host::init( + ops::web_worker::deno_web_worker::init_ops(), + ops::runtime::deno_runtime::init_ops(main_module.clone()), + ops::worker_host::deno_worker_host::init_ops( options.create_web_worker_cb.clone(), options.preload_module_cb.clone(), options.pre_execute_module_cb.clone(), options.format_js_error_fn.clone(), ), - ops::fs_events::deno_fs_events::init(), - ops::os::deno_os_worker::init(), - ops::permissions::deno_permissions::init(), - ops::process::deno_process::init(), - ops::signal::deno_signal::init(), - ops::tty::deno_tty::init(), - ops::http::deno_http_runtime::init(), - deno_permissions_web_worker::init( + ops::fs_events::deno_fs_events::init_ops(), + ops::os::deno_os_worker::init_ops(), + ops::permissions::deno_permissions::init_ops(), + ops::process::deno_process::init_ops(), + ops::signal::deno_signal::init_ops(), + ops::tty::deno_tty::init_ops(), + ops::http::deno_http_runtime::init_ops(), + deno_permissions_web_worker::init_ops( permissions, unstable, enable_testing_features, diff --git a/runtime/worker.rs b/runtime/worker.rs index 4b78c1a949..10375818d0 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -235,14 +235,14 @@ impl MainWorker { // `runtime/build.rs`, `runtime/web_worker.rs` and `cli/build.rs`! let mut extensions = vec![ // Web APIs - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::( options.blob_store.clone(), options.bootstrap.location.clone(), ), - deno_fetch::deno_fetch::init::( + deno_fetch::deno_fetch::init_ops::( deno_fetch::Options { user_agent: options.bootstrap.user_agent.clone(), root_cert_store_provider: options.root_cert_store_provider.clone(), @@ -253,60 +253,60 @@ impl MainWorker { ..Default::default() }, ), - deno_cache::deno_cache::init::(create_cache), - deno_websocket::deno_websocket::init::( + deno_cache::deno_cache::init_ops::(create_cache), + deno_websocket::deno_websocket::init_ops::( options.bootstrap.user_agent.clone(), options.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), ), - deno_webstorage::deno_webstorage::init( + deno_webstorage::deno_webstorage::init_ops( options.origin_storage_dir.clone(), ), - deno_crypto::deno_crypto::init(options.seed), - deno_broadcast_channel::deno_broadcast_channel::init( + deno_crypto::deno_crypto::init_ops(options.seed), + deno_broadcast_channel::deno_broadcast_channel::init_ops( options.broadcast_channel.clone(), unstable, ), - deno_ffi::deno_ffi::init::(unstable), - deno_net::deno_net::init::( + deno_ffi::deno_ffi::init_ops::(unstable), + deno_net::deno_net::init_ops::( options.root_cert_store_provider.clone(), unstable, options.unsafely_ignore_certificate_errors.clone(), ), - deno_tls::deno_tls::init(), - deno_kv::deno_kv::init( + deno_tls::deno_tls::init_ops(), + deno_kv::deno_kv::init_ops( SqliteDbHandler::::new( options.origin_storage_dir.clone(), ), unstable, ), - deno_napi::deno_napi::init::(), - deno_http::deno_http::init::(), - deno_io::deno_io::init(Some(options.stdio)), - deno_fs::deno_fs::init::( + deno_napi::deno_napi::init_ops::(), + deno_http::deno_http::init_ops::(), + deno_io::deno_io::init_ops(Some(options.stdio)), + deno_fs::deno_fs::init_ops::( unstable, options.fs.clone(), ), - deno_node::deno_node::init::( + deno_node::deno_node::init_ops::( options.npm_resolver, options.fs, ), // Ops from this crate - ops::runtime::deno_runtime::init(main_module.clone()), - ops::worker_host::deno_worker_host::init( + ops::runtime::deno_runtime::init_ops(main_module.clone()), + ops::worker_host::deno_worker_host::init_ops( options.create_web_worker_cb.clone(), options.web_worker_preload_module_cb.clone(), options.web_worker_pre_execute_module_cb.clone(), options.format_js_error_fn.clone(), ), - ops::fs_events::deno_fs_events::init(), - ops::os::deno_os::init(exit_code.clone()), - ops::permissions::deno_permissions::init(), - ops::process::deno_process::init(), - ops::signal::deno_signal::init(), - ops::tty::deno_tty::init(), - ops::http::deno_http_runtime::init(), - deno_permissions_worker::init( + ops::fs_events::deno_fs_events::init_ops(), + ops::os::deno_os::init_ops(exit_code.clone()), + ops::permissions::deno_permissions::init_ops(), + ops::process::deno_process::init_ops(), + ops::signal::deno_signal::init_ops(), + ops::tty::deno_tty::init_ops(), + ops::http::deno_http_runtime::init_ops(), + deno_permissions_worker::init_ops( permissions, unstable, enable_testing_features,