summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tools/bench/mod.rs7
-rw-r--r--cli/tools/test/mod.rs6
-rw-r--r--cli/worker.rs31
-rw-r--r--runtime/js/99_main.js17
-rw-r--r--runtime/worker.rs122
5 files changed, 112 insertions, 71 deletions
diff --git a/cli/tools/bench/mod.rs b/cli/tools/bench/mod.rs
index 8663fbbc8..88bff479c 100644
--- a/cli/tools/bench/mod.rs
+++ b/cli/tools/bench/mod.rs
@@ -26,7 +26,6 @@ use deno_core::error::JsError;
use deno_core::futures::future;
use deno_core::futures::stream;
use deno_core::futures::StreamExt;
-use deno_core::located_script_name;
use deno_core::serde_v8;
use deno_core::unsync::spawn;
use deno_core::unsync::spawn_blocking;
@@ -220,7 +219,7 @@ async fn bench_specifier_inner(
// Ensure that there are no pending exceptions before we start running tests
worker.run_up_to_duration(Duration::from_millis(0)).await?;
- worker.dispatch_load_event(located_script_name!())?;
+ worker.dispatch_load_event()?;
let benchmarks = {
let state_rc = worker.js_runtime.op_state();
@@ -269,8 +268,8 @@ async fn bench_specifier_inner(
// Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the
// event loop to continue beyond what's needed to await results.
- worker.dispatch_beforeunload_event(located_script_name!())?;
- worker.dispatch_unload_event(located_script_name!())?;
+ worker.dispatch_beforeunload_event()?;
+ worker.dispatch_unload_event()?;
// Ensure the worker has settled so we can catch any remaining unhandled rejections. We don't
// want to wait forever here.
diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs
index 2c7241de1..2a406e560 100644
--- a/cli/tools/test/mod.rs
+++ b/cli/tools/test/mod.rs
@@ -654,15 +654,15 @@ async fn test_specifier_inner(
// Ensure that there are no pending exceptions before we start running tests
worker.run_up_to_duration(Duration::from_millis(0)).await?;
- worker.dispatch_load_event(located_script_name!())?;
+ worker.dispatch_load_event()?;
run_tests_for_worker(&mut worker, &specifier, &options, &fail_fast_tracker)
.await?;
// Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the
// event loop to continue beyond what's needed to await results.
- worker.dispatch_beforeunload_event(located_script_name!())?;
- worker.dispatch_unload_event(located_script_name!())?;
+ worker.dispatch_beforeunload_event()?;
+ worker.dispatch_unload_event()?;
// Ensure all output has been flushed
_ = sender.flush();
diff --git a/cli/worker.rs b/cli/worker.rs
index ed82f4872..74ae1ef8f 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -10,7 +10,6 @@ use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
-use deno_core::located_script_name;
use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use deno_core::v8;
@@ -182,7 +181,7 @@ impl CliMainWorker {
self.execute_main_module_possibly_with_npm().await?;
}
- self.worker.dispatch_load_event(located_script_name!())?;
+ self.worker.dispatch_load_event()?;
loop {
if let Some(hmr_runner) = maybe_hmr_runner.as_mut() {
@@ -213,15 +212,12 @@ impl CliMainWorker {
.await?;
}
- if !self
- .worker
- .dispatch_beforeunload_event(located_script_name!())?
- {
+ if !self.worker.dispatch_beforeunload_event()? {
break;
}
}
- self.worker.dispatch_unload_event(located_script_name!())?;
+ self.worker.dispatch_unload_event()?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
self
@@ -268,10 +264,7 @@ impl CliMainWorker {
/// respectively.
pub async fn execute(&mut self) -> Result<(), AnyError> {
self.inner.execute_main_module_possibly_with_npm().await?;
- self
- .inner
- .worker
- .dispatch_load_event(located_script_name!())?;
+ self.inner.worker.dispatch_load_event()?;
self.pending_unload = true;
let result = loop {
@@ -279,11 +272,7 @@ impl CliMainWorker {
Ok(()) => {}
Err(error) => break Err(error),
}
- match self
- .inner
- .worker
- .dispatch_beforeunload_event(located_script_name!())
- {
+ match self.inner.worker.dispatch_beforeunload_event() {
Ok(default_prevented) if default_prevented => {} // continue loop
Ok(_) => break Ok(()),
Err(error) => break Err(error),
@@ -293,10 +282,7 @@ impl CliMainWorker {
result?;
- self
- .inner
- .worker
- .dispatch_unload_event(located_script_name!())?;
+ self.inner.worker.dispatch_unload_event()?;
Ok(())
}
@@ -305,10 +291,7 @@ impl CliMainWorker {
impl Drop for FileWatcherModuleExecutor {
fn drop(&mut self) {
if self.pending_unload {
- let _ = self
- .inner
- .worker
- .dispatch_unload_event(located_script_name!());
+ let _ = self.inner.worker.dispatch_unload_event();
}
}
}
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index e5b9b9778..0241a1936 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -528,6 +528,20 @@ function processRejectionHandled(promise, reason) {
}
}
+function dispatchLoadEvent() {
+ globalThis_.dispatchEvent(new Event("load"));
+}
+
+function dispatchBeforeUnloadEvent() {
+ return globalThis_.dispatchEvent(
+ new Event("beforeunload", { cancelable: true }),
+ );
+}
+
+function dispatchUnloadEvent() {
+ globalThis_.dispatchEvent(new Event("unload"));
+}
+
let hasBootstrapped = false;
// Delete the `console` object that V8 automaticaly adds onto the global wrapper
// object on context creation. We don't want this console object to shadow the
@@ -995,6 +1009,9 @@ delete globalThis.nodeBootstrap;
globalThis.bootstrap = {
mainRuntime: bootstrapMainRuntime,
workerRuntime: bootstrapWorkerRuntime,
+ dispatchLoadEvent,
+ dispatchUnloadEvent,
+ dispatchBeforeUnloadEvent,
};
event.setEventTargetData(globalThis);
diff --git a/runtime/worker.rs b/runtime/worker.rs
index 2fb32c766..236777335 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -11,7 +11,6 @@ use std::time::Instant;
use deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_cache::CreateCache;
use deno_cache::SqliteBackedCache;
-use deno_core::ascii_str;
use deno_core::error::AnyError;
use deno_core::error::JsError;
use deno_core::merge_op_metrics;
@@ -115,6 +114,9 @@ pub struct MainWorker {
should_wait_for_inspector_session: bool,
exit_code: ExitCode,
bootstrap_fn_global: Option<v8::Global<v8::Function>>,
+ dispatch_load_event_fn_global: v8::Global<v8::Function>,
+ dispatch_beforeunload_event_fn_global: v8::Global<v8::Function>,
+ dispatch_unload_event_fn_global: v8::Global<v8::Function>,
}
pub struct WorkerOptions {
@@ -523,7 +525,12 @@ impl MainWorker {
let inspector = js_runtime.inspector();
op_state.borrow_mut().put(inspector);
}
- let bootstrap_fn_global = {
+ let (
+ bootstrap_fn_global,
+ dispatch_load_event_fn_global,
+ dispatch_beforeunload_event_fn_global,
+ dispatch_unload_event_fn_global,
+ ) = {
let context = js_runtime.main_context();
let scope = &mut js_runtime.handle_scope();
let context_local = v8::Local::new(scope, context);
@@ -541,7 +548,40 @@ impl MainWorker {
bootstrap_ns.get(scope, main_runtime_str.into()).unwrap();
let bootstrap_fn =
v8::Local::<v8::Function>::try_from(bootstrap_fn).unwrap();
- v8::Global::new(scope, bootstrap_fn)
+ let dispatch_load_event_fn_str =
+ v8::String::new_external_onebyte_static(scope, b"dispatchLoadEvent")
+ .unwrap();
+ let dispatch_load_event_fn = bootstrap_ns
+ .get(scope, dispatch_load_event_fn_str.into())
+ .unwrap();
+ let dispatch_load_event_fn =
+ v8::Local::<v8::Function>::try_from(dispatch_load_event_fn).unwrap();
+ let dispatch_beforeunload_event_fn_str =
+ v8::String::new_external_onebyte_static(
+ scope,
+ b"dispatchBeforeUnloadEvent",
+ )
+ .unwrap();
+ let dispatch_beforeunload_event_fn = bootstrap_ns
+ .get(scope, dispatch_beforeunload_event_fn_str.into())
+ .unwrap();
+ let dispatch_beforeunload_event_fn =
+ v8::Local::<v8::Function>::try_from(dispatch_beforeunload_event_fn)
+ .unwrap();
+ let dispatch_unload_event_fn_str =
+ v8::String::new_external_onebyte_static(scope, b"dispatchUnloadEvent")
+ .unwrap();
+ let dispatch_unload_event_fn = bootstrap_ns
+ .get(scope, dispatch_unload_event_fn_str.into())
+ .unwrap();
+ let dispatch_unload_event_fn =
+ v8::Local::<v8::Function>::try_from(dispatch_unload_event_fn).unwrap();
+ (
+ v8::Global::new(scope, bootstrap_fn),
+ v8::Global::new(scope, dispatch_load_event_fn),
+ v8::Global::new(scope, dispatch_beforeunload_event_fn),
+ v8::Global::new(scope, dispatch_unload_event_fn),
+ )
};
Self {
@@ -551,6 +591,9 @@ impl MainWorker {
.should_wait_for_inspector_session,
exit_code,
bootstrap_fn_global: Some(bootstrap_fn_global),
+ dispatch_load_event_fn_global,
+ dispatch_beforeunload_event_fn_global,
+ dispatch_unload_event_fn_global,
}
}
@@ -708,54 +751,53 @@ impl MainWorker {
/// Dispatches "load" event to the JavaScript runtime.
///
/// Does not poll event loop, and thus not await any of the "load" event handlers.
- pub fn dispatch_load_event(
- &mut self,
- script_name: &'static str,
- ) -> Result<(), AnyError> {
- self.js_runtime.execute_script(
- script_name,
- // NOTE(@bartlomieju): not using `globalThis` here, because user might delete
- // it. Instead we're using global `dispatchEvent` function which will
- // used a saved reference to global scope.
- ascii_str!("dispatchEvent(new Event('load'))"),
- )?;
+ pub fn dispatch_load_event(&mut self) -> Result<(), AnyError> {
+ let scope = &mut self.js_runtime.handle_scope();
+ let tc_scope = &mut v8::TryCatch::new(scope);
+ let dispatch_load_event_fn =
+ v8::Local::new(tc_scope, &self.dispatch_load_event_fn_global);
+ let undefined = v8::undefined(tc_scope);
+ dispatch_load_event_fn.call(tc_scope, undefined.into(), &[]);
+ if let Some(exception) = tc_scope.exception() {
+ let error = JsError::from_v8_exception(tc_scope, exception);
+ return Err(error.into());
+ }
Ok(())
}
/// Dispatches "unload" event to the JavaScript runtime.
///
/// Does not poll event loop, and thus not await any of the "unload" event handlers.
- pub fn dispatch_unload_event(
- &mut self,
- script_name: &'static str,
- ) -> Result<(), AnyError> {
- self.js_runtime.execute_script(
- script_name,
- // NOTE(@bartlomieju): not using `globalThis` here, because user might delete
- // it. Instead we're using global `dispatchEvent` function which will
- // used a saved reference to global scope.
- ascii_str!("dispatchEvent(new Event('unload'))"),
- )?;
+ pub fn dispatch_unload_event(&mut self) -> Result<(), AnyError> {
+ let scope = &mut self.js_runtime.handle_scope();
+ let tc_scope = &mut v8::TryCatch::new(scope);
+ let dispatch_unload_event_fn =
+ v8::Local::new(tc_scope, &self.dispatch_unload_event_fn_global);
+ let undefined = v8::undefined(tc_scope);
+ dispatch_unload_event_fn.call(tc_scope, undefined.into(), &[]);
+ if let Some(exception) = tc_scope.exception() {
+ let error = JsError::from_v8_exception(tc_scope, exception);
+ return Err(error.into());
+ }
Ok(())
}
/// Dispatches "beforeunload" event to the JavaScript runtime. Returns a boolean
/// indicating if the event was prevented and thus event loop should continue
/// running.
- pub fn dispatch_beforeunload_event(
- &mut self,
- script_name: &'static str,
- ) -> Result<bool, AnyError> {
- let value = self.js_runtime.execute_script(
- script_name,
- // NOTE(@bartlomieju): not using `globalThis` here, because user might delete
- // it. Instead we're using global `dispatchEvent` function which will
- // used a saved reference to global scope.
- ascii_str!(
- "dispatchEvent(new Event('beforeunload', { cancelable: true }));"
- ),
- )?;
- let local_value = value.open(&mut self.js_runtime.handle_scope());
- Ok(local_value.is_false())
+ pub fn dispatch_beforeunload_event(&mut self) -> Result<bool, AnyError> {
+ let scope = &mut self.js_runtime.handle_scope();
+ let tc_scope = &mut v8::TryCatch::new(scope);
+ let dispatch_beforeunload_event_fn =
+ v8::Local::new(tc_scope, &self.dispatch_beforeunload_event_fn_global);
+ let undefined = v8::undefined(tc_scope);
+ let ret_val =
+ dispatch_beforeunload_event_fn.call(tc_scope, undefined.into(), &[]);
+ if let Some(exception) = tc_scope.exception() {
+ let error = JsError::from_v8_exception(tc_scope, exception);
+ return Err(error.into());
+ }
+ let ret_val = ret_val.unwrap();
+ Ok(ret_val.is_false())
}
}