diff options
Diffstat (limited to 'core/runtime.rs')
-rw-r--r-- | core/runtime.rs | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/core/runtime.rs b/core/runtime.rs index 5769bbb3b..b1d8f3d80 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -36,6 +36,7 @@ use std::any::Any; use std::cell::RefCell; use std::collections::HashMap; use std::collections::HashSet; +use std::collections::VecDeque; use std::ffi::c_void; use std::mem::forget; use std::option::Option; @@ -80,9 +81,6 @@ pub struct JsRuntime { // This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround // a safety issue with SnapshotCreator. See JsRuntime::drop. v8_isolate: Option<v8::OwnedIsolate>, - // This is an Option<Box<JsRuntimeInspector> instead of just Box<JsRuntimeInspector> - // to workaround a safety issue. See JsRuntime::drop. - inspector: Option<Box<JsRuntimeInspector>>, snapshot_creator: Option<v8::SnapshotCreator>, has_snapshotted: bool, built_from_snapshot: bool, @@ -182,19 +180,18 @@ pub(crate) struct JsRuntimeState { pub(crate) op_ctxs: Box<[OpCtx]>, pub(crate) shared_array_buffer_store: Option<SharedArrayBufferStore>, pub(crate) compiled_wasm_module_store: Option<CompiledWasmModuleStore>, - /// The error that was passed to an explicit `Deno.core.terminate` call. + /// The error that was passed to an `op_dispatch_exception` call. /// It will be retrieved by `exception_to_err_result` and used as an error /// instead of any other exceptions. - pub(crate) explicit_terminate_exception: Option<v8::Global<v8::Value>>, + // TODO(nayeemrmn): This is polled in `exception_to_err_result()` which is + // flimsy. Try to poll it similarly to `pending_promise_exceptions`. + pub(crate) dispatched_exceptions: VecDeque<v8::Global<v8::Value>>, + inspector: Option<Rc<RefCell<JsRuntimeInspector>>>, waker: AtomicWaker, } impl Drop for JsRuntime { fn drop(&mut self) { - // The Isolate object must outlive the Inspector object, but this is - // currently not enforced by the type system. - self.inspector.take(); - if let Some(creator) = self.snapshot_creator.take() { // TODO(ry): in rusty_v8, `SnapShotCreator::get_owned_isolate()` returns // a `struct OwnedIsolate` which is not actually owned, hence the need @@ -421,7 +418,8 @@ impl JsRuntime { op_state: op_state.clone(), op_ctxs, have_unpolled_ops: false, - explicit_terminate_exception: None, + dispatched_exceptions: Default::default(), + inspector: Some(inspector), waker: AtomicWaker::new(), }))); @@ -434,7 +432,6 @@ impl JsRuntime { let mut js_runtime = Self { v8_isolate: Some(isolate), - inspector: Some(inspector), snapshot_creator: maybe_snapshot_creator, has_snapshotted: false, built_from_snapshot: has_startup_snapshot, @@ -466,8 +463,8 @@ impl JsRuntime { self.v8_isolate.as_mut().unwrap() } - pub fn inspector(&mut self) -> &mut Box<JsRuntimeInspector> { - self.inspector.as_mut().unwrap() + pub fn inspector(&mut self) -> Rc<RefCell<JsRuntimeInspector>> { + Self::state(self.v8_isolate()).borrow().inspector() } pub fn global_realm(&mut self) -> JsRealm { @@ -740,7 +737,7 @@ impl JsRuntime { state.borrow_mut().global_realm.take(); - self.inspector.take(); + state.borrow_mut().inspector.take(); // Overwrite existing ModuleMap to drop v8::Global handles self @@ -941,8 +938,7 @@ impl JsRuntime { wait_for_inspector: bool, ) -> Poll<Result<(), Error>> { // We always poll the inspector first - let _ = self.inspector().poll_unpin(cx); - + let _ = self.inspector().borrow_mut().poll_unpin(cx); let state_rc = Self::state(self.v8_isolate()); let module_map_rc = Self::module_map(self.v8_isolate()); { @@ -1003,11 +999,8 @@ impl JsRuntime { self.evaluate_pending_module(); let pending_state = Self::event_loop_pending_state(self.v8_isolate()); - let inspector_has_active_sessions = self - .inspector - .as_ref() - .map(|i| i.has_active_sessions()) - .unwrap_or(false); + let inspector_has_active_sessions = + self.inspector().borrow_mut().has_active_sessions(); if !pending_state.is_pending() && !maybe_scheduling { if wait_for_inspector && inspector_has_active_sessions { @@ -1144,6 +1137,10 @@ where } impl JsRuntimeState { + pub(crate) fn inspector(&self) -> Rc<RefCell<JsRuntimeInspector>> { + self.inspector.as_ref().unwrap().clone() + } + /// Called by `bindings::host_import_module_dynamically_callback` /// after initiating new dynamic import load. pub fn notify_new_dynamic_import(&mut self) { @@ -1167,17 +1164,17 @@ pub(crate) fn exception_to_err_result<'s, T>( scope.cancel_terminate_execution(); let mut exception = exception; { - // If the termination is the result of a `Deno.core.terminate` call, we want + // If termination is the result of a `op_dispatch_exception` call, we want // to use the exception that was passed to it rather than the exception that // was passed to this function. let mut state = state_rc.borrow_mut(); exception = state - .explicit_terminate_exception - .take() + .dispatched_exceptions + .pop_back() .map(|exception| v8::Local::new(scope, exception)) .unwrap_or_else(|| { // Maybe make a new exception object. - if exception.is_null_or_undefined() { + if was_terminating_execution && exception.is_null_or_undefined() { let message = v8::String::new(scope, "execution terminated").unwrap(); v8::Exception::error(scope, message) } else { @@ -1385,10 +1382,11 @@ impl JsRuntime { // Update status after evaluating. status = module.get_status(); - let explicit_terminate_exception = - state_rc.borrow_mut().explicit_terminate_exception.take(); - if let Some(exception) = explicit_terminate_exception { - let exception = v8::Local::new(tc_scope, exception); + let has_dispatched_exception = + !state_rc.borrow_mut().dispatched_exceptions.is_empty(); + if has_dispatched_exception { + // This will be overrided in `exception_to_err_result()`. + let exception = v8::undefined(tc_scope).into(); let pending_mod_evaluate = { let mut state = state_rc.borrow_mut(); state.pending_mod_evaluate.take().unwrap() @@ -2702,7 +2700,7 @@ pub mod tests { Deno.core.setPromiseRejectCallback(() => { return false; }); - a = 1 + 2; + a = 1 + 2; "#, ) .unwrap(); |