diff options
author | Bartek Iwańczuk <biwanczuk@gmail.com> | 2023-06-14 00:36:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-13 22:36:16 +0000 |
commit | 60bf79c18410fd332b6b9b7c222e6d3d62bfe3f8 (patch) | |
tree | 070934eb82d906ee341d1ad4d1390f0b75860529 | |
parent | 82dd90f98d6817caadcb9b6bd81aba80b2ee848d (diff) |
Revert "refactor(core): cleanup feature flags for js source inclusion… (#19490)
… (#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
33 files changed, 380 insertions, 250 deletions
diff --git a/Cargo.lock b/Cargo.lock index 72b001148..edb0a6e12 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 a8aadda01..4b3bc0203 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<Extension> { - 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 6d0a5977e..9bc7cdaee 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<Extension> { 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<Extension> { const hello1kEncoded = Deno.core.encode(hello1k); const hello1mEncoded = Deno.core.encode(hello1m); "#, + ), }]) .build()] } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 41194bfcd..fe9f35844 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 77e0ee1de..5ff86fa20 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<Extension> = vec![ - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::<PermissionsContainer>( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::<PermissionsContainer>( deno_web::BlobStore::default(), Default::default(), ), - deno_fetch::deno_fetch::init::<PermissionsContainer>(Default::default()), - deno_cache::deno_cache::init::<SqliteBackedCache>(None), - deno_websocket::deno_websocket::init::<PermissionsContainer>( + deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(Default::default()), + deno_cache::deno_cache::init_ops::<SqliteBackedCache>(None), + deno_websocket::deno_websocket::init_ops::<PermissionsContainer>( "".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::<PermissionsContainer>(false), - deno_net::deno_net::init::<PermissionsContainer>( + deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(false), + deno_net::deno_net::init_ops::<PermissionsContainer>( 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::<PermissionsContainer>::new(None), false, // No --unstable. ), - deno_napi::deno_napi::init::<PermissionsContainer>(), - deno_http::deno_http::init::<DefaultHttpPropertyExtractor>(), - deno_io::deno_io::init(Default::default()), - deno_fs::deno_fs::init::<PermissionsContainer>(false, fs.clone()), - deno_node::deno_node::init::<PermissionsContainer>(None, fs), - cli::init(), + deno_napi::deno_napi::init_ops::<PermissionsContainer>(), + deno_http::deno_http::init_ops::<DefaultHttpPropertyExtractor>(), + deno_io::deno_io::init_ops(Default::default()), + deno_fs::deno_fs::init_ops::<PermissionsContainer>(false, fs.clone()), + deno_node::deno_node::init_ops::<PermissionsContainer>(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 4c26abdc1..66687789b 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<Performance>) -> 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 d0d668bfb..5066c44b9 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<CliNpmResolver>) -> Vec<Extension> { - 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 4e7e90ba7..a7b75d8be 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 6181ebac0..6f32d69e4 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 edc64e8ef..a4d6640f7 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -122,7 +122,7 @@ fn get_asset_texts_from_new_runtime() -> Result<Vec<AssetText>, 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<Response, AnyError> { 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 b85aa6673..60474e649 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 8b5a4ff66..13aa17c7e 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 ffca10a32..b29dc9b4e 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 251f15429..b9cb265e8 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 ab0578106..fa6d7851e 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::<String>() } - 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<ModuleCode, Error> { + 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![ + $($crate::ExtensionFileSource { + specifier: concat!("ext:", stringify!($name), "/", $file), + code: $crate::ExtensionFileSourceCode::IncludedInBinary( + include_str!(concat!($dir, "/", $file) + )), + },)+ + ] }; - ($name:ident $(dir $dir:literal,)? $($file:literal,)*) => { - vec![] + ($name:ident $($file:literal,)+) => { + vec![ + $($crate::ExtensionFileSource { + specifier: concat!("ext:", stringify!($name), "/", $file), + code: $crate::ExtensionFileSourceCode::IncludedInBinary( + include_str!($file) + ), + },)+ + ] }; } +#[cfg(feature = "include_js_files_for_snapshotting")] #[macro_export] -macro_rules! force_include_js_files { - ($name:ident dir $dir:literal, $($file:literal,)*) => { +macro_rules! include_js_files { + ($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::LoadedFromFsDuringSnapshot( + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join($dir).join($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::LoadedFromFsDuringSnapshot( + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join($file) + ), + },)+ ] }; } diff --git a/core/inspector.rs b/core/inspector.rs index d7592fbe4..d7c84608f 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 729182a4f..336d9c2b9 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 5d9fe2fc4..4f1875ae5 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 29064df63..ecfd0bd57 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -510,7 +510,7 @@ impl JsRuntime { maybe_load_callback: Option<ExtModuleLoaderCb>, ) -> 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<OpDecl>) { + fn create_opstate( + options: &mut RuntimeOptions, + init_mode: InitMode, + ) -> (OpState, Vec<OpDecl>) { // 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 200a81d15..88c273147 100644 --- a/core/snapshot_util.rs +++ b/core/snapshot_util.rs @@ -22,7 +22,16 @@ pub struct CreateSnapshotOptions { 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 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<dyn Fn(&PathBuf) -> bool>; diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index d27712927..7ba6cd7ca 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 354acb3bd..05aa416b4 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 1e3d201f6..835dfea2e 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<Extension> { 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 9d12d9c2c..5b147f00c 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<Extension> { vec![ - deno_webidl::deno_webidl::init(), - deno_url::deno_url::init(), - deno_console::deno_console::init(), - deno_web::deno_web::init::<Permissions>(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::<Permissions>( + 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 c6afea9c1..084fac98b 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<Extension> { vec![ - deno_webidl::deno_webidl::init(), - deno_url::deno_url::init(), - deno_console::deno_console::init(), - deno_web::deno_web::init::<Permissions>(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::<Permissions>(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 bf5c0554b..b3d95c8a3 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<Extension> { 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 e66698a01..77571b210 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 d7b4018fb..f656682a1 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<Extension> = vec![ - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::<Permissions>( + 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::<Permissions>( deno_web::BlobStore::default(), Default::default(), ), - deno_fetch::deno_fetch::init::<Permissions>(Default::default()), - deno_cache::deno_cache::init::<SqliteBackedCache>(None), - deno_websocket::deno_websocket::init::<Permissions>( + deno_fetch::deno_fetch::init_ops_and_esm::<Permissions>( + Default::default(), + ), + deno_cache::deno_cache::init_ops_and_esm::<SqliteBackedCache>(None), + deno_websocket::deno_websocket::init_ops_and_esm::<Permissions>( "".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::<Permissions>(false), - deno_net::deno_net::init::<Permissions>( + deno_ffi::deno_ffi::init_ops_and_esm::<Permissions>(false), + deno_net::deno_net::init_ops_and_esm::<Permissions>( 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::<Permissions>::new(None), false, // No --unstable ), - deno_napi::deno_napi::init::<Permissions>(), - deno_http::deno_http::init::<DefaultHttpPropertyExtractor>(), - deno_io::deno_io::init(Default::default()), - deno_fs::deno_fs::init::<Permissions>(false, fs.clone()), - runtime::init(), + deno_napi::deno_napi::init_ops_and_esm::<Permissions>(), + deno_http::deno_http::init_ops_and_esm::<DefaultHttpPropertyExtractor>(), + deno_io::deno_io::init_ops_and_esm(Default::default()), + deno_fs::deno_fs::init_ops_and_esm::<Permissions>(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::<Permissions>(None, fs), - runtime_main::init(), + deno_node::deno_node::init_ops_and_esm::<Permissions>(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 e2b7fccd1..6b21460a3 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 53b6ca4fc..1feb4ba27 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 6aaa32f5f..def2724ce 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 796e23c3c..36f9718b5 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<Extension> = vec![ // Web APIs - deno_webidl::deno_webidl::init(), - deno_console::deno_console::init(), - deno_url::deno_url::init(), - deno_web::deno_web::init::<PermissionsContainer>( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::<PermissionsContainer>( options.blob_store.clone(), Some(main_module.clone()), ), - deno_fetch::deno_fetch::init::<PermissionsContainer>( + deno_fetch::deno_fetch::init_ops::<PermissionsContainer>( 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::<SqliteBackedCache>(create_cache), - deno_websocket::deno_websocket::init::<PermissionsContainer>( + deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache), + deno_websocket::deno_websocket::init_ops::<PermissionsContainer>( 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::<PermissionsContainer>(unstable), - deno_net::deno_net::init::<PermissionsContainer>( + deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable), + deno_net::deno_net::init_ops::<PermissionsContainer>( 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::<PermissionsContainer>::new(None), unstable, ), - deno_napi::deno_napi::init::<PermissionsContainer>(), - deno_http::deno_http::init::<DefaultHttpPropertyExtractor>(), - deno_io::deno_io::init(Some(options.stdio)), - deno_fs::deno_fs::init::<PermissionsContainer>( + deno_napi::deno_napi::init_ops::<PermissionsContainer>(), + deno_http::deno_http::init_ops::<DefaultHttpPropertyExtractor>(), + deno_io::deno_io::init_ops(Some(options.stdio)), + deno_fs::deno_fs::init_ops::<PermissionsContainer>( unstable, options.fs.clone(), ), - deno_node::deno_node::init::<PermissionsContainer>( + deno_node::deno_node::init_ops::<PermissionsContainer>( 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 4b78c1a94..10375818d 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::<PermissionsContainer>( + deno_webidl::deno_webidl::init_ops(), + deno_console::deno_console::init_ops(), + deno_url::deno_url::init_ops(), + deno_web::deno_web::init_ops::<PermissionsContainer>( options.blob_store.clone(), options.bootstrap.location.clone(), ), - deno_fetch::deno_fetch::init::<PermissionsContainer>( + deno_fetch::deno_fetch::init_ops::<PermissionsContainer>( 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::<SqliteBackedCache>(create_cache), - deno_websocket::deno_websocket::init::<PermissionsContainer>( + deno_cache::deno_cache::init_ops::<SqliteBackedCache>(create_cache), + deno_websocket::deno_websocket::init_ops::<PermissionsContainer>( 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::<PermissionsContainer>(unstable), - deno_net::deno_net::init::<PermissionsContainer>( + deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(unstable), + deno_net::deno_net::init_ops::<PermissionsContainer>( 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::<PermissionsContainer>::new( options.origin_storage_dir.clone(), ), unstable, ), - deno_napi::deno_napi::init::<PermissionsContainer>(), - deno_http::deno_http::init::<DefaultHttpPropertyExtractor>(), - deno_io::deno_io::init(Some(options.stdio)), - deno_fs::deno_fs::init::<PermissionsContainer>( + deno_napi::deno_napi::init_ops::<PermissionsContainer>(), + deno_http::deno_http::init_ops::<DefaultHttpPropertyExtractor>(), + deno_io::deno_io::init_ops(Some(options.stdio)), + deno_fs::deno_fs::init_ops::<PermissionsContainer>( unstable, options.fs.clone(), ), - deno_node::deno_node::init::<PermissionsContainer>( + deno_node::deno_node::init_ops::<PermissionsContainer>( 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, |