From d4893eb51a01c5a692d8ca74a3b8ff95c5fd1d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 10 Jan 2024 16:30:50 +0100 Subject: [PATCH] refactor: remove snapshotting from deno_runtime (#21794) Closes https://github.com/denoland/deno/issues/21137 --- cli/Cargo.toml | 7 +- runtime/Cargo.toml | 6 +- runtime/build.rs | 318 ------------------------------------------ runtime/js.rs | 18 --- runtime/shared.rs | 1 - runtime/web_worker.rs | 19 ++- runtime/worker.rs | 19 ++- 7 files changed, 31 insertions(+), 357 deletions(-) delete mode 100644 runtime/build.rs diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ae6a11398c..beb1f0a744 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -39,10 +39,7 @@ __runtime_js_sources = ["deno_runtime/__runtime_js_sources"] __vendored_zlib_ng = ["flate2/zlib-ng-compat", "libz-sys/zlib-ng"] [build-dependencies] -# TODO(bartlomieju): should we not include `dont_create_runtime_snapshot` -# feature here and actually create the snapshot in `deno_runtime` build script? -# How do we pass options? -deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "include_js_files_for_snapshotting"] } +deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } lazy-regex.workspace = true serde.workspace = true @@ -66,7 +63,7 @@ deno_graph = "=0.63.0" deno_lint = { version = "=0.53.0", features = ["docs"] } deno_lockfile.workspace = true deno_npm = "=0.15.3" -deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "include_js_files_for_snapshotting"] } +deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } # todo(dsherret): investigate https://github.com/denoland/deno_semver/commit/98f9174baef199809295077b3b68c9fa58defb9b causing # lsp_completions_auto_import_and_quick_fix_with_import_map to fail when bumping this version deno_semver = "=0.5.1" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 95a00c9ccf..223c42ffbc 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -12,8 +12,8 @@ description = "Provides the deno runtime library" [features] # "fake" feature that allows to generate docs on docs.rs docsrs = [] -# A feature that disables creation of startup snapshot during in the build script. -dont_create_runtime_snapshot = [] +# A feature that disables the requirement for startup snapshot to be provided. +dont_use_runtime_snapshot = [] # A feature that allows excluding `./js/99_main.js` from the exported extension. exclude_runtime_main_js = [] # A feature that disables embedding of the JavaScript source files in the binary. @@ -24,7 +24,7 @@ include_js_files_for_snapshotting = [ ] # A dev feature to disable creations and loading of snapshots in favor of # loading JS sources at runtime. -__runtime_js_sources = ["dont_create_runtime_snapshot"] +__runtime_js_sources = [] [lib] name = "deno_runtime" diff --git a/runtime/build.rs b/runtime/build.rs deleted file mode 100644 index ca937b1550..0000000000 --- a/runtime/build.rs +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -mod shared; - -use std::env; -use std::path::PathBuf; - -#[cfg(all( - not(feature = "docsrs"), - not(feature = "dont_create_runtime_snapshot") -))] -mod startup_snapshot { - use super::*; - use deno_cache::SqliteBackedCache; - use deno_core::error::AnyError; - use deno_core::op2; - use deno_core::snapshot_util::*; - use deno_core::Extension; - use deno_core::OpState; - use deno_http::DefaultHttpPropertyExtractor; - use shared::maybe_transpile_source; - use shared::runtime; - use std::path::Path; - - // Keep in sync with `runtime/ops/bootstrap.rs` - #[derive(serde::Serialize, Default)] - #[serde(rename_all = "camelCase")] - pub struct SnapshotOptions { - pub deno_version: String, - pub ts_version: String, - pub v8_version: &'static str, - pub target: String, - } - - // TODO(@littledivy): Remove this once we get rid of deno_runtime snapshots. - #[op2] - #[serde] - pub fn op_snapshot_options(_: &mut OpState) -> SnapshotOptions { - SnapshotOptions::default() - } - - deno_core::extension!(snapshot, ops = [op_snapshot_options],); - - #[derive(Clone)] - struct Permissions; - - impl deno_fetch::FetchPermissions for Permissions { - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - - fn check_read( - &mut self, - _p: &Path, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_websocket::WebSocketPermissions for Permissions { - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - unreachable!("snapshotting!") - } - } - - impl deno_ffi::FfiPermissions for Permissions { - fn check_partial( - &mut self, - _path: Option<&Path>, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_napi::NapiPermissions for Permissions { - fn check( - &mut self, - _path: Option<&Path>, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_node::NodePermissions for Permissions { - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - fn check_read(&self, _p: &Path) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - fn check_read_with_api_name( - &self, - _: &Path, - _: std::option::Option<&str>, - ) -> Result<(), deno_core::anyhow::Error> { - unreachable!("snapshotting!") - } - fn check_sys( - &self, - _kind: &str, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_net::NetPermissions for Permissions { - fn check_net>( - &mut self, - _host: &(T, Option), - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - - fn check_read( - &mut self, - _p: &Path, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - - fn check_write( - &mut self, - _p: &Path, - _api_name: &str, - ) -> Result<(), deno_core::error::AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_fs::FsPermissions for Permissions { - fn check_read( - &mut self, - _path: &Path, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_read_all(&mut self, _api_name: &str) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_read_blind( - &mut self, - _path: &Path, - _display: &str, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_write( - &mut self, - _path: &Path, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_write_partial( - &mut self, - _path: &Path, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_write_all(&mut self, _api_name: &str) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_write_blind( - &mut self, - _path: &Path, - _display: &str, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - } - - impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions { - fn check_read( - &mut self, - _path: &Path, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - - fn check_write( - &mut self, - _path: &Path, - _api_name: &str, - ) -> Result<(), AnyError> { - unreachable!("snapshotting!") - } - } - - pub fn create_runtime_snapshot(snapshot_path: PathBuf) { - // NOTE(bartlomieju): ordering is important here, keep it in sync with - // `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/snapshot.rs`! - let fs = std::sync::Arc::new(deno_fs::RealFs); - let mut extensions: Vec = vec![ - 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::( - Default::default(), - Default::default(), - ), - deno_webgpu::deno_webgpu::init_ops_and_esm(), - 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_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(), - ), - deno_ffi::deno_ffi::init_ops_and_esm::(), - deno_net::deno_net::init_ops_and_esm::(None, None), - deno_tls::deno_tls::init_ops_and_esm(), - deno_kv::deno_kv::init_ops_and_esm(deno_kv::sqlite::SqliteDbHandler::< - Permissions, - >::new(None, None)), - deno_cron::deno_cron::init_ops_and_esm( - deno_cron::local::LocalCronHandler::new(), - ), - 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::(fs.clone()), - deno_node::deno_node::init_ops_and_esm::(None, fs), - runtime::init_ops_and_esm(), - snapshot::init_ops_and_esm(), - ]; - - for extension in &mut extensions { - for source in extension.esm_files.to_mut() { - maybe_transpile_source(source).unwrap(); - } - for source in extension.js_files.to_mut() { - maybe_transpile_source(source).unwrap(); - } - } - - let output = create_snapshot(CreateSnapshotOptions { - cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), - snapshot_path, - startup_snapshot: None, - extensions, - compression_cb: None, - with_runtime_cb: None, - skip_op_registration: false, - }); - for path in output.files_loaded_during_snapshot { - println!("cargo:rerun-if-changed={}", path.display()); - } - } -} - -fn main() { - // To debug snapshot issues uncomment: - // op_fetch_asset::trace_serializer(); - - println!("cargo:rustc-env=TARGET={}", env::var("TARGET").unwrap()); - println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap()); - let o = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - - // Main snapshot - let runtime_snapshot_path = o.join("RUNTIME_SNAPSHOT.bin"); - - // If we're building on docs.rs we just create - // and empty snapshot file and return, because `rusty_v8` - // doesn't actually compile on docs.rs - if env::var_os("DOCS_RS").is_some() { - let snapshot_slice = &[]; - #[allow(clippy::needless_borrow)] - #[allow(clippy::disallowed_methods)] - #[allow(clippy::needless_borrows_for_generic_args)] - std::fs::write(&runtime_snapshot_path, snapshot_slice).unwrap(); - } - - #[cfg(all( - not(feature = "docsrs"), - not(feature = "dont_create_runtime_snapshot") - ))] - startup_snapshot::create_runtime_snapshot(runtime_snapshot_path) -} diff --git a/runtime/js.rs b/runtime/js.rs index 97841ffb39..a8384ceacf 100644 --- a/runtime/js.rs +++ b/runtime/js.rs @@ -1,22 +1,4 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_core::Snapshot; -use log::debug; - -#[cfg(not(feature = "dont_create_runtime_snapshot"))] -static RUNTIME_SNAPSHOT: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/RUNTIME_SNAPSHOT.bin")); - -pub fn deno_isolate_init() -> Option { - debug!("Deno isolate init with snapshots."); - #[cfg(not(feature = "dont_create_runtime_snapshot"))] - { - Some(Snapshot::Static(RUNTIME_SNAPSHOT)) - } - #[cfg(feature = "dont_create_runtime_snapshot")] - { - None - } -} #[cfg(not(feature = "include_js_files_for_snapshotting"))] pub static SOURCE_CODE_FOR_99_MAIN_JS: &str = include_str!("js/99_main.js"); diff --git a/runtime/shared.rs b/runtime/shared.rs index 692be94b85..1f24fec0bb 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -67,7 +67,6 @@ extension!(runtime, } ); -#[allow(dead_code)] pub fn maybe_transpile_source( source: &mut ExtensionFileSource, ) -> Result<(), AnyError> { diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 87841923bf..11bcd328ae 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -398,7 +398,7 @@ impl WebWorker { }); // NOTE(bartlomieju): ordering is important here, keep it in sync with - // `runtime/build.rs`, `runtime/worker.rs` and `runtime/snapshot.rs`! + // `runtime/worker.rs` and `runtime/snapshot.rs`! let mut extensions = vec![ // Web APIs @@ -509,8 +509,17 @@ impl WebWorker { extensions.extend(std::mem::take(&mut options.extensions)); - #[cfg(all(feature = "include_js_files_for_snapshotting", feature = "dont_create_runtime_snapshot", not(feature = "__runtime_js_sources")))] - options.startup_snapshot.as_ref().expect("Sources are not embedded, snapshotting was disabled and a user snapshot was not provided."); + #[cfg(all( + feature = "include_js_files_for_snapshotting", + not(feature = "__runtime_js_sources") + ))] + options + .startup_snapshot + .as_ref() + .expect("Sources are not embedded and a user snapshot was not provided."); + + #[cfg(not(feature = "dont_use_runtime_snapshot"))] + options.startup_snapshot.as_ref().expect("A user snapshot was not provided, if you want to create a runtime without a snapshot use 'dont_use_runtime_snapshot' Cargo feature."); // Hook up the summary metrics if the user or subcommand requested them let (op_summary_metrics, op_metrics_factory_fn) = @@ -526,9 +535,7 @@ impl WebWorker { let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(options.module_loader.clone()), - startup_snapshot: options - .startup_snapshot - .or_else(crate::js::deno_isolate_init), + startup_snapshot: options.startup_snapshot, source_map_getter: options.source_map_getter, get_error_class_fn: options.get_error_class_fn, shared_array_buffer_store: options.shared_array_buffer_store.clone(), diff --git a/runtime/worker.rs b/runtime/worker.rs index 2a838c0f69..1fac28c6a9 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -308,7 +308,7 @@ impl MainWorker { }); // NOTE(bartlomieju): ordering is important here, keep it in sync with - // `runtime/build.rs`, `runtime/web_worker.rs` and `runtime/snapshot.rs`! + // `runtime/web_worker.rs` and `runtime/snapshot.rs`! let mut extensions = vec![ // Web APIs deno_webidl::deno_webidl::init_ops_and_esm(), @@ -428,8 +428,17 @@ impl MainWorker { extensions.extend(std::mem::take(&mut options.extensions)); - #[cfg(all(feature = "include_js_files_for_snapshotting", feature = "dont_create_runtime_snapshot", not(feature = "__runtime_js_sources")))] - options.startup_snapshot.as_ref().expect("Sources are not embedded, snapshotting was disabled and a user snapshot was not provided."); + #[cfg(all( + feature = "include_js_files_for_snapshotting", + not(feature = "__runtime_js_sources") + ))] + options + .startup_snapshot + .as_ref() + .expect("Sources are not embedded and a user snapshot was not provided."); + + #[cfg(not(feature = "dont_use_runtime_snapshot"))] + options.startup_snapshot.as_ref().expect("A user snapshot was not provided, if you want to create a runtime without a snapshot use 'dont_use_runtime_snapshot' Cargo feature."); let has_notified_of_inspector_disconnect = AtomicBool::new(false); let wait_for_inspector_disconnect_callback = Box::new(move || { @@ -442,9 +451,7 @@ impl MainWorker { let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(options.module_loader.clone()), - startup_snapshot: options - .startup_snapshot - .or_else(crate::js::deno_isolate_init), + startup_snapshot: options.startup_snapshot, create_params: options.create_params, source_map_getter: options.source_map_getter, skip_op_registration: options.skip_op_registration,