chore: ensure that each op provided to ensureFastOps is only used once (#21689)

When we migrate to op-import-per-extension, we will want to ensure that
ops have one and only one place where they are imported. This tackles
the ops that are imported via `ensureFastOps`, but does not yet tackle
direct `ops` imports.

Landing ahead of https://github.com/denoland/deno_core/pull/393
This commit is contained in:
Matt Mastracci 2023-12-24 06:04:32 -07:00 committed by GitHub
parent 1297c9a8f3
commit 92b2e28c64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 67 additions and 52 deletions

View file

@ -1,22 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
let [total, count] = typeof Deno !== "undefined"
? Deno.args
: [process.argv[2], process.argv[3]];
total = total ? parseInt(total, 0) : 50;
count = count ? parseInt(count, 10) : 1000000;
async function bench(fun) {
const start = Date.now();
for (let i = 0; i < count; i++) await fun();
const elapsed = Date.now() - start;
const rate = Math.floor(count / (elapsed / 1000));
console.log(`time ${elapsed} ms rate ${rate}`);
if (--total) queueMicrotask(() => bench(fun));
}
const core = Deno[Deno.internal].core;
const ops = core.ops;
const opVoidAsyncDeferred = ops.op_void_async_deferred;
bench(() => opVoidAsyncDeferred());

View file

@ -12,13 +12,13 @@ import {
setIsTrusted,
setTarget,
} 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 {
ArrayPrototypeIndexOf,
ArrayPrototypePush,
ArrayPrototypeSplice,
ObjectPrototypeIsPrototypeOf,
PromisePrototypeThen,
Symbol,
SymbolFor,
Uint8Array,
@ -68,14 +68,6 @@ function dispatch(source, name, data) {
defer(go);
}
}
// Defer to avoid starving the event loop. Not using queueMicrotask()
// for that reason: it lets promises make forward progress but can
// still starve other parts of the event loop.
function defer(go) {
PromisePrototypeThen(core.ops.op_void_async_deferred(), () => go());
}
class BroadcastChannel extends EventTarget {
[_name];
[_closed] = false;

View file

@ -386,9 +386,17 @@ function unrefTimer(id) {
core.unrefOpPromise(timerInfo.promise);
}
// Defer to avoid starving the event loop. Not using queueMicrotask()
// for that reason: it lets promises make forward progress but can
// still starve other parts of the event loop.
function defer(go) {
PromisePrototypeThen(op_void_async_deferred(), () => go());
}
export {
clearInterval,
clearTimeout,
defer,
handleTimerMacrotask,
opNow,
refTimer,

View file

@ -6895,6 +6895,7 @@ export {
errorReadableStream,
getReadableStreamResourceBacking,
getWritableStreamResourceBacking,
isDetachedBuffer,
isReadableStreamDisturbed,
ReadableByteStreamController,
ReadableStream,

View file

@ -17,6 +17,7 @@ import {
setEventTargetData,
setIsTrusted,
} from "ext:deno_web/02_event.js";
import { isDetachedBuffer } from "ext:deno_web/06_streams.js";
import DOMException from "ext:deno_web/01_dom_exception.js";
const {
ArrayBufferPrototype,
@ -282,7 +283,7 @@ function serializeJsMessageData(data, transferables) {
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, t)) {
if (
ArrayBufferPrototypeGetByteLength(t) === 0 &&
ops.op_arraybuffer_was_detached(t)
isDetachedBuffer(t)
) {
throw new DOMException(
`ArrayBuffer at index ${j} is already detached`,

35
ext/websocket/00_ops.js Normal file
View file

@ -0,0 +1,35 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import { core } from "ext:core/mod.js";
const {
op_ws_create,
op_ws_close,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_text,
op_ws_next_event,
op_ws_get_buffer,
op_ws_get_buffer_as_string,
op_ws_get_error,
op_ws_send_ping,
op_ws_get_buffered_amount,
op_ws_send_text_async,
op_ws_send_binary_async,
op_ws_check_permission_and_cancel_handle,
} = core.ensureFastOps();
export {
op_ws_check_permission_and_cancel_handle,
op_ws_close,
op_ws_create,
op_ws_get_buffer,
op_ws_get_buffer_as_string,
op_ws_get_buffered_amount,
op_ws_get_error,
op_ws_next_event,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_binary_async,
op_ws_send_ping,
op_ws_send_text,
op_ws_send_text_async,
};

View file

@ -44,20 +44,20 @@ const {
SymbolFor,
TypedArrayPrototypeGetByteLength,
} = primordials;
const { op_ws_check_permission_and_cancel_handle } = core.ops;
const {
op_ws_create,
import {
op_ws_check_permission_and_cancel_handle,
op_ws_close,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_text,
op_ws_next_event,
op_ws_create,
op_ws_get_buffer,
op_ws_get_buffer_as_string,
op_ws_get_error,
op_ws_send_ping,
op_ws_get_buffered_amount,
} = core.ensureFastOps();
op_ws_get_error,
op_ws_next_event,
op_ws_send_binary,
op_ws_send_binary_ab,
op_ws_send_ping,
op_ws_send_text,
} from "ext:deno_websocket/00_ops.js";
webidl.converters["sequence<DOMString> or DOMString"] = (
V,

View file

@ -3,7 +3,6 @@
/// <reference path="../../core/internal.d.ts" />
import { core, primordials } from "ext:core/mod.js";
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
import { Deferred, writableStreamClose } from "ext:deno_web/06_streams.js";
@ -32,16 +31,17 @@ const {
TypedArrayPrototypeGetByteLength,
Uint8ArrayPrototype,
} = primordials;
const {
op_ws_send_text_async,
op_ws_send_binary_async,
op_ws_next_event,
import {
op_ws_check_permission_and_cancel_handle,
op_ws_close,
op_ws_create,
op_ws_get_buffer,
op_ws_get_buffer_as_string,
op_ws_get_error,
op_ws_create,
op_ws_close,
} = core.ensureFastOps();
op_ws_next_event,
op_ws_send_binary_async,
op_ws_send_text_async,
} from "ext:deno_websocket/00_ops.js";
webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter(
"WebSocketStreamOptions",
@ -146,7 +146,7 @@ class WebSocketStream {
fillHeaders(headers, options.headers);
}
const cancelRid = ops.op_ws_check_permission_and_cancel_handle(
const cancelRid = op_ws_check_permission_and_cancel_handle(
"WebSocketStream.abort()",
this[_url],
true,

View file

@ -843,7 +843,7 @@ deno_core::extension!(deno_websocket,
op_ws_send_pong,
op_ws_get_buffered_amount,
],
esm = [ "01_websocket.js", "02_websocketstream.js" ],
esm = [ "00_ops.js", "01_websocket.js", "02_websocketstream.js" ],
options = {
user_agent: String,
root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,