mirror of
https://github.com/denoland/deno.git
synced 2025-01-11 16:42:21 -05:00
feat(ext/node): eagerly bootstrap node (#20153)
To fix bugs around detection of when node emulation is required, we will just eagerly initialize it. The improvements we make to reduce the impact of the startup time: - [x] Process stdin/stdout/stderr are lazily created - [x] node.js global proxy no longer allocates on each access check - [x] Process checks for `beforeExit` listeners before doing expensive shutdown work - [x] Process should avoid adding global event handlers until listeners are added Benchmarking this PR (`89de7e1ff`) vs main (`41cad2179`) ``` 12:36 $ third_party/prebuilt/mac/hyperfine --warmup 100 -S none './deno-41cad2179 run ./empty.js' './deno-89de7e1ff run ./empty.js' Benchmark 1: ./deno-41cad2179 run ./empty.js Time (mean ± σ): 24.3 ms ± 1.6 ms [User: 16.2 ms, System: 6.0 ms] Range (min … max): 21.1 ms … 29.1 ms 115 runs Benchmark 2: ./deno-89de7e1ff run ./empty.js Time (mean ± σ): 24.0 ms ± 1.4 ms [User: 16.3 ms, System: 5.6 ms] Range (min … max): 21.3 ms … 28.6 ms 126 runs ``` Fixes https://github.com/denoland/deno/issues/20142 Fixes https://github.com/denoland/deno/issues/15826 Fixes https://github.com/denoland/deno/issues/20028
This commit is contained in:
parent
3ba09eacd2
commit
851e08bd1f
15 changed files with 321 additions and 397 deletions
|
@ -44,7 +44,6 @@ use crate::util::progress_bar::ProgressBar;
|
||||||
use crate::util::progress_bar::ProgressBarStyle;
|
use crate::util::progress_bar::ProgressBarStyle;
|
||||||
use crate::worker::CliMainWorkerFactory;
|
use crate::worker::CliMainWorkerFactory;
|
||||||
use crate::worker::CliMainWorkerOptions;
|
use crate::worker::CliMainWorkerOptions;
|
||||||
use crate::worker::HasNodeSpecifierChecker;
|
|
||||||
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -623,7 +622,6 @@ impl CliFactory {
|
||||||
StorageKeyResolver::from_options(&self.options),
|
StorageKeyResolver::from_options(&self.options),
|
||||||
self.npm_resolver().await?.clone(),
|
self.npm_resolver().await?.clone(),
|
||||||
node_resolver.clone(),
|
node_resolver.clone(),
|
||||||
Box::new(CliHasNodeSpecifierChecker(self.graph_container().clone())),
|
|
||||||
self.blob_store().clone(),
|
self.blob_store().clone(),
|
||||||
Box::new(CliModuleLoaderFactory::new(
|
Box::new(CliModuleLoaderFactory::new(
|
||||||
&self.options,
|
&self.options,
|
||||||
|
@ -683,11 +681,3 @@ impl CliFactory {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CliHasNodeSpecifierChecker(Arc<ModuleGraphContainer>);
|
|
||||||
|
|
||||||
impl HasNodeSpecifierChecker for CliHasNodeSpecifierChecker {
|
|
||||||
fn has_node_specifier(&self) -> bool {
|
|
||||||
self.0.graph().has_node_specifier
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -179,11 +179,6 @@ impl CliNpmResolver {
|
||||||
specifier.as_ref().starts_with(root_dir_url.as_str())
|
specifier.as_ref().starts_with(root_dir_url.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the resolver has resolved any npm packages.
|
|
||||||
pub fn has_packages(&self) -> bool {
|
|
||||||
self.resolution.has_packages()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds package requirements to the resolver and ensures everything is setup.
|
/// Adds package requirements to the resolver and ensures everything is setup.
|
||||||
pub async fn add_package_reqs(
|
pub async fn add_package_reqs(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -26,7 +26,6 @@ use crate::util::progress_bar::ProgressBarStyle;
|
||||||
use crate::util::v8::construct_v8_flags;
|
use crate::util::v8::construct_v8_flags;
|
||||||
use crate::worker::CliMainWorkerFactory;
|
use crate::worker::CliMainWorkerFactory;
|
||||||
use crate::worker::CliMainWorkerOptions;
|
use crate::worker::CliMainWorkerOptions;
|
||||||
use crate::worker::HasNodeSpecifierChecker;
|
|
||||||
use crate::worker::ModuleLoaderFactory;
|
use crate::worker::ModuleLoaderFactory;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
|
@ -266,14 +265,6 @@ impl ModuleLoaderFactory for StandaloneModuleLoaderFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StandaloneHasNodeSpecifierChecker;
|
|
||||||
|
|
||||||
impl HasNodeSpecifierChecker for StandaloneHasNodeSpecifierChecker {
|
|
||||||
fn has_node_specifier(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StandaloneRootCertStoreProvider {
|
struct StandaloneRootCertStoreProvider {
|
||||||
ca_stores: Option<Vec<String>>,
|
ca_stores: Option<Vec<String>>,
|
||||||
ca_data: Option<CaData>,
|
ca_data: Option<CaData>,
|
||||||
|
@ -438,7 +429,6 @@ pub async fn run(
|
||||||
StorageKeyResolver::empty(),
|
StorageKeyResolver::empty(),
|
||||||
npm_resolver.clone(),
|
npm_resolver.clone(),
|
||||||
node_resolver,
|
node_resolver,
|
||||||
Box::new(StandaloneHasNodeSpecifierChecker),
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Box::new(module_loader_factory),
|
Box::new(module_loader_factory),
|
||||||
root_cert_store_provider,
|
root_cert_store_provider,
|
||||||
|
|
|
@ -25,7 +25,6 @@ use deno_core::serde_json;
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
use deno_core::LocalInspectorSession;
|
use deno_core::LocalInspectorSession;
|
||||||
use deno_graph::source::Resolver;
|
use deno_graph::source::Resolver;
|
||||||
use deno_runtime::deno_node;
|
|
||||||
use deno_runtime::worker::MainWorker;
|
use deno_runtime::worker::MainWorker;
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -123,7 +122,6 @@ struct TsEvaluateResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReplSession {
|
pub struct ReplSession {
|
||||||
has_node_modules_dir: bool,
|
|
||||||
npm_resolver: Arc<CliNpmResolver>,
|
npm_resolver: Arc<CliNpmResolver>,
|
||||||
resolver: Arc<CliGraphResolver>,
|
resolver: Arc<CliGraphResolver>,
|
||||||
pub worker: MainWorker,
|
pub worker: MainWorker,
|
||||||
|
@ -131,7 +129,6 @@ pub struct ReplSession {
|
||||||
pub context_id: u64,
|
pub context_id: u64,
|
||||||
pub language_server: ReplLanguageServer,
|
pub language_server: ReplLanguageServer,
|
||||||
pub notifications: Rc<RefCell<UnboundedReceiver<Value>>>,
|
pub notifications: Rc<RefCell<UnboundedReceiver<Value>>>,
|
||||||
has_initialized_node_runtime: bool,
|
|
||||||
referrer: ModuleSpecifier,
|
referrer: ModuleSpecifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,14 +180,12 @@ impl ReplSession {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut repl_session = ReplSession {
|
let mut repl_session = ReplSession {
|
||||||
has_node_modules_dir: cli_options.has_node_modules_dir(),
|
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
resolver,
|
resolver,
|
||||||
worker,
|
worker,
|
||||||
session,
|
session,
|
||||||
context_id,
|
context_id,
|
||||||
language_server,
|
language_server,
|
||||||
has_initialized_node_runtime: false,
|
|
||||||
referrer,
|
referrer,
|
||||||
notifications: Rc::new(RefCell::new(notification_rx)),
|
notifications: Rc::new(RefCell::new(notification_rx)),
|
||||||
};
|
};
|
||||||
|
@ -515,15 +510,6 @@ impl ReplSession {
|
||||||
let has_node_specifier =
|
let has_node_specifier =
|
||||||
resolved_imports.iter().any(|url| url.scheme() == "node");
|
resolved_imports.iter().any(|url| url.scheme() == "node");
|
||||||
if !npm_imports.is_empty() || has_node_specifier {
|
if !npm_imports.is_empty() || has_node_specifier {
|
||||||
if !self.has_initialized_node_runtime {
|
|
||||||
deno_node::initialize_runtime(
|
|
||||||
&mut self.worker.js_runtime,
|
|
||||||
self.has_node_modules_dir,
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
self.has_initialized_node_runtime = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.npm_resolver.add_package_reqs(&npm_imports).await?;
|
self.npm_resolver.add_package_reqs(&npm_imports).await?;
|
||||||
|
|
||||||
// prevent messages in the repl about @types/node not being cached
|
// prevent messages in the repl about @types/node not being cached
|
||||||
|
|
|
@ -8,7 +8,6 @@ use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::task::LocalFutureObj;
|
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -32,7 +31,6 @@ use deno_runtime::deno_web::BlobStore;
|
||||||
use deno_runtime::fmt_errors::format_js_error;
|
use deno_runtime::fmt_errors::format_js_error;
|
||||||
use deno_runtime::inspector_server::InspectorServer;
|
use deno_runtime::inspector_server::InspectorServer;
|
||||||
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
|
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
|
||||||
use deno_runtime::ops::worker_host::WorkerEventCb;
|
|
||||||
use deno_runtime::permissions::PermissionsContainer;
|
use deno_runtime::permissions::PermissionsContainer;
|
||||||
use deno_runtime::web_worker::WebWorker;
|
use deno_runtime::web_worker::WebWorker;
|
||||||
use deno_runtime::web_worker::WebWorkerOptions;
|
use deno_runtime::web_worker::WebWorkerOptions;
|
||||||
|
@ -97,7 +95,6 @@ struct SharedWorkerState {
|
||||||
storage_key_resolver: StorageKeyResolver,
|
storage_key_resolver: StorageKeyResolver,
|
||||||
npm_resolver: Arc<CliNpmResolver>,
|
npm_resolver: Arc<CliNpmResolver>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
has_node_specifier_checker: Box<dyn HasNodeSpecifierChecker>,
|
|
||||||
blob_store: Arc<BlobStore>,
|
blob_store: Arc<BlobStore>,
|
||||||
broadcast_channel: InMemoryBroadcastChannel,
|
broadcast_channel: InMemoryBroadcastChannel,
|
||||||
shared_array_buffer_store: SharedArrayBufferStore,
|
shared_array_buffer_store: SharedArrayBufferStore,
|
||||||
|
@ -110,11 +107,7 @@ struct SharedWorkerState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedWorkerState {
|
impl SharedWorkerState {
|
||||||
pub fn should_initialize_node_runtime(&self) -> bool {
|
// Currently empty
|
||||||
self.npm_resolver.has_packages()
|
|
||||||
|| self.has_node_specifier_checker.has_node_specifier()
|
|
||||||
|| self.options.is_npm_main
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CliMainWorker {
|
pub struct CliMainWorker {
|
||||||
|
@ -140,7 +133,6 @@ impl CliMainWorker {
|
||||||
log::debug!("main_module {}", self.main_module);
|
log::debug!("main_module {}", self.main_module);
|
||||||
|
|
||||||
if self.is_main_cjs {
|
if self.is_main_cjs {
|
||||||
self.initialize_main_module_for_node()?;
|
|
||||||
deno_node::load_cjs_module(
|
deno_node::load_cjs_module(
|
||||||
&mut self.worker.js_runtime,
|
&mut self.worker.js_runtime,
|
||||||
&self.main_module.to_file_path().unwrap().to_string_lossy(),
|
&self.main_module.to_file_path().unwrap().to_string_lossy(),
|
||||||
|
@ -266,22 +258,9 @@ impl CliMainWorker {
|
||||||
&mut self,
|
&mut self,
|
||||||
id: ModuleId,
|
id: ModuleId,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if self.shared.should_initialize_node_runtime() {
|
|
||||||
self.initialize_main_module_for_node()?;
|
|
||||||
}
|
|
||||||
self.worker.evaluate_module(id).await
|
self.worker.evaluate_module(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_main_module_for_node(&mut self) -> Result<(), AnyError> {
|
|
||||||
deno_node::initialize_runtime(
|
|
||||||
&mut self.worker.js_runtime,
|
|
||||||
self.shared.options.has_node_modules_dir,
|
|
||||||
self.shared.options.maybe_binary_npm_command_name.as_deref(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn maybe_setup_coverage_collector(
|
pub async fn maybe_setup_coverage_collector(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Result<Option<CoverageCollector>, AnyError> {
|
) -> Result<Option<CoverageCollector>, AnyError> {
|
||||||
|
@ -312,7 +291,6 @@ impl CliMainWorkerFactory {
|
||||||
storage_key_resolver: StorageKeyResolver,
|
storage_key_resolver: StorageKeyResolver,
|
||||||
npm_resolver: Arc<CliNpmResolver>,
|
npm_resolver: Arc<CliNpmResolver>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
has_node_specifier_checker: Box<dyn HasNodeSpecifierChecker>,
|
|
||||||
blob_store: Arc<BlobStore>,
|
blob_store: Arc<BlobStore>,
|
||||||
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
||||||
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
||||||
|
@ -327,7 +305,6 @@ impl CliMainWorkerFactory {
|
||||||
storage_key_resolver,
|
storage_key_resolver,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
node_resolver,
|
node_resolver,
|
||||||
has_node_specifier_checker,
|
|
||||||
blob_store,
|
blob_store,
|
||||||
broadcast_channel: Default::default(),
|
broadcast_channel: Default::default(),
|
||||||
shared_array_buffer_store: Default::default(),
|
shared_array_buffer_store: Default::default(),
|
||||||
|
@ -404,10 +381,6 @@ impl CliMainWorkerFactory {
|
||||||
|
|
||||||
let create_web_worker_cb =
|
let create_web_worker_cb =
|
||||||
create_web_worker_callback(shared.clone(), stdio.clone());
|
create_web_worker_callback(shared.clone(), stdio.clone());
|
||||||
let web_worker_preload_module_cb =
|
|
||||||
create_web_worker_preload_module_callback(shared);
|
|
||||||
let web_worker_pre_execute_module_cb =
|
|
||||||
create_web_worker_pre_execute_module_callback(shared.clone());
|
|
||||||
|
|
||||||
let maybe_storage_key = shared
|
let maybe_storage_key = shared
|
||||||
.storage_key_resolver
|
.storage_key_resolver
|
||||||
|
@ -448,6 +421,11 @@ impl CliMainWorkerFactory {
|
||||||
unstable: shared.options.unstable,
|
unstable: shared.options.unstable,
|
||||||
user_agent: version::get_user_agent().to_string(),
|
user_agent: version::get_user_agent().to_string(),
|
||||||
inspect: shared.options.is_inspecting,
|
inspect: shared.options.is_inspecting,
|
||||||
|
has_node_modules_dir: shared.options.has_node_modules_dir,
|
||||||
|
maybe_binary_npm_command_name: shared
|
||||||
|
.options
|
||||||
|
.maybe_binary_npm_command_name
|
||||||
|
.clone(),
|
||||||
},
|
},
|
||||||
extensions,
|
extensions,
|
||||||
startup_snapshot: crate::js::deno_isolate_init(),
|
startup_snapshot: crate::js::deno_isolate_init(),
|
||||||
|
@ -461,8 +439,6 @@ impl CliMainWorkerFactory {
|
||||||
source_map_getter: maybe_source_map_getter,
|
source_map_getter: maybe_source_map_getter,
|
||||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||||
create_web_worker_cb,
|
create_web_worker_cb,
|
||||||
web_worker_preload_module_cb,
|
|
||||||
web_worker_pre_execute_module_cb,
|
|
||||||
maybe_inspector_server,
|
maybe_inspector_server,
|
||||||
should_break_on_first_statement: shared.options.inspect_brk,
|
should_break_on_first_statement: shared.options.inspect_brk,
|
||||||
should_wait_for_inspector_session: shared.options.inspect_wait,
|
should_wait_for_inspector_session: shared.options.inspect_wait,
|
||||||
|
@ -555,38 +531,6 @@ impl CliMainWorkerFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bartlomieju): this callback could have default value
|
|
||||||
// and not be required
|
|
||||||
fn create_web_worker_preload_module_callback(
|
|
||||||
_shared: &Arc<SharedWorkerState>,
|
|
||||||
) -> Arc<WorkerEventCb> {
|
|
||||||
Arc::new(move |worker| {
|
|
||||||
let fut = async move { Ok(worker) };
|
|
||||||
LocalFutureObj::new(Box::new(fut))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_web_worker_pre_execute_module_callback(
|
|
||||||
shared: Arc<SharedWorkerState>,
|
|
||||||
) -> Arc<WorkerEventCb> {
|
|
||||||
Arc::new(move |mut worker| {
|
|
||||||
let shared = shared.clone();
|
|
||||||
let fut = async move {
|
|
||||||
// this will be up to date after pre-load
|
|
||||||
if shared.should_initialize_node_runtime() {
|
|
||||||
deno_node::initialize_runtime(
|
|
||||||
&mut worker.js_runtime,
|
|
||||||
shared.options.has_node_modules_dir,
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(worker)
|
|
||||||
};
|
|
||||||
LocalFutureObj::new(Box::new(fut))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_web_worker_callback(
|
fn create_web_worker_callback(
|
||||||
shared: Arc<SharedWorkerState>,
|
shared: Arc<SharedWorkerState>,
|
||||||
stdio: deno_runtime::deno_io::Stdio,
|
stdio: deno_runtime::deno_io::Stdio,
|
||||||
|
@ -602,9 +546,6 @@ fn create_web_worker_callback(
|
||||||
shared.module_loader_factory.create_source_map_getter();
|
shared.module_loader_factory.create_source_map_getter();
|
||||||
let create_web_worker_cb =
|
let create_web_worker_cb =
|
||||||
create_web_worker_callback(shared.clone(), stdio.clone());
|
create_web_worker_callback(shared.clone(), stdio.clone());
|
||||||
let preload_module_cb = create_web_worker_preload_module_callback(&shared);
|
|
||||||
let pre_execute_module_cb =
|
|
||||||
create_web_worker_pre_execute_module_callback(shared.clone());
|
|
||||||
|
|
||||||
let extensions = ops::cli_exts(shared.npm_resolver.clone());
|
let extensions = ops::cli_exts(shared.npm_resolver.clone());
|
||||||
|
|
||||||
|
@ -636,6 +577,11 @@ fn create_web_worker_callback(
|
||||||
unstable: shared.options.unstable,
|
unstable: shared.options.unstable,
|
||||||
user_agent: version::get_user_agent().to_string(),
|
user_agent: version::get_user_agent().to_string(),
|
||||||
inspect: shared.options.is_inspecting,
|
inspect: shared.options.is_inspecting,
|
||||||
|
has_node_modules_dir: shared.options.has_node_modules_dir,
|
||||||
|
maybe_binary_npm_command_name: shared
|
||||||
|
.options
|
||||||
|
.maybe_binary_npm_command_name
|
||||||
|
.clone(),
|
||||||
},
|
},
|
||||||
extensions,
|
extensions,
|
||||||
startup_snapshot: crate::js::deno_isolate_init(),
|
startup_snapshot: crate::js::deno_isolate_init(),
|
||||||
|
@ -646,8 +592,6 @@ fn create_web_worker_callback(
|
||||||
root_cert_store_provider: Some(shared.root_cert_store_provider.clone()),
|
root_cert_store_provider: Some(shared.root_cert_store_provider.clone()),
|
||||||
seed: shared.options.seed,
|
seed: shared.options.seed,
|
||||||
create_web_worker_cb,
|
create_web_worker_cb,
|
||||||
preload_module_cb,
|
|
||||||
pre_execute_module_cb,
|
|
||||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||||
source_map_getter: maybe_source_map_getter,
|
source_map_getter: maybe_source_map_getter,
|
||||||
module_loader,
|
module_loader,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
|
@ -266,13 +267,14 @@ fn current_mode(scope: &mut v8::HandleScope) -> Mode {
|
||||||
let Some(v8_string) = v8::StackTrace::current_script_name_or_source_url(scope) else {
|
let Some(v8_string) = v8::StackTrace::current_script_name_or_source_url(scope) else {
|
||||||
return Mode::Deno;
|
return Mode::Deno;
|
||||||
};
|
};
|
||||||
let string = v8_string.to_rust_string_lossy(scope);
|
|
||||||
let op_state = deno_core::JsRuntime::op_state_from(scope);
|
let op_state = deno_core::JsRuntime::op_state_from(scope);
|
||||||
let op_state = op_state.borrow();
|
let op_state = op_state.borrow();
|
||||||
let Some(node_resolver) = op_state.try_borrow::<Rc<NodeResolver>>() else {
|
let Some(node_resolver) = op_state.try_borrow::<Rc<NodeResolver>>() else {
|
||||||
return Mode::Deno;
|
return Mode::Deno;
|
||||||
};
|
};
|
||||||
if node_resolver.in_npm_package_with_cache(string) {
|
let mut buffer = [MaybeUninit::uninit(); 2048];
|
||||||
|
let str = v8_string.to_rust_cow_lossy(scope, &mut buffer);
|
||||||
|
if node_resolver.in_npm_package_with_cache(str) {
|
||||||
Mode::Node
|
Mode::Node
|
||||||
} else {
|
} else {
|
||||||
Mode::Deno
|
Mode::Deno
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::rc::Rc;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::serde_json;
|
|
||||||
use deno_core::serde_v8;
|
use deno_core::serde_v8;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -558,29 +557,6 @@ deno_core::extension!(deno_node,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn initialize_runtime(
|
|
||||||
js_runtime: &mut JsRuntime,
|
|
||||||
uses_local_node_modules_dir: bool,
|
|
||||||
maybe_binary_command_name: Option<&str>,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
let argv0 = if let Some(binary_command_name) = maybe_binary_command_name {
|
|
||||||
serde_json::to_string(binary_command_name)?
|
|
||||||
} else {
|
|
||||||
"undefined".to_string()
|
|
||||||
};
|
|
||||||
let source_code = format!(
|
|
||||||
r#"(function loadBuiltinNodeModules(usesLocalNodeModulesDir, argv0) {{
|
|
||||||
Deno[Deno.internal].node.initialize(
|
|
||||||
usesLocalNodeModulesDir,
|
|
||||||
argv0
|
|
||||||
);
|
|
||||||
}})({uses_local_node_modules_dir}, {argv0});"#,
|
|
||||||
);
|
|
||||||
|
|
||||||
js_runtime.execute_script(located_script_name!(), source_code.into())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_cjs_module(
|
pub fn load_cjs_module(
|
||||||
js_runtime: &mut JsRuntime,
|
js_runtime: &mut JsRuntime,
|
||||||
module: &str,
|
module: &str,
|
||||||
|
|
|
@ -7,6 +7,10 @@ const requireImpl = internals.requireImpl;
|
||||||
import { nodeGlobals } from "ext:deno_node/00_globals.js";
|
import { nodeGlobals } from "ext:deno_node/00_globals.js";
|
||||||
import "node:module";
|
import "node:module";
|
||||||
|
|
||||||
|
globalThis.nodeBootstrap = function (usesLocalNodeModulesDir, argv0) {
|
||||||
|
initialize(usesLocalNodeModulesDir, argv0);
|
||||||
|
};
|
||||||
|
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
function initialize(
|
function initialize(
|
||||||
|
|
|
@ -33,6 +33,8 @@ export { _nextTick as nextTick, chdir, cwd, env, version, versions };
|
||||||
import {
|
import {
|
||||||
createWritableStdioStream,
|
createWritableStdioStream,
|
||||||
initStdin,
|
initStdin,
|
||||||
|
Readable,
|
||||||
|
Writable,
|
||||||
} from "ext:deno_node/_process/streams.mjs";
|
} from "ext:deno_node/_process/streams.mjs";
|
||||||
import {
|
import {
|
||||||
enableNextTick,
|
enableNextTick,
|
||||||
|
@ -52,15 +54,42 @@ export let platform = "";
|
||||||
// TODO(kt3k): This should be set at start up time
|
// TODO(kt3k): This should be set at start up time
|
||||||
export let pid = 0;
|
export let pid = 0;
|
||||||
|
|
||||||
// TODO(kt3k): Give better types to stdio objects
|
// We want streams to be as lazy as possible, but we cannot export a getter in a module. To
|
||||||
// deno-lint-ignore no-explicit-any
|
// work around this we make these proxies that eagerly instantiate the underlying object on
|
||||||
let stderr = null as any;
|
// first access of any property/method.
|
||||||
// deno-lint-ignore no-explicit-any
|
function makeLazyStream<T>(objectFactory: () => T): T {
|
||||||
let stdin = null as any;
|
return new Proxy({}, {
|
||||||
// deno-lint-ignore no-explicit-any
|
get: function (_, prop, receiver) {
|
||||||
let stdout = null as any;
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.get(objectFactory() as any, prop, receiver);
|
||||||
|
},
|
||||||
|
has: function (_, prop) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.has(objectFactory() as any, prop);
|
||||||
|
},
|
||||||
|
ownKeys: function (_) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.ownKeys(objectFactory() as any);
|
||||||
|
},
|
||||||
|
set: function (_, prop, value, receiver) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.set(objectFactory() as any, prop, value, receiver);
|
||||||
|
},
|
||||||
|
getPrototypeOf: function (_) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.getPrototypeOf(objectFactory() as any);
|
||||||
|
},
|
||||||
|
getOwnPropertyDescriptor(_, prop) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return Reflect.getOwnPropertyDescriptor(objectFactory() as any, prop);
|
||||||
|
},
|
||||||
|
}) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export let stderr = makeLazyStream(getStderr);
|
||||||
|
export let stdin = makeLazyStream(getStdin);
|
||||||
|
export let stdout = makeLazyStream(getStdout);
|
||||||
|
|
||||||
export { stderr, stdin, stdout };
|
|
||||||
import { getBinding } from "ext:deno_node/internal_binding/mod.ts";
|
import { getBinding } from "ext:deno_node/internal_binding/mod.ts";
|
||||||
import * as constants from "ext:deno_node/internal_binding/constants.ts";
|
import * as constants from "ext:deno_node/internal_binding/constants.ts";
|
||||||
import * as uv from "ext:deno_node/internal_binding/uv.ts";
|
import * as uv from "ext:deno_node/internal_binding/uv.ts";
|
||||||
|
@ -605,13 +634,19 @@ class Process extends EventEmitter {
|
||||||
memoryUsage = memoryUsage;
|
memoryUsage = memoryUsage;
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_stderr */
|
/** https://nodejs.org/api/process.html#process_process_stderr */
|
||||||
stderr = stderr;
|
get stderr(): Writable {
|
||||||
|
return getStderr();
|
||||||
|
}
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_stdin */
|
/** https://nodejs.org/api/process.html#process_process_stdin */
|
||||||
stdin = stdin;
|
get stdin(): Readable {
|
||||||
|
return getStdin();
|
||||||
|
}
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_stdout */
|
/** https://nodejs.org/api/process.html#process_process_stdout */
|
||||||
stdout = stdout;
|
get stdout(): Writable {
|
||||||
|
return getStdout();
|
||||||
|
}
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_version */
|
/** https://nodejs.org/api/process.html#process_process_version */
|
||||||
version = version;
|
version = version;
|
||||||
|
@ -704,6 +739,115 @@ addReadOnlyProcessAlias("throwDeprecation", "--throw-deprecation");
|
||||||
export const removeListener = process.removeListener;
|
export const removeListener = process.removeListener;
|
||||||
export const removeAllListeners = process.removeAllListeners;
|
export const removeAllListeners = process.removeAllListeners;
|
||||||
|
|
||||||
|
let unhandledRejectionListenerCount = 0;
|
||||||
|
let uncaughtExceptionListenerCount = 0;
|
||||||
|
let beforeExitListenerCount = 0;
|
||||||
|
let exitListenerCount = 0;
|
||||||
|
|
||||||
|
process.on("newListener", (event: string) => {
|
||||||
|
switch (event) {
|
||||||
|
case "unhandledRejection":
|
||||||
|
unhandledRejectionListenerCount++;
|
||||||
|
break;
|
||||||
|
case "uncaughtException":
|
||||||
|
uncaughtExceptionListenerCount++;
|
||||||
|
break;
|
||||||
|
case "beforeExit":
|
||||||
|
beforeExitListenerCount++;
|
||||||
|
break;
|
||||||
|
case "exit":
|
||||||
|
exitListenerCount++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronizeListeners();
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on("removeListener", (event: string) => {
|
||||||
|
switch (event) {
|
||||||
|
case "unhandledRejection":
|
||||||
|
unhandledRejectionListenerCount--;
|
||||||
|
break;
|
||||||
|
case "uncaughtException":
|
||||||
|
uncaughtExceptionListenerCount--;
|
||||||
|
break;
|
||||||
|
case "beforeExit":
|
||||||
|
beforeExitListenerCount--;
|
||||||
|
break;
|
||||||
|
case "exit":
|
||||||
|
exitListenerCount--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronizeListeners();
|
||||||
|
});
|
||||||
|
|
||||||
|
function processOnError(event: ErrorEvent) {
|
||||||
|
if (process.listenerCount("uncaughtException") > 0) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
uncaughtExceptionHandler(event.error, "uncaughtException");
|
||||||
|
}
|
||||||
|
|
||||||
|
function processOnBeforeUnload(event: Event) {
|
||||||
|
process.emit("beforeExit", process.exitCode || 0);
|
||||||
|
processTicksAndRejections();
|
||||||
|
if (core.eventLoopHasMoreWork()) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processOnUnload() {
|
||||||
|
if (!process._exiting) {
|
||||||
|
process._exiting = true;
|
||||||
|
process.emit("exit", process.exitCode || 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function synchronizeListeners() {
|
||||||
|
// Install special "unhandledrejection" handler, that will be called
|
||||||
|
// last.
|
||||||
|
if (
|
||||||
|
unhandledRejectionListenerCount > 0 || uncaughtExceptionListenerCount > 0
|
||||||
|
) {
|
||||||
|
internals.nodeProcessUnhandledRejectionCallback = (event) => {
|
||||||
|
if (process.listenerCount("unhandledRejection") === 0) {
|
||||||
|
// The Node.js default behavior is to raise an uncaught exception if
|
||||||
|
// an unhandled rejection occurs and there are no unhandledRejection
|
||||||
|
// listeners.
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
uncaughtExceptionHandler(event.reason, "unhandledRejection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
process.emit("unhandledRejection", event.reason, event.promise);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
internals.nodeProcessUnhandledRejectionCallback = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uncaughtExceptionListenerCount > 0) {
|
||||||
|
globalThis.addEventListener("error", processOnError);
|
||||||
|
} else {
|
||||||
|
globalThis.removeEventListener("error", processOnError);
|
||||||
|
}
|
||||||
|
if (beforeExitListenerCount > 0) {
|
||||||
|
globalThis.addEventListener("beforeunload", processOnBeforeUnload);
|
||||||
|
} else {
|
||||||
|
globalThis.removeEventListener("beforeunload", processOnBeforeUnload);
|
||||||
|
}
|
||||||
|
if (exitListenerCount > 0) {
|
||||||
|
globalThis.addEventListener("unload", processOnUnload);
|
||||||
|
} else {
|
||||||
|
globalThis.removeEventListener("unload", processOnUnload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Should be called only once, in `runtime/js/99_main.js` when the runtime is
|
// Should be called only once, in `runtime/js/99_main.js` when the runtime is
|
||||||
// bootstrapped.
|
// bootstrapped.
|
||||||
internals.__bootstrapNodeProcess = function (
|
internals.__bootstrapNodeProcess = function (
|
||||||
|
@ -748,68 +892,52 @@ internals.__bootstrapNodeProcess = function (
|
||||||
core.setMacrotaskCallback(runNextTicks);
|
core.setMacrotaskCallback(runNextTicks);
|
||||||
enableNextTick();
|
enableNextTick();
|
||||||
|
|
||||||
// Install special "unhandledrejection" handler, that will be called
|
|
||||||
// last.
|
|
||||||
internals.nodeProcessUnhandledRejectionCallback = (event) => {
|
|
||||||
if (process.listenerCount("unhandledRejection") === 0) {
|
|
||||||
// The Node.js default behavior is to raise an uncaught exception if
|
|
||||||
// an unhandled rejection occurs and there are no unhandledRejection
|
|
||||||
// listeners.
|
|
||||||
if (process.listenerCount("uncaughtException") === 0) {
|
|
||||||
throw event.reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
uncaughtExceptionHandler(event.reason, "unhandledRejection");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
process.emit("unhandledRejection", event.reason, event.promise);
|
|
||||||
};
|
|
||||||
|
|
||||||
globalThis.addEventListener("error", (event) => {
|
|
||||||
if (process.listenerCount("uncaughtException") > 0) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
uncaughtExceptionHandler(event.error, "uncaughtException");
|
|
||||||
});
|
|
||||||
|
|
||||||
globalThis.addEventListener("beforeunload", (e) => {
|
|
||||||
process.emit("beforeExit", process.exitCode || 0);
|
|
||||||
processTicksAndRejections();
|
|
||||||
if (core.eventLoopHasMoreWork()) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
globalThis.addEventListener("unload", () => {
|
|
||||||
if (!process._exiting) {
|
|
||||||
process._exiting = true;
|
|
||||||
process.emit("exit", process.exitCode || 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initializes stdin
|
|
||||||
stdin = process.stdin = initStdin();
|
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_stderr */
|
|
||||||
stderr = process.stderr = createWritableStdioStream(
|
|
||||||
io.stderr,
|
|
||||||
"stderr",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** https://nodejs.org/api/process.html#process_process_stdout */
|
|
||||||
stdout = process.stdout = createWritableStdioStream(
|
|
||||||
io.stdout,
|
|
||||||
"stdout",
|
|
||||||
);
|
|
||||||
|
|
||||||
process.setStartTime(Date.now());
|
process.setStartTime(Date.now());
|
||||||
// @ts-ignore Remove setStartTime and #startTime is not modifiable
|
// @ts-ignore Remove setStartTime and #startTime is not modifiable
|
||||||
delete process.setStartTime;
|
delete process.setStartTime;
|
||||||
delete internals.__bootstrapNodeProcess;
|
delete internals.__bootstrapNodeProcess;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
let stderr_ = null as any;
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
let stdin_ = null as any;
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
let stdout_ = null as any;
|
||||||
|
|
||||||
|
function getStdin(): Readable {
|
||||||
|
if (!stdin_) {
|
||||||
|
stdin_ = initStdin();
|
||||||
|
stdin = stdin_;
|
||||||
|
Object.defineProperty(process, "stdin", { get: () => stdin_ });
|
||||||
|
}
|
||||||
|
return stdin_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** https://nodejs.org/api/process.html#process_process_stdout */
|
||||||
|
function getStdout(): Writable {
|
||||||
|
if (!stdout_) {
|
||||||
|
stdout_ = createWritableStdioStream(
|
||||||
|
io.stdout,
|
||||||
|
"stdout",
|
||||||
|
);
|
||||||
|
stdout = stdout_;
|
||||||
|
Object.defineProperty(process, "stdout", { get: () => stdout_ });
|
||||||
|
}
|
||||||
|
return stdout_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** https://nodejs.org/api/process.html#process_process_stderr */
|
||||||
|
function getStderr(): Writable {
|
||||||
|
if (!stderr_) {
|
||||||
|
stderr_ = createWritableStdioStream(
|
||||||
|
io.stderr,
|
||||||
|
"stderr",
|
||||||
|
);
|
||||||
|
stderr = stderr_;
|
||||||
|
Object.defineProperty(process, "stderr", { get: () => stderr_ });
|
||||||
|
}
|
||||||
|
return stderr_;
|
||||||
|
}
|
||||||
|
|
||||||
export default process;
|
export default process;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -128,10 +129,10 @@ impl NodeResolver {
|
||||||
self.npm_resolver.in_npm_package(specifier)
|
self.npm_resolver.in_npm_package(specifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn in_npm_package_with_cache(&self, specifier: String) -> bool {
|
pub fn in_npm_package_with_cache(&self, specifier: Cow<str>) -> bool {
|
||||||
let mut cache = self.in_npm_package_cache.lock();
|
let mut cache = self.in_npm_package_cache.lock();
|
||||||
|
|
||||||
if let Some(result) = cache.get(&specifier) {
|
if let Some(result) = cache.get(specifier.as_ref()) {
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ impl NodeResolver {
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
cache.insert(specifier, result);
|
cache.insert(specifier.into_owned(), result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -438,6 +438,7 @@ function bootstrapMainRuntime(runtimeOptions) {
|
||||||
if (hasBootstrapped) {
|
if (hasBootstrapped) {
|
||||||
throw new Error("Worker runtime already bootstrapped");
|
throw new Error("Worker runtime already bootstrapped");
|
||||||
}
|
}
|
||||||
|
const nodeBootstrap = globalThis.nodeBootstrap;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
0: args,
|
0: args,
|
||||||
|
@ -456,6 +457,8 @@ function bootstrapMainRuntime(runtimeOptions) {
|
||||||
13: userAgent,
|
13: userAgent,
|
||||||
14: inspectFlag,
|
14: inspectFlag,
|
||||||
// 15: enableTestingFeaturesFlag
|
// 15: enableTestingFeaturesFlag
|
||||||
|
16: hasNodeModulesDir,
|
||||||
|
17: maybeBinaryNpmCommandName,
|
||||||
} = runtimeOptions;
|
} = runtimeOptions;
|
||||||
|
|
||||||
performance.setTimeOrigin(DateNow());
|
performance.setTimeOrigin(DateNow());
|
||||||
|
@ -464,12 +467,13 @@ function bootstrapMainRuntime(runtimeOptions) {
|
||||||
// Remove bootstrapping data from the global scope
|
// Remove bootstrapping data from the global scope
|
||||||
delete globalThis.__bootstrap;
|
delete globalThis.__bootstrap;
|
||||||
delete globalThis.bootstrap;
|
delete globalThis.bootstrap;
|
||||||
|
delete globalThis.nodeBootstrap;
|
||||||
hasBootstrapped = true;
|
hasBootstrapped = true;
|
||||||
|
|
||||||
// If the `--location` flag isn't set, make `globalThis.location` `undefined` and
|
// If the `--location` flag isn't set, make `globalThis.location` `undefined` and
|
||||||
// writable, so that they can mock it themselves if they like. If the flag was
|
// writable, so that they can mock it themselves if they like. If the flag was
|
||||||
// set, define `globalThis.location`, using the provided value.
|
// set, define `globalThis.location`, using the provided value.
|
||||||
if (location_ === undefined) {
|
if (location_ == null) {
|
||||||
mainRuntimeGlobalProperties.location = {
|
mainRuntimeGlobalProperties.location = {
|
||||||
writable: true,
|
writable: true,
|
||||||
};
|
};
|
||||||
|
@ -542,6 +546,10 @@ function bootstrapMainRuntime(runtimeOptions) {
|
||||||
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
|
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
|
||||||
|
|
||||||
util.log("args", args);
|
util.log("args", args);
|
||||||
|
|
||||||
|
if (nodeBootstrap) {
|
||||||
|
nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bootstrapWorkerRuntime(
|
function bootstrapWorkerRuntime(
|
||||||
|
@ -553,6 +561,8 @@ function bootstrapWorkerRuntime(
|
||||||
throw new Error("Worker runtime already bootstrapped");
|
throw new Error("Worker runtime already bootstrapped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nodeBootstrap = globalThis.nodeBootstrap;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
0: args,
|
0: args,
|
||||||
1: cpuCount,
|
1: cpuCount,
|
||||||
|
@ -570,6 +580,8 @@ function bootstrapWorkerRuntime(
|
||||||
13: userAgent,
|
13: userAgent,
|
||||||
// 14: inspectFlag,
|
// 14: inspectFlag,
|
||||||
15: enableTestingFeaturesFlag,
|
15: enableTestingFeaturesFlag,
|
||||||
|
16: hasNodeModulesDir,
|
||||||
|
17: maybeBinaryNpmCommandName,
|
||||||
} = runtimeOptions;
|
} = runtimeOptions;
|
||||||
|
|
||||||
performance.setTimeOrigin(DateNow());
|
performance.setTimeOrigin(DateNow());
|
||||||
|
@ -580,6 +592,7 @@ function bootstrapWorkerRuntime(
|
||||||
// Remove bootstrapping data from the global scope
|
// Remove bootstrapping data from the global scope
|
||||||
delete globalThis.__bootstrap;
|
delete globalThis.__bootstrap;
|
||||||
delete globalThis.bootstrap;
|
delete globalThis.bootstrap;
|
||||||
|
delete globalThis.nodeBootstrap;
|
||||||
hasBootstrapped = true;
|
hasBootstrapped = true;
|
||||||
|
|
||||||
if (unstableFlag) {
|
if (unstableFlag) {
|
||||||
|
@ -649,6 +662,10 @@ function bootstrapWorkerRuntime(
|
||||||
// Setup `Deno` global - we're actually overriding already
|
// Setup `Deno` global - we're actually overriding already
|
||||||
// existing global `Deno` with `Deno` namespace from "./deno.ts".
|
// existing global `Deno` with `Deno` namespace from "./deno.ts".
|
||||||
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
|
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
|
||||||
|
|
||||||
|
if (nodeBootstrap) {
|
||||||
|
nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globalThis.bootstrap = {
|
globalThis.bootstrap = {
|
||||||
|
|
|
@ -13,7 +13,6 @@ use crate::web_worker::WorkerControlEvent;
|
||||||
use crate::web_worker::WorkerId;
|
use crate::web_worker::WorkerId;
|
||||||
use crate::worker::FormatJsErrorFn;
|
use crate::worker::FormatJsErrorFn;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::LocalFutureObj;
|
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::serde::Deserialize;
|
use deno_core::serde::Deserialize;
|
||||||
use deno_core::CancelFuture;
|
use deno_core::CancelFuture;
|
||||||
|
@ -40,10 +39,6 @@ pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, Sendable
|
||||||
+ Sync
|
+ Sync
|
||||||
+ Send;
|
+ Send;
|
||||||
|
|
||||||
pub type WorkerEventCb = dyn Fn(WebWorker) -> LocalFutureObj<'static, Result<WebWorker, AnyError>>
|
|
||||||
+ Sync
|
|
||||||
+ Send;
|
|
||||||
|
|
||||||
/// A holder for callback that is used to create a new
|
/// A holder for callback that is used to create a new
|
||||||
/// WebWorker. It's a struct instead of a type alias
|
/// WebWorker. It's a struct instead of a type alias
|
||||||
/// because `GothamState` used in `OpState` overrides
|
/// because `GothamState` used in `OpState` overrides
|
||||||
|
@ -54,12 +49,6 @@ struct CreateWebWorkerCbHolder(Arc<CreateWebWorkerCb>);
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct FormatJsErrorFnHolder(Option<Arc<FormatJsErrorFn>>);
|
struct FormatJsErrorFnHolder(Option<Arc<FormatJsErrorFn>>);
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct PreloadModuleCbHolder(Arc<WorkerEventCb>);
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct PreExecuteModuleCbHolder(Arc<WorkerEventCb>);
|
|
||||||
|
|
||||||
pub struct WorkerThread {
|
pub struct WorkerThread {
|
||||||
worker_handle: WebWorkerHandle,
|
worker_handle: WebWorkerHandle,
|
||||||
cancel_handle: Rc<CancelHandle>,
|
cancel_handle: Rc<CancelHandle>,
|
||||||
|
@ -98,8 +87,6 @@ deno_core::extension!(
|
||||||
],
|
],
|
||||||
options = {
|
options = {
|
||||||
create_web_worker_cb: Arc<CreateWebWorkerCb>,
|
create_web_worker_cb: Arc<CreateWebWorkerCb>,
|
||||||
preload_module_cb: Arc<WorkerEventCb>,
|
|
||||||
pre_execute_module_cb: Arc<WorkerEventCb>,
|
|
||||||
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
||||||
},
|
},
|
||||||
state = |state, options| {
|
state = |state, options| {
|
||||||
|
@ -109,12 +96,6 @@ deno_core::extension!(
|
||||||
let create_web_worker_cb_holder =
|
let create_web_worker_cb_holder =
|
||||||
CreateWebWorkerCbHolder(options.create_web_worker_cb);
|
CreateWebWorkerCbHolder(options.create_web_worker_cb);
|
||||||
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb_holder);
|
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb_holder);
|
||||||
let preload_module_cb_holder =
|
|
||||||
PreloadModuleCbHolder(options.preload_module_cb);
|
|
||||||
state.put::<PreloadModuleCbHolder>(preload_module_cb_holder);
|
|
||||||
let pre_execute_module_cb_holder =
|
|
||||||
PreExecuteModuleCbHolder(options.pre_execute_module_cb);
|
|
||||||
state.put::<PreExecuteModuleCbHolder>(pre_execute_module_cb_holder);
|
|
||||||
let format_js_error_fn_holder =
|
let format_js_error_fn_holder =
|
||||||
FormatJsErrorFnHolder(options.format_js_error_fn);
|
FormatJsErrorFnHolder(options.format_js_error_fn);
|
||||||
state.put::<FormatJsErrorFnHolder>(format_js_error_fn_holder);
|
state.put::<FormatJsErrorFnHolder>(format_js_error_fn_holder);
|
||||||
|
@ -174,10 +155,6 @@ fn op_create_worker(
|
||||||
let worker_id = state.take::<WorkerId>();
|
let worker_id = state.take::<WorkerId>();
|
||||||
let create_web_worker_cb = state.take::<CreateWebWorkerCbHolder>();
|
let create_web_worker_cb = state.take::<CreateWebWorkerCbHolder>();
|
||||||
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb.clone());
|
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb.clone());
|
||||||
let preload_module_cb = state.take::<PreloadModuleCbHolder>();
|
|
||||||
state.put::<PreloadModuleCbHolder>(preload_module_cb.clone());
|
|
||||||
let pre_execute_module_cb = state.take::<PreExecuteModuleCbHolder>();
|
|
||||||
state.put::<PreExecuteModuleCbHolder>(pre_execute_module_cb.clone());
|
|
||||||
let format_js_error_fn = state.take::<FormatJsErrorFnHolder>();
|
let format_js_error_fn = state.take::<FormatJsErrorFnHolder>();
|
||||||
state.put::<FormatJsErrorFnHolder>(format_js_error_fn.clone());
|
state.put::<FormatJsErrorFnHolder>(format_js_error_fn.clone());
|
||||||
state.put::<WorkerId>(worker_id.next().unwrap());
|
state.put::<WorkerId>(worker_id.next().unwrap());
|
||||||
|
@ -221,8 +198,6 @@ fn op_create_worker(
|
||||||
worker,
|
worker,
|
||||||
module_specifier,
|
module_specifier,
|
||||||
maybe_source_code,
|
maybe_source_code,
|
||||||
preload_module_cb.0,
|
|
||||||
pre_execute_module_cb.0,
|
|
||||||
format_js_error_fn.0,
|
format_js_error_fn.0,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -338,8 +338,6 @@ pub struct WebWorkerOptions {
|
||||||
pub module_loader: Rc<dyn ModuleLoader>,
|
pub module_loader: Rc<dyn ModuleLoader>,
|
||||||
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
|
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
|
||||||
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
|
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
|
||||||
pub preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
pub pre_execute_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
pub format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
pub format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
||||||
pub source_map_getter: Option<Box<dyn SourceMapGetter>>,
|
pub source_map_getter: Option<Box<dyn SourceMapGetter>>,
|
||||||
pub worker_type: WebWorkerType,
|
pub worker_type: WebWorkerType,
|
||||||
|
@ -460,8 +458,6 @@ impl WebWorker {
|
||||||
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
|
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
|
||||||
ops::worker_host::deno_worker_host::init_ops_and_esm(
|
ops::worker_host::deno_worker_host::init_ops_and_esm(
|
||||||
options.create_web_worker_cb.clone(),
|
options.create_web_worker_cb.clone(),
|
||||||
options.preload_module_cb.clone(),
|
|
||||||
options.pre_execute_module_cb.clone(),
|
|
||||||
options.format_js_error_fn.clone(),
|
options.format_js_error_fn.clone(),
|
||||||
),
|
),
|
||||||
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
||||||
|
@ -600,7 +596,7 @@ impl WebWorker {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into();
|
.into();
|
||||||
bootstrap_fn
|
bootstrap_fn
|
||||||
.call(scope, undefined.into(), &[args.into(), name_str, id_str])
|
.call(scope, undefined.into(), &[args, name_str, id_str])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
// TODO(bartlomieju): this could be done using V8 API, without calling `execute_script`.
|
// TODO(bartlomieju): this could be done using V8 API, without calling `execute_script`.
|
||||||
|
@ -782,11 +778,9 @@ fn print_worker_error(
|
||||||
/// This function should be called from a thread dedicated to this worker.
|
/// This function should be called from a thread dedicated to this worker.
|
||||||
// TODO(bartlomieju): check if order of actions is aligned to Worker spec
|
// TODO(bartlomieju): check if order of actions is aligned to Worker spec
|
||||||
pub fn run_web_worker(
|
pub fn run_web_worker(
|
||||||
worker: WebWorker,
|
mut worker: WebWorker,
|
||||||
specifier: ModuleSpecifier,
|
specifier: ModuleSpecifier,
|
||||||
mut maybe_source_code: Option<String>,
|
mut maybe_source_code: Option<String>,
|
||||||
preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
pre_execute_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let name = worker.name.to_string();
|
let name = worker.name.to_string();
|
||||||
|
@ -796,20 +790,6 @@ pub fn run_web_worker(
|
||||||
|
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let internal_handle = worker.internal_handle.clone();
|
let internal_handle = worker.internal_handle.clone();
|
||||||
let result = (preload_module_cb)(worker).await;
|
|
||||||
|
|
||||||
let mut worker = match result {
|
|
||||||
Ok(worker) => worker,
|
|
||||||
Err(e) => {
|
|
||||||
print_worker_error(&e, &name, format_js_error_fn.as_deref());
|
|
||||||
internal_handle
|
|
||||||
.post_event(WorkerControlEvent::TerminalError(e))
|
|
||||||
.expect("Failed to post message to host");
|
|
||||||
|
|
||||||
// Failure to execute script is a terminal error, bye, bye.
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Execute provided source code immediately
|
// Execute provided source code immediately
|
||||||
let result = if let Some(source_code) = maybe_source_code.take() {
|
let result = if let Some(source_code) = maybe_source_code.take() {
|
||||||
|
@ -821,18 +801,6 @@ pub fn run_web_worker(
|
||||||
// script instead of module
|
// script instead of module
|
||||||
match worker.preload_main_module(&specifier).await {
|
match worker.preload_main_module(&specifier).await {
|
||||||
Ok(id) => {
|
Ok(id) => {
|
||||||
worker = match (pre_execute_module_cb)(worker).await {
|
|
||||||
Ok(worker) => worker,
|
|
||||||
Err(e) => {
|
|
||||||
print_worker_error(&e, &name, format_js_error_fn.as_deref());
|
|
||||||
internal_handle
|
|
||||||
.post_event(WorkerControlEvent::TerminalError(e))
|
|
||||||
.expect("Failed to post message to host");
|
|
||||||
|
|
||||||
// Failure to execute script is a terminal error, bye, bye.
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
worker.start_polling_for_messages();
|
worker.start_polling_for_messages();
|
||||||
worker.execute_main_module(id).await
|
worker.execute_main_module(id).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,8 +178,6 @@ pub struct WorkerOptions {
|
||||||
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
|
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
|
||||||
// Callbacks invoked when creating new instance of WebWorker
|
// Callbacks invoked when creating new instance of WebWorker
|
||||||
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
|
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
|
||||||
pub web_worker_preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
pub web_worker_pre_execute_module_cb: Arc<ops::worker_host::WorkerEventCb>,
|
|
||||||
pub format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
pub format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
|
||||||
|
|
||||||
/// Source map reference for errors.
|
/// Source map reference for errors.
|
||||||
|
@ -221,12 +219,6 @@ pub struct WorkerOptions {
|
||||||
impl Default for WorkerOptions {
|
impl Default for WorkerOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
web_worker_preload_module_cb: Arc::new(|_| {
|
|
||||||
unimplemented!("web workers are not supported")
|
|
||||||
}),
|
|
||||||
web_worker_pre_execute_module_cb: Arc::new(|_| {
|
|
||||||
unimplemented!("web workers are not supported")
|
|
||||||
}),
|
|
||||||
create_web_worker_cb: Arc::new(|_| {
|
create_web_worker_cb: Arc::new(|_| {
|
||||||
unimplemented!("web workers are not supported")
|
unimplemented!("web workers are not supported")
|
||||||
}),
|
}),
|
||||||
|
@ -362,8 +354,6 @@ impl MainWorker {
|
||||||
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
|
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
|
||||||
ops::worker_host::deno_worker_host::init_ops_and_esm(
|
ops::worker_host::deno_worker_host::init_ops_and_esm(
|
||||||
options.create_web_worker_cb.clone(),
|
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(),
|
options.format_js_error_fn.clone(),
|
||||||
),
|
),
|
||||||
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
ops::fs_events::deno_fs_events::init_ops_and_esm(),
|
||||||
|
@ -478,9 +468,7 @@ impl MainWorker {
|
||||||
let bootstrap_fn = self.bootstrap_fn_global.take().unwrap();
|
let bootstrap_fn = self.bootstrap_fn_global.take().unwrap();
|
||||||
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
|
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
|
||||||
let undefined = v8::undefined(scope);
|
let undefined = v8::undefined(scope);
|
||||||
bootstrap_fn
|
bootstrap_fn.call(scope, undefined.into(), &[args]).unwrap();
|
||||||
.call(scope, undefined.into(), &[args.into()])
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
|
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
|
@ -55,6 +57,8 @@ pub struct BootstrapOptions {
|
||||||
pub unstable: bool,
|
pub unstable: bool,
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
pub inspect: bool,
|
pub inspect: bool,
|
||||||
|
pub has_node_modules_dir: bool,
|
||||||
|
pub maybe_binary_npm_command_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BootstrapOptions {
|
impl Default for BootstrapOptions {
|
||||||
|
@ -80,135 +84,91 @@ impl Default for BootstrapOptions {
|
||||||
unstable: Default::default(),
|
unstable: Default::default(),
|
||||||
inspect: Default::default(),
|
inspect: Default::default(),
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
|
has_node_modules_dir: Default::default(),
|
||||||
|
maybe_binary_npm_command_name: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is a struct that we use to serialize the contents of the `BootstrapOptions`
|
||||||
|
/// struct above to a V8 form. While `serde_v8` is not as fast as hand-coding this,
|
||||||
|
/// it's "fast enough" while serializing a large tuple like this that it doesn't appear
|
||||||
|
/// on flamegraphs.
|
||||||
|
///
|
||||||
|
/// Note that a few fields in here are derived from the process and environment and
|
||||||
|
/// are not sourced from the underlying `BootstrapOptions`.
|
||||||
|
///
|
||||||
|
/// Keep this in sync with `99_main.js`.
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct BootstrapV8<'a>(
|
||||||
|
// args
|
||||||
|
&'a Vec<String>,
|
||||||
|
// cpu_count
|
||||||
|
i32,
|
||||||
|
// log_level
|
||||||
|
i32,
|
||||||
|
// runtime_version
|
||||||
|
&'a str,
|
||||||
|
// locale
|
||||||
|
&'a str,
|
||||||
|
// location
|
||||||
|
Option<&'a str>,
|
||||||
|
// no_color
|
||||||
|
bool,
|
||||||
|
// is_tty
|
||||||
|
bool,
|
||||||
|
// ts_version
|
||||||
|
&'a str,
|
||||||
|
// unstable
|
||||||
|
bool,
|
||||||
|
// process_id
|
||||||
|
i32,
|
||||||
|
// env!("TARGET")
|
||||||
|
&'a str,
|
||||||
|
// v8_version
|
||||||
|
&'a str,
|
||||||
|
// user_agent
|
||||||
|
&'a str,
|
||||||
|
// inspect
|
||||||
|
bool,
|
||||||
|
// enable_testing_features
|
||||||
|
bool,
|
||||||
|
// has_node_modules_dir
|
||||||
|
bool,
|
||||||
|
// maybe_binary_npm_command_name
|
||||||
|
Option<&'a str>,
|
||||||
|
);
|
||||||
|
|
||||||
impl BootstrapOptions {
|
impl BootstrapOptions {
|
||||||
|
/// Return the v8 equivalent of this structure.
|
||||||
pub fn as_v8<'s>(
|
pub fn as_v8<'s>(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
) -> v8::Local<'s, v8::Array> {
|
) -> v8::Local<'s, v8::Value> {
|
||||||
let array = v8::Array::new(scope, 16);
|
let scope = RefCell::new(scope);
|
||||||
|
let ser = deno_core::serde_v8::Serializer::new(&scope);
|
||||||
|
|
||||||
{
|
let bootstrap = BootstrapV8(
|
||||||
let args = v8::Array::new(scope, self.args.len() as i32);
|
&self.args,
|
||||||
for (idx, arg) in self.args.iter().enumerate() {
|
self.cpu_count as _,
|
||||||
let arg_str = v8::String::new(scope, arg).unwrap();
|
self.log_level as _,
|
||||||
args.set_index(scope, idx as u32, arg_str.into());
|
&self.runtime_version,
|
||||||
}
|
&self.locale,
|
||||||
array.set_index(scope, 0, args.into());
|
self.location.as_ref().map(|l| l.as_str()),
|
||||||
}
|
self.no_color,
|
||||||
|
self.is_tty,
|
||||||
|
&self.ts_version,
|
||||||
|
self.unstable,
|
||||||
|
std::process::id() as _,
|
||||||
|
env!("TARGET"),
|
||||||
|
deno_core::v8_version(),
|
||||||
|
&self.user_agent,
|
||||||
|
self.inspect,
|
||||||
|
self.enable_testing_features,
|
||||||
|
self.has_node_modules_dir,
|
||||||
|
self.maybe_binary_npm_command_name.as_deref(),
|
||||||
|
);
|
||||||
|
|
||||||
{
|
bootstrap.serialize(ser).unwrap()
|
||||||
let val = v8::Integer::new(scope, self.cpu_count as i32);
|
|
||||||
array.set_index(scope, 1, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Integer::new(scope, self.log_level as i32);
|
|
||||||
array.set_index(scope, 2, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_from_one_byte(
|
|
||||||
scope,
|
|
||||||
self.runtime_version.as_bytes(),
|
|
||||||
v8::NewStringType::Internalized,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 3, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_from_one_byte(
|
|
||||||
scope,
|
|
||||||
self.locale.as_bytes(),
|
|
||||||
v8::NewStringType::Normal,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 4, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val: v8::Local<v8::Value> = if let Some(location) = &self.location {
|
|
||||||
v8::String::new(scope, location.as_str()).unwrap().into()
|
|
||||||
} else {
|
|
||||||
v8::undefined(scope).into()
|
|
||||||
};
|
|
||||||
|
|
||||||
array.set_index(scope, 5, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Boolean::new(scope, self.no_color);
|
|
||||||
array.set_index(scope, 6, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Boolean::new(scope, self.is_tty);
|
|
||||||
array.set_index(scope, 7, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_from_one_byte(
|
|
||||||
scope,
|
|
||||||
self.ts_version.as_bytes(),
|
|
||||||
v8::NewStringType::Normal,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 8, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Boolean::new(scope, self.unstable);
|
|
||||||
array.set_index(scope, 9, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Integer::new(scope, std::process::id() as i32);
|
|
||||||
array.set_index(scope, 10, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_external_onebyte_static(
|
|
||||||
scope,
|
|
||||||
env!("TARGET").as_bytes(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 11, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_from_one_byte(
|
|
||||||
scope,
|
|
||||||
deno_core::v8_version().as_bytes(),
|
|
||||||
v8::NewStringType::Normal,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 12, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::String::new_from_one_byte(
|
|
||||||
scope,
|
|
||||||
self.user_agent.as_bytes(),
|
|
||||||
v8::NewStringType::Normal,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
array.set_index(scope, 13, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Boolean::new(scope, self.inspect);
|
|
||||||
array.set_index(scope, 14, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let val = v8::Boolean::new(scope, self.enable_testing_features);
|
|
||||||
array.set_index(scope, 15, val.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
array
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue