summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2021-10-04 11:45:41 +0200
committerGitHub <noreply@github.com>2021-10-04 11:45:41 +0200
commit4a1300edde424f134bd2298d8f30ba3ceb159c16 (patch)
treefa67c695ad82fd2875cf6853ea41e0f82c813322 /core/runtime.rs
parent11acdf1ea8b2978dcacad37b386f45e43a1f2748 (diff)
fix(core/runtime): sync_ops_cache if nuked Deno ns (#12302)
Decouple JsRuntime::sync_ops_cache() from the availability of the Deno.* namespace in the global scope This avoids crashes when calling sync_ops_cache() on a bootstrapped WebWorker who has dropped its Deno.* namespace It's also just cleaner and more robust ...
Diffstat (limited to 'core/runtime.rs')
-rw-r--r--core/runtime.rs47
1 files changed, 30 insertions, 17 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index 0d566d118..304ca68db 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -146,6 +146,7 @@ pub type CompiledWasmModuleStore = CrossIsolateStore<v8::CompiledWasmModule>;
pub(crate) struct JsRuntimeState {
pub global_context: Option<v8::Global<v8::Context>>,
pub(crate) js_recv_cb: Option<v8::Global<v8::Function>>,
+ pub(crate) js_sync_cb: Option<v8::Global<v8::Function>>,
pub(crate) js_macrotask_cb: Option<v8::Global<v8::Function>>,
pub(crate) js_wasm_streaming_cb: Option<v8::Global<v8::Function>>,
pub(crate) pending_promise_exceptions:
@@ -350,6 +351,7 @@ impl JsRuntime {
pending_mod_evaluate: None,
dyn_module_evaluate_idle_counter: 0,
js_recv_cb: None,
+ js_sync_cb: None,
js_macrotask_cb: None,
js_wasm_streaming_cb: None,
js_error_create_fn,
@@ -386,9 +388,10 @@ impl JsRuntime {
}
// Init extension ops
js_runtime.init_extension_ops().unwrap();
+ // Init callbacks (opresolve & syncOpsCache)
+ js_runtime.init_cbs();
+ // Sync ops cache
js_runtime.sync_ops_cache();
- // Init async ops callback
- js_runtime.init_recv_cb();
js_runtime
}
@@ -476,35 +479,44 @@ impl JsRuntime {
self.register_op(name, macroware(name, opfn));
}
}
- // Sync ops cache
- self.sync_ops_cache();
// Restore extensions
self.extensions = extensions;
Ok(())
}
- /// Grabs a reference to core.js' opresolve
- fn init_recv_cb(&mut self) {
- let scope = &mut self.handle_scope();
-
- // Get Deno.core.opresolve
- let code = v8::String::new(scope, "Deno.core.opresolve").unwrap();
+ /// Grab a Global handle to a function returned by the given expression
+ fn grab_fn(
+ scope: &mut v8::HandleScope,
+ code: &str,
+ ) -> v8::Global<v8::Function> {
+ let code = v8::String::new(scope, code).unwrap();
let script = v8::Script::compile(scope, code, None).unwrap();
let v8_value = script.run(scope).unwrap();
+ let cb = v8::Local::<v8::Function>::try_from(v8_value).unwrap();
+ v8::Global::new(scope, cb)
+ }
- // Put global handle in state.js_recv_cb
- let state_rc = JsRuntime::state(scope);
+ /// Grabs a reference to core.js' opresolve & syncOpsCache()
+ fn init_cbs(&mut self) {
+ let mut scope = self.handle_scope();
+ let recv_cb = Self::grab_fn(&mut scope, "Deno.core.opresolve");
+ let sync_cb = Self::grab_fn(&mut scope, "Deno.core.syncOpsCache");
+ // Put global handles in state
+ let state_rc = JsRuntime::state(&scope);
let mut state = state_rc.borrow_mut();
- let cb = v8::Local::<v8::Function>::try_from(v8_value).unwrap();
- state.js_recv_cb.replace(v8::Global::new(scope, cb));
+ state.js_recv_cb.replace(recv_cb);
+ state.js_sync_cb.replace(sync_cb);
}
/// Ensures core.js has the latest op-name to op-id mappings
pub fn sync_ops_cache(&mut self) {
- self
- .execute_script("<anon>", "Deno.core.syncOpsCache()")
- .unwrap();
+ let scope = &mut self.handle_scope();
+ let state_rc = JsRuntime::state(scope);
+ let js_sync_cb_handle = state_rc.borrow().js_sync_cb.clone().unwrap();
+ let js_sync_cb = js_sync_cb_handle.get(scope);
+ let this = v8::undefined(scope).into();
+ js_sync_cb.call(scope, this, &[]);
}
/// Returns the runtime's op state, which can be used to maintain ops
@@ -590,6 +602,7 @@ impl JsRuntime {
))));
// Drop other v8::Global handles before snapshotting
std::mem::take(&mut state.borrow_mut().js_recv_cb);
+ std::mem::take(&mut state.borrow_mut().js_sync_cb);
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
let snapshot = snapshot_creator