diff options
-rw-r--r-- | bench_util/js_runtime.rs | 3 | ||||
-rw-r--r-- | core/01_core.js | 87 | ||||
-rw-r--r-- | core/bindings.rs | 87 | ||||
-rw-r--r-- | core/examples/http_bench_json_ops/http_bench_json_ops.js | 7 | ||||
-rw-r--r-- | core/runtime.rs | 48 | ||||
-rw-r--r-- | runtime/js/99_main.js | 2 |
6 files changed, 42 insertions, 192 deletions
diff --git a/bench_util/js_runtime.rs b/bench_util/js_runtime.rs index 376d30593..e45af2bdd 100644 --- a/bench_util/js_runtime.rs +++ b/bench_util/js_runtime.rs @@ -104,9 +104,6 @@ pub fn bench_js_async_with( }; let looped = loop_code(inner_iters, src); let src = looped.as_ref(); - runtime - .execute_script("init", "Deno.core.initializeAsyncOps();") - .unwrap(); if is_profiling() { for _ in 0..opts.profiling_outer { tokio_runtime.block_on(inner_async(src, &mut runtime)); diff --git a/core/01_core.js b/core/01_core.js index bea9c4290..5a622b0ea 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -10,24 +10,19 @@ TypeError, URIError, Array, - ArrayFrom, ArrayPrototypeFill, - ArrayPrototypeJoin, ArrayPrototypePush, ArrayPrototypeMap, ErrorCaptureStackTrace, - Function, Promise, ObjectAssign, ObjectFromEntries, - ObjectPrototypeHasOwnProperty, Map, MapPrototypeGet, MapPrototypeHas, MapPrototypeDelete, MapPrototypeSet, PromisePrototypeThen, - ReflectApply, SafePromisePrototypeFinally, StringPrototypeSlice, SymbolFor, @@ -175,61 +170,20 @@ return nextPromiseId++; } - // Generate async op wrappers. See core/bindings.rs - function initializeAsyncOps() { - function genAsyncOp(op, name, args) { - return new Function( - "setPromise", - "getPromise", - "promiseIdSymbol", - "rollPromiseId", - "handleOpCallTracing", - "op", - "unwrapOpResult", - "PromisePrototypeThen", - ` - return function ${name}(${args}) { - const id = rollPromiseId(); - let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult); - try { - op(id, ${args}); - } catch (err) { - // Cleanup the just-created promise - getPromise(id); - // Rethrow the error - throw err; - } - promise = handleOpCallTracing("${name}", id, promise); - promise[promiseIdSymbol] = id; - return promise; - } - `, - )( - setPromise, - getPromise, - promiseIdSymbol, - rollPromiseId, - handleOpCallTracing, - op, - unwrapOpResult, - PromisePrototypeThen, - ); - } - - // { <name>: <argc>, ... } - const info = ops.asyncOpsInfo(); - for (const name in info) { - if (!ObjectPrototypeHasOwnProperty(info, name)) { - continue; - } - const argc = info[name]; - const op = ops[name]; - const args = ArrayPrototypeJoin( - ArrayFrom({ length: argc }, (_, i) => `arg${i}`), - ", ", - ); - ops[name] = genAsyncOp(op, name, args); + function opAsync(name, ...args) { + const id = rollPromiseId(); + let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult); + try { + ops[name](id, ...args); + } catch (err) { + // Cleanup the just-created promise + getPromise(id); + // Rethrow the error + throw err; } + promise = handleOpCallTracing(name, id, promise); + promise[promiseIdSymbol] = id; + return promise; } function handleOpCallTracing(opName, promiseId, p) { @@ -245,10 +199,6 @@ } } - function opAsync(opName, ...args) { - return ReflectApply(ops[opName], ops, args); - } - function refOp(promiseId) { if (!hasPromise(promiseId)) { return; @@ -401,7 +351,6 @@ // Extra Deno.core.* exports const core = ObjectAssign(globalThis.Deno.core, { opAsync, - initializeAsyncOps, resources, metrics, registerErrorBuilder, @@ -421,11 +370,11 @@ setPromiseHooks, close: (rid) => ops.op_close(rid), tryClose: (rid) => ops.op_try_close(rid), - read: (rid, buffer) => ops.op_read(rid, buffer), - readAll: (rid) => ops.op_read_all(rid), - write: (rid, buffer) => ops.op_write(rid, buffer), - writeAll: (rid, buffer) => ops.op_write_all(rid, buffer), - shutdown: (rid) => ops.op_shutdown(rid), + read: opAsync.bind(null, "op_read"), + readAll: opAsync.bind(null, "op_read_all"), + write: opAsync.bind(null, "op_write"), + writeAll: opAsync.bind(null, "op_write_all"), + shutdown: opAsync.bind(null, "op_shutdown"), print: (msg, isErr) => ops.op_print(msg, isErr), setMacrotaskCallback: (fn) => ops.op_set_macrotask_callback(fn), setNextTickCallback: (fn) => ops.op_set_next_tick_callback(fn), diff --git a/core/bindings.rs b/core/bindings.rs index 8ac308250..aa42c2b77 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -135,9 +135,6 @@ pub fn initialize_context<'s>( .try_into() .unwrap(); initialize_ops(scope, ops_obj, op_ctxs, snapshot_options); - if snapshot_options != SnapshotOptions::CreateFromExisting { - initialize_async_ops_info(scope, ops_obj, op_ctxs); - } return scope.escape(context); } @@ -161,9 +158,6 @@ pub fn initialize_context<'s>( let ops_obj = v8::Object::new(scope); core_obj.set(scope, ops_str.into(), ops_obj.into()); - if !snapshot_options.will_snapshot() { - initialize_async_ops_info(scope, ops_obj, op_ctxs); - } initialize_ops(scope, ops_obj, op_ctxs, snapshot_options); scope.escape(context) } @@ -657,84 +651,3 @@ pub fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef<str>) { let exception = v8::Exception::type_error(scope, message); scope.throw_exception(exception); } - -struct AsyncOpsInfo { - ptr: *const OpCtx, - len: usize, -} - -impl<'s> IntoIterator for &'s AsyncOpsInfo { - type Item = &'s OpCtx; - type IntoIter = AsyncOpsInfoIterator<'s>; - - fn into_iter(self) -> Self::IntoIter { - AsyncOpsInfoIterator { - // SAFETY: OpCtx slice is valid for the lifetime of the Isolate - info: unsafe { std::slice::from_raw_parts(self.ptr, self.len) }, - index: 0, - } - } -} - -struct AsyncOpsInfoIterator<'s> { - info: &'s [OpCtx], - index: usize, -} - -impl<'s> Iterator for AsyncOpsInfoIterator<'s> { - type Item = &'s OpCtx; - - fn next(&mut self) -> Option<Self::Item> { - loop { - match self.info.get(self.index) { - Some(ctx) if ctx.decl.is_async => { - self.index += 1; - return Some(ctx); - } - Some(_) => { - self.index += 1; - } - None => return None, - } - } - } -} - -fn async_ops_info( - scope: &mut v8::HandleScope, - args: v8::FunctionCallbackArguments, - mut rv: v8::ReturnValue, -) { - let async_op_names = v8::Object::new(scope); - let external: v8::Local<v8::External> = args.data().try_into().unwrap(); - let info: &AsyncOpsInfo = - // SAFETY: external is guaranteed to be a valid pointer to AsyncOpsInfo - unsafe { &*(external.value() as *const AsyncOpsInfo) }; - for ctx in info { - let name = v8::String::new(scope, ctx.decl.name).unwrap(); - let argc = v8::Integer::new(scope, ctx.decl.argc as i32); - async_op_names.set(scope, name.into(), argc.into()); - } - rv.set(async_op_names.into()); -} - -fn initialize_async_ops_info( - scope: &mut v8::HandleScope, - ops_obj: v8::Local<v8::Object>, - op_ctxs: &[OpCtx], -) { - let key = v8::String::new(scope, "asyncOpsInfo").unwrap(); - let external = v8::External::new( - scope, - Box::into_raw(Box::new(AsyncOpsInfo { - ptr: op_ctxs as *const [OpCtx] as _, - len: op_ctxs.len(), - })) as *mut c_void, - ); - let val = v8::Function::builder(async_ops_info) - .data(external.into()) - .build(scope) - .unwrap(); - val.set_name(key); - ops_obj.set(scope, key.into(), val.into()); -} diff --git a/core/examples/http_bench_json_ops/http_bench_json_ops.js b/core/examples/http_bench_json_ops/http_bench_json_ops.js index 9650804c7..5a205188b 100644 --- a/core/examples/http_bench_json_ops/http_bench_json_ops.js +++ b/core/examples/http_bench_json_ops/http_bench_json_ops.js @@ -2,9 +2,8 @@ // This is not a real HTTP server. We read blindly one time into 'requestBuf', // then write this fixed 'responseBuf'. The point of this benchmark is to // exercise the event loop in a simple yet semi-realistic way. -Deno.core.initializeAsyncOps(); -const { ops } = Deno.core; +const { ops, opAsync } = Deno.core; const requestBuf = new Uint8Array(64 * 1024); const responseBuf = new Uint8Array( @@ -20,11 +19,11 @@ function listen() { /** Accepts a connection, returns rid. */ function accept(serverRid) { - return ops.op_accept(serverRid); + return opAsync("op_accept", serverRid); } function read(serverRid, buf) { - return ops.op_read_socket(serverRid, buf); + return opAsync("op_read_socket", serverRid, buf); } async function serve(rid) { diff --git a/core/runtime.rs b/core/runtime.rs index 1f325ad32..81314f0bf 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -322,12 +322,6 @@ impl SnapshotOptions { SnapshotOptions::Load | SnapshotOptions::CreateFromExisting ) } - pub fn will_snapshot(&self) -> bool { - matches!( - self, - SnapshotOptions::Create | SnapshotOptions::CreateFromExisting - ) - } fn from_bools(snapshot_loaded: bool, will_snapshot: bool) -> Self { match (snapshot_loaded, will_snapshot) { @@ -2923,10 +2917,10 @@ pub mod tests { .execute_script( "filename.js", r#" - Deno.core.initializeAsyncOps(); + var promiseIdSymbol = Symbol.for("Deno.core.internalPromiseId"); - var p1 = Deno.core.ops.op_test(42); - var p2 = Deno.core.ops.op_test(42); + var p1 = Deno.core.opAsync("op_test", 42); + var p2 = Deno.core.opAsync("op_test", 42); "#, ) .unwrap(); @@ -2979,7 +2973,7 @@ pub mod tests { "filename.js", r#" let control = 42; - Deno.core.initializeAsyncOps(); + Deno.core.opAsync("op_test", control); async function main() { Deno.core.opAsync("op_test", control); @@ -2998,7 +2992,7 @@ pub mod tests { .execute_script( "filename.js", r#" - Deno.core.initializeAsyncOps(); + const p = Deno.core.opAsync("op_test", 42); if (p[Symbol.for("Deno.core.internalPromiseId")] == undefined) { throw new Error("missing id on returned promise"); @@ -3015,7 +3009,7 @@ pub mod tests { .execute_script( "filename.js", r#" - Deno.core.initializeAsyncOps(); + Deno.core.opAsync("op_test"); "#, ) @@ -3030,7 +3024,7 @@ pub mod tests { .execute_script( "filename.js", r#" - Deno.core.initializeAsyncOps(); + let zero_copy_a = new Uint8Array([0]); Deno.core.opAsync("op_test", null, zero_copy_a); "#, @@ -3904,7 +3898,7 @@ if (errMessage !== "higher-level sync error: original sync error") { .execute_script( "test_error_context_async.js", r#" -Deno.core.initializeAsyncOps(); + (async () => { let errMessage; try { @@ -4059,7 +4053,7 @@ assertEquals(1, notify_return_value); runtime .execute_script( "op_async_borrow.js", - "Deno.core.initializeAsyncOps(); Deno.core.ops.op_async_borrow()", + "Deno.core.opAsync(\"op_async_borrow\")", ) .unwrap(); runtime.run_event_loop(false).await.unwrap(); @@ -4133,8 +4127,8 @@ Deno.core.ops.op_sync_serialize_object_with_numbers_as_keys({ .execute_script( "op_async_serialize_object_with_numbers_as_keys.js", r#" -Deno.core.initializeAsyncOps(); -Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ + +Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { lines: { 100: { unit: "m" @@ -4172,7 +4166,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ .execute_script( "macrotasks_and_nextticks.js", r#" - Deno.core.initializeAsyncOps(); + (async function () { const results = []; Deno.core.ops.op_set_macrotask_callback(() => { @@ -4440,12 +4434,12 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ "", &format!( r#" - Deno.core.initializeAsyncOps(); + globalThis.rejectValue = undefined; Deno.core.setPromiseRejectCallback((_type, _promise, reason) => {{ globalThis.rejectValue = `{realm_name}/${{reason}}`; }}); - Deno.core.ops.op_void_async().then(() => Promise.reject({number})); + Deno.core.opAsync("op_void_async").then(() => Promise.reject({number})); "# ), ) @@ -4876,12 +4870,12 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ runtime.v8_isolate(), "", r#" - Deno.core.initializeAsyncOps(); + (async function () { - const buf = await Deno.core.ops.op_test(false); + const buf = await Deno.core.opAsync("op_test", false); let err; try { - await Deno.core.ops.op_test(true); + await Deno.core.opAsync("op_test", true); } catch(e) { err = e; } @@ -4930,8 +4924,8 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ runtime.v8_isolate(), "", r#" - Deno.core.initializeAsyncOps(); - var promise = Deno.core.ops.op_pending(); + + var promise = Deno.core.opAsync("op_pending"); "#, ) .unwrap(); @@ -4940,8 +4934,8 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({ runtime.v8_isolate(), "", r#" - Deno.core.initializeAsyncOps(); - var promise = Deno.core.ops.op_pending(); + + var promise = Deno.core.opAsync("op_pending"); "#, ) .unwrap(); diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index da5b5f1b8..ffb479c32 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -390,7 +390,6 @@ function bootstrapMainRuntime(runtimeOptions) { throw new Error("Worker runtime already bootstrapped"); } - core.initializeAsyncOps(); performance.setTimeOrigin(DateNow()); globalThis_ = globalThis; @@ -523,7 +522,6 @@ function bootstrapWorkerRuntime( throw new Error("Worker runtime already bootstrapped"); } - core.initializeAsyncOps(); performance.setTimeOrigin(DateNow()); globalThis_ = globalThis; |