From 936d265f8ab07ec49be72783236bfda3085f62a2 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 26 Dec 2023 18:30:26 -0700 Subject: [PATCH] perf: remove opAsync (#21690) `opAsync` requires a lookup by name on each async call. This is a mechanical translation of all opAsync calls to ensureFastOps. The `opAsync` API on Deno.core will be removed at a later time. --- cli/bench/http/deno_http_ops.js | 43 --------- cli/tests/unit/cron_test.ts | 7 +- ext/broadcast_channel/01_broadcast_channel.js | 8 +- ext/cron/01_cron.ts | 12 ++- ext/crypto/00_crypto.js | 65 ++++++++------ ext/fetch/26_fetch.js | 6 +- ext/ffi/00_ffi.js | 22 ++--- ext/fs/30_fs.js | 90 ++++++++++--------- ext/http/01_http.js | 25 +++--- ext/kv/01_db.ts | 35 ++++---- ext/net/01_net.js | 62 +++++++------ ext/net/02_tls.js | 16 ++-- ext/net/lib.rs | 26 ++++++ ext/node/polyfills/_brotli.js | 6 +- ext/node/polyfills/_zlib_binding.mjs | 6 +- ext/node/polyfills/http.ts | 9 +- ext/node/polyfills/http2.ts | 35 ++++---- ext/node/polyfills/internal/child_process.ts | 9 +- .../polyfills/internal/crypto/_randomFill.mjs | 5 +- ext/node/polyfills/internal/crypto/hkdf.ts | 5 +- ext/node/polyfills/internal/crypto/keygen.ts | 32 ++++--- ext/node/polyfills/internal/crypto/pbkdf2.ts | 4 +- ext/node/polyfills/internal/crypto/scrypt.ts | 6 +- ext/web/06_streams.js | 7 +- ext/web/09_file.js | 7 +- ext/web/13_message_port.js | 6 +- ext/webgpu/01_webgpu.js | 18 ++-- runtime/js/11_workers.js | 8 +- runtime/js/40_fs_events.js | 5 +- runtime/js/40_process.js | 8 +- runtime/js/40_signals.js | 5 +- runtime/js/99_main.js | 4 +- 32 files changed, 344 insertions(+), 258 deletions(-) delete mode 100644 cli/bench/http/deno_http_ops.js diff --git a/cli/bench/http/deno_http_ops.js b/cli/bench/http/deno_http_ops.js deleted file mode 100644 index 216a47905d..0000000000 --- a/cli/bench/http/deno_http_ops.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -const addr = Deno.args[0] || "127.0.0.1:4500"; -const [hostname, port] = addr.split(":"); -const tcp = Deno.listen({ hostname, port: Number(port) }); -console.log("Server listening on", addr); - -class Http { - id; - constructor(id) { - this.id = id; - } - [Symbol.asyncIterator]() { - return { - next: async () => { - const reqEvt = await Deno[Deno.internal].core.opAsync( - "op_http_accept", - this.id, - ); - return { value: reqEvt ?? undefined, done: reqEvt === null }; - }, - }; - } -} - -for await (const conn of tcp) { - const id = Deno[Deno.internal].core.ops.op_http_start(conn.rid); - const http = new Http(id); - (async () => { - for await (const req of http) { - if (req == null) continue; - const { 0: stream } = req; - await Deno[Deno.internal].core.opAsync( - "op_http_write_headers", - stream, - 200, - [], - "Hello World", - ); - Deno[Deno.internal].core.close(stream); - } - })(); -} diff --git a/cli/tests/unit/cron_test.ts b/cli/tests/unit/cron_test.ts index 2a146bcfa5..8c484af320 100644 --- a/cli/tests/unit/cron_test.ts +++ b/cli/tests/unit/cron_test.ts @@ -1,9 +1,12 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. import { assertEquals, assertThrows } from "./test_util.ts"; -import { + +// @ts-ignore This is not publicly typed namespace, but it's there for sure. +const { formatToCronSchedule, parseScheduleToString, -} from "../../../ext/cron/01_cron.ts"; + // @ts-expect-error TypeScript (as of 3.7) does not support indexing namespaces by symbol +} = Deno[Deno.internal]; const sleep = (time: number) => new Promise((r) => setTimeout(r, time)); diff --git a/ext/broadcast_channel/01_broadcast_channel.js b/ext/broadcast_channel/01_broadcast_channel.js index 0e95fe3cd7..85f45a5d68 100644 --- a/ext/broadcast_channel/01_broadcast_channel.js +++ b/ext/broadcast_channel/01_broadcast_channel.js @@ -14,6 +14,10 @@ import { } from "ext:deno_web/02_event.js"; import { defer } from "ext:deno_web/02_timers.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; +const { + op_broadcast_recv, + op_broadcast_send, +} = core.ensureFastOps(); const { ArrayPrototypeIndexOf, ArrayPrototypePush, @@ -32,7 +36,7 @@ let rid = null; async function recv() { while (channels.length > 0) { - const message = await core.opAsync("op_broadcast_recv", rid); + const message = await op_broadcast_recv(rid); if (message === null) { break; @@ -118,7 +122,7 @@ class BroadcastChannel extends EventTarget { // Send to listeners in other VMs. defer(() => { if (!this[_closed]) { - core.opAsync("op_broadcast_send", rid, this[_name], data); + op_broadcast_send(rid, this[_name], data); } }); } diff --git a/ext/cron/01_cron.ts b/ext/cron/01_cron.ts index 4a52506180..07b2f26eb1 100644 --- a/ext/cron/01_cron.ts +++ b/ext/cron/01_cron.ts @@ -1,7 +1,9 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -// @ts-ignore internal api -const core = Deno.core; +import { core, internals } from "ext:core/mod.js"; +const { + op_cron_next, +} = core.ensureFastOps(); export function formatToCronSchedule( value?: number | { exact: number | number[] } | { @@ -122,7 +124,7 @@ function cron( return (async () => { let success = true; while (true) { - const r = await core.opAsync("op_cron_next", rid, success); + const r = await op_cron_next(rid, success); if (r === false) { break; } @@ -138,4 +140,8 @@ function cron( })(); } +// For testing +internals.formatToCronSchedule = formatToCronSchedule; +internals.parseScheduleToString = parseScheduleToString; + export { cron }; diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index f20de7a409..72744e3716 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -8,6 +8,16 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; +const { + op_crypto_decrypt, + op_crypto_derive_bits, + op_crypto_encrypt, + op_crypto_generate_key, + op_crypto_sign_key, + op_crypto_subtle_digest, + op_crypto_verify_key, +} = core.ensureFastOps(); + import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; @@ -491,8 +501,7 @@ class SubtleCrypto { algorithm = normalizeAlgorithm(algorithm, "digest"); - const result = await core.opAsync( - "op_crypto_subtle_digest", + const result = await op_crypto_subtle_digest( algorithm.name, data, ); @@ -605,7 +614,7 @@ class SubtleCrypto { // 3-5. const hashAlgorithm = key[_algorithm].hash.name; - const plainText = await core.opAsync("op_crypto_decrypt", { + const plainText = await op_crypto_decrypt({ key: keyData, algorithm: "RSA-OAEP", hash: hashAlgorithm, @@ -626,7 +635,7 @@ class SubtleCrypto { ); } - const plainText = await core.opAsync("op_crypto_decrypt", { + const plainText = await op_crypto_decrypt({ key: keyData, algorithm: "AES-CBC", iv: normalizedAlgorithm.iv, @@ -660,7 +669,7 @@ class SubtleCrypto { } // 3. - const cipherText = await core.opAsync("op_crypto_decrypt", { + const cipherText = await op_crypto_decrypt({ key: keyData, algorithm: "AES-CTR", keyLength: key[_algorithm].length, @@ -728,7 +737,7 @@ class SubtleCrypto { } // 5-8. - const plaintext = await core.opAsync("op_crypto_decrypt", { + const plaintext = await op_crypto_decrypt({ key: keyData, algorithm: "AES-GCM", length: key[_algorithm].length, @@ -801,7 +810,7 @@ class SubtleCrypto { // 2. const hashAlgorithm = key[_algorithm].hash.name; - const signature = await core.opAsync("op_crypto_sign_key", { + const signature = await op_crypto_sign_key({ key: keyData, algorithm: "RSASSA-PKCS1-v1_5", hash: hashAlgorithm, @@ -820,7 +829,7 @@ class SubtleCrypto { // 2. const hashAlgorithm = key[_algorithm].hash.name; - const signature = await core.opAsync("op_crypto_sign_key", { + const signature = await op_crypto_sign_key({ key: keyData, algorithm: "RSA-PSS", hash: hashAlgorithm, @@ -857,7 +866,7 @@ class SubtleCrypto { ); } - const signature = await core.opAsync("op_crypto_sign_key", { + const signature = await op_crypto_sign_key({ key: keyData, algorithm: "ECDSA", hash: hashAlgorithm, @@ -869,7 +878,7 @@ class SubtleCrypto { case "HMAC": { const hashAlgorithm = key[_algorithm].hash.name; - const signature = await core.opAsync("op_crypto_sign_key", { + const signature = await op_crypto_sign_key({ key: keyData, algorithm: "HMAC", hash: hashAlgorithm, @@ -1297,7 +1306,7 @@ class SubtleCrypto { } const hashAlgorithm = key[_algorithm].hash.name; - return await core.opAsync("op_crypto_verify_key", { + return await op_crypto_verify_key({ key: keyData, algorithm: "RSASSA-PKCS1-v1_5", hash: hashAlgorithm, @@ -1313,7 +1322,7 @@ class SubtleCrypto { } const hashAlgorithm = key[_algorithm].hash.name; - return await core.opAsync("op_crypto_verify_key", { + return await op_crypto_verify_key({ key: keyData, algorithm: "RSA-PSS", hash: hashAlgorithm, @@ -1323,7 +1332,7 @@ class SubtleCrypto { } case "HMAC": { const hash = key[_algorithm].hash.name; - return await core.opAsync("op_crypto_verify_key", { + return await op_crypto_verify_key({ key: keyData, algorithm: "HMAC", hash, @@ -1352,7 +1361,7 @@ class SubtleCrypto { } // 3-8. - return await core.opAsync("op_crypto_verify_key", { + return await op_crypto_verify_key({ key: keyData, algorithm: "ECDSA", hash, @@ -1739,8 +1748,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) { } // 2. - const keyData = await core.opAsync( - "op_crypto_generate_key", + const keyData = await op_crypto_generate_key( { algorithm: "RSA", modulusLength: normalizedAlgorithm.modulusLength, @@ -1799,8 +1807,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) { } // 2. - const keyData = await core.opAsync( - "op_crypto_generate_key", + const keyData = await op_crypto_generate_key( { algorithm: "RSA", modulusLength: normalizedAlgorithm.modulusLength, @@ -1863,7 +1870,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) { namedCurve, ) ) { - const keyData = await core.opAsync("op_crypto_generate_key", { + const keyData = await op_crypto_generate_key({ algorithm: "EC", namedCurve, }); @@ -1923,7 +1930,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) { namedCurve, ) ) { - const keyData = await core.opAsync("op_crypto_generate_key", { + const keyData = await op_crypto_generate_key({ algorithm: "EC", namedCurve, }); @@ -2107,7 +2114,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) { } // 3-4. - const keyData = await core.opAsync("op_crypto_generate_key", { + const keyData = await op_crypto_generate_key({ algorithm: "HMAC", hash: normalizedAlgorithm.hash.name, length, @@ -4318,7 +4325,7 @@ async function generateKeyAES(normalizedAlgorithm, extractable, usages) { } // 3. - const keyData = await core.opAsync("op_crypto_generate_key", { + const keyData = await op_crypto_generate_key({ algorithm: "AES", length: normalizedAlgorithm.length, }); @@ -4367,7 +4374,7 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) { normalizedAlgorithm.salt = copyBuffer(normalizedAlgorithm.salt); - const buf = await core.opAsync("op_crypto_derive_bits", { + const buf = await op_crypto_derive_bits({ key: keyData, algorithm: "PBKDF2", hash: normalizedAlgorithm.hash.name, @@ -4416,7 +4423,7 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) { const publicKeyhandle = publicKey[_handle]; const publicKeyData = WeakMapPrototypeGet(KEY_STORE, publicKeyhandle); - const buf = await core.opAsync("op_crypto_derive_bits", { + const buf = await op_crypto_derive_bits({ key: baseKeyData, publicKey: publicKeyData, algorithm: "ECDH", @@ -4453,7 +4460,7 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) { normalizedAlgorithm.info = copyBuffer(normalizedAlgorithm.info); - const buf = await core.opAsync("op_crypto_derive_bits", { + const buf = await op_crypto_derive_bits({ key: keyDerivationKey, algorithm: "HKDF", hash: normalizedAlgorithm.hash.name, @@ -4540,7 +4547,7 @@ async function encrypt(normalizedAlgorithm, key, data) { // 3-5. const hashAlgorithm = key[_algorithm].hash.name; - const cipherText = await core.opAsync("op_crypto_encrypt", { + const cipherText = await op_crypto_encrypt({ key: keyData, algorithm: "RSA-OAEP", hash: hashAlgorithm, @@ -4562,7 +4569,7 @@ async function encrypt(normalizedAlgorithm, key, data) { } // 2. - const cipherText = await core.opAsync("op_crypto_encrypt", { + const cipherText = await op_crypto_encrypt({ key: keyData, algorithm: "AES-CBC", length: key[_algorithm].length, @@ -4596,7 +4603,7 @@ async function encrypt(normalizedAlgorithm, key, data) { } // 3. - const cipherText = await core.opAsync("op_crypto_encrypt", { + const cipherText = await op_crypto_encrypt({ key: keyData, algorithm: "AES-CTR", keyLength: key[_algorithm].length, @@ -4664,7 +4671,7 @@ async function encrypt(normalizedAlgorithm, key, data) { ); } // 6-7. - const cipherText = await core.opAsync("op_crypto_encrypt", { + const cipherText = await op_crypto_encrypt({ key: keyData, algorithm: "AES-GCM", length: key[_algorithm].length, diff --git a/ext/fetch/26_fetch.js b/ext/fetch/26_fetch.js index b70d6d8733..2391dcbdbd 100644 --- a/ext/fetch/26_fetch.js +++ b/ext/fetch/26_fetch.js @@ -12,6 +12,10 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; +const { + op_fetch_send, +} = core.ensureFastOps(); + import * as webidl from "ext:deno_webidl/00_webidl.js"; import { byteLowerCase } from "ext:deno_web/00_infra.js"; import { @@ -62,7 +66,7 @@ const REQUEST_BODY_HEADER_NAMES = [ * @returns {Promise<{ status: number, statusText: string, headers: [string, string][], url: string, responseRid: number, error: string? }>} */ function opFetchSend(rid) { - return core.opAsync("op_fetch_send", rid); + return op_fetch_send(rid); } /** diff --git a/ext/ffi/00_ffi.js b/ext/ffi/00_ffi.js index ef9123442e..7cc3bb9829 100644 --- a/ext/ffi/00_ffi.js +++ b/ext/ffi/00_ffi.js @@ -33,6 +33,13 @@ const { SafeWeakMap, } = primordials; import { pathFromURL } from "ext:deno_web/00_infra.js"; +const { + op_ffi_call_nonblocking, + op_ffi_unsafe_callback_ref, +} = core.ensureFastOps(); +const { + op_ffi_call_ptr_nonblocking, +} = core.ensureFastOps(true); /** * @param {BufferSource} source @@ -275,8 +282,7 @@ class UnsafeFnPointer { call(...parameters) { if (this.definition.nonblocking) { if (this.#structSize === null) { - return core.opAsync( - "op_ffi_call_ptr_nonblocking", + return op_ffi_call_ptr_nonblocking( this.pointer, this.definition, parameters, @@ -284,8 +290,7 @@ class UnsafeFnPointer { } else { const buffer = new Uint8Array(this.#structSize); return PromisePrototypeThen( - core.opAsync( - "op_ffi_call_ptr_nonblocking", + op_ffi_call_ptr_nonblocking( this.pointer, this.definition, parameters, @@ -420,8 +425,7 @@ class UnsafeCallback { // Re-refing core.refOpPromise(this.#refpromise); } else { - this.#refpromise = core.opAsync( - "op_ffi_unsafe_callback_ref", + this.#refpromise = op_ffi_unsafe_callback_ref( this.#rid, ); } @@ -508,8 +512,7 @@ class DynamicLibrary { value: (...parameters) => { if (isStructResult) { const buffer = new Uint8Array(structSize); - const ret = core.opAsync( - "op_ffi_call_nonblocking", + const ret = op_ffi_call_nonblocking( this.#rid, symbol, parameters, @@ -520,8 +523,7 @@ class DynamicLibrary { () => buffer, ); } else { - return core.opAsync( - "op_ffi_call_nonblocking", + return op_ffi_call_nonblocking( this.#rid, symbol, parameters, diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js index 29c6c4aace..a43a5297cb 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -8,7 +8,32 @@ const { op_fs_truncate_async, op_fs_link_async, op_fs_flock_async, -} = Deno.core.ensureFastOps(); + op_fs_chown_async, + op_fs_copy_file_async, + op_fs_fdatasync_async, + op_fs_fstat_async, + op_fs_fsync_async, + op_fs_funlock_async, + op_fs_futime_async, + op_fs_lstat_async, + op_fs_make_temp_dir_async, + op_fs_make_temp_file_async, + op_fs_mkdir_async, + op_fs_open_async, + op_fs_read_dir_async, + op_fs_read_file_async, + op_fs_read_file_text_async, + op_fs_read_link_async, + op_fs_realpath_async, + op_fs_remove_async, + op_fs_rename_async, + op_fs_seek_async, + op_fs_stat_async, + op_fs_symlink_async, + op_fs_utime_async, + op_fs_write_file_async, +} = core.ensureFastOps(); + const { ArrayPrototypeFilter, Date, @@ -56,8 +81,7 @@ async function chown( uid, gid, ) { - await core.opAsync( - "op_fs_chown_async", + await op_fs_chown_async( pathFromURL(path), uid, gid, @@ -78,8 +102,7 @@ async function copyFile( fromPath, toPath, ) { - await core.opAsync( - "op_fs_copy_file_async", + await op_fs_copy_file_async( pathFromURL(fromPath), pathFromURL(toPath), ); @@ -102,8 +125,7 @@ function makeTempDirSync(options = {}) { } function makeTempDir(options = {}) { - return core.opAsync( - "op_fs_make_temp_dir_async", + return op_fs_make_temp_dir_async( options.dir, options.prefix, options.suffix, @@ -119,8 +141,7 @@ function makeTempFileSync(options = {}) { } function makeTempFile(options = {}) { - return core.opAsync( - "op_fs_make_temp_file_async", + return op_fs_make_temp_file_async( options.dir, options.prefix, options.suffix, @@ -136,8 +157,7 @@ function mkdirSync(path, options) { } async function mkdir(path, options) { - await core.opAsync( - "op_fs_mkdir_async", + await op_fs_mkdir_async( pathFromURL(path), options?.recursive ?? false, options?.mode, @@ -151,8 +171,7 @@ function readDirSync(path) { } function readDir(path) { - const array = core.opAsync( - "op_fs_read_dir_async", + const array = op_fs_read_dir_async( pathFromURL(path), ); return { @@ -170,7 +189,7 @@ function readLinkSync(path) { } function readLink(path) { - return core.opAsync("op_fs_read_link_async", pathFromURL(path)); + return op_fs_read_link_async(pathFromURL(path)); } function realPathSync(path) { @@ -178,7 +197,7 @@ function realPathSync(path) { } function realPath(path) { - return core.opAsync("op_fs_realpath_async", pathFromURL(path)); + return op_fs_realpath_async(pathFromURL(path)); } function removeSync( @@ -195,8 +214,7 @@ async function remove( path, options = {}, ) { - await core.opAsync( - "op_fs_remove_async", + await op_fs_remove_async( pathFromURL(path), !!options.recursive, ); @@ -210,8 +228,7 @@ function renameSync(oldpath, newpath) { } async function rename(oldpath, newpath) { - await core.opAsync( - "op_fs_rename_async", + await op_fs_rename_async( pathFromURL(oldpath), pathFromURL(newpath), ); @@ -340,11 +357,11 @@ function fstatSync(rid) { } async function fstat(rid) { - return parseFileInfo(await core.opAsync("op_fs_fstat_async", rid)); + return parseFileInfo(await op_fs_fstat_async(rid)); } async function lstat(path) { - const res = await core.opAsync("op_fs_lstat_async", pathFromURL(path)); + const res = await op_fs_lstat_async(pathFromURL(path)); return parseFileInfo(res); } @@ -354,7 +371,7 @@ function lstatSync(path) { } async function stat(path) { - const res = await core.opAsync("op_fs_stat_async", pathFromURL(path)); + const res = await op_fs_stat_async(pathFromURL(path)); return parseFileInfo(res); } @@ -436,8 +453,7 @@ async function futime( ) { const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - await core.opAsync( - "op_fs_futime_async", + await op_fs_futime_async( rid, atimeSec, atimeNsec, @@ -469,8 +485,7 @@ async function utime( ) { const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - await core.opAsync( - "op_fs_utime_async", + await op_fs_utime_async( pathFromURL(path), atimeSec, atimeNsec, @@ -496,8 +511,7 @@ async function symlink( newpath, options, ) { - await core.opAsync( - "op_fs_symlink_async", + await op_fs_symlink_async( pathFromURL(oldpath), pathFromURL(newpath), options?.type, @@ -509,7 +523,7 @@ function fdatasyncSync(rid) { } async function fdatasync(rid) { - await core.opAsync("op_fs_fdatasync_async", rid); + await op_fs_fdatasync_async(rid); } function fsyncSync(rid) { @@ -517,7 +531,7 @@ function fsyncSync(rid) { } async function fsync(rid) { - await core.opAsync("op_fs_fsync_async", rid); + await op_fs_fsync_async(rid); } function flockSync(rid, exclusive) { @@ -533,7 +547,7 @@ function funlockSync(rid) { } async function funlock(rid) { - await core.opAsync("op_fs_funlock_async", rid); + await op_fs_funlock_async(rid); } function seekSync( @@ -549,7 +563,7 @@ function seek( offset, whence, ) { - return core.opAsync("op_fs_seek_async", rid, offset, whence); + return op_fs_seek_async(rid, offset, whence); } function openSync( @@ -570,8 +584,7 @@ async function open( options, ) { if (options) checkOpenOptions(options); - const rid = await core.opAsync( - "op_fs_open_async", + const rid = await op_fs_open_async( pathFromURL(path), options, ); @@ -716,8 +729,7 @@ async function readFile(path, options) { } try { - const read = await core.opAsync( - "op_fs_read_file_async", + const read = await op_fs_read_file_async( pathFromURL(path), cancelRid, ); @@ -747,8 +759,7 @@ async function readTextFile(path, options) { } try { - const read = await core.opAsync( - "op_fs_read_file_text_async", + const read = await op_fs_read_file_text_async( pathFromURL(path), cancelRid, ); @@ -805,8 +816,7 @@ async function writeFile( signal: options.signal, }); } else { - await core.opAsync( - "op_fs_write_file_async", + await op_fs_write_file_async( pathFromURL(path), options.mode, options.append ?? false, diff --git a/ext/http/01_http.js b/ext/http/01_http.js index 309e44ee46..1953895fd6 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -2,7 +2,6 @@ import { core, internals, primordials } from "ext:core/mod.js"; const { BadResourcePrototype, InterruptedPrototype, ops } = core; -const { op_http_write } = Deno.core.ensureFastOps(); import { InnerBody } from "ext:deno_fetch/22_body.js"; import { Event, setEventTargetData } from "ext:deno_web/02_event.js"; import { BlobPrototype } from "ext:deno_web/09_file.js"; @@ -64,6 +63,15 @@ const { Uint8Array, Uint8ArrayPrototype, } = primordials; +const { + op_http_accept, + op_http_shutdown, + op_http_upgrade, + op_http_write, + op_http_upgrade_websocket, + op_http_write_headers, + op_http_write_resource, +} = core.ensureFastOps(); const connErrorSymbol = Symbol("connError"); const _deferred = Symbol("upgradeHttpDeferred"); @@ -103,7 +111,7 @@ class HttpConn { async nextRequest() { let nextRequest; try { - nextRequest = await core.opAsync("op_http_accept", this.#rid); + nextRequest = await op_http_accept(this.#rid); } catch (error) { this.close(); // A connection error seen here would cause disrupted responses to throw @@ -267,8 +275,7 @@ function createRespondWith( ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, respBody) ); try { - await core.opAsync( - "op_http_write_headers", + await op_http_write_headers( streamRid, innerResp.status ?? 200, innerResp.headerList, @@ -308,8 +315,7 @@ function createRespondWith( } reader = respBody.getReader(); // Acquire JS lock. try { - await core.opAsync( - "op_http_write_resource", + await op_http_write_resource( streamRid, resourceBacking.rid, ); @@ -357,7 +363,7 @@ function createRespondWith( if (success) { try { - await core.opAsync("op_http_shutdown", streamRid); + await op_http_shutdown(streamRid); } catch (error) { await reader.cancel(error); throw error; @@ -367,7 +373,7 @@ function createRespondWith( const deferred = request[_deferred]; if (deferred) { - const res = await core.opAsync("op_http_upgrade", streamRid); + const res = await op_http_upgrade(streamRid); let conn; if (res.connType === "tcp") { conn = new TcpConn(res.connRid, remoteAddr, localAddr); @@ -383,8 +389,7 @@ function createRespondWith( } const ws = resp[_ws]; if (ws) { - const wsRid = await core.opAsync( - "op_http_upgrade_websocket", + const wsRid = await op_http_upgrade_websocket( streamRid, ); ws[_rid] = wsRid; diff --git a/ext/kv/01_db.ts b/ext/kv/01_db.ts index 1817f9f07e..99efad8444 100644 --- a/ext/kv/01_db.ts +++ b/ext/kv/01_db.ts @@ -17,6 +17,14 @@ import { SymbolDispose } from "ext:deno_web/00_infra.js"; import { ReadableStream } from "ext:deno_web/06_streams.js"; const core = Deno.core; const ops = core.ops; +const { + op_kv_atomic_write, + op_kv_database_open, + op_kv_dequeue_next_message, + op_kv_finish_dequeued_message, + op_kv_snapshot_read, + op_kv_watch_next, +} = core.ensureFastOps(); const encodeCursor: ( selector: [Deno.KvKey | null, Deno.KvKey | null, Deno.KvKey | null], @@ -25,7 +33,7 @@ const encodeCursor: ( ops.op_kv_encode_cursor(selector, boundaryKey); async function openKv(path: string) { - const rid = await core.opAsync("op_kv_database_open", path); + const rid = await op_kv_database_open(path); return new Kv(rid, kvSymbol); } @@ -100,8 +108,7 @@ class Kv { } async get(key: Deno.KvKey, opts?: { consistency?: Deno.KvConsistencyLevel }) { - const [entries]: [RawKvEntry[]] = await core.opAsync( - "op_kv_snapshot_read", + const [entries]: [RawKvEntry[]] = await op_kv_snapshot_read( this.#rid, [[ null, @@ -127,8 +134,7 @@ class Kv { keys: Deno.KvKey[], opts?: { consistency?: Deno.KvConsistencyLevel }, ): Promise[]> { - const ranges: RawKvEntry[][] = await core.opAsync( - "op_kv_snapshot_read", + const ranges: RawKvEntry[][] = await op_kv_snapshot_read( this.#rid, keys.map((key) => [ null, @@ -209,8 +215,7 @@ class Kv { consistency: Deno.KvConsistencyLevel, ) => Promise[]> { return async (selector, cursor, reverse, consistency) => { - const [entries]: [RawKvEntry[]] = await core.opAsync( - "op_kv_snapshot_read", + const [entries]: [RawKvEntry[]] = await op_kv_snapshot_read( this.#rid, [[ "prefix" in selector ? selector.prefix : null, @@ -268,10 +273,10 @@ class Kv { const finishMessageOps = new Map>(); while (true) { // Wait for the next message. - const next: { 0: Uint8Array; 1: number } = await core.opAsync( - "op_kv_dequeue_next_message", - this.#rid, - ); + const next: { 0: Uint8Array; 1: number } = + await op_kv_dequeue_next_message( + this.#rid, + ); if (next === null) { break; } @@ -292,8 +297,7 @@ class Kv { } catch (error) { console.error("Exception in queue handler", error); } finally { - const promise: Promise = core.opAsync( - "op_kv_finish_dequeued_message", + const promise: Promise = op_kv_finish_dequeued_message( handleId, success, ); @@ -325,7 +329,7 @@ class Kv { while (true) { let updates; try { - updates = await core.opAsync("op_kv_watch_next", rid); + updates = await op_kv_watch_next(rid); } catch (err) { core.tryClose(rid); controller.error(err); @@ -768,8 +772,7 @@ async function doAtomicWriteInPlace( } } - return await core.opAsync( - "op_kv_atomic_write", + return await op_kv_atomic_write( rid, checks, mutations, diff --git a/ext/net/01_net.js b/ext/net/01_net.js index c81ca61c55..0f9a65122f 100644 --- a/ext/net/01_net.js +++ b/ext/net/01_net.js @@ -10,6 +10,23 @@ import { } from "ext:deno_web/06_streams.js"; import * as abortSignal from "ext:deno_web/03_abort_signal.js"; import { SymbolDispose } from "ext:deno_web/00_infra.js"; +const { + op_dns_resolve, + op_net_accept_tcp, + op_net_accept_unix, + op_net_connect_tcp, + op_net_connect_unix, + op_net_recv_udp, + op_net_recv_unixpacket, + op_net_send_udp, + op_net_send_unixpacket, + op_net_set_multi_loopback_udp, + op_net_set_multi_ttl_udp, + op_net_join_multi_v4_udp, + op_net_join_multi_v6_udp, + op_net_leave_multi_v4_udp, + op_net_leave_multi_v6_udp, +} = core.ensureFastOps(); const { Error, @@ -46,7 +63,7 @@ async function resolveDns(query, recordType, options) { } try { - return await core.opAsync("op_dns_resolve", { + return await op_dns_resolve({ cancelRid, query, recordType, @@ -200,10 +217,10 @@ class Listener { let promise; switch (this.addr.transport) { case "tcp": - promise = core.opAsync("op_net_accept_tcp", this.rid); + promise = op_net_accept_tcp(this.rid); break; case "unix": - promise = core.opAsync("op_net_accept_unix", this.rid); + promise = op_net_accept_unix(this.rid); break; default: throw new Error(`Unsupported transport: ${this.addr.transport}`); @@ -294,8 +311,7 @@ class Datagram { } async joinMulticastV4(addr, multiInterface) { - await core.opAsync( - "op_net_join_multi_v4_udp", + await op_net_join_multi_v4_udp( this.rid, addr, multiInterface, @@ -303,22 +319,19 @@ class Datagram { return { leave: () => - core.opAsync( - "op_net_leave_multi_v4_udp", + op_net_leave_multi_v4_udp( this.rid, addr, multiInterface, ), setLoopback: (loopback) => - core.opAsync( - "op_net_set_multi_loopback_udp", + op_net_set_multi_loopback_udp( this.rid, true, loopback, ), setTTL: (ttl) => - core.opAsync( - "op_net_set_multi_ttl_udp", + op_net_set_multi_ttl_udp( this.rid, ttl, ), @@ -326,8 +339,7 @@ class Datagram { } async joinMulticastV6(addr, multiInterface) { - await core.opAsync( - "op_net_join_multi_v6_udp", + await op_net_join_multi_v6_udp( this.rid, addr, multiInterface, @@ -335,15 +347,13 @@ class Datagram { return { leave: () => - core.opAsync( - "op_net_leave_multi_v6_udp", + op_net_leave_multi_v6_udp( this.rid, addr, multiInterface, ), setLoopback: (loopback) => - core.opAsync( - "op_net_set_multi_loopback_udp", + op_net_set_multi_loopback_udp( this.rid, false, loopback, @@ -357,8 +367,7 @@ class Datagram { let remoteAddr; switch (this.addr.transport) { case "udp": { - ({ 0: nread, 1: remoteAddr } = await core.opAsync( - "op_net_recv_udp", + ({ 0: nread, 1: remoteAddr } = await op_net_recv_udp( this.rid, buf, )); @@ -367,8 +376,7 @@ class Datagram { } case "unixpacket": { let path; - ({ 0: nread, 1: path } = await core.opAsync( - "op_net_recv_unixpacket", + ({ 0: nread, 1: path } = await op_net_recv_unixpacket( this.rid, buf, )); @@ -385,15 +393,13 @@ class Datagram { async send(p, opts) { switch (this.addr.transport) { case "udp": - return await core.opAsync( - "op_net_send_udp", + return await op_net_send_udp( this.rid, { hostname: opts.hostname ?? "127.0.0.1", port: opts.port }, p, ); case "unixpacket": - return await core.opAsync( - "op_net_send_unixpacket", + return await op_net_send_unixpacket( this.rid, opts.path, p, @@ -484,8 +490,7 @@ function createListenDatagram(udpOpFn, unixOpFn) { async function connect(args) { switch (args.transport ?? "tcp") { case "tcp": { - const { 0: rid, 1: localAddr, 2: remoteAddr } = await core.opAsync( - "op_net_connect_tcp", + const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tcp( { hostname: args.hostname ?? "127.0.0.1", port: args.port, @@ -496,8 +501,7 @@ async function connect(args) { return new TcpConn(rid, remoteAddr, localAddr); } case "unix": { - const { 0: rid, 1: localAddr, 2: remoteAddr } = await core.opAsync( - "op_net_connect_unix", + const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_unix( args.path, ); return new UnixConn( diff --git a/ext/net/02_tls.js b/ext/net/02_tls.js index a73e3ef047..492e5fc304 100644 --- a/ext/net/02_tls.js +++ b/ext/net/02_tls.js @@ -4,13 +4,19 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; import { Conn, Listener } from "ext:deno_net/01_net.js"; const { Number, TypeError } = primordials; +const { + op_tls_handshake, + op_tls_start, + op_net_accept_tls, + op_net_connect_tls, +} = core.ensureFastOps(); function opStartTls(args) { - return core.opAsync("op_tls_start", args); + return op_tls_start(args); } function opTlsHandshake(rid) { - return core.opAsync("op_tls_handshake", rid); + return op_tls_handshake(rid); } class TlsConn extends Conn { @@ -32,8 +38,7 @@ async function connectTls({ if (transport !== "tcp") { throw new TypeError(`Unsupported transport: '${transport}'`); } - const { 0: rid, 1: localAddr, 2: remoteAddr } = await core.opAsync( - "op_net_connect_tls", + const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tls( { hostname, port }, { certFile, caCerts, certChain, privateKey, alpnProtocols }, ); @@ -44,8 +49,7 @@ async function connectTls({ class TlsListener extends Listener { async accept() { - const { 0: rid, 1: localAddr, 2: remoteAddr } = await core.opAsync( - "op_net_accept_tls", + const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_accept_tls( this.rid, ); localAddr.transport = "tcp"; diff --git a/ext/net/lib.rs b/ext/net/lib.rs index fb8dda514c..1695fd264f 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -9,6 +9,7 @@ pub mod raw; pub mod resolve_addr; use deno_core::error::AnyError; +use deno_core::op2; use deno_core::OpState; use deno_tls::rustls::RootCertStore; use deno_tls::RootCertStoreProvider; @@ -96,6 +97,14 @@ deno_core::extension!(deno_net, #[cfg(unix)] ops_unix::op_node_unstable_net_listen_unixpacket

, #[cfg(unix)] ops_unix::op_net_recv_unixpacket, #[cfg(unix)] ops_unix::op_net_send_unixpacket

, + + #[cfg(not(unix))] op_net_accept_unix, + #[cfg(not(unix))] op_net_connect_unix, + #[cfg(not(unix))] op_net_listen_unix, + #[cfg(not(unix))] op_net_listen_unixpacket, + #[cfg(not(unix))] op_node_unstable_net_listen_unixpacket, + #[cfg(not(unix))] op_net_recv_unixpacket, + #[cfg(not(unix))] op_net_send_unixpacket, ], esm = [ "01_net.js", "02_tls.js" ], options = { @@ -111,3 +120,20 @@ deno_core::extension!(deno_net, )); }, ); + +macro_rules! stub_op { + ($name:ident) => { + #[op2(fast)] + fn $name() { + panic!("Unsupported on non-unix platforms") + } + }; +} + +stub_op!(op_net_accept_unix); +stub_op!(op_net_connect_unix); +stub_op!(op_net_listen_unix); +stub_op!(op_net_listen_unixpacket); +stub_op!(op_node_unstable_net_listen_unixpacket); +stub_op!(op_net_recv_unixpacket); +stub_op!(op_net_send_unixpacket); diff --git a/ext/node/polyfills/_brotli.js b/ext/node/polyfills/_brotli.js index 6f77bb341a..bf099759b3 100644 --- a/ext/node/polyfills/_brotli.js +++ b/ext/node/polyfills/_brotli.js @@ -7,9 +7,11 @@ import { zlib as constants } from "ext:deno_node/internal_binding/constants.ts"; import { TextEncoder } from "ext:deno_web/08_text_encoding.js"; import { Transform } from "node:stream"; import { Buffer } from "node:buffer"; - const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_brotli_compress_async, +} = core.ensureFastOps(); const enc = new TextEncoder(); const toU8 = (input) => { @@ -119,7 +121,7 @@ export function brotliCompress( } const { quality, lgwin, mode } = oneOffCompressOptions(options); - core.opAsync("op_brotli_compress_async", buf, quality, lgwin, mode) + op_brotli_compress_async(buf, quality, lgwin, mode) .then((result) => callback(null, result)) .catch((err) => callback(err)); } diff --git a/ext/node/polyfills/_zlib_binding.mjs b/ext/node/polyfills/_zlib_binding.mjs index 30bd1400ae..9cece7feb4 100644 --- a/ext/node/polyfills/_zlib_binding.mjs +++ b/ext/node/polyfills/_zlib_binding.mjs @@ -45,6 +45,9 @@ export const UNZIP = 7; const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_zlib_write_async, +} = core.ensureFastOps(); const writeResult = new Uint32Array(2); @@ -117,8 +120,7 @@ class Zlib { out_off, out_len, ) { - core.opAsync( - "op_zlib_write_async", + op_zlib_write_async( this.#handle, flush ?? Z_NO_FLUSH, input, diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts index e49f717023..8b7bcc21f2 100644 --- a/ext/node/polyfills/http.ts +++ b/ext/node/polyfills/http.ts @@ -60,6 +60,10 @@ import { timerId } from "ext:deno_web/03_abort_signal.js"; import { clearTimeout as webClearTimeout } from "ext:deno_web/02_timers.js"; import { resourceForReadableStream } from "ext:deno_web/06_streams.js"; import { TcpConn } from "ext:deno_net/01_net.js"; +const { + op_fetch_response_upgrade, + op_fetch_send, +} = core.ensureFastOps(); enum STATUS_CODES { /** RFC 7231, 6.2.1 */ @@ -656,7 +660,7 @@ class ClientRequest extends OutgoingMessage { (async () => { try { - const res = await core.opAsync("op_fetch_send", this._req.requestRid); + const res = await op_fetch_send(this._req.requestRid); try { cb?.(); } catch (_) { @@ -710,8 +714,7 @@ class ClientRequest extends OutgoingMessage { throw new Error("not implemented CONNECT"); } - const upgradeRid = await core.opAsync( - "op_fetch_response_upgrade", + const upgradeRid = await op_fetch_response_upgrade( res.responseRid, ); assert(typeof res.remoteAddrIp !== "undefined"); diff --git a/ext/node/polyfills/http2.ts b/ext/node/polyfills/http2.ts index bab607b80c..e3bba25e08 100644 --- a/ext/node/polyfills/http2.ts +++ b/ext/node/polyfills/http2.ts @@ -45,6 +45,14 @@ import { _checkIsHttpToken } from "ext:deno_node/_http_common.ts"; const { op_http2_connect, + op_http2_client_get_response, + op_http2_client_get_response_body_chunk, + op_http2_client_get_response_trailers, + op_http2_client_request, + op_http2_client_reset_stream, + op_http2_client_send_data, + op_http2_client_send_trailers, + op_http2_poll_client_connection, } = core.ensureFastOps(); const kSession = Symbol("session"); @@ -389,8 +397,7 @@ export class ClientHttp2Session extends Http2Session { this[kDenoConnRid] = connRid; (async () => { try { - const promise = core.opAsync( - "op_http2_poll_client_connection", + const promise = op_http2_poll_client_connection( this[kDenoConnRid], ); this[kPollConnPromise] = promise; @@ -725,8 +732,7 @@ async function clientHttp2Request( reqHeaders, ); - return await core.opAsync( - "op_http2_client_request", + return await op_http2_client_request( session[kDenoClientRid], pseudoHeaders, reqHeaders, @@ -786,8 +792,7 @@ export class ClientHttp2Stream extends Duplex { session[kDenoClientRid], this.#rid, ); - const response = await core.opAsync( - "op_http2_client_get_response", + const response = await op_http2_client_get_response( this.#rid, ); debugHttp2(">>> after get response", response); @@ -907,8 +912,7 @@ export class ClientHttp2Stream extends Duplex { this.#requestPromise .then(() => { debugHttp2(">>> _write", this.#rid, data, encoding, callback); - return core.opAsync( - "op_http2_client_send_data", + return op_http2_client_send_data( this.#rid, data, ); @@ -967,15 +971,13 @@ export class ClientHttp2Stream extends Duplex { debugHttp2(">>> read"); (async () => { - const [chunk, finished] = await core.opAsync( - "op_http2_client_get_response_body_chunk", + const [chunk, finished] = await op_http2_client_get_response_body_chunk( this[kDenoResponse].bodyRid, ); debugHttp2(">>> chunk", chunk, finished, this[kDenoResponse].bodyRid); if (chunk === null) { - const trailerList = await core.opAsync( - "op_http2_client_get_response_trailers", + const trailerList = await op_http2_client_get_response_trailers( this[kDenoResponse].bodyRid, ); if (trailerList) { @@ -1030,8 +1032,7 @@ export class ClientHttp2Stream extends Duplex { stream[kState].flags &= ~STREAM_FLAGS_HAS_TRAILERS; debugHttp2("sending trailers", this.#rid, trailers); - core.opAsync( - "op_http2_client_send_trailers", + op_http2_client_send_trailers( this.#rid, trailerList, ).then(() => { @@ -1207,8 +1208,7 @@ function finishCloseStream(stream, code) { if (stream.pending) { stream.push(null); stream.once("ready", () => { - core.opAsync( - "op_http2_client_reset_stream", + op_http2_client_reset_stream( stream[kDenoRid], code, ).then(() => { @@ -1224,8 +1224,7 @@ function finishCloseStream(stream, code) { }); } else { stream.resume(); - core.opAsync( - "op_http2_client_reset_stream", + op_http2_client_reset_stream( stream[kDenoRid], code, ).then(() => { diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index 39c7633e4f..7f40ce94b0 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -43,8 +43,11 @@ import { import { kEmptyObject } from "ext:deno_node/internal/util.mjs"; import { getValidatedPath } from "ext:deno_node/internal/fs/utils.mjs"; import process from "node:process"; - const core = globalThis.__bootstrap.core; +const { + op_node_ipc_read, + op_node_ipc_write, +} = core.ensureFastOps(); export function mapValues( record: Readonly>, @@ -1079,7 +1082,7 @@ export function setupChannel(target, ipc) { if (!target.connected || target.killed) { return; } - const msg = await core.opAsync("op_node_ipc_read", ipc); + const msg = await op_node_ipc_read(ipc); if (msg == null) { // Channel closed. target.disconnect(); @@ -1124,7 +1127,7 @@ export function setupChannel(target, ipc) { notImplemented("ChildProcess.send with handle"); } - core.opAsync("op_node_ipc_write", ipc, message) + op_node_ipc_write(ipc, message) .then(() => { if (callback) { process.nextTick(callback, null); diff --git a/ext/node/polyfills/internal/crypto/_randomFill.mjs b/ext/node/polyfills/internal/crypto/_randomFill.mjs index 6afc654b4b..7f66cfb4bb 100644 --- a/ext/node/polyfills/internal/crypto/_randomFill.mjs +++ b/ext/node/polyfills/internal/crypto/_randomFill.mjs @@ -11,6 +11,9 @@ import { isAnyArrayBuffer, isArrayBufferView } from "node:util/types"; import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_node_generate_secret_async, +} = core.ensureFastOps(); const kBufferMaxLength = 0x7fffffff; @@ -52,7 +55,7 @@ export default function randomFill( assertOffset(offset, buf.length); assertSize(size, offset, buf.length); - core.opAsync("op_node_generate_secret_async", Math.floor(size)) + op_node_generate_secret_async(Math.floor(size)) .then( (randomData) => { const randomBuf = Buffer.from(randomData.buffer); diff --git a/ext/node/polyfills/internal/crypto/hkdf.ts b/ext/node/polyfills/internal/crypto/hkdf.ts index 4454b0488b..8f3e8c7a97 100644 --- a/ext/node/polyfills/internal/crypto/hkdf.ts +++ b/ext/node/polyfills/internal/crypto/hkdf.ts @@ -33,6 +33,9 @@ import { const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_node_hkdf_async, +} = core.ensureFastOps(); const validateParameters = hideStackFrames((hash, key, salt, info, length) => { validateString(hash, "digest"); @@ -109,7 +112,7 @@ export function hkdf( validateFunction(callback, "callback"); - core.opAsync("op_node_hkdf_async", hash, key, salt, info, length) + op_node_hkdf_async(hash, key, salt, info, length) .then((okm) => callback(null, okm.buffer)) .catch((err) => callback(new ERR_CRYPTO_INVALID_DIGEST(err), undefined)); } diff --git a/ext/node/polyfills/internal/crypto/keygen.ts b/ext/node/polyfills/internal/crypto/keygen.ts index 29a062e002..f757f5eafc 100644 --- a/ext/node/polyfills/internal/crypto/keygen.ts +++ b/ext/node/polyfills/internal/crypto/keygen.ts @@ -31,6 +31,16 @@ import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts"; const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_node_dh_generate_async, + op_node_dh_generate_group_async, + op_node_dsa_generate_async, + op_node_ec_generate_async, + op_node_generate_rsa_async, + op_node_generate_secret_async, + op_node_ed25519_generate_async, + op_node_x25519_generate_async, +} = core.ensureFastOps(); function validateGenerateKey( type: "hmac" | "aes", @@ -81,7 +91,7 @@ export function generateKey( validateFunction(callback, "callback"); const { length } = options; - core.opAsync("op_node_generate_secret_async", Math.floor(length / 8)).then( + op_node_generate_secret_async(Math.floor(length / 8)).then( (key) => { callback(null, new SecretKeyObject(setOwnedKey(key))); }, @@ -799,8 +809,7 @@ function createJob(mode, type, options) { publicExponent, ); } else { - return core.opAsync( - "op_node_generate_rsa_async", + return op_node_generate_rsa_async( modulusLength, publicExponent, ); @@ -855,8 +864,7 @@ function createJob(mode, type, options) { publicExponent, ); } else { - return core.opAsync( - "op_node_generate_rsa_async", + return op_node_generate_rsa_async( modulusLength, publicExponent, ); @@ -877,8 +885,7 @@ function createJob(mode, type, options) { if (mode === kSync) { return ops.op_node_dsa_generate(modulusLength, divisorLength); } - return core.opAsync( - "op_node_dsa_generate_async", + return op_node_dsa_generate_async( modulusLength, divisorLength, ); @@ -900,20 +907,20 @@ function createJob(mode, type, options) { if (mode === kSync) { return ops.op_node_ec_generate(namedCurve); } else { - return core.opAsync("op_node_ec_generate_async", namedCurve); + return op_node_ec_generate_async(namedCurve); } } case "ed25519": { if (mode === kSync) { return ops.op_node_ed25519_generate(); } - return core.opAsync("op_node_ed25519_generate_async"); + return op_node_ed25519_generate_async(); } case "x25519": { if (mode === kSync) { return ops.op_node_x25519_generate(); } - return core.opAsync("op_node_x25519_generate_async"); + return op_node_x25519_generate_async(); } case "ed448": case "x448": { @@ -939,7 +946,7 @@ function createJob(mode, type, options) { if (mode === kSync) { return ops.op_node_dh_generate_group(group); } else { - return core.opAsync("op_node_dh_generate_group_async", group); + return op_node_dh_generate_group_async(group); } } @@ -966,8 +973,7 @@ function createJob(mode, type, options) { if (mode === kSync) { return ops.op_node_dh_generate(prime, primeLength ?? 0, g); } else { - return core.opAsync( - "op_node_dh_generate_async", + return op_node_dh_generate_async( prime, primeLength ?? 0, g, diff --git a/ext/node/polyfills/internal/crypto/pbkdf2.ts b/ext/node/polyfills/internal/crypto/pbkdf2.ts index f177d153a2..50cc3a83eb 100644 --- a/ext/node/polyfills/internal/crypto/pbkdf2.ts +++ b/ext/node/polyfills/internal/crypto/pbkdf2.ts @@ -8,6 +8,7 @@ import { HASH_DATA } from "ext:deno_node/internal/crypto/types.ts"; const { core } = globalThis.__bootstrap; const { ops } = core; +const { op_node_pbkdf2_async } = core.ensureFastOps(); export const MAX_ALLOC = Math.pow(2, 30) - 1; @@ -77,8 +78,7 @@ export function pbkdf2( throw new TypeError("Bad key length"); } - core.opAsync( - "op_node_pbkdf2_async", + op_node_pbkdf2_async( password, salt, iterations, diff --git a/ext/node/polyfills/internal/crypto/scrypt.ts b/ext/node/polyfills/internal/crypto/scrypt.ts index e87cdb856c..2ceac5139b 100644 --- a/ext/node/polyfills/internal/crypto/scrypt.ts +++ b/ext/node/polyfills/internal/crypto/scrypt.ts @@ -31,6 +31,9 @@ import { HASH_DATA } from "ext:deno_node/internal/crypto/types.ts"; const { core } = globalThis.__bootstrap; const { ops } = core; +const { + op_node_scrypt_async, +} = core.ensureFastOps(); type Opts = Partial<{ N: number; @@ -110,8 +113,7 @@ export function scrypt( } try { - core.opAsync( - "op_node_scrypt_async", + op_node_scrypt_async( password, salt, keylen, diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index 988f1d990c..31f0f28624 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -19,6 +19,11 @@ const { op_readable_stream_resource_close, op_readable_stream_resource_await_close, } = core.ensureFastOps(); +// TODO(mmastrac): use readAll +const { + op_read_all, +} = core.ensureFastOps(true); + import * as webidl from "ext:deno_webidl/00_webidl.js"; import { structuredClone } from "ext:deno_web/02_structured_clone.js"; import { @@ -1065,7 +1070,7 @@ async function readableStreamCollectIntoUint8Array(stream) { // fast path, read whole body in a single op call try { readableStreamDisturb(stream); - const promise = core.opAsync("op_read_all", resourceBacking.rid); + const promise = op_read_all(resourceBacking.rid); if (readableStreamIsUnrefable(stream)) { stream[promiseSymbol] = promise; if (stream[_isUnref]) core.unrefOpPromise(promise); diff --git a/ext/web/09_file.js b/ext/web/09_file.js index 6e91e24921..058346cfc6 100644 --- a/ext/web/09_file.js +++ b/ext/web/09_file.js @@ -49,6 +49,9 @@ const { Uint8Array, } = primordials; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; +const { + op_blob_read_part, +} = core.ensureFastOps(); // TODO(lucacasonato): this needs to not be hardcoded and instead depend on // host os. @@ -626,7 +629,7 @@ class BlobReference { * @returns {AsyncGenerator} */ async *stream() { - yield core.opAsync("op_blob_read_part", this._id); + yield op_blob_read_part(this._id); // let position = 0; // const end = this.size; @@ -634,7 +637,7 @@ class BlobReference { // const size = MathMin(end - position, 65536); // const chunk = this.slice(position, position + size); // position += chunk.size; - // yield core.opAsync("op_blob_read_part", chunk._id); + // yield op_blob_read_part( chunk._id); // } } } diff --git a/ext/web/13_message_port.js b/ext/web/13_message_port.js index 9645f5f115..c7d7d24f96 100644 --- a/ext/web/13_message_port.js +++ b/ext/web/13_message_port.js @@ -31,6 +31,9 @@ const { SymbolIterator, TypeError, } = primordials; +const { + op_message_port_recv_message, +} = core.ensureFastOps(); class MessageChannel { /** @type {MessagePort} */ @@ -147,8 +150,7 @@ class MessagePort extends EventTarget { if (this[_id] === null) break; let data; try { - data = await core.opAsync( - "op_message_port_recv_message", + data = await op_message_port_recv_message( this[_id], ); } catch (err) { diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js index 264eaa4433..2b5e36e7ff 100644 --- a/ext/webgpu/01_webgpu.js +++ b/ext/webgpu/01_webgpu.js @@ -48,6 +48,12 @@ const { Uint32ArrayPrototype, Uint8Array, } = primordials; +const { + op_webgpu_buffer_get_map_async, + op_webgpu_request_adapter, + op_webgpu_request_adapter_info, + op_webgpu_request_device, +} = core.ensureFastOps(); const _rid = Symbol("[[rid]]"); const _size = Symbol("[[size]]"); @@ -253,8 +259,7 @@ class GPU { "Argument 1", ); - const { err, ...data } = await core.opAsync( - "op_webgpu_request_adapter", + const { err, ...data } = await op_webgpu_request_adapter( options.powerPreference, options.forceFallbackAdapter, ); @@ -343,8 +348,7 @@ class GPUAdapter { } } - const { rid, features, limits } = await core.opAsync( - "op_webgpu_request_device", + const { rid, features, limits } = await op_webgpu_request_device( this[_adapter].rid, descriptor.label, requiredFeatures, @@ -382,8 +386,7 @@ class GPUAdapter { architecture, device, description, - } = await core.opAsync( - "op_webgpu_request_adapter_info", + } = await op_webgpu_request_adapter_info( this[_adapter].rid, ); @@ -1949,8 +1952,7 @@ class GPUBuffer { this[_mapMode] = mode; this[_state] = "pending"; const promise = PromisePrototypeThen( - core.opAsync( - "op_webgpu_buffer_get_map_async", + op_webgpu_buffer_get_map_async( bufferRid, device.rid, mode, diff --git a/runtime/js/11_workers.js b/runtime/js/11_workers.js index 60ea94bf4a..e8e66848e9 100644 --- a/runtime/js/11_workers.js +++ b/runtime/js/11_workers.js @@ -30,6 +30,10 @@ import { MessagePortPrototype, serializeJsMessageData, } from "ext:deno_web/13_message_port.js"; +const { + op_host_recv_ctrl, + op_host_recv_message, +} = core.ensureFastOps(); function createWorker( specifier, @@ -58,11 +62,11 @@ function hostPostMessage(id, data) { } function hostRecvCtrl(id) { - return core.opAsync("op_host_recv_ctrl", id); + return op_host_recv_ctrl(id); } function hostRecvMessage(id) { - return core.opAsync("op_host_recv_message", id); + return op_host_recv_message(id); } class Worker extends EventTarget { diff --git a/runtime/js/40_fs_events.js b/runtime/js/40_fs_events.js index c9d0f1feb6..ba806c1820 100644 --- a/runtime/js/40_fs_events.js +++ b/runtime/js/40_fs_events.js @@ -9,6 +9,9 @@ const { SymbolAsyncIterator, } = primordials; import { SymbolDispose } from "ext:deno_web/00_infra.js"; +const { + op_fs_events_poll, +} = core.ensureFastOps(); class FsWatcher { #rid = 0; @@ -24,7 +27,7 @@ class FsWatcher { async next() { try { - const value = await core.opAsync("op_fs_events_poll", this.rid); + const value = await op_fs_events_poll(this.rid); return value ? { value, done: false } : { value: undefined, done: true }; } catch (error) { if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) { diff --git a/runtime/js/40_process.js b/runtime/js/40_process.js index e628aeb4a6..9239f8e993 100644 --- a/runtime/js/40_process.js +++ b/runtime/js/40_process.js @@ -30,6 +30,10 @@ import { ReadableStreamPrototype, writableStreamForRid, } from "ext:deno_web/06_streams.js"; +const { + op_run_status, + op_spawn_wait, +} = core.ensureFastOps(); function opKill(pid, signo, apiName) { ops.op_kill(pid, signo, apiName); @@ -40,7 +44,7 @@ function kill(pid, signo = "SIGTERM") { } function opRunStatus(rid) { - return core.opAsync("op_run_status", rid); + return op_run_status(rid); } function opRun(request) { @@ -272,7 +276,7 @@ class ChildProcess { const onAbort = () => this.kill("SIGTERM"); signal?.[abortSignal.add](onAbort); - const waitPromise = core.opAsync("op_spawn_wait", this.#rid); + const waitPromise = op_spawn_wait(this.#rid); this.#waitPromise = waitPromise; this.#status = PromisePrototypeThen(waitPromise, (res) => { signal?.[abortSignal.remove](onAbort); diff --git a/runtime/js/40_signals.js b/runtime/js/40_signals.js index 20771da36a..7faa6a8bcc 100644 --- a/runtime/js/40_signals.js +++ b/runtime/js/40_signals.js @@ -9,13 +9,16 @@ const { SetPrototypeDelete, TypeError, } = primordials; +const { + op_signal_poll, +} = core.ensureFastOps(); function bindSignal(signo) { return ops.op_signal_bind(signo); } function pollSignal(rid) { - const promise = core.opAsync("op_signal_poll", rid); + const promise = op_signal_poll(rid); core.unrefOpPromise(promise); return promise; } diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 0469b38bfc..b67b6a0bf6 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -141,6 +141,8 @@ let isClosing = false; let globalDispatchEvent; async function pollForMessages() { + const { op_worker_recv_message } = core.ensureFastOps(); + if (!globalDispatchEvent) { globalDispatchEvent = FunctionPrototypeBind( globalThis.dispatchEvent, @@ -148,7 +150,7 @@ async function pollForMessages() { ); } while (!isClosing) { - const data = await core.opAsync("op_worker_recv_message"); + const data = await op_worker_recv_message(); if (data === null) break; const v = messagePort.deserializeJsMessageData(data); const message = v[0];