summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/js/99_main.js19
-rw-r--r--runtime/ops/worker_host.rs25
-rw-r--r--runtime/web_worker.rs36
-rw-r--r--runtime/worker.rs14
-rw-r--r--runtime/worker_bootstrap.rs204
5 files changed, 103 insertions, 195 deletions
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index c8fdabc25..fdd82862c 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -438,6 +438,7 @@ function bootstrapMainRuntime(runtimeOptions) {
if (hasBootstrapped) {
throw new Error("Worker runtime already bootstrapped");
}
+ const nodeBootstrap = globalThis.nodeBootstrap;
const {
0: args,
@@ -456,6 +457,8 @@ function bootstrapMainRuntime(runtimeOptions) {
13: userAgent,
14: inspectFlag,
// 15: enableTestingFeaturesFlag
+ 16: hasNodeModulesDir,
+ 17: maybeBinaryNpmCommandName,
} = runtimeOptions;
performance.setTimeOrigin(DateNow());
@@ -464,12 +467,13 @@ function bootstrapMainRuntime(runtimeOptions) {
// Remove bootstrapping data from the global scope
delete globalThis.__bootstrap;
delete globalThis.bootstrap;
+ delete globalThis.nodeBootstrap;
hasBootstrapped = true;
// 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
// set, define `globalThis.location`, using the provided value.
- if (location_ === undefined) {
+ if (location_ == null) {
mainRuntimeGlobalProperties.location = {
writable: true,
};
@@ -542,6 +546,10 @@ function bootstrapMainRuntime(runtimeOptions) {
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
util.log("args", args);
+
+ if (nodeBootstrap) {
+ nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName);
+ }
}
function bootstrapWorkerRuntime(
@@ -553,6 +561,8 @@ function bootstrapWorkerRuntime(
throw new Error("Worker runtime already bootstrapped");
}
+ const nodeBootstrap = globalThis.nodeBootstrap;
+
const {
0: args,
1: cpuCount,
@@ -570,6 +580,8 @@ function bootstrapWorkerRuntime(
13: userAgent,
// 14: inspectFlag,
15: enableTestingFeaturesFlag,
+ 16: hasNodeModulesDir,
+ 17: maybeBinaryNpmCommandName,
} = runtimeOptions;
performance.setTimeOrigin(DateNow());
@@ -580,6 +592,7 @@ function bootstrapWorkerRuntime(
// Remove bootstrapping data from the global scope
delete globalThis.__bootstrap;
delete globalThis.bootstrap;
+ delete globalThis.nodeBootstrap;
hasBootstrapped = true;
if (unstableFlag) {
@@ -649,6 +662,10 @@ function bootstrapWorkerRuntime(
// Setup `Deno` global - we're actually overriding already
// existing global `Deno` with `Deno` namespace from "./deno.ts".
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
+
+ if (nodeBootstrap) {
+ nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName);
+ }
}
globalThis.bootstrap = {
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index f96ae38e8..9bfbd9d10 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -13,7 +13,6 @@ use crate::web_worker::WorkerControlEvent;
use crate::web_worker::WorkerId;
use crate::worker::FormatJsErrorFn;
use deno_core::error::AnyError;
-use deno_core::futures::future::LocalFutureObj;
use deno_core::op;
use deno_core::serde::Deserialize;
use deno_core::CancelFuture;
@@ -40,10 +39,6 @@ pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, Sendable
+ Sync
+ 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
/// WebWorker. It's a struct instead of a type alias
/// because `GothamState` used in `OpState` overrides
@@ -54,12 +49,6 @@ struct CreateWebWorkerCbHolder(Arc<CreateWebWorkerCb>);
#[derive(Clone)]
struct FormatJsErrorFnHolder(Option<Arc<FormatJsErrorFn>>);
-#[derive(Clone)]
-struct PreloadModuleCbHolder(Arc<WorkerEventCb>);
-
-#[derive(Clone)]
-struct PreExecuteModuleCbHolder(Arc<WorkerEventCb>);
-
pub struct WorkerThread {
worker_handle: WebWorkerHandle,
cancel_handle: Rc<CancelHandle>,
@@ -98,8 +87,6 @@ deno_core::extension!(
],
options = {
create_web_worker_cb: Arc<CreateWebWorkerCb>,
- preload_module_cb: Arc<WorkerEventCb>,
- pre_execute_module_cb: Arc<WorkerEventCb>,
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
},
state = |state, options| {
@@ -109,12 +96,6 @@ deno_core::extension!(
let create_web_worker_cb_holder =
CreateWebWorkerCbHolder(options.create_web_worker_cb);
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 =
FormatJsErrorFnHolder(options.format_js_error_fn);
state.put::<FormatJsErrorFnHolder>(format_js_error_fn_holder);
@@ -174,10 +155,6 @@ fn op_create_worker(
let worker_id = state.take::<WorkerId>();
let create_web_worker_cb = state.take::<CreateWebWorkerCbHolder>();
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>();
state.put::<FormatJsErrorFnHolder>(format_js_error_fn.clone());
state.put::<WorkerId>(worker_id.next().unwrap());
@@ -221,8 +198,6 @@ fn op_create_worker(
worker,
module_specifier,
maybe_source_code,
- preload_module_cb.0,
- pre_execute_module_cb.0,
format_js_error_fn.0,
)
})?;
diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs
index a3b93836c..0c4e95140 100644
--- a/runtime/web_worker.rs
+++ b/runtime/web_worker.rs
@@ -338,8 +338,6 @@ pub struct WebWorkerOptions {
pub module_loader: Rc<dyn ModuleLoader>,
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
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 source_map_getter: Option<Box<dyn SourceMapGetter>>,
pub worker_type: WebWorkerType,
@@ -460,8 +458,6 @@ impl WebWorker {
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
ops::worker_host::deno_worker_host::init_ops_and_esm(
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_and_esm(),
@@ -600,7 +596,7 @@ impl WebWorker {
.unwrap()
.into();
bootstrap_fn
- .call(scope, undefined.into(), &[args.into(), name_str, id_str])
+ .call(scope, undefined.into(), &[args, name_str, id_str])
.unwrap();
}
// 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.
// TODO(bartlomieju): check if order of actions is aligned to Worker spec
pub fn run_web_worker(
- worker: WebWorker,
+ mut worker: WebWorker,
specifier: ModuleSpecifier,
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>>,
) -> Result<(), AnyError> {
let name = worker.name.to_string();
@@ -796,20 +790,6 @@ pub fn run_web_worker(
let fut = async move {
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
let result = if let Some(source_code) = maybe_source_code.take() {
@@ -821,18 +801,6 @@ pub fn run_web_worker(
// script instead of module
match worker.preload_main_module(&specifier).await {
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.execute_main_module(id).await
}
diff --git a/runtime/worker.rs b/runtime/worker.rs
index 060f5537b..5eefd5fa8 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -178,8 +178,6 @@ pub struct WorkerOptions {
pub npm_resolver: Option<Arc<dyn deno_node::NpmResolver>>,
// Callbacks invoked when creating new instance of WebWorker
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>>,
/// Source map reference for errors.
@@ -221,12 +219,6 @@ pub struct WorkerOptions {
impl Default for WorkerOptions {
fn default() -> 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(|_| {
unimplemented!("web workers are not supported")
}),
@@ -362,8 +354,6 @@ impl MainWorker {
ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()),
ops::worker_host::deno_worker_host::init_ops_and_esm(
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_and_esm(),
@@ -478,9 +468,7 @@ impl MainWorker {
let bootstrap_fn = self.bootstrap_fn_global.take().unwrap();
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
let undefined = v8::undefined(scope);
- bootstrap_fn
- .call(scope, undefined.into(), &[args.into()])
- .unwrap();
+ bootstrap_fn.call(scope, undefined.into(), &[args]).unwrap();
}
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs
index 9627281a6..0f533344f 100644
--- a/runtime/worker_bootstrap.rs
+++ b/runtime/worker_bootstrap.rs
@@ -2,6 +2,8 @@
use deno_core::v8;
use deno_core::ModuleSpecifier;
+use serde::Serialize;
+use std::cell::RefCell;
use std::thread;
use crate::colors;
@@ -55,6 +57,8 @@ pub struct BootstrapOptions {
pub unstable: bool,
pub user_agent: String,
pub inspect: bool,
+ pub has_node_modules_dir: bool,
+ pub maybe_binary_npm_command_name: Option<String>,
}
impl Default for BootstrapOptions {
@@ -80,135 +84,91 @@ impl Default for BootstrapOptions {
unstable: Default::default(),
inspect: 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 {
+ /// Return the v8 equivalent of this structure.
pub fn as_v8<'s>(
&self,
scope: &mut v8::HandleScope<'s>,
- ) -> v8::Local<'s, v8::Array> {
- let array = v8::Array::new(scope, 16);
-
- {
- let args = v8::Array::new(scope, self.args.len() as i32);
- for (idx, arg) in self.args.iter().enumerate() {
- let arg_str = v8::String::new(scope, arg).unwrap();
- args.set_index(scope, idx as u32, arg_str.into());
- }
- array.set_index(scope, 0, args.into());
- }
-
- {
- 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
+ ) -> v8::Local<'s, v8::Value> {
+ let scope = RefCell::new(scope);
+ let ser = deno_core::serde_v8::Serializer::new(&scope);
+
+ let bootstrap = BootstrapV8(
+ &self.args,
+ self.cpu_count as _,
+ self.log_level as _,
+ &self.runtime_version,
+ &self.locale,
+ 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()
}
}