diff options
author | Colin Ihrig <cjihrig@gmail.com> | 2022-06-28 10:49:30 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-28 10:49:30 -0400 |
commit | 0f6a5c5fc24e8dc9125c5c536c8547a86ca87b15 (patch) | |
tree | 41538ee1df06dc80d60e49ed50177f99ba8dc297 /core | |
parent | ab11b45d1d2678cfea2217ac72fc24317eef777d (diff) |
feat(web): add beforeunload event (#14830)
This commit adds the 'beforeunload' event.
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/01_core.js | 1 | ||||
-rw-r--r-- | core/ops_builtin_v8.rs | 24 | ||||
-rw-r--r-- | core/runtime.rs | 32 |
3 files changed, 53 insertions, 4 deletions
diff --git a/core/01_core.js b/core/01_core.js index 9337c0231..156300327 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -267,6 +267,7 @@ destructureError: opSync.bind(null, "op_destructure_error"), terminate: opSync.bind(null, "op_terminate"), opNames: opSync.bind(null, "op_op_names"), + eventLoopHasMoreWork: opSync.bind(null, "op_event_loop_has_more_work"), }); ObjectAssign(globalThis.__bootstrap, { core }); diff --git a/core/ops_builtin_v8.rs b/core/ops_builtin_v8.rs index 7f0c58212..4bc80faa5 100644 --- a/core/ops_builtin_v8.rs +++ b/core/ops_builtin_v8.rs @@ -47,6 +47,7 @@ pub(crate) fn init_builtins_v8() -> Vec<OpDecl> { op_op_names::decl(), op_apply_source_map::decl(), op_set_format_exception_callback::decl(), + op_event_loop_has_more_work::decl(), ] } @@ -786,3 +787,26 @@ fn op_set_format_exception_callback<'a>( let old = old.map(|v| v8::Local::new(scope, v)); Ok(old.map(|v| from_v8(scope, v.into()).unwrap())) } + +#[op(v8)] +fn op_event_loop_has_more_work(scope: &mut v8::HandleScope) -> bool { + let state_rc = JsRuntime::state(scope); + let module_map_rc = JsRuntime::module_map(scope); + let state = state_rc.borrow_mut(); + let module_map = module_map_rc.borrow(); + + let has_pending_refed_ops = state.pending_ops.len() > state.unrefed_ops.len(); + let has_pending_dyn_imports = module_map.has_pending_dynamic_imports(); + let has_pending_dyn_module_evaluation = + !state.pending_dyn_mod_evaluate.is_empty(); + let has_pending_module_evaluation = state.pending_mod_evaluate.is_some(); + let has_pending_background_tasks = scope.has_pending_background_tasks(); + let has_tick_scheduled = state.has_tick_scheduled; + + has_pending_refed_ops + || has_pending_dyn_imports + || has_pending_dyn_module_evaluation + || has_pending_module_evaluation + || has_pending_background_tasks + || has_tick_scheduled +} diff --git a/core/runtime.rs b/core/runtime.rs index 23fe73013..8b150e4e9 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -90,14 +90,14 @@ pub struct JsRuntime { event_loop_middlewares: Vec<Box<OpEventLoopFn>>, } -struct DynImportModEvaluate { +pub(crate) struct DynImportModEvaluate { load_id: ModuleLoadId, module_id: ModuleId, promise: v8::Global<v8::Promise>, module: v8::Global<v8::Module>, } -struct ModEvaluate { +pub(crate) struct ModEvaluate { promise: v8::Global<v8::Promise>, sender: oneshot::Sender<Result<(), Error>>, } @@ -158,8 +158,8 @@ pub(crate) struct JsRuntimeState { pub(crate) js_wasm_streaming_cb: Option<v8::Global<v8::Function>>, pub(crate) pending_promise_exceptions: HashMap<v8::Global<v8::Promise>, v8::Global<v8::Value>>, - pending_dyn_mod_evaluate: Vec<DynImportModEvaluate>, - pending_mod_evaluate: Option<ModEvaluate>, + pub(crate) pending_dyn_mod_evaluate: Vec<DynImportModEvaluate>, + pub(crate) pending_mod_evaluate: Option<ModEvaluate>, /// A counter used to delay our dynamic import deadlock detection by one spin /// of the event loop. dyn_module_evaluate_idle_counter: u32, @@ -1021,6 +1021,30 @@ Pending dynamic modules:\n".to_string(); Poll::Pending } + + pub fn event_loop_has_work(&mut self) -> bool { + let state_rc = Self::state(self.v8_isolate()); + let module_map_rc = Self::module_map(self.v8_isolate()); + let state = state_rc.borrow_mut(); + let module_map = module_map_rc.borrow(); + + let has_pending_refed_ops = + state.pending_ops.len() > state.unrefed_ops.len(); + let has_pending_dyn_imports = module_map.has_pending_dynamic_imports(); + let has_pending_dyn_module_evaluation = + !state.pending_dyn_mod_evaluate.is_empty(); + let has_pending_module_evaluation = state.pending_mod_evaluate.is_some(); + let has_pending_background_tasks = + self.v8_isolate().has_pending_background_tasks(); + let has_tick_scheduled = state.has_tick_scheduled; + + has_pending_refed_ops + || has_pending_dyn_imports + || has_pending_dyn_module_evaluation + || has_pending_module_evaluation + || has_pending_background_tasks + || has_tick_scheduled + } } extern "C" fn near_heap_limit_callback<F>( |