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);
|
setup(&mut rt);
|
||||||
|
|
||||||
// Init ops
|
// Init ops
|
||||||
rt.execute(
|
rt.sync_ops_cache();
|
||||||
"init",
|
|
||||||
r#"
|
|
||||||
Deno.core.ops();
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
rt
|
rt
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,8 @@ fn create_compiler_snapshot(
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
js_runtime.sync_ops_cache();
|
||||||
|
|
||||||
create_snapshot(js_runtime, snapshot_path, files);
|
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_respond", op(respond));
|
||||||
runtime.register_op("op_script_names", op(script_names));
|
runtime.register_op("op_script_names", op(script_names));
|
||||||
runtime.register_op("op_script_version", op(script_version));
|
runtime.register_op("op_script_version", op(script_version));
|
||||||
|
runtime.sync_ops_cache();
|
||||||
|
|
||||||
let init_config = json!({ "debug": debug });
|
let init_config = json!({ "debug": debug });
|
||||||
let init_src = format!("globalThis.serverInit({});", init_config);
|
let init_src = format!("globalThis.serverInit({});", init_config);
|
||||||
|
|
|
@ -148,6 +148,7 @@ fn create_web_worker_callback(
|
||||||
if args.use_deno_namespace {
|
if args.use_deno_namespace {
|
||||||
ops::runtime_compiler::init(js_runtime);
|
ops::runtime_compiler::init(js_runtime);
|
||||||
}
|
}
|
||||||
|
js_runtime.sync_ops_cache();
|
||||||
}
|
}
|
||||||
worker.bootstrap(&options);
|
worker.bootstrap(&options);
|
||||||
|
|
||||||
|
@ -218,6 +219,7 @@ pub fn create_main_worker(
|
||||||
// above
|
// above
|
||||||
ops::errors::init(js_runtime);
|
ops::errors::init(js_runtime);
|
||||||
ops::runtime_compiler::init(js_runtime);
|
ops::runtime_compiler::init(js_runtime);
|
||||||
|
js_runtime.sync_ops_cache();
|
||||||
}
|
}
|
||||||
worker.bootstrap(&options);
|
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_load", op(load));
|
||||||
runtime.register_op("op_resolve", op(resolve));
|
runtime.register_op("op_resolve", op(resolve));
|
||||||
runtime.register_op("op_respond", op(respond));
|
runtime.register_op("op_respond", op(respond));
|
||||||
|
runtime.sync_ops_cache();
|
||||||
|
|
||||||
let startup_source = "globalThis.startup({ legacyFlag: false })";
|
let startup_source = "globalThis.startup({ legacyFlag: false })";
|
||||||
let request_value = json!({
|
let request_value = json!({
|
||||||
|
|
|
@ -778,7 +778,6 @@ delete Object.prototype.__proto__;
|
||||||
}
|
}
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
languageService = ts.createLanguageService(host);
|
languageService = ts.createLanguageService(host);
|
||||||
core.ops();
|
|
||||||
setLogDebug(debugFlag, "TSLS");
|
setLogDebug(debugFlag, "TSLS");
|
||||||
debug("serverInit()");
|
debug("serverInit()");
|
||||||
}
|
}
|
||||||
|
@ -793,13 +792,9 @@ delete Object.prototype.__proto__;
|
||||||
throw new Error("The compiler runtime already started.");
|
throw new Error("The compiler runtime already started.");
|
||||||
}
|
}
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
core.ops();
|
|
||||||
setLogDebug(!!debugFlag, "TS");
|
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
|
// A build time only op that provides some setup information that is used to
|
||||||
// ensure the snapshot is setup properly.
|
// ensure the snapshot is setup properly.
|
||||||
/** @type {{ buildSpecifier: string; libs: string[] }} */
|
/** @type {{ buildSpecifier: string; libs: string[] }} */
|
||||||
|
|
|
@ -20,16 +20,7 @@ fn create_js_runtime() -> JsRuntime {
|
||||||
runtime.register_op("nop", |state, _, _| {
|
runtime.register_op("nop", |state, _, _| {
|
||||||
Op::Sync(serialize_op_result(Ok(9), state))
|
Op::Sync(serialize_op_result(Ok(9), state))
|
||||||
});
|
});
|
||||||
|
runtime.sync_ops_cache();
|
||||||
// Init ops
|
|
||||||
runtime
|
|
||||||
.execute(
|
|
||||||
"init",
|
|
||||||
r#"
|
|
||||||
Deno.core.ops();
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
runtime
|
runtime
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,12 +60,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function ops() {
|
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;
|
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() {
|
function handleAsyncMsgFromRust() {
|
||||||
for (let i = 0; i < arguments.length; i += 2) {
|
for (let i = 0; i < arguments.length; i += 2) {
|
||||||
const promiseId = arguments[i];
|
const promiseId = arguments[i];
|
||||||
|
@ -130,5 +132,6 @@
|
||||||
resources,
|
resources,
|
||||||
registerErrorClass,
|
registerErrorClass,
|
||||||
handleAsyncMsgFromRust,
|
handleAsyncMsgFromRust,
|
||||||
|
syncOpsCache,
|
||||||
});
|
});
|
||||||
})(this);
|
})(this);
|
||||||
|
|
|
@ -56,6 +56,7 @@ fn main() {
|
||||||
Ok(sum)
|
Ok(sum)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
runtime.sync_ops_cache();
|
||||||
|
|
||||||
// Now we see how to invoke the ops we just defined. The runtime automatically
|
// 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.
|
// contains a Deno.core object with several functions for interacting with it.
|
||||||
|
@ -64,11 +65,7 @@ fn main() {
|
||||||
.execute(
|
.execute(
|
||||||
"<init>",
|
"<init>",
|
||||||
r#"
|
r#"
|
||||||
// First we initialize the ops cache.
|
// Define a print function that uses
|
||||||
// This maps op names to their id's.
|
|
||||||
Deno.core.ops();
|
|
||||||
|
|
||||||
// Then we define a print function that uses
|
|
||||||
// our op_print op to display the stringified argument.
|
// our op_print op to display the stringified argument.
|
||||||
const _newline = new Uint8Array([10]);
|
const _newline = new Uint8Array([10]);
|
||||||
function print(value) {
|
function print(value) {
|
||||||
|
|
|
@ -54,8 +54,6 @@ async function serve(rid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
Deno.core.ops();
|
|
||||||
|
|
||||||
const listenerRid = listen();
|
const listenerRid = listen();
|
||||||
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4544/\n`);
|
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("accept", deno_core::op_async(op_accept));
|
||||||
runtime.register_op("read", deno_core::op_async(op_read));
|
runtime.register_op("read", deno_core::op_async(op_read));
|
||||||
runtime.register_op("write", deno_core::op_async(op_write));
|
runtime.register_op("write", deno_core::op_async(op_write));
|
||||||
|
runtime.sync_ops_cache();
|
||||||
runtime
|
runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,15 @@ use std::rc::Rc;
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// let mut runtime = JsRuntime::new(...);
|
/// let mut runtime = JsRuntime::new(...);
|
||||||
/// runtime.register_op("hello", deno_core::op_sync(Self::hello_op));
|
/// 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:
|
/// ...it can be invoked from JS using the provided name, for example:
|
||||||
/// ```js
|
/// ```js
|
||||||
/// Deno.core.ops();
|
|
||||||
/// let result = Deno.core.opSync("function_name", args);
|
/// 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.
|
/// A more complete example is available in the examples directory.
|
||||||
pub fn op_sync<F, V, R>(op_fn: F) -> Box<OpFn>
|
pub fn op_sync<F, V, R>(op_fn: F) -> Box<OpFn>
|
||||||
where
|
where
|
||||||
|
@ -63,15 +63,15 @@ where
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// let mut runtime = JsRuntime::new(...);
|
/// let mut runtime = JsRuntime::new(...);
|
||||||
/// runtime.register_op("hello", deno_core::op_async(Self::hello_op));
|
/// 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:
|
/// ...it can be invoked from JS using the provided name, for example:
|
||||||
/// ```js
|
/// ```js
|
||||||
/// Deno.core.ops();
|
|
||||||
/// let future = Deno.core.opAsync("function_name", args);
|
/// 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.
|
/// A more complete example is available in the examples directory.
|
||||||
pub fn op_async<F, V, R, RV>(op_fn: F) -> Box<OpFn>
|
pub fn op_async<F, V, R, RV>(op_fn: F) -> Box<OpFn>
|
||||||
where
|
where
|
||||||
|
@ -116,13 +116,11 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.register_op("op_throw", op_async(op_throw));
|
runtime.register_op("op_throw", op_async(op_throw));
|
||||||
|
runtime.sync_ops_cache();
|
||||||
runtime
|
runtime
|
||||||
.execute(
|
.execute(
|
||||||
"<init>",
|
"<init>",
|
||||||
r#"
|
r#"
|
||||||
// First we initialize the ops cache. This maps op names to their id's.
|
|
||||||
Deno.core.ops();
|
|
||||||
|
|
||||||
async function f1() {
|
async function f1() {
|
||||||
await Deno.core.opAsync('op_throw', 'hello');
|
await Deno.core.opAsync('op_throw', 'hello');
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,6 +367,11 @@ impl JsRuntime {
|
||||||
state.js_recv_cb.replace(v8::Global::new(scope, cb));
|
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
|
/// Returns the runtime's op state, which can be used to maintain ops
|
||||||
/// and access resources between op calls.
|
/// and access resources between op calls.
|
||||||
pub fn op_state(&mut self) -> Rc<RefCell<OpState>> {
|
pub fn op_state(&mut self) -> Rc<RefCell<OpState>> {
|
||||||
|
@ -2140,6 +2145,7 @@ pub mod tests {
|
||||||
module_loader: Some(loader),
|
module_loader: Some(loader),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
runtime.sync_ops_cache();
|
||||||
runtime
|
runtime
|
||||||
.execute(
|
.execute(
|
||||||
"file:///dyn_import3.js",
|
"file:///dyn_import3.js",
|
||||||
|
@ -2149,8 +2155,6 @@ pub mod tests {
|
||||||
if (mod.b() !== 'b') {
|
if (mod.b() !== 'b') {
|
||||||
throw Error("bad");
|
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_url_stringify_search_params",
|
||||||
op_sync(deno_url::op_url_stringify_search_params),
|
op_sync(deno_url::op_url_stringify_search_params),
|
||||||
);
|
);
|
||||||
|
runtime.sync_ops_cache();
|
||||||
|
|
||||||
runtime
|
runtime
|
||||||
.execute(
|
.execute(
|
||||||
|
@ -23,14 +24,6 @@ fn create_js_runtime() -> JsRuntime {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
deno_url::init(&mut runtime);
|
deno_url::init(&mut runtime);
|
||||||
runtime
|
|
||||||
.execute(
|
|
||||||
"init",
|
|
||||||
r#"
|
|
||||||
Deno.core.ops();
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
runtime
|
runtime
|
||||||
.execute("setup", "const { URL } = globalThis.__bootstrap.url;")
|
.execute("setup", "const { URL } = globalThis.__bootstrap.url;")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -142,8 +142,6 @@ delete Object.prototype.__proto__;
|
||||||
}
|
}
|
||||||
|
|
||||||
function runtimeStart(runtimeOptions, source) {
|
function runtimeStart(runtimeOptions, source) {
|
||||||
core.ops();
|
|
||||||
|
|
||||||
core.setMacrotaskCallback(timers.handleTimerMacrotask);
|
core.setMacrotaskCallback(timers.handleTimerMacrotask);
|
||||||
version.setVersions(
|
version.setVersions(
|
||||||
runtimeOptions.denoVersion,
|
runtimeOptions.denoVersion,
|
||||||
|
|
|
@ -284,6 +284,7 @@ impl WebWorker {
|
||||||
t.add(stream);
|
t.add(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
js_runtime.sync_ops_cache();
|
||||||
|
|
||||||
worker
|
worker
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,6 +171,7 @@ impl MainWorker {
|
||||||
t.add(stream);
|
t.add(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
js_runtime.sync_ops_cache();
|
||||||
|
|
||||||
worker
|
worker
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue