mirror of
https://github.com/denoland/deno.git
synced 2024-12-27 01:29:14 -05:00
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 ...
This commit is contained in:
parent
11acdf1ea8
commit
4a1300edde
1 changed files with 31 additions and 18 deletions
|
@ -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();
|
||||
|
||||
// Put global handle in state.js_recv_cb
|
||||
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));
|
||||
v8::Global::new(scope, cb)
|
||||
}
|
||||
|
||||
/// 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();
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue