mirror of
https://github.com/denoland/deno.git
synced 2024-10-29 08:58:01 -04: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(crate) struct JsRuntimeState {
|
||||||
pub global_context: Option<v8::Global<v8::Context>>,
|
pub global_context: Option<v8::Global<v8::Context>>,
|
||||||
pub(crate) js_recv_cb: Option<v8::Global<v8::Function>>,
|
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_macrotask_cb: Option<v8::Global<v8::Function>>,
|
||||||
pub(crate) js_wasm_streaming_cb: Option<v8::Global<v8::Function>>,
|
pub(crate) js_wasm_streaming_cb: Option<v8::Global<v8::Function>>,
|
||||||
pub(crate) pending_promise_exceptions:
|
pub(crate) pending_promise_exceptions:
|
||||||
|
@ -350,6 +351,7 @@ impl JsRuntime {
|
||||||
pending_mod_evaluate: None,
|
pending_mod_evaluate: None,
|
||||||
dyn_module_evaluate_idle_counter: 0,
|
dyn_module_evaluate_idle_counter: 0,
|
||||||
js_recv_cb: None,
|
js_recv_cb: None,
|
||||||
|
js_sync_cb: None,
|
||||||
js_macrotask_cb: None,
|
js_macrotask_cb: None,
|
||||||
js_wasm_streaming_cb: None,
|
js_wasm_streaming_cb: None,
|
||||||
js_error_create_fn,
|
js_error_create_fn,
|
||||||
|
@ -386,9 +388,10 @@ impl JsRuntime {
|
||||||
}
|
}
|
||||||
// Init extension ops
|
// Init extension ops
|
||||||
js_runtime.init_extension_ops().unwrap();
|
js_runtime.init_extension_ops().unwrap();
|
||||||
|
// Init callbacks (opresolve & syncOpsCache)
|
||||||
|
js_runtime.init_cbs();
|
||||||
|
// Sync ops cache
|
||||||
js_runtime.sync_ops_cache();
|
js_runtime.sync_ops_cache();
|
||||||
// Init async ops callback
|
|
||||||
js_runtime.init_recv_cb();
|
|
||||||
|
|
||||||
js_runtime
|
js_runtime
|
||||||
}
|
}
|
||||||
|
@ -476,35 +479,44 @@ impl JsRuntime {
|
||||||
self.register_op(name, macroware(name, opfn));
|
self.register_op(name, macroware(name, opfn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sync ops cache
|
|
||||||
self.sync_ops_cache();
|
|
||||||
// Restore extensions
|
// Restore extensions
|
||||||
self.extensions = extensions;
|
self.extensions = extensions;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Grabs a reference to core.js' opresolve
|
/// Grab a Global handle to a function returned by the given expression
|
||||||
fn init_recv_cb(&mut self) {
|
fn grab_fn(
|
||||||
let scope = &mut self.handle_scope();
|
scope: &mut v8::HandleScope,
|
||||||
|
code: &str,
|
||||||
// Get Deno.core.opresolve
|
) -> v8::Global<v8::Function> {
|
||||||
let code = v8::String::new(scope, "Deno.core.opresolve").unwrap();
|
let code = v8::String::new(scope, code).unwrap();
|
||||||
let script = v8::Script::compile(scope, code, None).unwrap();
|
let script = v8::Script::compile(scope, code, None).unwrap();
|
||||||
let v8_value = script.run(scope).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();
|
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
|
/// Ensures core.js has the latest op-name to op-id mappings
|
||||||
pub fn sync_ops_cache(&mut self) {
|
pub fn sync_ops_cache(&mut self) {
|
||||||
self
|
let scope = &mut self.handle_scope();
|
||||||
.execute_script("<anon>", "Deno.core.syncOpsCache()")
|
let state_rc = JsRuntime::state(scope);
|
||||||
.unwrap();
|
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
|
/// 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
|
// 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_recv_cb);
|
||||||
|
std::mem::take(&mut state.borrow_mut().js_sync_cb);
|
||||||
|
|
||||||
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
|
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
|
||||||
let snapshot = snapshot_creator
|
let snapshot = snapshot_creator
|
||||||
|
|
Loading…
Reference in a new issue