1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-27 01:29:14 -05:00

refactor: migrate async ops to generated wrappers (#18937)

Migrates some of existing async ops to generated wrappers introduced in
https://github.com/denoland/deno/pull/18887. As a result "core.opAsync2"
was removed.

I will follow up with more PRs that migrate all the async ops to
generated wrappers.
This commit is contained in:
Bartek Iwańczuk 2023-05-01 17:40:00 +02:00 committed by Levente Kurusa
parent 3d0b879c0d
commit 016b43441b
No known key found for this signature in database
GPG key ID: 9F72F3C05BA137C4
10 changed files with 109 additions and 99 deletions

View file

@ -564,31 +564,6 @@ for (let i = 0; i < 10; i++) {
return (ops[opName] = fn); return (ops[opName] = fn);
} }
function opAsync2(name, arg0, arg1) {
const id = nextPromiseId++;
try {
const maybeResult = asyncOps[name](id, arg0, arg1);
if (maybeResult !== undefined) {
movePromise(id);
return unwrapOpResultNewPromise(id, maybeResult, opAsync2);
}
} catch (err) {
movePromise(id);
if (!ReflectHas(asyncOps, name)) {
return PromiseReject(new TypeError(`${name} is not a registered op`));
}
ErrorCaptureStackTrace(err, opAsync2);
return PromiseReject(err);
}
let promise = PromisePrototypeThen(
setPromise(id),
unwrapOpError(eventLoopTick),
);
promise = handleOpCallTracing(name, id, promise);
promise[promiseIdSymbol] = id;
return promise;
}
function opAsync(name, ...args) { function opAsync(name, ...args) {
const id = nextPromiseId++; const id = nextPromiseId++;
try { try {
@ -823,7 +798,6 @@ for (let i = 0; i < 10; i++) {
asyncStub, asyncStub,
generateAsyncOpHandler, generateAsyncOpHandler,
opAsync, opAsync,
opAsync2,
resources, resources,
metrics, metrics,
registerErrorBuilder, registerErrorBuilder,

View file

@ -3,7 +3,16 @@
// then write this fixed 'responseBuf'. The point of this benchmark is to // then write this fixed 'responseBuf'. The point of this benchmark is to
// exercise the event loop in a simple yet semi-realistic way. // exercise the event loop in a simple yet semi-realistic way.
const { ops, opAsync, opAsync2 } = Deno.core; // deno-lint-ignore-file camelcase
const { op_listen } = Deno.core.ops;
const {
op_accept,
op_read_socket,
} = core.generateAsyncOpHandler(
"op_accept",
"op_read_socket",
);
const requestBuf = new Uint8Array(64 * 1024); const requestBuf = new Uint8Array(64 * 1024);
const responseBuf = new Uint8Array( const responseBuf = new Uint8Array(
@ -12,24 +21,10 @@ const responseBuf = new Uint8Array(
.map((c) => c.charCodeAt(0)), .map((c) => c.charCodeAt(0)),
); );
/** Listens on 0.0.0.0:4570, returns rid. */
function listen() {
return ops.op_listen();
}
/** Accepts a connection, returns rid. */
function accept(serverRid) {
return opAsync("op_accept", serverRid);
}
function read(serverRid, buf) {
return opAsync2("op_read_socket", serverRid, buf);
}
async function serve(rid) { async function serve(rid) {
try { try {
while (true) { while (true) {
await read(rid, requestBuf); await op_read_socket(rid, requestBuf);
if (!ops.op_try_write(rid, responseBuf)) { if (!ops.op_try_write(rid, responseBuf)) {
await Deno.core.writeAll(rid, responseBuf); await Deno.core.writeAll(rid, responseBuf);
} }
@ -41,11 +36,12 @@ async function serve(rid) {
} }
async function main() { async function main() {
const listenerRid = listen(); /** Listens on 0.0.0.0:4570, returns rid. */
const listenerRid = op_listen();
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4570/\n`); Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4570/\n`);
while (true) { while (true) {
const rid = await accept(listenerRid); const rid = await op_accept(listenerRid);
serve(rid); serve(rid);
} }
} }

View file

@ -2765,9 +2765,9 @@ pub mod tests {
.execute_script_static( .execute_script_static(
"filename.js", "filename.js",
r#" r#"
const { op_test } = Deno.core.generateAsyncOpHandler("op_test");
let zero_copy_a = new Uint8Array([0]); let zero_copy_a = new Uint8Array([0]);
Deno.core.opAsync2("op_test", null, zero_copy_a); op_test(null, zero_copy_a);
"#, "#,
) )
.unwrap(); .unwrap();

View file

@ -1,7 +1,22 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const ops = core.ops; const ops = core.ops;
const {
op_chmod_async,
op_ftruncate_async,
op_truncate_async,
op_link_async,
op_flock_async,
} = Deno.core.generateAsyncOpHandler(
"op_chmod_async",
"op_ftruncate_async",
"op_truncate_async",
"op_link_async",
"op_flock_async",
);
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
const { const {
ArrayPrototypeFilter, ArrayPrototypeFilter,
@ -34,7 +49,7 @@ function chmodSync(path, mode) {
} }
async function chmod(path, mode) { async function chmod(path, mode) {
await core.opAsync2("op_chmod_async", pathFromURL(path), mode); await op_chmod_async(pathFromURL(path), mode);
} }
function chownSync( function chownSync(
@ -347,7 +362,7 @@ function ftruncateSync(rid, len) {
} }
async function ftruncate(rid, len) { async function ftruncate(rid, len) {
await core.opAsync2("op_ftruncate_async", rid, coerceLen(len)); await op_ftruncate_async(rid, coerceLen(len));
} }
function truncateSync(path, len) { function truncateSync(path, len) {
@ -355,7 +370,7 @@ function truncateSync(path, len) {
} }
async function truncate(path, len) { async function truncate(path, len) {
await core.opAsync2("op_truncate_async", path, coerceLen(len)); await op_truncate_async(path, coerceLen(len));
} }
function umask(mask) { function umask(mask) {
@ -367,7 +382,7 @@ function linkSync(oldpath, newpath) {
} }
async function link(oldpath, newpath) { async function link(oldpath, newpath) {
await core.opAsync2("op_link_async", oldpath, newpath); await op_link_async(oldpath, newpath);
} }
function toUnixTimeFromEpoch(value) { function toUnixTimeFromEpoch(value) {
@ -497,7 +512,7 @@ function flockSync(rid, exclusive) {
} }
async function flock(rid, exclusive) { async function flock(rid, exclusive) {
await core.opAsync2("op_flock_async", rid, exclusive === true); await op_flock_async(rid, exclusive === true);
} }
function funlockSync(rid) { function funlockSync(rid) {

View file

@ -64,7 +64,7 @@ const {
op_set_response_headers, op_set_response_headers,
op_upgrade_raw, op_upgrade_raw,
op_ws_server_create, op_ws_server_create,
} = Deno.core.generateAsyncOpHandler( } = core.generateAsyncOpHandler(
"op_http_wait", "op_http_wait",
"op_upgrade", "op_upgrade",
"op_get_request_headers", "op_get_request_headers",

View file

@ -1,8 +1,12 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const internals = globalThis.__bootstrap.internals; const internals = globalThis.__bootstrap.internals;
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
const { BadResourcePrototype, InterruptedPrototype, ops } = core; const { BadResourcePrototype, InterruptedPrototype, ops } = core;
const { op_http_write } = Deno.core.generateAsyncOpHandler("op_http_write");
import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as webidl from "ext:deno_webidl/00_webidl.js";
import { InnerBody } from "ext:deno_fetch/22_body.js"; import { InnerBody } from "ext:deno_fetch/22_body.js";
import { Event, setEventTargetData } from "ext:deno_web/02_event.js"; import { Event, setEventTargetData } from "ext:deno_web/02_event.js";
@ -321,7 +325,7 @@ function createRespondWith(
break; break;
} }
try { try {
await core.opAsync2("op_http_write", streamRid, value); await op_http_write(streamRid, value);
} catch (error) { } catch (error) {
const connError = httpConn[connErrorSymbol]; const connError = httpConn[connErrorSymbol];
if ( if (

View file

@ -1,6 +1,8 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license. // Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
import { notImplemented } from "ext:deno_node/_utils.ts"; import { notImplemented } from "ext:deno_node/_utils.ts";
import randomBytes from "ext:deno_node/internal/crypto/_randomBytes.ts"; import randomBytes from "ext:deno_node/internal/crypto/_randomBytes.ts";
import randomFill, { import randomFill, {
@ -31,6 +33,15 @@ export { default as randomInt } from "ext:deno_node/internal/crypto/_randomInt.t
const { core } = globalThis.__bootstrap; const { core } = globalThis.__bootstrap;
const { ops } = core; const { ops } = core;
const {
op_node_gen_prime_async,
op_node_check_prime_bytes_async,
op_node_check_prime_async,
} = Deno.core.generateAsyncOpHandler(
"op_node_gen_prime_async",
"op_node_check_prime_bytes_async",
"op_node_check_prime_async",
);
export type LargeNumberLike = export type LargeNumberLike =
| ArrayBufferView | ArrayBufferView
@ -79,9 +90,9 @@ export function checkPrime(
validateInt32(checks, "options.checks", 0); validateInt32(checks, "options.checks", 0);
let op = "op_node_check_prime_bytes_async"; let op = op_node_check_prime_bytes_async;
if (typeof candidate === "bigint") { if (typeof candidate === "bigint") {
op = "op_node_check_prime_async"; op = op_node_check_prime_async;
} else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) { } else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) {
throw new ERR_INVALID_ARG_TYPE( throw new ERR_INVALID_ARG_TYPE(
"candidate", "candidate",
@ -96,7 +107,7 @@ export function checkPrime(
); );
} }
core.opAsync2(op, candidate, checks).then( op(candidate, checks).then(
(result) => { (result) => {
callback?.(null, result); callback?.(null, result);
}, },
@ -160,7 +171,7 @@ export function generatePrime(
const { const {
bigint, bigint,
} = validateRandomPrimeJob(size, options); } = validateRandomPrimeJob(size, options);
core.opAsync2("op_node_gen_prime_async", size).then((prime: Uint8Array) => op_node_gen_prime_async(size).then((prime: Uint8Array) =>
bigint ? arrayBufferToUnsignedBigInt(prime.buffer) : prime.buffer bigint ? arrayBufferToUnsignedBigInt(prime.buffer) : prime.buffer
).then((prime: ArrayBuffer | bigint) => { ).then((prime: ArrayBuffer | bigint) => {
callback?.(null, prime); callback?.(null, prime);

View file

@ -1,5 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const ops = core.ops; const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
@ -13,7 +15,6 @@ const {
MapPrototypeSet, MapPrototypeSet,
Uint8Array, Uint8Array,
Uint32Array, Uint32Array,
// deno-lint-ignore camelcase
NumberPOSITIVE_INFINITY, NumberPOSITIVE_INFINITY,
PromisePrototypeThen, PromisePrototypeThen,
SafeArrayIterator, SafeArrayIterator,
@ -26,6 +27,7 @@ const {
import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as webidl from "ext:deno_webidl/00_webidl.js";
import { reportException } from "ext:deno_web/02_event.js"; import { reportException } from "ext:deno_web/02_event.js";
import { assert } from "ext:deno_web/00_infra.js"; import { assert } from "ext:deno_web/00_infra.js";
const { op_sleep } = core.generateAsyncOpHandler("op_sleep");
const hrU8 = new Uint8Array(8); const hrU8 = new Uint8Array(8);
const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8)); const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8));
@ -216,7 +218,7 @@ const scheduledTimers = { head: null, tail: null };
*/ */
function runAfterTimeout(cb, millis, timerInfo) { function runAfterTimeout(cb, millis, timerInfo) {
const cancelRid = timerInfo.cancelRid; const cancelRid = timerInfo.cancelRid;
const sleepPromise = core.opAsync2("op_sleep", millis, cancelRid); const sleepPromise = op_sleep(millis, cancelRid);
timerInfo.promiseId = sleepPromise[SymbolFor("Deno.core.internalPromiseId")]; timerInfo.promiseId = sleepPromise[SymbolFor("Deno.core.internalPromiseId")];
if (!timerInfo.isRef) { if (!timerInfo.isRef) {
core.unrefOp(timerInfo.promiseId); core.unrefOp(timerInfo.promiseId);

View file

@ -1,12 +1,9 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
/// <reference path="../../core/internal.d.ts" /> /// <reference path="../../core/internal.d.ts" />
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const { opAsync, opAsync2 } = core;
// deno-lint-ignore camelcase
const op_ws_check_permission_and_cancel_handle =
core.ops.op_ws_check_permission_and_cancel_handle;
import { URL } from "ext:deno_url/00_url.js"; import { URL } from "ext:deno_url/00_url.js";
import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as webidl from "ext:deno_webidl/00_webidl.js";
import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js"; import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js";
@ -51,6 +48,23 @@ const {
TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetByteLength,
TypedArrayPrototypeGetSymbolToStringTag, TypedArrayPrototypeGetSymbolToStringTag,
} = primordials; } = primordials;
const op_ws_check_permission_and_cancel_handle =
core.ops.op_ws_check_permission_and_cancel_handle;
const {
op_ws_create,
op_ws_close,
op_ws_send_binary,
op_ws_send_text,
op_ws_next_event,
op_ws_send_ping,
} = core.generateAsyncOpHandler(
"op_ws_create",
"op_ws_close",
"op_ws_send_binary",
"op_ws_send_text",
"op_ws_next_event",
"op_ws_send_ping",
);
webidl.converters["sequence<DOMString> or DOMString"] = ( webidl.converters["sequence<DOMString> or DOMString"] = (
V, V,
@ -252,8 +266,7 @@ class WebSocket extends EventTarget {
} }
PromisePrototypeThen( PromisePrototypeThen(
opAsync( op_ws_create(
"op_ws_create",
"new WebSocket()", "new WebSocket()",
wsURL.href, wsURL.href,
ArrayPrototypeJoin(protocols, ", "), ArrayPrototypeJoin(protocols, ", "),
@ -265,7 +278,7 @@ class WebSocket extends EventTarget {
if (this[_readyState] === CLOSING) { if (this[_readyState] === CLOSING) {
PromisePrototypeThen( PromisePrototypeThen(
opAsync("op_ws_close", this[_rid]), op_ws_close(this[_rid]),
() => { () => {
this[_readyState] = CLOSED; this[_readyState] = CLOSED;
@ -318,8 +331,7 @@ class WebSocket extends EventTarget {
const sendTypedArray = (view, byteLength) => { const sendTypedArray = (view, byteLength) => {
this[_bufferedAmount] += byteLength; this[_bufferedAmount] += byteLength;
PromisePrototypeThen( PromisePrototypeThen(
opAsync2( op_ws_send_binary(
"op_ws_send_binary",
this[_rid], this[_rid],
view, view,
), ),
@ -353,8 +365,7 @@ class WebSocket extends EventTarget {
const d = core.encode(string); const d = core.encode(string);
this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d); this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d);
PromisePrototypeThen( PromisePrototypeThen(
opAsync2( op_ws_send_text(
"op_ws_send_text",
this[_rid], this[_rid],
string, string,
), ),
@ -407,8 +418,7 @@ class WebSocket extends EventTarget {
this[_readyState] = CLOSING; this[_readyState] = CLOSING;
PromisePrototypeCatch( PromisePrototypeCatch(
opAsync( op_ws_close(
"op_ws_close",
this[_rid], this[_rid],
code, code,
reason, reason,
@ -432,10 +442,7 @@ class WebSocket extends EventTarget {
async [_eventLoop]() { async [_eventLoop]() {
while (this[_readyState] !== CLOSED) { while (this[_readyState] !== CLOSED) {
const { 0: kind, 1: value } = await opAsync2( const { 0: kind, 1: value } = await op_ws_next_event(this[_rid]);
"op_ws_next_event",
this[_rid],
);
switch (kind) { switch (kind) {
case 0: { case 0: {
@ -495,8 +502,7 @@ class WebSocket extends EventTarget {
if (prevState === OPEN) { if (prevState === OPEN) {
try { try {
await opAsync( await op_ws_close(
"op_ws_close",
this[_rid], this[_rid],
code, code,
value, value,
@ -524,17 +530,12 @@ class WebSocket extends EventTarget {
clearTimeout(this[_idleTimeoutTimeout]); clearTimeout(this[_idleTimeoutTimeout]);
this[_idleTimeoutTimeout] = setTimeout(async () => { this[_idleTimeoutTimeout] = setTimeout(async () => {
if (this[_readyState] === OPEN) { if (this[_readyState] === OPEN) {
await opAsync("op_ws_send_ping", this[_rid]); await op_ws_send_ping(this[_rid]);
this[_idleTimeoutTimeout] = setTimeout(async () => { this[_idleTimeoutTimeout] = setTimeout(async () => {
if (this[_readyState] === OPEN) { if (this[_readyState] === OPEN) {
this[_readyState] = CLOSING; this[_readyState] = CLOSING;
const reason = "No response from ping frame."; const reason = "No response from ping frame.";
await opAsync( await op_ws_close(this[_rid], 1001, reason);
"op_ws_close",
this[_rid],
1001,
reason,
);
this[_readyState] = CLOSED; this[_readyState] = CLOSED;
const errEvent = new ErrorEvent("error", { const errEvent = new ErrorEvent("error", {

View file

@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file camelcase
/// <reference path="../../core/internal.d.ts" /> /// <reference path="../../core/internal.d.ts" />
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
@ -32,6 +33,19 @@ const {
TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetByteLength,
Uint8ArrayPrototype, Uint8ArrayPrototype,
} = primordials; } = primordials;
const {
op_ws_send_text,
op_ws_send_binary,
op_ws_next_event,
op_ws_create,
op_ws_close,
} = core.generateAsyncOpHandler(
"op_ws_send_text",
"op_ws_send_binary",
"op_ws_next_event",
"op_ws_create",
"op_ws_close",
);
webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter( webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter(
"WebSocketStreamOptions", "WebSocketStreamOptions",
@ -153,8 +167,7 @@ class WebSocketStream {
}; };
options.signal?.[add](abort); options.signal?.[add](abort);
PromisePrototypeThen( PromisePrototypeThen(
core.opAsync( op_ws_create(
"op_ws_create",
"new WebSocketStream()", "new WebSocketStream()",
this[_url], this[_url],
options.protocols ? ArrayPrototypeJoin(options.protocols, ", ") : "", options.protocols ? ArrayPrototypeJoin(options.protocols, ", ") : "",
@ -165,15 +178,12 @@ class WebSocketStream {
options.signal?.[remove](abort); options.signal?.[remove](abort);
if (this[_earlyClose]) { if (this[_earlyClose]) {
PromisePrototypeThen( PromisePrototypeThen(
core.opAsync("op_ws_close", create.rid), op_ws_close(create.rid),
() => { () => {
PromisePrototypeThen( PromisePrototypeThen(
(async () => { (async () => {
while (true) { while (true) {
const { 0: kind } = await core.opAsync( const { 0: kind } = await op_ws_next_event(create.rid);
"op_ws_next_event",
create.rid,
);
if (kind > 5) { if (kind > 5) {
/* close */ /* close */
@ -206,11 +216,11 @@ class WebSocketStream {
const writable = new WritableStream({ const writable = new WritableStream({
write: async (chunk) => { write: async (chunk) => {
if (typeof chunk === "string") { if (typeof chunk === "string") {
await core.opAsync2("op_ws_send_text", this[_rid], chunk); await op_ws_send_text(this[_rid], chunk);
} else if ( } else if (
ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk) ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk)
) { ) {
await core.opAsync2("op_ws_send_binary", this[_rid], chunk); await op_ws_send_binary(this[_rid], chunk);
} else { } else {
throw new TypeError( throw new TypeError(
"A chunk may only be either a string or an Uint8Array", "A chunk may only be either a string or an Uint8Array",
@ -235,10 +245,7 @@ class WebSocketStream {
}, },
}); });
const pull = async (controller) => { const pull = async (controller) => {
const { 0: kind, 1: value } = await core.opAsync2( const { 0: kind, 1: value } = await op_ws_next_event(this[_rid]);
"op_ws_next_event",
this[_rid],
);
switch (kind) { switch (kind) {
case 0: case 0:
@ -402,7 +409,7 @@ class WebSocketStream {
this[_earlyClose] = true; this[_earlyClose] = true;
} else if (this[_closed].state === "pending") { } else if (this[_closed].state === "pending") {
PromisePrototypeThen( PromisePrototypeThen(
core.opAsync("op_ws_close", this[_rid], code, closeInfo.reason), op_ws_close(this[_rid], code, closeInfo.reason),
() => { () => {
setTimeout(() => { setTimeout(() => {
this[_closeSent].resolve(DateNow()); this[_closeSent].resolve(DateNow());