mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
refactor(core): move op cache sync responsibility to rust space (#10340)
Even if bootstrapping the JS runtime is low level, it's an abstraction leak of core to require users to call `Deno.core.ops()` in JS space. So instead we're introducing a `JsRuntime::sync_ops_cache()` method, once we have runtime extensions a new runtime will ensure the ops cache is setup (for the provided extensions) and then loading/unloading plugins should be the only operations that require op cache syncs
This commit is contained in:
parent
1c7164257d
commit
83bece56b0
17 changed files with 31 additions and 51 deletions
|
@ -16,13 +16,7 @@ pub fn create_js_runtime(setup: impl FnOnce(&mut JsRuntime)) -> JsRuntime {
|
|||
setup(&mut rt);
|
||||
|
||||
// Init ops
|
||||
rt.execute(
|
||||
"init",
|
||||
r#"
|
||||
Deno.core.ops();
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
rt.sync_ops_cache();
|
||||
|
||||
rt
|
||||
}
|
||||
|
|
|
@ -210,6 +210,8 @@ fn create_compiler_snapshot(
|
|||
}
|
||||
}),
|
||||
);
|
||||
js_runtime.sync_ops_cache();
|
||||
|
||||
create_snapshot(js_runtime, snapshot_path, files);
|
||||
}
|
||||
|
||||
|
|
|
@ -2122,6 +2122,7 @@ pub fn start(debug: bool) -> Result<JsRuntime, AnyError> {
|
|||
runtime.register_op("op_respond", op(respond));
|
||||
runtime.register_op("op_script_names", op(script_names));
|
||||
runtime.register_op("op_script_version", op(script_version));
|
||||
runtime.sync_ops_cache();
|
||||
|
||||
let init_config = json!({ "debug": debug });
|
||||
let init_src = format!("globalThis.serverInit({});", init_config);
|
||||
|
|
|
@ -148,6 +148,7 @@ fn create_web_worker_callback(
|
|||
if args.use_deno_namespace {
|
||||
ops::runtime_compiler::init(js_runtime);
|
||||
}
|
||||
js_runtime.sync_ops_cache();
|
||||
}
|
||||
worker.bootstrap(&options);
|
||||
|
||||
|
@ -218,6 +219,7 @@ pub fn create_main_worker(
|
|||
// above
|
||||
ops::errors::init(js_runtime);
|
||||
ops::runtime_compiler::init(js_runtime);
|
||||
js_runtime.sync_ops_cache();
|
||||
}
|
||||
worker.bootstrap(&options);
|
||||
|
||||
|
|
|
@ -496,6 +496,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
|||
runtime.register_op("op_load", op(load));
|
||||
runtime.register_op("op_resolve", op(resolve));
|
||||
runtime.register_op("op_respond", op(respond));
|
||||
runtime.sync_ops_cache();
|
||||
|
||||
let startup_source = "globalThis.startup({ legacyFlag: false })";
|
||||
let request_value = json!({
|
||||
|
|
|
@ -778,7 +778,6 @@ delete Object.prototype.__proto__;
|
|||
}
|
||||
hasStarted = true;
|
||||
languageService = ts.createLanguageService(host);
|
||||
core.ops();
|
||||
setLogDebug(debugFlag, "TSLS");
|
||||
debug("serverInit()");
|
||||
}
|
||||
|
@ -793,13 +792,9 @@ delete Object.prototype.__proto__;
|
|||
throw new Error("The compiler runtime already started.");
|
||||
}
|
||||
hasStarted = true;
|
||||
core.ops();
|
||||
setLogDebug(!!debugFlag, "TS");
|
||||
}
|
||||
|
||||
// Setup the compiler runtime during the build process.
|
||||
core.ops();
|
||||
|
||||
// A build time only op that provides some setup information that is used to
|
||||
// ensure the snapshot is setup properly.
|
||||
/** @type {{ buildSpecifier: string; libs: string[] }} */
|
||||
|
|
|
@ -20,16 +20,7 @@ fn create_js_runtime() -> JsRuntime {
|
|||
runtime.register_op("nop", |state, _, _| {
|
||||
Op::Sync(serialize_op_result(Ok(9), state))
|
||||
});
|
||||
|
||||
// Init ops
|
||||
runtime
|
||||
.execute(
|
||||
"init",
|
||||
r#"
|
||||
Deno.core.ops();
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
runtime.sync_ops_cache();
|
||||
|
||||
runtime
|
||||
}
|
||||
|
|
|
@ -60,12 +60,14 @@
|
|||
}
|
||||
|
||||
function ops() {
|
||||
// op id 0 is a special value to retrieve the map of registered ops.
|
||||
const newOpsCache = Object.fromEntries(opcall(0));
|
||||
opsCache = Object.freeze(newOpsCache);
|
||||
return opsCache;
|
||||
}
|
||||
|
||||
function syncOpsCache() {
|
||||
// op id 0 is a special value to retrieve the map of registered ops.
|
||||
opsCache = Object.freeze(Object.fromEntries(opcall(0)));
|
||||
}
|
||||
|
||||
function handleAsyncMsgFromRust() {
|
||||
for (let i = 0; i < arguments.length; i += 2) {
|
||||
const promiseId = arguments[i];
|
||||
|
@ -130,5 +132,6 @@
|
|||
resources,
|
||||
registerErrorClass,
|
||||
handleAsyncMsgFromRust,
|
||||
syncOpsCache,
|
||||
});
|
||||
})(this);
|
||||
|
|
|
@ -56,6 +56,7 @@ fn main() {
|
|||
Ok(sum)
|
||||
}),
|
||||
);
|
||||
runtime.sync_ops_cache();
|
||||
|
||||
// Now we see how to invoke the ops we just defined. The runtime automatically
|
||||
// contains a Deno.core object with several functions for interacting with it.
|
||||
|
@ -64,11 +65,7 @@ fn main() {
|
|||
.execute(
|
||||
"<init>",
|
||||
r#"
|
||||
// First we initialize the ops cache.
|
||||
// This maps op names to their id's.
|
||||
Deno.core.ops();
|
||||
|
||||
// Then we define a print function that uses
|
||||
// Define a print function that uses
|
||||
// our op_print op to display the stringified argument.
|
||||
const _newline = new Uint8Array([10]);
|
||||
function print(value) {
|
||||
|
|
|
@ -54,8 +54,6 @@ async function serve(rid) {
|
|||
}
|
||||
|
||||
async function main() {
|
||||
Deno.core.ops();
|
||||
|
||||
const listenerRid = listen();
|
||||
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4544/\n`);
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ fn create_js_runtime() -> JsRuntime {
|
|||
runtime.register_op("accept", deno_core::op_async(op_accept));
|
||||
runtime.register_op("read", deno_core::op_async(op_read));
|
||||
runtime.register_op("write", deno_core::op_async(op_write));
|
||||
runtime.sync_ops_cache();
|
||||
runtime
|
||||
}
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@ use std::rc::Rc;
|
|||
/// ```ignore
|
||||
/// let mut runtime = JsRuntime::new(...);
|
||||
/// runtime.register_op("hello", deno_core::op_sync(Self::hello_op));
|
||||
/// runtime.sync_ops_cache();
|
||||
/// ```
|
||||
///
|
||||
/// ...it can be invoked from JS using the provided name, for example:
|
||||
/// ```js
|
||||
/// Deno.core.ops();
|
||||
/// let result = Deno.core.opSync("function_name", args);
|
||||
/// ```
|
||||
///
|
||||
/// The `Deno.core.ops()` statement is needed once before any op calls, for initialization.
|
||||
/// `runtime.sync_ops_cache()` must be called after registering new ops
|
||||
/// A more complete example is available in the examples directory.
|
||||
pub fn op_sync<F, V, R>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
|
@ -63,15 +63,15 @@ where
|
|||
/// ```ignore
|
||||
/// let mut runtime = JsRuntime::new(...);
|
||||
/// runtime.register_op("hello", deno_core::op_async(Self::hello_op));
|
||||
/// runtime.sync_ops_cache();
|
||||
/// ```
|
||||
///
|
||||
/// ...it can be invoked from JS using the provided name, for example:
|
||||
/// ```js
|
||||
/// Deno.core.ops();
|
||||
/// let future = Deno.core.opAsync("function_name", args);
|
||||
/// ```
|
||||
///
|
||||
/// The `Deno.core.ops()` statement is needed once before any op calls, for initialization.
|
||||
/// `runtime.sync_ops_cache()` must be called after registering new ops
|
||||
/// A more complete example is available in the examples directory.
|
||||
pub fn op_async<F, V, R, RV>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
|
@ -116,13 +116,11 @@ mod tests {
|
|||
}
|
||||
|
||||
runtime.register_op("op_throw", op_async(op_throw));
|
||||
runtime.sync_ops_cache();
|
||||
runtime
|
||||
.execute(
|
||||
"<init>",
|
||||
r#"
|
||||
// First we initialize the ops cache. This maps op names to their id's.
|
||||
Deno.core.ops();
|
||||
|
||||
async function f1() {
|
||||
await Deno.core.opAsync('op_throw', 'hello');
|
||||
}
|
||||
|
|
|
@ -367,6 +367,11 @@ impl JsRuntime {
|
|||
state.js_recv_cb.replace(v8::Global::new(scope, cb));
|
||||
}
|
||||
|
||||
/// Ensures core.js has the latest op-name to op-id mappings
|
||||
pub fn sync_ops_cache(&mut self) {
|
||||
self.execute("<anon>", "Deno.core.syncOpsCache()").unwrap()
|
||||
}
|
||||
|
||||
/// Returns the runtime's op state, which can be used to maintain ops
|
||||
/// and access resources between op calls.
|
||||
pub fn op_state(&mut self) -> Rc<RefCell<OpState>> {
|
||||
|
@ -2140,6 +2145,7 @@ pub mod tests {
|
|||
module_loader: Some(loader),
|
||||
..Default::default()
|
||||
});
|
||||
runtime.sync_ops_cache();
|
||||
runtime
|
||||
.execute(
|
||||
"file:///dyn_import3.js",
|
||||
|
@ -2149,8 +2155,6 @@ pub mod tests {
|
|||
if (mod.b() !== 'b') {
|
||||
throw Error("bad");
|
||||
}
|
||||
// Now do any op
|
||||
Deno.core.ops();
|
||||
})();
|
||||
"#,
|
||||
)
|
||||
|
|
|
@ -15,6 +15,7 @@ fn create_js_runtime() -> JsRuntime {
|
|||
"op_url_stringify_search_params",
|
||||
op_sync(deno_url::op_url_stringify_search_params),
|
||||
);
|
||||
runtime.sync_ops_cache();
|
||||
|
||||
runtime
|
||||
.execute(
|
||||
|
@ -23,14 +24,6 @@ fn create_js_runtime() -> JsRuntime {
|
|||
)
|
||||
.unwrap();
|
||||
deno_url::init(&mut runtime);
|
||||
runtime
|
||||
.execute(
|
||||
"init",
|
||||
r#"
|
||||
Deno.core.ops();
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
runtime
|
||||
.execute("setup", "const { URL } = globalThis.__bootstrap.url;")
|
||||
.unwrap();
|
||||
|
|
|
@ -142,8 +142,6 @@ delete Object.prototype.__proto__;
|
|||
}
|
||||
|
||||
function runtimeStart(runtimeOptions, source) {
|
||||
core.ops();
|
||||
|
||||
core.setMacrotaskCallback(timers.handleTimerMacrotask);
|
||||
version.setVersions(
|
||||
runtimeOptions.denoVersion,
|
||||
|
|
|
@ -284,6 +284,7 @@ impl WebWorker {
|
|||
t.add(stream);
|
||||
}
|
||||
}
|
||||
js_runtime.sync_ops_cache();
|
||||
|
||||
worker
|
||||
}
|
||||
|
|
|
@ -171,6 +171,7 @@ impl MainWorker {
|
|||
t.add(stream);
|
||||
}
|
||||
}
|
||||
js_runtime.sync_ops_cache();
|
||||
|
||||
worker
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue