diff options
Diffstat (limited to 'runtime/js')
-rw-r--r-- | runtime/js/01_build.js | 51 | ||||
-rw-r--r-- | runtime/js/01_errors.js | 262 | ||||
-rw-r--r-- | runtime/js/01_version.js | 41 | ||||
-rw-r--r-- | runtime/js/01_web_util.js | 25 | ||||
-rw-r--r-- | runtime/js/06_util.js | 255 | ||||
-rw-r--r-- | runtime/js/10_permissions.js | 479 | ||||
-rw-r--r-- | runtime/js/11_workers.js | 441 | ||||
-rw-r--r-- | runtime/js/12_io.js | 392 | ||||
-rw-r--r-- | runtime/js/13_buffer.js | 428 | ||||
-rw-r--r-- | runtime/js/30_fs.js | 1052 | ||||
-rw-r--r-- | runtime/js/30_os.js | 229 | ||||
-rw-r--r-- | runtime/js/40_diagnostics.js | 27 | ||||
-rw-r--r-- | runtime/js/40_files.js | 480 | ||||
-rw-r--r-- | runtime/js/40_fs_events.js | 109 | ||||
-rw-r--r-- | runtime/js/40_http.js | 20 | ||||
-rw-r--r-- | runtime/js/40_process.js | 232 | ||||
-rw-r--r-- | runtime/js/40_read_file.js | 114 | ||||
-rw-r--r-- | runtime/js/40_signals.js | 129 | ||||
-rw-r--r-- | runtime/js/40_spawn.js | 584 | ||||
-rw-r--r-- | runtime/js/40_tty.js | 41 | ||||
-rw-r--r-- | runtime/js/40_write_file.js | 183 | ||||
-rw-r--r-- | runtime/js/41_prompt.js | 112 | ||||
-rw-r--r-- | runtime/js/90_deno_ns.js | 327 | ||||
-rw-r--r-- | runtime/js/98_global_scope.js | 589 | ||||
-rw-r--r-- | runtime/js/99_main.js | 1194 |
25 files changed, 3857 insertions, 3939 deletions
diff --git a/runtime/js/01_build.js b/runtime/js/01_build.js index 778331cdd..a9515c5b8 100644 --- a/runtime/js/01_build.js +++ b/runtime/js/01_build.js @@ -1,33 +1,28 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const { ObjectFreeze, StringPrototypeSplit } = window.__bootstrap.primordials; +const primordials = globalThis.__bootstrap.primordials; +const { ObjectFreeze, StringPrototypeSplit } = primordials; - const build = { - target: "unknown", - arch: "unknown", - os: "unknown", - vendor: "unknown", - env: undefined, - }; +const build = { + target: "unknown", + arch: "unknown", + os: "unknown", + vendor: "unknown", + env: undefined, +}; - function setBuildInfo(target) { - const { 0: arch, 1: vendor, 2: os, 3: env } = StringPrototypeSplit( - target, - "-", - 4, - ); - build.target = target; - build.arch = arch; - build.vendor = vendor; - build.os = os; - build.env = env; - ObjectFreeze(build); - } +function setBuildInfo(target) { + const { 0: arch, 1: vendor, 2: os, 3: env } = StringPrototypeSplit( + target, + "-", + 4, + ); + build.target = target; + build.arch = arch; + build.vendor = vendor; + build.os = os; + build.env = env; + ObjectFreeze(build); +} - window.__bootstrap.build = { - build, - setBuildInfo, - }; -})(this); +export { build, setBuildInfo }; diff --git a/runtime/js/01_errors.js b/runtime/js/01_errors.js index 620c64c33..7e2ad29ab 100644 --- a/runtime/js/01_errors.js +++ b/runtime/js/01_errors.js @@ -1,153 +1,149 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.Deno.core; - const { Error } = window.__bootstrap.primordials; - const { BadResource, Interrupted } = core; +const core = globalThis.Deno.core; +const { BadResource, Interrupted } = core; +const primordials = globalThis.__bootstrap.primordials; +const { Error } = primordials; - class NotFound extends Error { - constructor(msg) { - super(msg); - this.name = "NotFound"; - } +class NotFound extends Error { + constructor(msg) { + super(msg); + this.name = "NotFound"; } +} - class PermissionDenied extends Error { - constructor(msg) { - super(msg); - this.name = "PermissionDenied"; - } +class PermissionDenied extends Error { + constructor(msg) { + super(msg); + this.name = "PermissionDenied"; } +} - class ConnectionRefused extends Error { - constructor(msg) { - super(msg); - this.name = "ConnectionRefused"; - } +class ConnectionRefused extends Error { + constructor(msg) { + super(msg); + this.name = "ConnectionRefused"; } +} - class ConnectionReset extends Error { - constructor(msg) { - super(msg); - this.name = "ConnectionReset"; - } +class ConnectionReset extends Error { + constructor(msg) { + super(msg); + this.name = "ConnectionReset"; } +} - class ConnectionAborted extends Error { - constructor(msg) { - super(msg); - this.name = "ConnectionAborted"; - } +class ConnectionAborted extends Error { + constructor(msg) { + super(msg); + this.name = "ConnectionAborted"; } +} - class NotConnected extends Error { - constructor(msg) { - super(msg); - this.name = "NotConnected"; - } +class NotConnected extends Error { + constructor(msg) { + super(msg); + this.name = "NotConnected"; } +} - class AddrInUse extends Error { - constructor(msg) { - super(msg); - this.name = "AddrInUse"; - } - } - - class AddrNotAvailable extends Error { - constructor(msg) { - super(msg); - this.name = "AddrNotAvailable"; - } - } - - class BrokenPipe extends Error { - constructor(msg) { - super(msg); - this.name = "BrokenPipe"; - } - } - - class AlreadyExists extends Error { - constructor(msg) { - super(msg); - this.name = "AlreadyExists"; - } - } - - class InvalidData extends Error { - constructor(msg) { - super(msg); - this.name = "InvalidData"; - } - } - - class TimedOut extends Error { - constructor(msg) { - super(msg); - this.name = "TimedOut"; - } - } - - class WriteZero extends Error { - constructor(msg) { - super(msg); - this.name = "WriteZero"; - } - } - - class UnexpectedEof extends Error { - constructor(msg) { - super(msg); - this.name = "UnexpectedEof"; - } - } - - class Http extends Error { - constructor(msg) { - super(msg); - this.name = "Http"; - } +class AddrInUse extends Error { + constructor(msg) { + super(msg); + this.name = "AddrInUse"; } +} - class Busy extends Error { - constructor(msg) { - super(msg); - this.name = "Busy"; - } +class AddrNotAvailable extends Error { + constructor(msg) { + super(msg); + this.name = "AddrNotAvailable"; } +} - class NotSupported extends Error { - constructor(msg) { - super(msg); - this.name = "NotSupported"; - } - } +class BrokenPipe extends Error { + constructor(msg) { + super(msg); + this.name = "BrokenPipe"; + } +} + +class AlreadyExists extends Error { + constructor(msg) { + super(msg); + this.name = "AlreadyExists"; + } +} + +class InvalidData extends Error { + constructor(msg) { + super(msg); + this.name = "InvalidData"; + } +} + +class TimedOut extends Error { + constructor(msg) { + super(msg); + this.name = "TimedOut"; + } +} + +class WriteZero extends Error { + constructor(msg) { + super(msg); + this.name = "WriteZero"; + } +} + +class UnexpectedEof extends Error { + constructor(msg) { + super(msg); + this.name = "UnexpectedEof"; + } +} + +class Http extends Error { + constructor(msg) { + super(msg); + this.name = "Http"; + } +} + +class Busy extends Error { + constructor(msg) { + super(msg); + this.name = "Busy"; + } +} + +class NotSupported extends Error { + constructor(msg) { + super(msg); + this.name = "NotSupported"; + } +} - const errors = { - NotFound, - PermissionDenied, - ConnectionRefused, - ConnectionReset, - ConnectionAborted, - NotConnected, - AddrInUse, - AddrNotAvailable, - BrokenPipe, - AlreadyExists, - InvalidData, - TimedOut, - Interrupted, - WriteZero, - UnexpectedEof, - BadResource, - Http, - Busy, - NotSupported, - }; - - window.__bootstrap.errors = { - errors, - }; -})(this); +const errors = { + NotFound, + PermissionDenied, + ConnectionRefused, + ConnectionReset, + ConnectionAborted, + NotConnected, + AddrInUse, + AddrNotAvailable, + BrokenPipe, + AlreadyExists, + InvalidData, + TimedOut, + Interrupted, + WriteZero, + UnexpectedEof, + BadResource, + Http, + Busy, + NotSupported, +}; + +export { errors }; diff --git a/runtime/js/01_version.js b/runtime/js/01_version.js index b1b778a42..62f3df17c 100644 --- a/runtime/js/01_version.js +++ b/runtime/js/01_version.js @@ -1,29 +1,24 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const { ObjectFreeze } = window.__bootstrap.primordials; +const primordials = globalThis.__bootstrap.primordials; +const { ObjectFreeze } = primordials; - const version = { - deno: "", - v8: "", - typescript: "", - }; +const version = { + deno: "", + v8: "", + typescript: "", +}; - function setVersions( - denoVersion, - v8Version, - tsVersion, - ) { - version.deno = denoVersion; - version.v8 = v8Version; - version.typescript = tsVersion; +function setVersions( + denoVersion, + v8Version, + tsVersion, +) { + version.deno = denoVersion; + version.v8 = v8Version; + version.typescript = tsVersion; - ObjectFreeze(version); - } + ObjectFreeze(version); +} - window.__bootstrap.version = { - version, - setVersions, - }; -})(this); +export { setVersions, version }; diff --git a/runtime/js/01_web_util.js b/runtime/js/01_web_util.js deleted file mode 100644 index 9e0bedbd8..000000000 --- a/runtime/js/01_web_util.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const { TypeError, Symbol } = window.__bootstrap.primordials; - const illegalConstructorKey = Symbol("illegalConstructorKey"); - - function requiredArguments( - name, - length, - required, - ) { - if (length < required) { - const errMsg = `${name} requires at least ${required} argument${ - required === 1 ? "" : "s" - }, but only ${length} present`; - throw new TypeError(errMsg); - } - } - - window.__bootstrap.webUtil = { - illegalConstructorKey, - requiredArguments, - }; -})(this); diff --git a/runtime/js/06_util.js b/runtime/js/06_util.js index 391497ba8..6ad1b3ce1 100644 --- a/runtime/js/06_util.js +++ b/runtime/js/06_util.js @@ -1,150 +1,147 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const { - decodeURIComponent, - ObjectPrototypeIsPrototypeOf, - Promise, - SafeArrayIterator, - StringPrototypeReplace, - TypeError, - } = window.__bootstrap.primordials; - const { build } = window.__bootstrap.build; - const { URLPrototype } = window.__bootstrap.url; - let logDebug = false; - let logSource = "JS"; +const internals = globalThis.__bootstrap.internals; +const primordials = globalThis.__bootstrap.primordials; +const { + decodeURIComponent, + ObjectPrototypeIsPrototypeOf, + Promise, + SafeArrayIterator, + StringPrototypeReplace, + TypeError, +} = primordials; +import { build } from "internal:runtime/js/01_build.js"; +import { URLPrototype } from "internal:ext/url/00_url.js"; +let logDebug = false; +let logSource = "JS"; - function setLogDebug(debug, source) { - logDebug = debug; - if (source) { - logSource = source; - } +function setLogDebug(debug, source) { + logDebug = debug; + if (source) { + logSource = source; } +} - function log(...args) { - if (logDebug) { - // if we destructure `console` off `globalThis` too early, we don't bind to - // the right console, therefore we don't log anything out. - globalThis.console.log( - `DEBUG ${logSource} -`, - ...new SafeArrayIterator(args), - ); - } +function log(...args) { + if (logDebug) { + // if we destructure `console` off `globalThis` too early, we don't bind to + // the right console, therefore we don't log anything out. + globalThis.console.log( + `DEBUG ${logSource} -`, + ...new SafeArrayIterator(args), + ); } +} - function createResolvable() { - let resolve; - let reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - promise.resolve = resolve; - promise.reject = reject; - return promise; - } +function createResolvable() { + let resolve; + let reject; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + promise.resolve = resolve; + promise.reject = reject; + return promise; +} - // Keep in sync with `fromFileUrl()` in `std/path/win32.ts`. - function pathFromURLWin32(url) { - let p = StringPrototypeReplace( - url.pathname, - /^\/*([A-Za-z]:)(\/|$)/, - "$1/", - ); - p = StringPrototypeReplace( - p, - /\//g, - "\\", - ); - p = StringPrototypeReplace( - p, - /%(?![0-9A-Fa-f]{2})/g, - "%25", - ); - let path = decodeURIComponent(p); - if (url.hostname != "") { - // Note: The `URL` implementation guarantees that the drive letter and - // hostname are mutually exclusive. Otherwise it would not have been valid - // to append the hostname and path like this. - path = `\\\\${url.hostname}${path}`; - } - return path; +// Keep in sync with `fromFileUrl()` in `std/path/win32.ts`. +function pathFromURLWin32(url) { + let p = StringPrototypeReplace( + url.pathname, + /^\/*([A-Za-z]:)(\/|$)/, + "$1/", + ); + p = StringPrototypeReplace( + p, + /\//g, + "\\", + ); + p = StringPrototypeReplace( + p, + /%(?![0-9A-Fa-f]{2})/g, + "%25", + ); + let path = decodeURIComponent(p); + if (url.hostname != "") { + // Note: The `URL` implementation guarantees that the drive letter and + // hostname are mutually exclusive. Otherwise it would not have been valid + // to append the hostname and path like this. + path = `\\\\${url.hostname}${path}`; } + return path; +} - // Keep in sync with `fromFileUrl()` in `std/path/posix.ts`. - function pathFromURLPosix(url) { - if (url.hostname !== "") { - throw new TypeError(`Host must be empty.`); - } - - return decodeURIComponent( - StringPrototypeReplace(url.pathname, /%(?![0-9A-Fa-f]{2})/g, "%25"), - ); +// Keep in sync with `fromFileUrl()` in `std/path/posix.ts`. +function pathFromURLPosix(url) { + if (url.hostname !== "") { + throw new TypeError(`Host must be empty.`); } - function pathFromURL(pathOrUrl) { - if (ObjectPrototypeIsPrototypeOf(URLPrototype, pathOrUrl)) { - if (pathOrUrl.protocol != "file:") { - throw new TypeError("Must be a file URL."); - } + return decodeURIComponent( + StringPrototypeReplace(url.pathname, /%(?![0-9A-Fa-f]{2})/g, "%25"), + ); +} - return build.os == "windows" - ? pathFromURLWin32(pathOrUrl) - : pathFromURLPosix(pathOrUrl); +function pathFromURL(pathOrUrl) { + if (ObjectPrototypeIsPrototypeOf(URLPrototype, pathOrUrl)) { + if (pathOrUrl.protocol != "file:") { + throw new TypeError("Must be a file URL."); } - return pathOrUrl; - } - - window.__bootstrap.internals = { - ...window.__bootstrap.internals ?? {}, - pathFromURL, - }; - function writable(value) { - return { - value, - writable: true, - enumerable: true, - configurable: true, - }; + return build.os == "windows" + ? pathFromURLWin32(pathOrUrl) + : pathFromURLPosix(pathOrUrl); } + return pathOrUrl; +} - function nonEnumerable(value) { - return { - value, - writable: true, - enumerable: false, - configurable: true, - }; - } +// TODO(bartlomieju): remove +internals.pathFromURL = pathFromURL; - function readOnly(value) { - return { - value, - enumerable: true, - writable: false, - configurable: true, - }; - } +function writable(value) { + return { + value, + writable: true, + enumerable: true, + configurable: true, + }; +} - function getterOnly(getter) { - return { - get: getter, - set() {}, - enumerable: true, - configurable: true, - }; - } +function nonEnumerable(value) { + return { + value, + writable: true, + enumerable: false, + configurable: true, + }; +} - window.__bootstrap.util = { - log, - setLogDebug, - createResolvable, - pathFromURL, - writable, - nonEnumerable, - readOnly, - getterOnly, +function readOnly(value) { + return { + value, + enumerable: true, + writable: false, + configurable: true, }; -})(this); +} + +function getterOnly(getter) { + return { + get: getter, + set() {}, + enumerable: true, + configurable: true, + }; +} + +export { + createResolvable, + getterOnly, + log, + nonEnumerable, + pathFromURL, + readOnly, + setLogDebug, + writable, +}; diff --git a/runtime/js/10_permissions.js b/runtime/js/10_permissions.js index 7c4af8ed0..6019302e4 100644 --- a/runtime/js/10_permissions.js +++ b/runtime/js/10_permissions.js @@ -1,287 +1,282 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const { ops } = Deno.core; - const { Event } = window.__bootstrap.event; - const { EventTarget } = window.__bootstrap.eventTarget; - const { pathFromURL } = window.__bootstrap.util; - const { illegalConstructorKey } = window.__bootstrap.webUtil; - const { - ArrayIsArray, - ArrayPrototypeIncludes, - ArrayPrototypeMap, - ArrayPrototypeSlice, - Map, - MapPrototypeGet, - MapPrototypeHas, - MapPrototypeSet, - FunctionPrototypeCall, - PromiseResolve, - PromiseReject, - ReflectHas, - SafeArrayIterator, - SymbolFor, - TypeError, - } = window.__bootstrap.primordials; - /** - * @typedef StatusCacheValue - * @property {PermissionState} state - * @property {PermissionStatus} status - */ - - /** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "sys" | "run" | "ffi" | "hrtime">} */ - const permissionNames = [ - "read", - "write", - "net", - "env", - "sys", - "run", - "ffi", - "hrtime", - ]; - - /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} - */ - function opQuery(desc) { - return ops.op_query_permission(desc); +const core = globalThis.Deno.core; +const ops = core.ops; +import { Event, EventTarget } from "internal:ext/web/02_event.js"; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayIsArray, + ArrayPrototypeIncludes, + ArrayPrototypeMap, + ArrayPrototypeSlice, + Map, + MapPrototypeGet, + MapPrototypeHas, + MapPrototypeSet, + FunctionPrototypeCall, + PromiseResolve, + PromiseReject, + ReflectHas, + SafeArrayIterator, + Symbol, + SymbolFor, + TypeError, +} = primordials; + +const illegalConstructorKey = Symbol("illegalConstructorKey"); + +/** + * @typedef StatusCacheValue + * @property {PermissionState} state + * @property {PermissionStatus} status + */ + +/** @type {ReadonlyArray<"read" | "write" | "net" | "env" | "sys" | "run" | "ffi" | "hrtime">} */ +const permissionNames = [ + "read", + "write", + "net", + "env", + "sys", + "run", + "ffi", + "hrtime", +]; + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opQuery(desc) { + return ops.op_query_permission(desc); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opRevoke(desc) { + return ops.op_revoke_permission(desc); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {Deno.PermissionState} + */ +function opRequest(desc) { + return ops.op_request_permission(desc); +} + +class PermissionStatus extends EventTarget { + /** @type {{ state: Deno.PermissionState }} */ + #state; + + /** @type {((this: PermissionStatus, event: Event) => any) | null} */ + onchange = null; + + /** @returns {Deno.PermissionState} */ + get state() { + return this.#state.state; } /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} + * @param {{ state: Deno.PermissionState }} state + * @param {unknown} key */ - function opRevoke(desc) { - return ops.op_revoke_permission(desc); + constructor(state = null, key = null) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + super(); + this.#state = state; } /** - * @param {Deno.PermissionDescriptor} desc - * @returns {Deno.PermissionState} + * @param {Event} event + * @returns {boolean} */ - function opRequest(desc) { - return ops.op_request_permission(desc); - } - - class PermissionStatus extends EventTarget { - /** @type {{ state: Deno.PermissionState }} */ - #state; - - /** @type {((this: PermissionStatus, event: Event) => any) | null} */ - onchange = null; - - /** @returns {Deno.PermissionState} */ - get state() { - return this.#state.state; - } - - /** - * @param {{ state: Deno.PermissionState }} state - * @param {unknown} key - */ - constructor(state = null, key = null) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } - super(); - this.#state = state; - } - - /** - * @param {Event} event - * @returns {boolean} - */ - dispatchEvent(event) { - let dispatched = super.dispatchEvent(event); - if (dispatched && this.onchange) { - FunctionPrototypeCall(this.onchange, this, event); - dispatched = !event.defaultPrevented; - } - return dispatched; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${ - inspect({ state: this.state, onchange: this.onchange }) - }`; + dispatchEvent(event) { + let dispatched = super.dispatchEvent(event); + if (dispatched && this.onchange) { + FunctionPrototypeCall(this.onchange, this, event); + dispatched = !event.defaultPrevented; } + return dispatched; } - /** @type {Map<string, StatusCacheValue>} */ - const statusCache = new Map(); - - /** - * @param {Deno.PermissionDescriptor} desc - * @param {Deno.PermissionState} state - * @returns {PermissionStatus} - */ - function cache(desc, state) { - let { name: key } = desc; - if ( - (desc.name === "read" || desc.name === "write" || desc.name === "ffi") && - ReflectHas(desc, "path") - ) { - key += `-${desc.path}&`; - } else if (desc.name === "net" && desc.host) { - key += `-${desc.host}&`; - } else if (desc.name === "run" && desc.command) { - key += `-${desc.command}&`; - } else if (desc.name === "env" && desc.variable) { - key += `-${desc.variable}&`; - } else if (desc.name === "sys" && desc.kind) { - key += `-${desc.kind}&`; - } else { - key += "$"; - } - if (MapPrototypeHas(statusCache, key)) { - const status = MapPrototypeGet(statusCache, key); - if (status.state !== state) { - status.state = state; - status.status.dispatchEvent(new Event("change", { cancelable: false })); - } - return status.status; + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${ + inspect({ state: this.state, onchange: this.onchange }) + }`; + } +} + +/** @type {Map<string, StatusCacheValue>} */ +const statusCache = new Map(); + +/** + * @param {Deno.PermissionDescriptor} desc + * @param {Deno.PermissionState} state + * @returns {PermissionStatus} + */ +function cache(desc, state) { + let { name: key } = desc; + if ( + (desc.name === "read" || desc.name === "write" || desc.name === "ffi") && + ReflectHas(desc, "path") + ) { + key += `-${desc.path}&`; + } else if (desc.name === "net" && desc.host) { + key += `-${desc.host}&`; + } else if (desc.name === "run" && desc.command) { + key += `-${desc.command}&`; + } else if (desc.name === "env" && desc.variable) { + key += `-${desc.variable}&`; + } else if (desc.name === "sys" && desc.kind) { + key += `-${desc.kind}&`; + } else { + key += "$"; + } + if (MapPrototypeHas(statusCache, key)) { + const status = MapPrototypeGet(statusCache, key); + if (status.state !== state) { + status.state = state; + status.status.dispatchEvent(new Event("change", { cancelable: false })); } - /** @type {{ state: Deno.PermissionState; status?: PermissionStatus }} */ - const status = { state }; - status.status = new PermissionStatus(status, illegalConstructorKey); - MapPrototypeSet(statusCache, key, status); return status.status; } - - /** - * @param {unknown} desc - * @returns {desc is Deno.PermissionDescriptor} - */ - function isValidDescriptor(desc) { - return typeof desc === "object" && desc !== null && - ArrayPrototypeIncludes(permissionNames, desc.name); + /** @type {{ state: Deno.PermissionState; status?: PermissionStatus }} */ + const status = { state }; + status.status = new PermissionStatus(status, illegalConstructorKey); + MapPrototypeSet(statusCache, key, status); + return status.status; +} + +/** + * @param {unknown} desc + * @returns {desc is Deno.PermissionDescriptor} + */ +function isValidDescriptor(desc) { + return typeof desc === "object" && desc !== null && + ArrayPrototypeIncludes(permissionNames, desc.name); +} + +/** + * @param {Deno.PermissionDescriptor} desc + * @returns {desc is Deno.PermissionDescriptor} + */ +function formDescriptor(desc) { + if ( + desc.name === "read" || desc.name === "write" || desc.name === "ffi" + ) { + desc.path = pathFromURL(desc.path); + } else if (desc.name === "run") { + desc.command = pathFromURL(desc.command); } +} - /** - * @param {Deno.PermissionDescriptor} desc - * @returns {desc is Deno.PermissionDescriptor} - */ - function formDescriptor(desc) { - if ( - desc.name === "read" || desc.name === "write" || desc.name === "ffi" - ) { - desc.path = pathFromURL(desc.path); - } else if (desc.name === "run") { - desc.command = pathFromURL(desc.command); +class Permissions { + constructor(key = null) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); } } - class Permissions { - constructor(key = null) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } + query(desc) { + try { + return PromiseResolve(this.querySync(desc)); + } catch (error) { + return PromiseReject(error); } + } - query(desc) { - try { - return PromiseResolve(this.querySync(desc)); - } catch (error) { - return PromiseReject(error); - } + querySync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - querySync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } + formDescriptor(desc); - formDescriptor(desc); + const state = opQuery(desc); + return cache(desc, state); + } - const state = opQuery(desc); - return cache(desc, state); + revoke(desc) { + try { + return PromiseResolve(this.revokeSync(desc)); + } catch (error) { + return PromiseReject(error); } + } - revoke(desc) { - try { - return PromiseResolve(this.revokeSync(desc)); - } catch (error) { - return PromiseReject(error); - } + revokeSync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - revokeSync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } + formDescriptor(desc); - formDescriptor(desc); + const state = opRevoke(desc); + return cache(desc, state); + } - const state = opRevoke(desc); - return cache(desc, state); + request(desc) { + try { + return PromiseResolve(this.requestSync(desc)); + } catch (error) { + return PromiseReject(error); } + } - request(desc) { - try { - return PromiseResolve(this.requestSync(desc)); - } catch (error) { - return PromiseReject(error); - } + requestSync(desc) { + if (!isValidDescriptor(desc)) { + throw new TypeError( + `The provided value "${desc?.name}" is not a valid permission name.`, + ); } - requestSync(desc) { - if (!isValidDescriptor(desc)) { - throw new TypeError( - `The provided value "${desc?.name}" is not a valid permission name.`, - ); - } - - formDescriptor(desc); + formDescriptor(desc); - const state = opRequest(desc); - return cache(desc, state); - } + const state = opRequest(desc); + return cache(desc, state); } +} + +const permissions = new Permissions(illegalConstructorKey); - const permissions = new Permissions(illegalConstructorKey); - - /** Converts all file URLs in FS allowlists to paths. */ - function serializePermissions(permissions) { - if (typeof permissions == "object" && permissions != null) { - const serializedPermissions = {}; - for ( - const key of new SafeArrayIterator(["read", "write", "run", "ffi"]) - ) { - if (ArrayIsArray(permissions[key])) { - serializedPermissions[key] = ArrayPrototypeMap( - permissions[key], - (path) => pathFromURL(path), - ); - } else { - serializedPermissions[key] = permissions[key]; - } +/** Converts all file URLs in FS allowlists to paths. */ +function serializePermissions(permissions) { + if (typeof permissions == "object" && permissions != null) { + const serializedPermissions = {}; + for ( + const key of new SafeArrayIterator(["read", "write", "run", "ffi"]) + ) { + if (ArrayIsArray(permissions[key])) { + serializedPermissions[key] = ArrayPrototypeMap( + permissions[key], + (path) => pathFromURL(path), + ); + } else { + serializedPermissions[key] = permissions[key]; } - for ( - const key of new SafeArrayIterator(["env", "hrtime", "net", "sys"]) - ) { - if (ArrayIsArray(permissions[key])) { - serializedPermissions[key] = ArrayPrototypeSlice(permissions[key]); - } else { - serializedPermissions[key] = permissions[key]; - } + } + for ( + const key of new SafeArrayIterator(["env", "hrtime", "net", "sys"]) + ) { + if (ArrayIsArray(permissions[key])) { + serializedPermissions[key] = ArrayPrototypeSlice(permissions[key]); + } else { + serializedPermissions[key] = permissions[key]; } - return serializedPermissions; } - return permissions; + return serializedPermissions; } + return permissions; +} - window.__bootstrap.permissions = { - serializePermissions, - permissions, - Permissions, - PermissionStatus, - }; -})(this); +export { Permissions, permissions, PermissionStatus, serializePermissions }; diff --git a/runtime/js/11_workers.js b/runtime/js/11_workers.js index 85c01e1a9..56ceb92f3 100644 --- a/runtime/js/11_workers.js +++ b/runtime/js/11_workers.js @@ -1,254 +1,253 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { - Error, - ObjectPrototypeIsPrototypeOf, - StringPrototypeStartsWith, - String, - SymbolIterator, - SymbolToStringTag, - } = window.__bootstrap.primordials; - const webidl = window.__bootstrap.webidl; - const { URL } = window.__bootstrap.url; - const { getLocationHref } = window.__bootstrap.location; - const { serializePermissions } = window.__bootstrap.permissions; - const { log } = window.__bootstrap.util; - const { ErrorEvent, MessageEvent, defineEventHandler } = - window.__bootstrap.event; - const { EventTarget } = window.__bootstrap.eventTarget; - const { - deserializeJsMessageData, - serializeJsMessageData, - MessagePortPrototype, - } = window.__bootstrap.messagePort; - - function createWorker( - specifier, + +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +const { + Error, + ObjectPrototypeIsPrototypeOf, + StringPrototypeStartsWith, + String, + SymbolIterator, + SymbolToStringTag, +} = primordials; +import * as webidl from "internal:ext/webidl/00_webidl.js"; +import { URL } from "internal:ext/url/00_url.js"; +import { getLocationHref } from "internal:ext/web/12_location.js"; +import { serializePermissions } from "internal:runtime/js/10_permissions.js"; +import { log } from "internal:runtime/js/06_util.js"; +import { + defineEventHandler, + ErrorEvent, + EventTarget, + MessageEvent, +} from "internal:ext/web/02_event.js"; +import { + deserializeJsMessageData, + MessagePortPrototype, + serializeJsMessageData, +} from "internal:ext/web/13_message_port.js"; + +function createWorker( + specifier, + hasSourceCode, + sourceCode, + permissions, + name, + workerType, +) { + return ops.op_create_worker({ hasSourceCode, - sourceCode, - permissions, name, + permissions: serializePermissions(permissions), + sourceCode, + specifier, workerType, - ) { - return ops.op_create_worker({ - hasSourceCode, + }); +} + +function hostTerminateWorker(id) { + ops.op_host_terminate_worker(id); +} + +function hostPostMessage(id, data) { + ops.op_host_post_message(id, data); +} + +function hostRecvCtrl(id) { + return core.opAsync("op_host_recv_ctrl", id); +} + +function hostRecvMessage(id) { + return core.opAsync("op_host_recv_message", id); +} + +class Worker extends EventTarget { + #id = 0; + #name = ""; + + // "RUNNING" | "CLOSED" | "TERMINATED" + // "TERMINATED" means that any controls or messages received will be + // discarded. "CLOSED" means that we have received a control + // indicating that the worker is no longer running, but there might + // still be messages left to receive. + #status = "RUNNING"; + + constructor(specifier, options = {}) { + super(); + specifier = String(specifier); + const { + deno, name, - permissions: serializePermissions(permissions), - sourceCode, + type = "classic", + } = options; + + const workerType = webidl.converters["WorkerType"](type); + + if ( + StringPrototypeStartsWith(specifier, "./") || + StringPrototypeStartsWith(specifier, "../") || + StringPrototypeStartsWith(specifier, "/") || workerType === "classic" + ) { + const baseUrl = getLocationHref(); + if (baseUrl != null) { + specifier = new URL(specifier, baseUrl).href; + } + } + + this.#name = name; + let hasSourceCode, sourceCode; + if (workerType === "classic") { + hasSourceCode = true; + sourceCode = `importScripts("#");`; + } else { + hasSourceCode = false; + sourceCode = ""; + } + + const id = createWorker( specifier, + hasSourceCode, + sourceCode, + deno?.permissions, + name, workerType, - }); + ); + this.#id = id; + this.#pollControl(); + this.#pollMessages(); } - function hostTerminateWorker(id) { - ops.op_host_terminate_worker(id); - } - - function hostPostMessage(id, data) { - ops.op_host_post_message(id, data); - } + #handleError(e) { + const event = new ErrorEvent("error", { + cancelable: true, + message: e.message, + lineno: e.lineNumber ? e.lineNumber : undefined, + colno: e.columnNumber ? e.columnNumber : undefined, + filename: e.fileName, + error: null, + }); - function hostRecvCtrl(id) { - return core.opAsync("op_host_recv_ctrl", id); - } + this.dispatchEvent(event); + // Don't bubble error event to window for loader errors (`!e.fileName`). + // TODO(nayeemrmn): It's not correct to use `e.fileName` to detect user + // errors. It won't be there for non-awaited async ops for example. + if (e.fileName && !event.defaultPrevented) { + globalThis.dispatchEvent(event); + } - function hostRecvMessage(id) { - return core.opAsync("op_host_recv_message", id); + return event.defaultPrevented; } - class Worker extends EventTarget { - #id = 0; - #name = ""; - - // "RUNNING" | "CLOSED" | "TERMINATED" - // "TERMINATED" means that any controls or messages received will be - // discarded. "CLOSED" means that we have received a control - // indicating that the worker is no longer running, but there might - // still be messages left to receive. - #status = "RUNNING"; - - constructor(specifier, options = {}) { - super(); - specifier = String(specifier); - const { - deno, - name, - type = "classic", - } = options; - - const workerType = webidl.converters["WorkerType"](type); - - if ( - StringPrototypeStartsWith(specifier, "./") || - StringPrototypeStartsWith(specifier, "../") || - StringPrototypeStartsWith(specifier, "/") || workerType === "classic" - ) { - const baseUrl = getLocationHref(); - if (baseUrl != null) { - specifier = new URL(specifier, baseUrl).href; - } - } + #pollControl = async () => { + while (this.#status === "RUNNING") { + const { 0: type, 1: data } = await hostRecvCtrl(this.#id); - this.#name = name; - let hasSourceCode, sourceCode; - if (workerType === "classic") { - hasSourceCode = true; - sourceCode = `importScripts("#");`; - } else { - hasSourceCode = false; - sourceCode = ""; + // If terminate was called then we ignore all messages + if (this.#status === "TERMINATED") { + return; } - const id = createWorker( - specifier, - hasSourceCode, - sourceCode, - deno?.permissions, - name, - workerType, - ); - this.#id = id; - this.#pollControl(); - this.#pollMessages(); - } - - #handleError(e) { - const event = new ErrorEvent("error", { - cancelable: true, - message: e.message, - lineno: e.lineNumber ? e.lineNumber : undefined, - colno: e.columnNumber ? e.columnNumber : undefined, - filename: e.fileName, - error: null, - }); - - this.dispatchEvent(event); - // Don't bubble error event to window for loader errors (`!e.fileName`). - // TODO(nayeemrmn): It's not correct to use `e.fileName` to detect user - // errors. It won't be there for non-awaited async ops for example. - if (e.fileName && !event.defaultPrevented) { - window.dispatchEvent(event); - } - - return event.defaultPrevented; - } - - #pollControl = async () => { - while (this.#status === "RUNNING") { - const { 0: type, 1: data } = await hostRecvCtrl(this.#id); - - // If terminate was called then we ignore all messages - if (this.#status === "TERMINATED") { - return; - } - - switch (type) { - case 1: { // TerminalError - this.#status = "CLOSED"; - } /* falls through */ - case 2: { // Error - if (!this.#handleError(data)) { - throw new Error("Unhandled error in child worker."); - } - break; - } - case 3: { // Close - log(`Host got "close" message from worker: ${this.#name}`); - this.#status = "CLOSED"; - return; - } - default: { - throw new Error(`Unknown worker event: "${type}"`); + switch (type) { + case 1: { // TerminalError + this.#status = "CLOSED"; + } /* falls through */ + case 2: { // Error + if (!this.#handleError(data)) { + throw new Error("Unhandled error in child worker."); } + break; } - } - }; - - #pollMessages = async () => { - while (this.#status !== "TERMINATED") { - const data = await hostRecvMessage(this.#id); - if (this.#status === "TERMINATED" || data === null) { + case 3: { // Close + log(`Host got "close" message from worker: ${this.#name}`); + this.#status = "CLOSED"; return; } - let message, transferables; - try { - const v = deserializeJsMessageData(data); - message = v[0]; - transferables = v[1]; - } catch (err) { - const event = new MessageEvent("messageerror", { - cancelable: false, - data: err, - }); - this.dispatchEvent(event); - return; + default: { + throw new Error(`Unknown worker event: "${type}"`); } - const event = new MessageEvent("message", { + } + } + }; + + #pollMessages = async () => { + while (this.#status !== "TERMINATED") { + const data = await hostRecvMessage(this.#id); + if (this.#status === "TERMINATED" || data === null) { + return; + } + let message, transferables; + try { + const v = deserializeJsMessageData(data); + message = v[0]; + transferables = v[1]; + } catch (err) { + const event = new MessageEvent("messageerror", { cancelable: false, - data: message, - ports: transferables.filter((t) => - ObjectPrototypeIsPrototypeOf(MessagePortPrototype, t) - ), + data: err, }); this.dispatchEvent(event); + return; } - }; - - postMessage(message, transferOrOptions = {}) { - const prefix = "Failed to execute 'postMessage' on 'MessagePort'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - message = webidl.converters.any(message); - let options; - if ( - webidl.type(transferOrOptions) === "Object" && - transferOrOptions !== undefined && - transferOrOptions[SymbolIterator] !== undefined - ) { - const transfer = webidl.converters["sequence<object>"]( - transferOrOptions, - { prefix, context: "Argument 2" }, - ); - options = { transfer }; - } else { - options = webidl.converters.StructuredSerializeOptions( - transferOrOptions, - { - prefix, - context: "Argument 2", - }, - ); - } - const { transfer } = options; - const data = serializeJsMessageData(message, transfer); - if (this.#status === "RUNNING") { - hostPostMessage(this.#id, data); - } + const event = new MessageEvent("message", { + cancelable: false, + data: message, + ports: transferables.filter((t) => + ObjectPrototypeIsPrototypeOf(MessagePortPrototype, t) + ), + }); + this.dispatchEvent(event); } + }; - terminate() { - if (this.#status !== "TERMINATED") { - this.#status = "TERMINATED"; - hostTerminateWorker(this.#id); - } + postMessage(message, transferOrOptions = {}) { + const prefix = "Failed to execute 'postMessage' on 'MessagePort'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + message = webidl.converters.any(message); + let options; + if ( + webidl.type(transferOrOptions) === "Object" && + transferOrOptions !== undefined && + transferOrOptions[SymbolIterator] !== undefined + ) { + const transfer = webidl.converters["sequence<object>"]( + transferOrOptions, + { prefix, context: "Argument 2" }, + ); + options = { transfer }; + } else { + options = webidl.converters.StructuredSerializeOptions( + transferOrOptions, + { + prefix, + context: "Argument 2", + }, + ); } + const { transfer } = options; + const data = serializeJsMessageData(message, transfer); + if (this.#status === "RUNNING") { + hostPostMessage(this.#id, data); + } + } - [SymbolToStringTag] = "Worker"; + terminate() { + if (this.#status !== "TERMINATED") { + this.#status = "TERMINATED"; + hostTerminateWorker(this.#id); + } } - defineEventHandler(Worker.prototype, "error"); - defineEventHandler(Worker.prototype, "message"); - defineEventHandler(Worker.prototype, "messageerror"); + [SymbolToStringTag] = "Worker"; +} - webidl.converters["WorkerType"] = webidl.createEnumConverter("WorkerType", [ - "classic", - "module", - ]); +defineEventHandler(Worker.prototype, "error"); +defineEventHandler(Worker.prototype, "message"); +defineEventHandler(Worker.prototype, "messageerror"); - window.__bootstrap.worker = { - Worker, - }; -})(this); +webidl.converters["WorkerType"] = webidl.createEnumConverter("WorkerType", [ + "classic", + "module", +]); + +export { Worker }; diff --git a/runtime/js/12_io.js b/runtime/js/12_io.js index f6b2d6b87..b9ff1190b 100644 --- a/runtime/js/12_io.js +++ b/runtime/js/12_io.js @@ -3,238 +3,236 @@ // Interfaces 100% copied from Go. // Documentation liberally lifted from them too. // Thank you! We love Go! <3 -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { - Uint8Array, - ArrayPrototypePush, - MathMin, - TypedArrayPrototypeSubarray, - TypedArrayPrototypeSet, - } = window.__bootstrap.primordials; - - const DEFAULT_BUFFER_SIZE = 32 * 1024; - // Seek whence values. - // https://golang.org/pkg/io/#pkg-constants - const SeekMode = { - 0: "Start", - 1: "Current", - 2: "End", - - Start: 0, - Current: 1, - End: 2, - }; - - async function copy( - src, - dst, - options, - ) { - let n = 0; - const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; - const b = new Uint8Array(bufSize); - let gotEOF = false; - while (gotEOF === false) { - const result = await src.read(b); - if (result === null) { - gotEOF = true; - } else { - let nwritten = 0; - while (nwritten < result) { - nwritten += await dst.write( - TypedArrayPrototypeSubarray(b, nwritten, result), - ); - } - n += nwritten; - } - } - return n; - } - async function* iter( - r, - options, - ) { - const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; - const b = new Uint8Array(bufSize); - while (true) { - const result = await r.read(b); - if (result === null) { - break; +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +const { + Uint8Array, + ArrayPrototypePush, + MathMin, + TypedArrayPrototypeSubarray, + TypedArrayPrototypeSet, +} = primordials; + +const DEFAULT_BUFFER_SIZE = 32 * 1024; +// Seek whence values. +// https://golang.org/pkg/io/#pkg-constants +const SeekMode = { + 0: "Start", + 1: "Current", + 2: "End", + + Start: 0, + Current: 1, + End: 2, +}; + +async function copy( + src, + dst, + options, +) { + let n = 0; + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + let gotEOF = false; + while (gotEOF === false) { + const result = await src.read(b); + if (result === null) { + gotEOF = true; + } else { + let nwritten = 0; + while (nwritten < result) { + nwritten += await dst.write( + TypedArrayPrototypeSubarray(b, nwritten, result), + ); } - - yield TypedArrayPrototypeSubarray(b, 0, result); + n += nwritten; } } - - function* iterSync( - r, - options, - ) { - const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; - const b = new Uint8Array(bufSize); - while (true) { - const result = r.readSync(b); - if (result === null) { - break; - } - - yield TypedArrayPrototypeSubarray(b, 0, result); + return n; +} + +async function* iter( + r, + options, +) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while (true) { + const result = await r.read(b); + if (result === null) { + break; } - } - function readSync(rid, buffer) { - if (buffer.length === 0) { - return 0; + yield TypedArrayPrototypeSubarray(b, 0, result); + } +} + +function* iterSync( + r, + options, +) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while (true) { + const result = r.readSync(b); + if (result === null) { + break; } - const nread = ops.op_read_sync(rid, buffer); + yield TypedArrayPrototypeSubarray(b, 0, result); + } +} - return nread === 0 ? null : nread; +function readSync(rid, buffer) { + if (buffer.length === 0) { + return 0; } - async function read(rid, buffer) { - if (buffer.length === 0) { - return 0; - } + const nread = ops.op_read_sync(rid, buffer); - const nread = await core.read(rid, buffer); + return nread === 0 ? null : nread; +} - return nread === 0 ? null : nread; +async function read(rid, buffer) { + if (buffer.length === 0) { + return 0; } - function writeSync(rid, data) { - return ops.op_write_sync(rid, data); - } + const nread = await core.read(rid, buffer); - function write(rid, data) { - return core.write(rid, data); - } + return nread === 0 ? null : nread; +} - const READ_PER_ITER = 64 * 1024; // 64kb +function writeSync(rid, data) { + return ops.op_write_sync(rid, data); +} - function readAll(r) { - return readAllInner(r); - } - async function readAllInner(r, options) { - const buffers = []; - const signal = options?.signal ?? null; - while (true) { - signal?.throwIfAborted(); - const buf = new Uint8Array(READ_PER_ITER); - const read = await r.read(buf); - if (typeof read == "number") { - ArrayPrototypePush(buffers, new Uint8Array(buf.buffer, 0, read)); - } else { - break; - } - } - signal?.throwIfAborted(); +function write(rid, data) { + return core.write(rid, data); +} - return concatBuffers(buffers); +const READ_PER_ITER = 64 * 1024; // 64kb + +function readAll(r) { + return readAllInner(r); +} +async function readAllInner(r, options) { + const buffers = []; + const signal = options?.signal ?? null; + while (true) { + signal?.throwIfAborted(); + const buf = new Uint8Array(READ_PER_ITER); + const read = await r.read(buf); + if (typeof read == "number") { + ArrayPrototypePush(buffers, new Uint8Array(buf.buffer, 0, read)); + } else { + break; + } } + signal?.throwIfAborted(); - function readAllSync(r) { - const buffers = []; + return concatBuffers(buffers); +} - while (true) { - const buf = new Uint8Array(READ_PER_ITER); - const read = r.readSync(buf); - if (typeof read == "number") { - ArrayPrototypePush(buffers, TypedArrayPrototypeSubarray(buf, 0, read)); - } else { - break; - } - } +function readAllSync(r) { + const buffers = []; - return concatBuffers(buffers); + while (true) { + const buf = new Uint8Array(READ_PER_ITER); + const read = r.readSync(buf); + if (typeof read == "number") { + ArrayPrototypePush(buffers, TypedArrayPrototypeSubarray(buf, 0, read)); + } else { + break; + } } - function concatBuffers(buffers) { - let totalLen = 0; - for (let i = 0; i < buffers.length; ++i) { - totalLen += buffers[i].byteLength; - } + return concatBuffers(buffers); +} - const contents = new Uint8Array(totalLen); +function concatBuffers(buffers) { + let totalLen = 0; + for (let i = 0; i < buffers.length; ++i) { + totalLen += buffers[i].byteLength; + } - let n = 0; - for (let i = 0; i < buffers.length; ++i) { - const buf = buffers[i]; - TypedArrayPrototypeSet(contents, buf, n); - n += buf.byteLength; - } + const contents = new Uint8Array(totalLen); - return contents; + let n = 0; + for (let i = 0; i < buffers.length; ++i) { + const buf = buffers[i]; + TypedArrayPrototypeSet(contents, buf, n); + n += buf.byteLength; } - function readAllSyncSized(r, size) { - const buf = new Uint8Array(size + 1); // 1B to detect extended files - let cursor = 0; - - while (cursor < size) { - const sliceEnd = MathMin(size + 1, cursor + READ_PER_ITER); - const slice = TypedArrayPrototypeSubarray(buf, cursor, sliceEnd); - const read = r.readSync(slice); - if (typeof read == "number") { - cursor += read; - } else { - break; - } - } + return contents; +} + +function readAllSyncSized(r, size) { + const buf = new Uint8Array(size + 1); // 1B to detect extended files + let cursor = 0; - // Handle truncated or extended files during read - if (cursor > size) { - // Read remaining and concat - return concatBuffers([buf, readAllSync(r)]); - } else { // cursor == size - return TypedArrayPrototypeSubarray(buf, 0, cursor); + while (cursor < size) { + const sliceEnd = MathMin(size + 1, cursor + READ_PER_ITER); + const slice = TypedArrayPrototypeSubarray(buf, cursor, sliceEnd); + const read = r.readSync(slice); + if (typeof read == "number") { + cursor += read; + } else { + break; } } - async function readAllInnerSized(r, size, options) { - const buf = new Uint8Array(size + 1); // 1B to detect extended files - let cursor = 0; - const signal = options?.signal ?? null; - while (cursor < size) { - signal?.throwIfAborted(); - const sliceEnd = MathMin(size + 1, cursor + READ_PER_ITER); - const slice = TypedArrayPrototypeSubarray(buf, cursor, sliceEnd); - const read = await r.read(slice); - if (typeof read == "number") { - cursor += read; - } else { - break; - } - } - signal?.throwIfAborted(); + // Handle truncated or extended files during read + if (cursor > size) { + // Read remaining and concat + return concatBuffers([buf, readAllSync(r)]); + } else { // cursor == size + return TypedArrayPrototypeSubarray(buf, 0, cursor); + } +} - // Handle truncated or extended files during read - if (cursor > size) { - // Read remaining and concat - return concatBuffers([buf, await readAllInner(r, options)]); +async function readAllInnerSized(r, size, options) { + const buf = new Uint8Array(size + 1); // 1B to detect extended files + let cursor = 0; + const signal = options?.signal ?? null; + while (cursor < size) { + signal?.throwIfAborted(); + const sliceEnd = MathMin(size + 1, cursor + READ_PER_ITER); + const slice = TypedArrayPrototypeSubarray(buf, cursor, sliceEnd); + const read = await r.read(slice); + if (typeof read == "number") { + cursor += read; } else { - return TypedArrayPrototypeSubarray(buf, 0, cursor); + break; } } - - window.__bootstrap.io = { - iterSync, - iter, - copy, - SeekMode, - read, - readSync, - write, - writeSync, - readAll, - readAllInner, - readAllSync, - readAllSyncSized, - readAllInnerSized, - }; -})(this); + signal?.throwIfAborted(); + + // Handle truncated or extended files during read + if (cursor > size) { + // Read remaining and concat + return concatBuffers([buf, await readAllInner(r, options)]); + } else { + return TypedArrayPrototypeSubarray(buf, 0, cursor); + } +} + +export { + copy, + iter, + iterSync, + read, + readAll, + readAllInner, + readAllInnerSized, + readAllSync, + readAllSyncSized, + readSync, + SeekMode, + write, + writeSync, +}; diff --git a/runtime/js/13_buffer.js b/runtime/js/13_buffer.js index 180e9d26d..8e87eefa5 100644 --- a/runtime/js/13_buffer.js +++ b/runtime/js/13_buffer.js @@ -3,257 +3,249 @@ // This code has been ported almost directly from Go's src/bytes/buffer.go // Copyright 2009 The Go Authors. All rights reserved. BSD license. // https://github.com/golang/go/blob/master/LICENSE -"use strict"; - -((window) => { - const { assert } = window.__bootstrap.infra; - const { - TypedArrayPrototypeSubarray, - TypedArrayPrototypeSlice, - TypedArrayPrototypeSet, - MathFloor, - MathMin, - PromiseResolve, - Uint8Array, - Error, - } = window.__bootstrap.primordials; - - // MIN_READ is the minimum ArrayBuffer size passed to a read call by - // buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond - // what is required to hold the contents of r, readFrom() will not grow the - // underlying buffer. - const MIN_READ = 32 * 1024; - const MAX_SIZE = 2 ** 32 - 2; - - // `off` is the offset into `dst` where it will at which to begin writing values - // from `src`. - // Returns the number of bytes copied. - function copyBytes(src, dst, off = 0) { - const r = dst.byteLength - off; - if (src.byteLength > r) { - src = TypedArrayPrototypeSubarray(src, 0, r); - } - TypedArrayPrototypeSet(dst, src, off); - return src.byteLength; - } - class Buffer { - #buf = null; // contents are the bytes buf[off : len(buf)] - #off = 0; // read at buf[off], write at buf[buf.byteLength] +import { assert } from "internal:ext/web/00_infra.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + TypedArrayPrototypeSubarray, + TypedArrayPrototypeSlice, + TypedArrayPrototypeSet, + MathFloor, + MathMin, + PromiseResolve, + Uint8Array, + Error, +} = primordials; + +// MIN_READ is the minimum ArrayBuffer size passed to a read call by +// buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond +// what is required to hold the contents of r, readFrom() will not grow the +// underlying buffer. +const MIN_READ = 32 * 1024; +const MAX_SIZE = 2 ** 32 - 2; + +// `off` is the offset into `dst` where it will at which to begin writing values +// from `src`. +// Returns the number of bytes copied. +function copyBytes(src, dst, off = 0) { + const r = dst.byteLength - off; + if (src.byteLength > r) { + src = TypedArrayPrototypeSubarray(src, 0, r); + } + TypedArrayPrototypeSet(dst, src, off); + return src.byteLength; +} - constructor(ab) { - if (ab == null) { - this.#buf = new Uint8Array(0); - return; - } +class Buffer { + #buf = null; // contents are the bytes buf[off : len(buf)] + #off = 0; // read at buf[off], write at buf[buf.byteLength] - this.#buf = new Uint8Array(ab); + constructor(ab) { + if (ab == null) { + this.#buf = new Uint8Array(0); + return; } - bytes(options = { copy: true }) { - if (options.copy === false) { - return TypedArrayPrototypeSubarray(this.#buf, this.#off); - } - return TypedArrayPrototypeSlice(this.#buf, this.#off); - } + this.#buf = new Uint8Array(ab); + } - empty() { - return this.#buf.byteLength <= this.#off; + bytes(options = { copy: true }) { + if (options.copy === false) { + return TypedArrayPrototypeSubarray(this.#buf, this.#off); } + return TypedArrayPrototypeSlice(this.#buf, this.#off); + } - get length() { - return this.#buf.byteLength - this.#off; - } + empty() { + return this.#buf.byteLength <= this.#off; + } - get capacity() { - return this.#buf.buffer.byteLength; - } + get length() { + return this.#buf.byteLength - this.#off; + } - truncate(n) { - if (n === 0) { - this.reset(); - return; - } - if (n < 0 || n > this.length) { - throw Error("bytes.Buffer: truncation out of range"); - } - this.#reslice(this.#off + n); - } + get capacity() { + return this.#buf.buffer.byteLength; + } - reset() { - this.#reslice(0); - this.#off = 0; + truncate(n) { + if (n === 0) { + this.reset(); + return; } - - #tryGrowByReslice(n) { - const l = this.#buf.byteLength; - if (n <= this.capacity - l) { - this.#reslice(l + n); - return l; - } - return -1; + if (n < 0 || n > this.length) { + throw Error("bytes.Buffer: truncation out of range"); } + this.#reslice(this.#off + n); + } + + reset() { + this.#reslice(0); + this.#off = 0; + } - #reslice(len) { - assert(len <= this.#buf.buffer.byteLength); - this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + #tryGrowByReslice(n) { + const l = this.#buf.byteLength; + if (n <= this.capacity - l) { + this.#reslice(l + n); + return l; } + return -1; + } + + #reslice(len) { + assert(len <= this.#buf.buffer.byteLength); + this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + } - readSync(p) { - if (this.empty()) { - // Buffer is empty, reset to recover space. - this.reset(); - if (p.byteLength === 0) { - // this edge case is tested in 'bufferReadEmptyAtEOF' test - return 0; - } - return null; + readSync(p) { + if (this.empty()) { + // Buffer is empty, reset to recover space. + this.reset(); + if (p.byteLength === 0) { + // this edge case is tested in 'bufferReadEmptyAtEOF' test + return 0; } - const nread = copyBytes( - TypedArrayPrototypeSubarray(this.#buf, this.#off), - p, - ); - this.#off += nread; - return nread; - } + return null; + } + const nread = copyBytes( + TypedArrayPrototypeSubarray(this.#buf, this.#off), + p, + ); + this.#off += nread; + return nread; + } - read(p) { - const rr = this.readSync(p); - return PromiseResolve(rr); - } + read(p) { + const rr = this.readSync(p); + return PromiseResolve(rr); + } - writeSync(p) { - const m = this.#grow(p.byteLength); - return copyBytes(p, this.#buf, m); - } + writeSync(p) { + const m = this.#grow(p.byteLength); + return copyBytes(p, this.#buf, m); + } - write(p) { - const n = this.writeSync(p); - return PromiseResolve(n); - } + write(p) { + const n = this.writeSync(p); + return PromiseResolve(n); + } - #grow(n) { - const m = this.length; - // If buffer is empty, reset to recover space. - if (m === 0 && this.#off !== 0) { - this.reset(); - } - // Fast: Try to grow by means of a reslice. - const i = this.#tryGrowByReslice(n); - if (i >= 0) { - return i; - } - const c = this.capacity; - if (n <= MathFloor(c / 2) - m) { - // We can slide things down instead of allocating a new - // ArrayBuffer. We only need m+n <= c to slide, but - // we instead let capacity get twice as large so we - // don't spend all our time copying. - copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), this.#buf); - } else if (c + n > MAX_SIZE) { - throw new Error("The buffer cannot be grown beyond the maximum size."); - } else { - // Not enough space anywhere, we need to allocate. - const buf = new Uint8Array(MathMin(2 * c + n, MAX_SIZE)); - copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), buf); - this.#buf = buf; - } - // Restore this.#off and len(this.#buf). - this.#off = 0; - this.#reslice(MathMin(m + n, MAX_SIZE)); - return m; - } + #grow(n) { + const m = this.length; + // If buffer is empty, reset to recover space. + if (m === 0 && this.#off !== 0) { + this.reset(); + } + // Fast: Try to grow by means of a reslice. + const i = this.#tryGrowByReslice(n); + if (i >= 0) { + return i; + } + const c = this.capacity; + if (n <= MathFloor(c / 2) - m) { + // We can slide things down instead of allocating a new + // ArrayBuffer. We only need m+n <= c to slide, but + // we instead let capacity get twice as large so we + // don't spend all our time copying. + copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), this.#buf); + } else if (c + n > MAX_SIZE) { + throw new Error("The buffer cannot be grown beyond the maximum size."); + } else { + // Not enough space anywhere, we need to allocate. + const buf = new Uint8Array(MathMin(2 * c + n, MAX_SIZE)); + copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), buf); + this.#buf = buf; + } + // Restore this.#off and len(this.#buf). + this.#off = 0; + this.#reslice(MathMin(m + n, MAX_SIZE)); + return m; + } - grow(n) { - if (n < 0) { - throw Error("Buffer.grow: negative count"); - } - const m = this.#grow(n); - this.#reslice(m); + grow(n) { + if (n < 0) { + throw Error("Buffer.grow: negative count"); } + const m = this.#grow(n); + this.#reslice(m); + } - async readFrom(r) { - let n = 0; - const tmp = new Uint8Array(MIN_READ); - while (true) { - const shouldGrow = this.capacity - this.length < MIN_READ; - // read into tmp buffer if there's not enough room - // otherwise read directly into the internal buffer - const buf = shouldGrow - ? tmp - : new Uint8Array(this.#buf.buffer, this.length); - - const nread = await r.read(buf); - if (nread === null) { - return n; - } - - // write will grow if needed - if (shouldGrow) { - this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); - } else this.#reslice(this.length + nread); - - n += nread; + async readFrom(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while (true) { + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow + ? tmp + : new Uint8Array(this.#buf.buffer, this.length); + + const nread = await r.read(buf); + if (nread === null) { + return n; } - } - readFromSync(r) { - let n = 0; - const tmp = new Uint8Array(MIN_READ); - while (true) { - const shouldGrow = this.capacity - this.length < MIN_READ; - // read into tmp buffer if there's not enough room - // otherwise read directly into the internal buffer - const buf = shouldGrow - ? tmp - : new Uint8Array(this.#buf.buffer, this.length); - - const nread = r.readSync(buf); - if (nread === null) { - return n; - } - - // write will grow if needed - if (shouldGrow) { - this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); - } else this.#reslice(this.length + nread); - - n += nread; - } + // write will grow if needed + if (shouldGrow) { + this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); + } else this.#reslice(this.length + nread); + + n += nread; } } - async function readAll(r) { - const buf = new Buffer(); - await buf.readFrom(r); - return buf.bytes(); - } + readFromSync(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while (true) { + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow + ? tmp + : new Uint8Array(this.#buf.buffer, this.length); + + const nread = r.readSync(buf); + if (nread === null) { + return n; + } - function readAllSync(r) { - const buf = new Buffer(); - buf.readFromSync(r); - return buf.bytes(); - } + // write will grow if needed + if (shouldGrow) { + this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); + } else this.#reslice(this.length + nread); - async function writeAll(w, arr) { - let nwritten = 0; - while (nwritten < arr.length) { - nwritten += await w.write(TypedArrayPrototypeSubarray(arr, nwritten)); + n += nread; } } +} + +async function readAll(r) { + const buf = new Buffer(); + await buf.readFrom(r); + return buf.bytes(); +} + +function readAllSync(r) { + const buf = new Buffer(); + buf.readFromSync(r); + return buf.bytes(); +} + +async function writeAll(w, arr) { + let nwritten = 0; + while (nwritten < arr.length) { + nwritten += await w.write(TypedArrayPrototypeSubarray(arr, nwritten)); + } +} - function writeAllSync(w, arr) { - let nwritten = 0; - while (nwritten < arr.length) { - nwritten += w.writeSync(TypedArrayPrototypeSubarray(arr, nwritten)); - } +function writeAllSync(w, arr) { + let nwritten = 0; + while (nwritten < arr.length) { + nwritten += w.writeSync(TypedArrayPrototypeSubarray(arr, nwritten)); } +} - window.__bootstrap.buffer = { - writeAll, - writeAllSync, - readAll, - readAllSync, - Buffer, - }; -})(this); +export { Buffer, readAll, readAllSync, writeAll, writeAllSync }; diff --git a/runtime/js/30_fs.js b/runtime/js/30_fs.js index 87b2015fb..17b0b41ac 100644 --- a/runtime/js/30_fs.js +++ b/runtime/js/30_fs.js @@ -1,385 +1,375 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { - Date, - DatePrototype, - MathTrunc, - ObjectPrototypeIsPrototypeOf, - SymbolAsyncIterator, - SymbolIterator, - Function, - ObjectEntries, - Uint32Array, - } = window.__bootstrap.primordials; - const { pathFromURL } = window.__bootstrap.util; - const build = window.__bootstrap.build.build; - - function chmodSync(path, mode) { - ops.op_chmod_sync(pathFromURL(path), mode); - } - - async function chmod(path, mode) { - await core.opAsync("op_chmod_async", pathFromURL(path), mode); - } - - function chownSync( - path, - uid, - gid, - ) { - ops.op_chown_sync(pathFromURL(path), uid, gid); - } - async function chown( - path, +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +const { + Date, + DatePrototype, + MathTrunc, + ObjectPrototypeIsPrototypeOf, + SymbolAsyncIterator, + SymbolIterator, + Function, + ObjectEntries, + Uint32Array, +} = primordials; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import { build } from "internal:runtime/js/01_build.js"; + +function chmodSync(path, mode) { + ops.op_chmod_sync(pathFromURL(path), mode); +} + +async function chmod(path, mode) { + await core.opAsync("op_chmod_async", pathFromURL(path), mode); +} + +function chownSync( + path, + uid, + gid, +) { + ops.op_chown_sync(pathFromURL(path), uid, gid); +} + +async function chown( + path, + uid, + gid, +) { + await core.opAsync( + "op_chown_async", + pathFromURL(path), uid, gid, - ) { - await core.opAsync( - "op_chown_async", - pathFromURL(path), - uid, - gid, - ); - } - - function copyFileSync( - fromPath, - toPath, - ) { - ops.op_copy_file_sync( - pathFromURL(fromPath), - pathFromURL(toPath), - ); - } - - async function copyFile( - fromPath, - toPath, - ) { - await core.opAsync( - "op_copy_file_async", - pathFromURL(fromPath), - pathFromURL(toPath), - ); - } - - function cwd() { - return ops.op_cwd(); - } - - function chdir(directory) { - ops.op_chdir(pathFromURL(directory)); - } - - function makeTempDirSync(options = {}) { - return ops.op_make_temp_dir_sync(options); - } - - function makeTempDir(options = {}) { - return core.opAsync("op_make_temp_dir_async", options); - } - - function makeTempFileSync(options = {}) { - return ops.op_make_temp_file_sync(options); - } - - function makeTempFile(options = {}) { - return core.opAsync("op_make_temp_file_async", options); - } - - function mkdirArgs(path, options) { - const args = { path: pathFromURL(path), recursive: false }; - if (options != null) { - if (typeof options.recursive == "boolean") { - args.recursive = options.recursive; - } - if (options.mode) { - args.mode = options.mode; - } + ); +} + +function copyFileSync( + fromPath, + toPath, +) { + ops.op_copy_file_sync( + pathFromURL(fromPath), + pathFromURL(toPath), + ); +} + +async function copyFile( + fromPath, + toPath, +) { + await core.opAsync( + "op_copy_file_async", + pathFromURL(fromPath), + pathFromURL(toPath), + ); +} + +function cwd() { + return ops.op_cwd(); +} + +function chdir(directory) { + ops.op_chdir(pathFromURL(directory)); +} + +function makeTempDirSync(options = {}) { + return ops.op_make_temp_dir_sync(options); +} + +function makeTempDir(options = {}) { + return core.opAsync("op_make_temp_dir_async", options); +} + +function makeTempFileSync(options = {}) { + return ops.op_make_temp_file_sync(options); +} + +function makeTempFile(options = {}) { + return core.opAsync("op_make_temp_file_async", options); +} + +function mkdirArgs(path, options) { + const args = { path: pathFromURL(path), recursive: false }; + if (options != null) { + if (typeof options.recursive == "boolean") { + args.recursive = options.recursive; + } + if (options.mode) { + args.mode = options.mode; } - return args; - } - - function mkdirSync(path, options) { - ops.op_mkdir_sync(mkdirArgs(path, options)); - } - - async function mkdir( - path, - options, - ) { - await core.opAsync("op_mkdir_async", mkdirArgs(path, options)); - } - - function readDirSync(path) { - return ops.op_read_dir_sync(pathFromURL(path))[ - SymbolIterator - ](); - } - - function readDir(path) { - const array = core.opAsync( - "op_read_dir_async", - pathFromURL(path), - ); - return { - async *[SymbolAsyncIterator]() { - yield* await array; - }, - }; - } - - function readLinkSync(path) { - return ops.op_read_link_sync(pathFromURL(path)); - } - - function readLink(path) { - return core.opAsync("op_read_link_async", pathFromURL(path)); - } - - function realPathSync(path) { - return ops.op_realpath_sync(pathFromURL(path)); - } - - function realPath(path) { - return core.opAsync("op_realpath_async", pathFromURL(path)); - } - - function removeSync( - path, - options = {}, - ) { - ops.op_remove_sync( - pathFromURL(path), - !!options.recursive, - ); - } - - async function remove( - path, - options = {}, - ) { - await core.opAsync( - "op_remove_async", - pathFromURL(path), - !!options.recursive, - ); - } - - function renameSync(oldpath, newpath) { - ops.op_rename_sync( - pathFromURL(oldpath), - pathFromURL(newpath), - ); - } - - async function rename(oldpath, newpath) { - await core.opAsync( - "op_rename_async", - pathFromURL(oldpath), - pathFromURL(newpath), - ); } - - // Extract the FsStat object from the encoded buffer. - // See `runtime/ops/fs.rs` for the encoder. - // - // This is not a general purpose decoder. There are 4 types: - // - // 1. date - // offset += 4 - // 1/0 | extra padding | high u32 | low u32 - // if date[0] == 1, new Date(u64) else null - // - // 2. bool - // offset += 2 - // 1/0 | extra padding - // - // 3. u64 - // offset += 2 - // high u32 | low u32 - // - // 4. ?u64 converts a zero u64 value to JS null on Windows. - function createByteStruct(types) { - // types can be "date", "bool" or "u64". - // `?` prefix means optional on windows. - let offset = 0; - let str = - 'const unix = Deno.build.os === "darwin" || Deno.build.os === "linux"; return {'; - const typeEntries = ObjectEntries(types); - for (let i = 0; i < typeEntries.length; ++i) { - let { 0: name, 1: type } = typeEntries[i]; - - const optional = type.startsWith("?"); - if (optional) type = type.slice(1); - - if (type == "u64") { - if (!optional) { - str += `${name}: view[${offset}] + view[${offset + 1}] * 2**32,`; - } else { - str += `${name}: (unix ? (view[${offset}] + view[${ - offset + 1 - }] * 2**32) : (view[${offset}] + view[${ - offset + 1 - }] * 2**32) || null),`; - } - } else if (type == "date") { - str += `${name}: view[${offset}] === 0 ? null : new Date(view[${ - offset + 2 - }] + view[${offset + 3}] * 2**32),`; - offset += 2; + return args; +} + +function mkdirSync(path, options) { + ops.op_mkdir_sync(mkdirArgs(path, options)); +} + +async function mkdir( + path, + options, +) { + await core.opAsync("op_mkdir_async", mkdirArgs(path, options)); +} + +function readDirSync(path) { + return ops.op_read_dir_sync(pathFromURL(path))[ + SymbolIterator + ](); +} + +function readDir(path) { + const array = core.opAsync( + "op_read_dir_async", + pathFromURL(path), + ); + return { + async *[SymbolAsyncIterator]() { + yield* await array; + }, + }; +} + +function readLinkSync(path) { + return ops.op_read_link_sync(pathFromURL(path)); +} + +function readLink(path) { + return core.opAsync("op_read_link_async", pathFromURL(path)); +} + +function realPathSync(path) { + return ops.op_realpath_sync(pathFromURL(path)); +} + +function realPath(path) { + return core.opAsync("op_realpath_async", pathFromURL(path)); +} + +function removeSync( + path, + options = {}, +) { + ops.op_remove_sync( + pathFromURL(path), + !!options.recursive, + ); +} + +async function remove( + path, + options = {}, +) { + await core.opAsync( + "op_remove_async", + pathFromURL(path), + !!options.recursive, + ); +} + +function renameSync(oldpath, newpath) { + ops.op_rename_sync( + pathFromURL(oldpath), + pathFromURL(newpath), + ); +} + +async function rename(oldpath, newpath) { + await core.opAsync( + "op_rename_async", + pathFromURL(oldpath), + pathFromURL(newpath), + ); +} + +// Extract the FsStat object from the encoded buffer. +// See `runtime/ops/fs.rs` for the encoder. +// +// This is not a general purpose decoder. There are 4 types: +// +// 1. date +// offset += 4 +// 1/0 | extra padding | high u32 | low u32 +// if date[0] == 1, new Date(u64) else null +// +// 2. bool +// offset += 2 +// 1/0 | extra padding +// +// 3. u64 +// offset += 2 +// high u32 | low u32 +// +// 4. ?u64 converts a zero u64 value to JS null on Windows. +function createByteStruct(types) { + // types can be "date", "bool" or "u64". + // `?` prefix means optional on windows. + let offset = 0; + let str = + 'const unix = Deno.build.os === "darwin" || Deno.build.os === "linux"; return {'; + const typeEntries = ObjectEntries(types); + for (let i = 0; i < typeEntries.length; ++i) { + let { 0: name, 1: type } = typeEntries[i]; + + const optional = type.startsWith("?"); + if (optional) type = type.slice(1); + + if (type == "u64") { + if (!optional) { + str += `${name}: view[${offset}] + view[${offset + 1}] * 2**32,`; } else { - str += `${name}: !!(view[${offset}] + view[${offset + 1}] * 2**32),`; + str += `${name}: (unix ? (view[${offset}] + view[${ + offset + 1 + }] * 2**32) : (view[${offset}] + view[${ + offset + 1 + }] * 2**32) || null),`; } + } else if (type == "date") { + str += `${name}: view[${offset}] === 0 ? null : new Date(view[${ + offset + 2 + }] + view[${offset + 3}] * 2**32),`; offset += 2; + } else { + str += `${name}: !!(view[${offset}] + view[${offset + 1}] * 2**32),`; } - str += "};"; - // ...so you don't like eval huh? don't worry, it only executes during snapshot :) - return [new Function("view", str), new Uint32Array(offset)]; - } - - const { 0: statStruct, 1: statBuf } = createByteStruct({ - isFile: "bool", - isDirectory: "bool", - isSymlink: "bool", - size: "u64", - mtime: "date", - atime: "date", - birthtime: "date", - dev: "?u64", - ino: "?u64", - mode: "?u64", - nlink: "?u64", - uid: "?u64", - gid: "?u64", - rdev: "?u64", - blksize: "?u64", - blocks: "?u64", - }); - - function parseFileInfo(response) { - const unix = build.os === "darwin" || build.os === "linux"; - return { - isFile: response.isFile, - isDirectory: response.isDirectory, - isSymlink: response.isSymlink, - size: response.size, - mtime: response.mtimeSet !== null ? new Date(response.mtime) : null, - atime: response.atimeSet !== null ? new Date(response.atime) : null, - birthtime: response.birthtimeSet !== null - ? new Date(response.birthtime) - : null, - // Only non-null if on Unix - dev: unix ? response.dev : null, - ino: unix ? response.ino : null, - mode: unix ? response.mode : null, - nlink: unix ? response.nlink : null, - uid: unix ? response.uid : null, - gid: unix ? response.gid : null, - rdev: unix ? response.rdev : null, - blksize: unix ? response.blksize : null, - blocks: unix ? response.blocks : null, - }; - } - - function fstatSync(rid) { - ops.op_fstat_sync(rid, statBuf); - return statStruct(statBuf); - } - - async function fstat(rid) { - return parseFileInfo(await core.opAsync("op_fstat_async", rid)); - } - - async function lstat(path) { - const res = await core.opAsync("op_stat_async", { - path: pathFromURL(path), - lstat: true, - }); - return parseFileInfo(res); - } - - function lstatSync(path) { - ops.op_stat_sync( - pathFromURL(path), - true, - statBuf, - ); - return statStruct(statBuf); - } + offset += 2; + } + str += "};"; + // ...so you don't like eval huh? don't worry, it only executes during snapshot :) + return [new Function("view", str), new Uint32Array(offset)]; +} + +const { 0: statStruct, 1: statBuf } = createByteStruct({ + isFile: "bool", + isDirectory: "bool", + isSymlink: "bool", + size: "u64", + mtime: "date", + atime: "date", + birthtime: "date", + dev: "?u64", + ino: "?u64", + mode: "?u64", + nlink: "?u64", + uid: "?u64", + gid: "?u64", + rdev: "?u64", + blksize: "?u64", + blocks: "?u64", +}); + +function parseFileInfo(response) { + const unix = build.os === "darwin" || build.os === "linux"; + return { + isFile: response.isFile, + isDirectory: response.isDirectory, + isSymlink: response.isSymlink, + size: response.size, + mtime: response.mtimeSet !== null ? new Date(response.mtime) : null, + atime: response.atimeSet !== null ? new Date(response.atime) : null, + birthtime: response.birthtimeSet !== null + ? new Date(response.birthtime) + : null, + // Only non-null if on Unix + dev: unix ? response.dev : null, + ino: unix ? response.ino : null, + mode: unix ? response.mode : null, + nlink: unix ? response.nlink : null, + uid: unix ? response.uid : null, + gid: unix ? response.gid : null, + rdev: unix ? response.rdev : null, + blksize: unix ? response.blksize : null, + blocks: unix ? response.blocks : null, + }; +} - async function stat(path) { - const res = await core.opAsync("op_stat_async", { - path: pathFromURL(path), - lstat: false, - }); - return parseFileInfo(res); - } +function fstatSync(rid) { + ops.op_fstat_sync(rid, statBuf); + return statStruct(statBuf); +} - function statSync(path) { - ops.op_stat_sync( - pathFromURL(path), - false, - statBuf, - ); - return statStruct(statBuf); - } +async function fstat(rid) { + return parseFileInfo(await core.opAsync("op_fstat_async", rid)); +} - function coerceLen(len) { - if (len == null || len < 0) { - return 0; - } +async function lstat(path) { + const res = await core.opAsync("op_stat_async", { + path: pathFromURL(path), + lstat: true, + }); + return parseFileInfo(res); +} + +function lstatSync(path) { + ops.op_stat_sync( + pathFromURL(path), + true, + statBuf, + ); + return statStruct(statBuf); +} + +async function stat(path) { + const res = await core.opAsync("op_stat_async", { + path: pathFromURL(path), + lstat: false, + }); + return parseFileInfo(res); +} - return len; - } +function statSync(path) { + ops.op_stat_sync( + pathFromURL(path), + false, + statBuf, + ); + return statStruct(statBuf); +} - function ftruncateSync(rid, len) { - ops.op_ftruncate_sync(rid, coerceLen(len)); +function coerceLen(len) { + if (len == null || len < 0) { + return 0; } - async function ftruncate(rid, len) { - await core.opAsync("op_ftruncate_async", rid, coerceLen(len)); - } + return len; +} - function truncateSync(path, len) { - ops.op_truncate_sync(path, coerceLen(len)); - } +function ftruncateSync(rid, len) { + ops.op_ftruncate_sync(rid, coerceLen(len)); +} - async function truncate(path, len) { - await core.opAsync("op_truncate_async", path, coerceLen(len)); - } +async function ftruncate(rid, len) { + await core.opAsync("op_ftruncate_async", rid, coerceLen(len)); +} - function umask(mask) { - return ops.op_umask(mask); - } +function truncateSync(path, len) { + ops.op_truncate_sync(path, coerceLen(len)); +} - function linkSync(oldpath, newpath) { - ops.op_link_sync(oldpath, newpath); - } +async function truncate(path, len) { + await core.opAsync("op_truncate_async", path, coerceLen(len)); +} - async function link(oldpath, newpath) { - await core.opAsync("op_link_async", oldpath, newpath); - } +function umask(mask) { + return ops.op_umask(mask); +} - function toUnixTimeFromEpoch(value) { - if (ObjectPrototypeIsPrototypeOf(DatePrototype, value)) { - const time = value.valueOf(); - const seconds = MathTrunc(time / 1e3); - const nanoseconds = MathTrunc(time - (seconds * 1e3)) * 1e6; +function linkSync(oldpath, newpath) { + ops.op_link_sync(oldpath, newpath); +} - return [ - seconds, - nanoseconds, - ]; - } +async function link(oldpath, newpath) { + await core.opAsync("op_link_async", oldpath, newpath); +} - const seconds = value; - const nanoseconds = 0; +function toUnixTimeFromEpoch(value) { + if (ObjectPrototypeIsPrototypeOf(DatePrototype, value)) { + const time = value.valueOf(); + const seconds = MathTrunc(time / 1e3); + const nanoseconds = MathTrunc(time - (seconds * 1e3)) * 1e6; return [ seconds, @@ -387,174 +377,182 @@ ]; } - function futimeSync( - rid, - atime, - mtime, - ) { - const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); - const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - ops.op_futime_sync(rid, atimeSec, atimeNsec, mtimeSec, mtimeNsec); - } - - async function futime( + const seconds = value; + const nanoseconds = 0; + + return [ + seconds, + nanoseconds, + ]; +} + +function futimeSync( + rid, + atime, + mtime, +) { + const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); + const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); + ops.op_futime_sync(rid, atimeSec, atimeNsec, mtimeSec, mtimeNsec); +} + +async function futime( + rid, + atime, + mtime, +) { + const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); + const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); + await core.opAsync( + "op_futime_async", rid, - atime, - mtime, - ) { - const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); - const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - await core.opAsync( - "op_futime_async", - rid, - atimeSec, - atimeNsec, - mtimeSec, - mtimeNsec, - ); - } - - function utimeSync( - path, - atime, - mtime, - ) { - const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); - const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - ops.op_utime_sync( - pathFromURL(path), - atimeSec, - atimeNsec, - mtimeSec, - mtimeNsec, - ); - } - - async function utime( - path, - atime, - mtime, - ) { - const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); - const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); - await core.opAsync( - "op_utime_async", - pathFromURL(path), - atimeSec, - atimeNsec, - mtimeSec, - mtimeNsec, - ); - } - - function symlinkSync( - oldpath, - newpath, - options, - ) { - ops.op_symlink_sync( - pathFromURL(oldpath), - pathFromURL(newpath), - options?.type, - ); - } - - async function symlink( - oldpath, - newpath, - options, - ) { - await core.opAsync( - "op_symlink_async", - pathFromURL(oldpath), - pathFromURL(newpath), - options?.type, - ); - } - - function fdatasyncSync(rid) { - ops.op_fdatasync_sync(rid); - } - - async function fdatasync(rid) { - await core.opAsync("op_fdatasync_async", rid); - } - - function fsyncSync(rid) { - ops.op_fsync_sync(rid); - } - - async function fsync(rid) { - await core.opAsync("op_fsync_async", rid); - } - - function flockSync(rid, exclusive) { - ops.op_flock_sync(rid, exclusive === true); - } - - async function flock(rid, exclusive) { - await core.opAsync("op_flock_async", rid, exclusive === true); - } - - function funlockSync(rid) { - ops.op_funlock_sync(rid); - } - - async function funlock(rid) { - await core.opAsync("op_funlock_async", rid); - } - - window.__bootstrap.fs = { - cwd, - chdir, - chmodSync, - chmod, - chown, - chownSync, - copyFile, - copyFileSync, - makeTempFile, - makeTempDir, - makeTempFileSync, - makeTempDirSync, - mkdir, - mkdirSync, - readDir, - readDirSync, - readLinkSync, - readLink, - realPathSync, - realPath, - remove, - removeSync, - renameSync, - rename, - lstat, - lstatSync, - stat, - statSync, - ftruncate, - ftruncateSync, - truncate, - truncateSync, - umask, - link, - linkSync, - fstatSync, - fstat, - futime, - futimeSync, - utime, - utimeSync, - symlink, - symlinkSync, - fdatasync, - fdatasyncSync, - fsync, - fsyncSync, - flock, - flockSync, - funlock, - funlockSync, - }; -})(this); + atimeSec, + atimeNsec, + mtimeSec, + mtimeNsec, + ); +} + +function utimeSync( + path, + atime, + mtime, +) { + const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); + const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); + ops.op_utime_sync( + pathFromURL(path), + atimeSec, + atimeNsec, + mtimeSec, + mtimeNsec, + ); +} + +async function utime( + path, + atime, + mtime, +) { + const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); + const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); + await core.opAsync( + "op_utime_async", + pathFromURL(path), + atimeSec, + atimeNsec, + mtimeSec, + mtimeNsec, + ); +} + +function symlinkSync( + oldpath, + newpath, + options, +) { + ops.op_symlink_sync( + pathFromURL(oldpath), + pathFromURL(newpath), + options?.type, + ); +} + +async function symlink( + oldpath, + newpath, + options, +) { + await core.opAsync( + "op_symlink_async", + pathFromURL(oldpath), + pathFromURL(newpath), + options?.type, + ); +} + +function fdatasyncSync(rid) { + ops.op_fdatasync_sync(rid); +} + +async function fdatasync(rid) { + await core.opAsync("op_fdatasync_async", rid); +} + +function fsyncSync(rid) { + ops.op_fsync_sync(rid); +} + +async function fsync(rid) { + await core.opAsync("op_fsync_async", rid); +} + +function flockSync(rid, exclusive) { + ops.op_flock_sync(rid, exclusive === true); +} + +async function flock(rid, exclusive) { + await core.opAsync("op_flock_async", rid, exclusive === true); +} + +function funlockSync(rid) { + ops.op_funlock_sync(rid); +} + +async function funlock(rid) { + await core.opAsync("op_funlock_async", rid); +} + +export { + chdir, + chmod, + chmodSync, + chown, + chownSync, + copyFile, + copyFileSync, + cwd, + fdatasync, + fdatasyncSync, + flock, + flockSync, + fstat, + fstatSync, + fsync, + fsyncSync, + ftruncate, + ftruncateSync, + funlock, + funlockSync, + futime, + futimeSync, + link, + linkSync, + lstat, + lstatSync, + makeTempDir, + makeTempDirSync, + makeTempFile, + makeTempFileSync, + mkdir, + mkdirSync, + readDir, + readDirSync, + readLink, + readLinkSync, + realPath, + realPathSync, + remove, + removeSync, + rename, + renameSync, + stat, + statSync, + symlink, + symlinkSync, + truncate, + truncateSync, + umask, + utime, + utimeSync, +}; diff --git a/runtime/js/30_os.js b/runtime/js/30_os.js index 8069c3a34..720545b40 100644 --- a/runtime/js/30_os.js +++ b/runtime/js/30_os.js @@ -1,123 +1,122 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { Event } = window.__bootstrap.event; - const { EventTarget } = window.__bootstrap.eventTarget; - const { - Error, - SymbolFor, - } = window.__bootstrap.primordials; - - const windowDispatchEvent = EventTarget.prototype.dispatchEvent.bind(window); - - function loadavg() { - return ops.op_loadavg(); - } - - function hostname() { - return ops.op_hostname(); - } - - function osRelease() { - return ops.op_os_release(); - } - - function createOsUptime(opFn) { - return function osUptime() { - return opFn(); - }; - } - - function systemMemoryInfo() { - return ops.op_system_memory_info(); - } - - function networkInterfaces() { - return ops.op_network_interfaces(); - } - - function gid() { - return ops.op_gid(); - } - function uid() { - return ops.op_uid(); - } - - // This is an internal only method used by the test harness to override the - // behavior of exit when the exit sanitizer is enabled. - let exitHandler = null; - function setExitHandler(fn) { - exitHandler = fn; - } - - function exit(code) { - // Set exit code first so unload event listeners can override it. - if (typeof code === "number") { - ops.op_set_exit_code(code); - } else { - code = 0; - } - - // Dispatches `unload` only when it's not dispatched yet. - if (!window[SymbolFor("isUnloadDispatched")]) { - // Invokes the `unload` hooks before exiting - // ref: https://github.com/denoland/deno/issues/3603 - windowDispatchEvent(new Event("unload")); - } - - if (exitHandler) { - exitHandler(code); - return; - } - - ops.op_exit(); - throw new Error("Code not reachable"); - } - - function setEnv(key, value) { - ops.op_set_env(key, value); - } - - function getEnv(key) { - return ops.op_get_env(key) ?? undefined; +const core = globalThis.Deno.core; +const ops = core.ops; +import { Event, EventTarget } from "internal:ext/web/02_event.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + Error, + SymbolFor, +} = primordials; + +const windowDispatchEvent = EventTarget.prototype.dispatchEvent.bind( + globalThis, +); + +function loadavg() { + return ops.op_loadavg(); +} + +function hostname() { + return ops.op_hostname(); +} + +function osRelease() { + return ops.op_os_release(); +} + +function createOsUptime(opFn) { + return function osUptime() { + return opFn(); + }; +} + +function systemMemoryInfo() { + return ops.op_system_memory_info(); +} + +function networkInterfaces() { + return ops.op_network_interfaces(); +} + +function gid() { + return ops.op_gid(); +} + +function uid() { + return ops.op_uid(); +} + +// This is an internal only method used by the test harness to override the +// behavior of exit when the exit sanitizer is enabled. +let exitHandler = null; +function setExitHandler(fn) { + exitHandler = fn; +} + +function exit(code) { + // Set exit code first so unload event listeners can override it. + if (typeof code === "number") { + ops.op_set_exit_code(code); + } else { + code = 0; } - function deleteEnv(key) { - ops.op_delete_env(key); + // Dispatches `unload` only when it's not dispatched yet. + if (!globalThis[SymbolFor("isUnloadDispatched")]) { + // Invokes the `unload` hooks before exiting + // ref: https://github.com/denoland/deno/issues/3603 + windowDispatchEvent(new Event("unload")); } - const env = { - get: getEnv, - toObject() { - return ops.op_env(); - }, - set: setEnv, - has(key) { - return getEnv(key) !== undefined; - }, - delete: deleteEnv, - }; - - function execPath() { - return ops.op_exec_path(); + if (exitHandler) { + exitHandler(code); + return; } - window.__bootstrap.os = { - env, - execPath, - exit, - gid, - hostname, - loadavg, - networkInterfaces, - osRelease, - createOsUptime, - setExitHandler, - systemMemoryInfo, - uid, - }; -})(this); + ops.op_exit(); + throw new Error("Code not reachable"); +} + +function setEnv(key, value) { + ops.op_set_env(key, value); +} + +function getEnv(key) { + return ops.op_get_env(key) ?? undefined; +} + +function deleteEnv(key) { + ops.op_delete_env(key); +} + +const env = { + get: getEnv, + toObject() { + return ops.op_env(); + }, + set: setEnv, + has(key) { + return getEnv(key) !== undefined; + }, + delete: deleteEnv, +}; + +function execPath() { + return ops.op_exec_path(); +} + +export { + createOsUptime, + env, + execPath, + exit, + gid, + hostname, + loadavg, + networkInterfaces, + osRelease, + setExitHandler, + systemMemoryInfo, + uid, +}; diff --git a/runtime/js/40_diagnostics.js b/runtime/js/40_diagnostics.js index 6939b5204..669a54263 100644 --- a/runtime/js/40_diagnostics.js +++ b/runtime/js/40_diagnostics.js @@ -3,22 +3,17 @@ // Diagnostic provides an abstraction for advice/errors received from a // compiler, which is strongly influenced by the format of TypeScript // diagnostics. -"use strict"; -((window) => { - const DiagnosticCategory = { - 0: "Warning", - 1: "Error", - 2: "Suggestion", - 3: "Message", +const DiagnosticCategory = { + 0: "Warning", + 1: "Error", + 2: "Suggestion", + 3: "Message", - Warning: 0, - Error: 1, - Suggestion: 2, - Message: 3, - }; + Warning: 0, + Error: 1, + Suggestion: 2, + Message: 3, +}; - window.__bootstrap.diagnostics = { - DiagnosticCategory, - }; -})(this); +export { DiagnosticCategory }; diff --git a/runtime/js/40_files.js b/runtime/js/40_files.js index 4471610cc..98c569a09 100644 --- a/runtime/js/40_files.js +++ b/runtime/js/40_files.js @@ -1,293 +1,299 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { read, readSync, write, writeSync } = window.__bootstrap.io; - const { ftruncate, ftruncateSync, fstat, fstatSync } = window.__bootstrap.fs; - const { pathFromURL } = window.__bootstrap.util; - const { readableStreamForRid, writableStreamForRid } = - window.__bootstrap.streams; - const { - ArrayPrototypeFilter, - Error, - ObjectValues, - } = window.__bootstrap.primordials; - - function seekSync( - rid, - offset, - whence, - ) { - return ops.op_seek_sync({ rid, offset, whence }); - } - - function seek( - rid, - offset, - whence, - ) { - return core.opAsync("op_seek_async", { rid, offset, whence }); - } - function openSync( - path, +const core = globalThis.Deno.core; +const ops = core.ops; +import { read, readSync, write, writeSync } from "internal:runtime/js/12_io.js"; +import { + fstat, + fstatSync, + ftruncate, + ftruncateSync, +} from "internal:runtime/js/30_fs.js"; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import { + readableStreamForRid, + writableStreamForRid, +} from "internal:ext/web/06_streams.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayPrototypeFilter, + Error, + ObjectValues, +} = primordials; + +function seekSync( + rid, + offset, + whence, +) { + return ops.op_seek_sync({ rid, offset, whence }); +} + +function seek( + rid, + offset, + whence, +) { + return core.opAsync("op_seek_async", { rid, offset, whence }); +} + +function openSync( + path, + options, +) { + if (options) checkOpenOptions(options); + const mode = options?.mode; + const rid = ops.op_open_sync( + pathFromURL(path), options, - ) { - if (options) checkOpenOptions(options); - const mode = options?.mode; - const rid = ops.op_open_sync( - pathFromURL(path), - options, - mode, - ); - - return new FsFile(rid); - } - - async function open( - path, + mode, + ); + + return new FsFile(rid); +} + +async function open( + path, + options, +) { + if (options) checkOpenOptions(options); + const mode = options?.mode; + const rid = await core.opAsync( + "op_open_async", + pathFromURL(path), options, - ) { - if (options) checkOpenOptions(options); - const mode = options?.mode; - const rid = await core.opAsync( - "op_open_async", - pathFromURL(path), - options, - mode, - ); - - return new FsFile(rid); + mode, + ); + + return new FsFile(rid); +} + +function createSync(path) { + return openSync(path, { + read: true, + write: true, + truncate: true, + create: true, + }); +} + +function create(path) { + return open(path, { + read: true, + write: true, + truncate: true, + create: true, + }); +} + +class FsFile { + #rid = 0; + + #readable; + #writable; + + constructor(rid) { + this.#rid = rid; } - function createSync(path) { - return openSync(path, { - read: true, - write: true, - truncate: true, - create: true, - }); + get rid() { + return this.#rid; } - function create(path) { - return open(path, { - read: true, - write: true, - truncate: true, - create: true, - }); + write(p) { + return write(this.rid, p); } - class FsFile { - #rid = 0; - - #readable; - #writable; - - constructor(rid) { - this.#rid = rid; - } - - get rid() { - return this.#rid; - } - - write(p) { - return write(this.rid, p); - } - - writeSync(p) { - return writeSync(this.rid, p); - } + writeSync(p) { + return writeSync(this.rid, p); + } - truncate(len) { - return ftruncate(this.rid, len); - } + truncate(len) { + return ftruncate(this.rid, len); + } - truncateSync(len) { - return ftruncateSync(this.rid, len); - } + truncateSync(len) { + return ftruncateSync(this.rid, len); + } - read(p) { - return read(this.rid, p); - } + read(p) { + return read(this.rid, p); + } - readSync(p) { - return readSync(this.rid, p); - } + readSync(p) { + return readSync(this.rid, p); + } - seek(offset, whence) { - return seek(this.rid, offset, whence); - } + seek(offset, whence) { + return seek(this.rid, offset, whence); + } - seekSync(offset, whence) { - return seekSync(this.rid, offset, whence); - } + seekSync(offset, whence) { + return seekSync(this.rid, offset, whence); + } - stat() { - return fstat(this.rid); - } + stat() { + return fstat(this.rid); + } - statSync() { - return fstatSync(this.rid); - } + statSync() { + return fstatSync(this.rid); + } - close() { - core.close(this.rid); - } + close() { + core.close(this.rid); + } - get readable() { - if (this.#readable === undefined) { - this.#readable = readableStreamForRid(this.rid); - } - return this.#readable; + get readable() { + if (this.#readable === undefined) { + this.#readable = readableStreamForRid(this.rid); } + return this.#readable; + } - get writable() { - if (this.#writable === undefined) { - this.#writable = writableStreamForRid(this.rid); - } - return this.#writable; + get writable() { + if (this.#writable === undefined) { + this.#writable = writableStreamForRid(this.rid); } + return this.#writable; } +} - class Stdin { - #readable; +class Stdin { + #readable; - constructor() { - } - - get rid() { - return 0; - } + constructor() { + } - read(p) { - return read(this.rid, p); - } + get rid() { + return 0; + } - readSync(p) { - return readSync(this.rid, p); - } + read(p) { + return read(this.rid, p); + } - close() { - core.close(this.rid); - } + readSync(p) { + return readSync(this.rid, p); + } - get readable() { - if (this.#readable === undefined) { - this.#readable = readableStreamForRid(this.rid); - } - return this.#readable; - } + close() { + core.close(this.rid); + } - setRaw(mode, options = {}) { - const cbreak = !!(options.cbreak ?? false); - ops.op_stdin_set_raw(mode, cbreak); + get readable() { + if (this.#readable === undefined) { + this.#readable = readableStreamForRid(this.rid); } + return this.#readable; } - class Stdout { - #writable; - - constructor() { - } + setRaw(mode, options = {}) { + const cbreak = !!(options.cbreak ?? false); + ops.op_stdin_set_raw(mode, cbreak); + } +} - get rid() { - return 1; - } +class Stdout { + #writable; - write(p) { - return write(this.rid, p); - } + constructor() { + } - writeSync(p) { - return writeSync(this.rid, p); - } + get rid() { + return 1; + } - close() { - core.close(this.rid); - } + write(p) { + return write(this.rid, p); + } - get writable() { - if (this.#writable === undefined) { - this.#writable = writableStreamForRid(this.rid); - } - return this.#writable; - } + writeSync(p) { + return writeSync(this.rid, p); } - class Stderr { - #writable; + close() { + core.close(this.rid); + } - constructor() { + get writable() { + if (this.#writable === undefined) { + this.#writable = writableStreamForRid(this.rid); } + return this.#writable; + } +} - get rid() { - return 2; - } +class Stderr { + #writable; - write(p) { - return write(this.rid, p); - } + constructor() { + } - writeSync(p) { - return writeSync(this.rid, p); - } + get rid() { + return 2; + } - close() { - core.close(this.rid); - } + write(p) { + return write(this.rid, p); + } - get writable() { - if (this.#writable === undefined) { - this.#writable = writableStreamForRid(this.rid); - } - return this.#writable; - } + writeSync(p) { + return writeSync(this.rid, p); } - const stdin = new Stdin(); - const stdout = new Stdout(); - const stderr = new Stderr(); + close() { + core.close(this.rid); + } - function checkOpenOptions(options) { - if ( - ArrayPrototypeFilter( - ObjectValues(options), - (val) => val === true, - ).length === 0 - ) { - throw new Error("OpenOptions requires at least one option to be true"); + get writable() { + if (this.#writable === undefined) { + this.#writable = writableStreamForRid(this.rid); } + return this.#writable; + } +} + +const stdin = new Stdin(); +const stdout = new Stdout(); +const stderr = new Stderr(); + +function checkOpenOptions(options) { + if ( + ArrayPrototypeFilter( + ObjectValues(options), + (val) => val === true, + ).length === 0 + ) { + throw new Error("OpenOptions requires at least one option to be true"); + } - if (options.truncate && !options.write) { - throw new Error("'truncate' option requires 'write' option"); - } + if (options.truncate && !options.write) { + throw new Error("'truncate' option requires 'write' option"); + } - const createOrCreateNewWithoutWriteOrAppend = - (options.create || options.createNew) && - !(options.write || options.append); + const createOrCreateNewWithoutWriteOrAppend = + (options.create || options.createNew) && + !(options.write || options.append); - if (createOrCreateNewWithoutWriteOrAppend) { - throw new Error( - "'create' or 'createNew' options require 'write' or 'append' option", - ); - } + if (createOrCreateNewWithoutWriteOrAppend) { + throw new Error( + "'create' or 'createNew' options require 'write' or 'append' option", + ); } - - window.__bootstrap.files = { - stdin, - stdout, - stderr, - File: FsFile, - FsFile, - create, - createSync, - open, - openSync, - seek, - seekSync, - }; -})(this); +} + +const File = FsFile; +export { + create, + createSync, + File, + FsFile, + open, + openSync, + seek, + seekSync, + stderr, + stdin, + stdout, +}; diff --git a/runtime/js/40_fs_events.js b/runtime/js/40_fs_events.js index b410e2299..4c2f5fc9a 100644 --- a/runtime/js/40_fs_events.js +++ b/runtime/js/40_fs_events.js @@ -1,70 +1,63 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { BadResourcePrototype, InterruptedPrototype } = core; - const { - ArrayIsArray, - ObjectPrototypeIsPrototypeOf, - PromiseResolve, - SymbolAsyncIterator, - } = window.__bootstrap.primordials; - class FsWatcher { - #rid = 0; - - constructor(paths, options) { - const { recursive } = options; - this.#rid = ops.op_fs_events_open({ recursive, paths }); - } +const core = globalThis.Deno.core; +const { BadResourcePrototype, InterruptedPrototype, ops } = core; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayIsArray, + ObjectPrototypeIsPrototypeOf, + PromiseResolve, + SymbolAsyncIterator, +} = primordials; +class FsWatcher { + #rid = 0; + + constructor(paths, options) { + const { recursive } = options; + this.#rid = ops.op_fs_events_open({ recursive, paths }); + } - get rid() { - return this.#rid; - } + get rid() { + return this.#rid; + } - async next() { - try { - const value = await core.opAsync("op_fs_events_poll", this.rid); - return value - ? { value, done: false } - : { value: undefined, done: true }; - } catch (error) { - if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) { - return { value: undefined, done: true }; - } else if ( - ObjectPrototypeIsPrototypeOf(InterruptedPrototype, error) - ) { - return { value: undefined, done: true }; - } - throw error; + async next() { + try { + const value = await core.opAsync("op_fs_events_poll", this.rid); + return value ? { value, done: false } : { value: undefined, done: true }; + } catch (error) { + if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) { + return { value: undefined, done: true }; + } else if ( + ObjectPrototypeIsPrototypeOf(InterruptedPrototype, error) + ) { + return { value: undefined, done: true }; } + throw error; } + } - // TODO(kt3k): This is deprecated. Will be removed in v2.0. - // See https://github.com/denoland/deno/issues/10577 for details - return(value) { - core.close(this.rid); - return PromiseResolve({ value, done: true }); - } - - close() { - core.close(this.rid); - } + // TODO(kt3k): This is deprecated. Will be removed in v2.0. + // See https://github.com/denoland/deno/issues/10577 for details + return(value) { + core.close(this.rid); + return PromiseResolve({ value, done: true }); + } - [SymbolAsyncIterator]() { - return this; - } + close() { + core.close(this.rid); } - function watchFs( - paths, - options = { recursive: true }, - ) { - return new FsWatcher(ArrayIsArray(paths) ? paths : [paths], options); + [SymbolAsyncIterator]() { + return this; } +} + +function watchFs( + paths, + options = { recursive: true }, +) { + return new FsWatcher(ArrayIsArray(paths) ? paths : [paths], options); +} - window.__bootstrap.fsEvents = { - watchFs, - }; -})(this); +export { watchFs }; diff --git a/runtime/js/40_http.js b/runtime/js/40_http.js index 22288b5d5..afacf7b27 100644 --- a/runtime/js/40_http.js +++ b/runtime/js/40_http.js @@ -1,15 +1,11 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; +const core = globalThis.Deno.core; +const ops = core.ops; +import { HttpConn } from "internal:ext/http/01_http.js"; -((window) => { - const core = window.__bootstrap.core; - const ops = core.ops; - const { HttpConn } = window.__bootstrap.http; +function serveHttp(conn) { + const rid = ops.op_http_start(conn.rid); + return new HttpConn(rid, conn.remoteAddr, conn.localAddr); +} - function serveHttp(conn) { - const rid = ops.op_http_start(conn.rid); - return new HttpConn(rid, conn.remoteAddr, conn.localAddr); - } - - window.__bootstrap.http.serveHttp = serveHttp; -})(globalThis); +export { serveHttp }; diff --git a/runtime/js/40_process.js b/runtime/js/40_process.js index 5ad24c094..87e898b56 100644 --- a/runtime/js/40_process.js +++ b/runtime/js/40_process.js @@ -1,139 +1,133 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { FsFile } = window.__bootstrap.files; - const { readAll } = window.__bootstrap.io; - const { pathFromURL } = window.__bootstrap.util; - const { assert } = window.__bootstrap.infra; - const { - ArrayPrototypeMap, - ArrayPrototypeSlice, - TypeError, - ObjectEntries, - SafeArrayIterator, - String, - } = window.__bootstrap.primordials; - - function opKill(pid, signo, apiName) { - ops.op_kill(pid, signo, apiName); - } - - function kill(pid, signo = "SIGTERM") { - opKill(pid, signo, "Deno.kill()"); - } - - function opRunStatus(rid) { - return core.opAsync("op_run_status", rid); - } - function opRun(request) { - assert(request.cmd.length > 0); - return ops.op_run(request); +const core = globalThis.Deno.core; +const ops = core.ops; +import { FsFile } from "internal:runtime/js/40_files.js"; +import { readAll } from "internal:runtime/js/12_io.js"; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import { assert } from "internal:ext/web/00_infra.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayPrototypeMap, + ArrayPrototypeSlice, + TypeError, + ObjectEntries, + SafeArrayIterator, + String, +} = primordials; + +function opKill(pid, signo, apiName) { + ops.op_kill(pid, signo, apiName); +} + +function kill(pid, signo = "SIGTERM") { + opKill(pid, signo, "Deno.kill()"); +} + +function opRunStatus(rid) { + return core.opAsync("op_run_status", rid); +} + +function opRun(request) { + assert(request.cmd.length > 0); + return ops.op_run(request); +} + +async function runStatus(rid) { + const res = await opRunStatus(rid); + + if (res.gotSignal) { + const signal = res.exitSignal; + return { success: false, code: 128 + signal, signal }; + } else if (res.exitCode != 0) { + return { success: false, code: res.exitCode }; + } else { + return { success: true, code: 0 }; } +} - async function runStatus(rid) { - const res = await opRunStatus(rid); +class Process { + constructor(res) { + this.rid = res.rid; + this.pid = res.pid; - if (res.gotSignal) { - const signal = res.exitSignal; - return { success: false, code: 128 + signal, signal }; - } else if (res.exitCode != 0) { - return { success: false, code: res.exitCode }; - } else { - return { success: true, code: 0 }; + if (res.stdinRid && res.stdinRid > 0) { + this.stdin = new FsFile(res.stdinRid); } - } - - class Process { - constructor(res) { - this.rid = res.rid; - this.pid = res.pid; - - if (res.stdinRid && res.stdinRid > 0) { - this.stdin = new FsFile(res.stdinRid); - } - - if (res.stdoutRid && res.stdoutRid > 0) { - this.stdout = new FsFile(res.stdoutRid); - } - if (res.stderrRid && res.stderrRid > 0) { - this.stderr = new FsFile(res.stderrRid); - } + if (res.stdoutRid && res.stdoutRid > 0) { + this.stdout = new FsFile(res.stdoutRid); } - status() { - return runStatus(this.rid); + if (res.stderrRid && res.stderrRid > 0) { + this.stderr = new FsFile(res.stderrRid); } + } - async output() { - if (!this.stdout) { - throw new TypeError("stdout was not piped"); - } - try { - return await readAll(this.stdout); - } finally { - this.stdout.close(); - } - } + status() { + return runStatus(this.rid); + } - async stderrOutput() { - if (!this.stderr) { - throw new TypeError("stderr was not piped"); - } - try { - return await readAll(this.stderr); - } finally { - this.stderr.close(); - } + async output() { + if (!this.stdout) { + throw new TypeError("stdout was not piped"); } - - close() { - core.close(this.rid); + try { + return await readAll(this.stdout); + } finally { + this.stdout.close(); } + } - kill(signo = "SIGTERM") { - opKill(this.pid, signo, "Deno.Process.kill()"); + async stderrOutput() { + if (!this.stderr) { + throw new TypeError("stderr was not piped"); + } + try { + return await readAll(this.stderr); + } finally { + this.stderr.close(); } } - function run({ - cmd, - cwd = undefined, - clearEnv = false, - env = {}, - gid = undefined, - uid = undefined, - stdout = "inherit", - stderr = "inherit", - stdin = "inherit", - }) { - if (cmd[0] != null) { - cmd = [ - pathFromURL(cmd[0]), - ...new SafeArrayIterator(ArrayPrototypeSlice(cmd, 1)), - ]; - } - const res = opRun({ - cmd: ArrayPrototypeMap(cmd, String), - cwd, - clearEnv, - env: ObjectEntries(env), - gid, - uid, - stdin, - stdout, - stderr, - }); - return new Process(res); + close() { + core.close(this.rid); } - window.__bootstrap.process = { - run, - Process, - kill, - }; -})(this); + kill(signo = "SIGTERM") { + opKill(this.pid, signo, "Deno.Process.kill()"); + } +} + +function run({ + cmd, + cwd = undefined, + clearEnv = false, + env = {}, + gid = undefined, + uid = undefined, + stdout = "inherit", + stderr = "inherit", + stdin = "inherit", +}) { + if (cmd[0] != null) { + cmd = [ + pathFromURL(cmd[0]), + ...new SafeArrayIterator(ArrayPrototypeSlice(cmd, 1)), + ]; + } + const res = opRun({ + cmd: ArrayPrototypeMap(cmd, String), + cwd, + clearEnv, + env: ObjectEntries(env), + gid, + uid, + stdin, + stdout, + stderr, + }); + return new Process(res); +} + +export { kill, Process, run }; diff --git a/runtime/js/40_read_file.js b/runtime/js/40_read_file.js index 7c2898903..b7f0a7012 100644 --- a/runtime/js/40_read_file.js +++ b/runtime/js/40_read_file.js @@ -1,78 +1,70 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { pathFromURL } = window.__bootstrap.util; - const { abortSignal } = window.__bootstrap; +const core = globalThis.Deno.core; +const ops = core.ops; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import * as abortSignal from "internal:ext/web/03_abort_signal.js"; - function readFileSync(path) { - return ops.op_readfile_sync(pathFromURL(path)); +function readFileSync(path) { + return ops.op_readfile_sync(pathFromURL(path)); +} + +async function readFile(path, options) { + let cancelRid; + let abortHandler; + if (options?.signal) { + options.signal.throwIfAborted(); + cancelRid = ops.op_cancel_handle(); + abortHandler = () => core.tryClose(cancelRid); + options.signal[abortSignal.add](abortHandler); } - async function readFile(path, options) { - let cancelRid; - let abortHandler; + try { + const read = await core.opAsync( + "op_readfile_async", + pathFromURL(path), + cancelRid, + ); + return read; + } finally { if (options?.signal) { - options.signal.throwIfAborted(); - cancelRid = ops.op_cancel_handle(); - abortHandler = () => core.tryClose(cancelRid); - options.signal[abortSignal.add](abortHandler); - } + options.signal[abortSignal.remove](abortHandler); - try { - const read = await core.opAsync( - "op_readfile_async", - pathFromURL(path), - cancelRid, - ); - return read; - } finally { - if (options?.signal) { - options.signal[abortSignal.remove](abortHandler); - - // always throw the abort error when aborted - options.signal.throwIfAborted(); - } + // always throw the abort error when aborted + options.signal.throwIfAborted(); } } +} - function readTextFileSync(path) { - return ops.op_readfile_text_sync(pathFromURL(path)); +function readTextFileSync(path) { + return ops.op_readfile_text_sync(pathFromURL(path)); +} + +async function readTextFile(path, options) { + let cancelRid; + let abortHandler; + if (options?.signal) { + options.signal.throwIfAborted(); + cancelRid = ops.op_cancel_handle(); + abortHandler = () => core.tryClose(cancelRid); + options.signal[abortSignal.add](abortHandler); } - async function readTextFile(path, options) { - let cancelRid; - let abortHandler; + try { + const read = await core.opAsync( + "op_readfile_text_async", + pathFromURL(path), + cancelRid, + ); + return read; + } finally { if (options?.signal) { - options.signal.throwIfAborted(); - cancelRid = ops.op_cancel_handle(); - abortHandler = () => core.tryClose(cancelRid); - options.signal[abortSignal.add](abortHandler); - } + options.signal[abortSignal.remove](abortHandler); - try { - const read = await core.opAsync( - "op_readfile_text_async", - pathFromURL(path), - cancelRid, - ); - return read; - } finally { - if (options?.signal) { - options.signal[abortSignal.remove](abortHandler); - - // always throw the abort error when aborted - options.signal.throwIfAborted(); - } + // always throw the abort error when aborted + options.signal.throwIfAborted(); } } +} - window.__bootstrap.readFile = { - readFile, - readFileSync, - readTextFileSync, - readTextFile, - }; -})(this); +export { readFile, readFileSync, readTextFile, readTextFileSync }; diff --git a/runtime/js/40_signals.js b/runtime/js/40_signals.js index ff1502a55..4ae310151 100644 --- a/runtime/js/40_signals.js +++ b/runtime/js/40_signals.js @@ -1,88 +1,83 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { - SafeSetIterator, - Set, - SetPrototypeDelete, - SymbolFor, - TypeError, - } = window.__bootstrap.primordials; +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +const { + SafeSetIterator, + Set, + SetPrototypeDelete, + SymbolFor, + TypeError, +} = primordials; - function bindSignal(signo) { - return ops.op_signal_bind(signo); - } +function bindSignal(signo) { + return ops.op_signal_bind(signo); +} - function pollSignal(rid) { - const promise = core.opAsync("op_signal_poll", rid); - core.unrefOp(promise[SymbolFor("Deno.core.internalPromiseId")]); - return promise; - } +function pollSignal(rid) { + const promise = core.opAsync("op_signal_poll", rid); + core.unrefOp(promise[SymbolFor("Deno.core.internalPromiseId")]); + return promise; +} - function unbindSignal(rid) { - ops.op_signal_unbind(rid); - } +function unbindSignal(rid) { + ops.op_signal_unbind(rid); +} - // Stores signal listeners and resource data. This has type of - // `Record<string, { rid: number | undefined, listeners: Set<() => void> }` - const signalData = {}; +// Stores signal listeners and resource data. This has type of +// `Record<string, { rid: number | undefined, listeners: Set<() => void> }` +const signalData = {}; - /** Gets the signal handlers and resource data of the given signal */ - function getSignalData(signo) { - return signalData[signo] ?? - (signalData[signo] = { rid: undefined, listeners: new Set() }); - } +/** Gets the signal handlers and resource data of the given signal */ +function getSignalData(signo) { + return signalData[signo] ?? + (signalData[signo] = { rid: undefined, listeners: new Set() }); +} - function checkSignalListenerType(listener) { - if (typeof listener !== "function") { - throw new TypeError( - `Signal listener must be a function. "${typeof listener}" is given.`, - ); - } +function checkSignalListenerType(listener) { + if (typeof listener !== "function") { + throw new TypeError( + `Signal listener must be a function. "${typeof listener}" is given.`, + ); } +} - function addSignalListener(signo, listener) { - checkSignalListenerType(listener); +function addSignalListener(signo, listener) { + checkSignalListenerType(listener); - const sigData = getSignalData(signo); - sigData.listeners.add(listener); + const sigData = getSignalData(signo); + sigData.listeners.add(listener); - if (!sigData.rid) { - // If signal resource doesn't exist, create it. - // The program starts listening to the signal - sigData.rid = bindSignal(signo); - loop(sigData); - } + if (!sigData.rid) { + // If signal resource doesn't exist, create it. + // The program starts listening to the signal + sigData.rid = bindSignal(signo); + loop(sigData); } +} - function removeSignalListener(signo, listener) { - checkSignalListenerType(listener); +function removeSignalListener(signo, listener) { + checkSignalListenerType(listener); - const sigData = getSignalData(signo); - SetPrototypeDelete(sigData.listeners, listener); + const sigData = getSignalData(signo); + SetPrototypeDelete(sigData.listeners, listener); - if (sigData.listeners.size === 0 && sigData.rid) { - unbindSignal(sigData.rid); - sigData.rid = undefined; - } + if (sigData.listeners.size === 0 && sigData.rid) { + unbindSignal(sigData.rid); + sigData.rid = undefined; } +} - async function loop(sigData) { - while (sigData.rid) { - if (await pollSignal(sigData.rid)) { - return; - } - for (const listener of new SafeSetIterator(sigData.listeners)) { - listener(); - } +async function loop(sigData) { + while (sigData.rid) { + if (await pollSignal(sigData.rid)) { + return; + } + for (const listener of new SafeSetIterator(sigData.listeners)) { + listener(); } } +} - window.__bootstrap.signals = { - addSignalListener, - removeSignalListener, - }; -})(this); +export { addSignalListener, removeSignalListener }; diff --git a/runtime/js/40_spawn.js b/runtime/js/40_spawn.js index ecbab52ad..dfccec5d7 100644 --- a/runtime/js/40_spawn.js +++ b/runtime/js/40_spawn.js @@ -1,333 +1,335 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - const ops = core.ops; - const { pathFromURL } = window.__bootstrap.util; - const { illegalConstructorKey } = window.__bootstrap.webUtil; - const { add, remove } = window.__bootstrap.abortSignal; - const { - ArrayPrototypeMap, - ObjectEntries, - ObjectPrototypeIsPrototypeOf, - String, - TypeError, - PromisePrototypeThen, - SafePromiseAll, - SymbolFor, - } = window.__bootstrap.primordials; - const { - readableStreamCollectIntoUint8Array, - readableStreamForRidUnrefable, - readableStreamForRidUnrefableRef, - readableStreamForRidUnrefableUnref, - ReadableStreamPrototype, - writableStreamForRid, - } = window.__bootstrap.streams; - - const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId"); - - function spawnChildInner(opFn, command, apiName, { - args = [], - cwd = undefined, - clearEnv = false, - env = {}, - uid = undefined, - gid = undefined, - stdin = "null", - stdout = "piped", - stderr = "piped", - signal = undefined, - windowsRawArguments = false, - } = {}) { - const child = opFn({ - cmd: pathFromURL(command), - args: ArrayPrototypeMap(args, String), - cwd: pathFromURL(cwd), - clearEnv, - env: ObjectEntries(env), - uid, - gid, - stdin, - stdout, - stderr, - windowsRawArguments, - }, apiName); - return new Child(illegalConstructorKey, { - ...child, - signal, - }); - } - function createSpawnChild(opFn) { - return function spawnChild(command, options = {}) { - return spawnChildInner(opFn, command, "Deno.Command().spawn()", options); - }; +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import { add, remove } from "internal:ext/web/03_abort_signal.js"; +const { + ArrayPrototypeMap, + ObjectEntries, + ObjectPrototypeIsPrototypeOf, + String, + TypeError, + PromisePrototypeThen, + SafePromiseAll, + SymbolFor, + Symbol, +} = primordials; +import { + readableStreamCollectIntoUint8Array, + readableStreamForRidUnrefable, + readableStreamForRidUnrefableRef, + readableStreamForRidUnrefableUnref, + ReadableStreamPrototype, + writableStreamForRid, +} from "internal:ext/web/06_streams.js"; + +const illegalConstructorKey = Symbol("illegalConstructorKey"); + +const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId"); + +function spawnChildInner(opFn, command, apiName, { + args = [], + cwd = undefined, + clearEnv = false, + env = {}, + uid = undefined, + gid = undefined, + stdin = "null", + stdout = "piped", + stderr = "piped", + signal = undefined, + windowsRawArguments = false, +} = {}) { + const child = opFn({ + cmd: pathFromURL(command), + args: ArrayPrototypeMap(args, String), + cwd: pathFromURL(cwd), + clearEnv, + env: ObjectEntries(env), + uid, + gid, + stdin, + stdout, + stderr, + windowsRawArguments, + }, apiName); + return new Child(illegalConstructorKey, { + ...child, + signal, + }); +} + +function createSpawnChild(opFn) { + return function spawnChild(command, options = {}) { + return spawnChildInner(opFn, command, "Deno.Command().spawn()", options); + }; +} + +function collectOutput(readableStream) { + if ( + !(ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, readableStream)) + ) { + return null; } - function collectOutput(readableStream) { - if ( - !(ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, readableStream)) - ) { - return null; - } + return readableStreamCollectIntoUint8Array(readableStream); +} - return readableStreamCollectIntoUint8Array(readableStream); - } +class Child { + #rid; + #waitPromiseId; + #unrefed = false; - class Child { - #rid; - #waitPromiseId; - #unrefed = false; + #pid; + get pid() { + return this.#pid; + } - #pid; - get pid() { - return this.#pid; + #stdin = null; + get stdin() { + if (this.#stdin == null) { + throw new TypeError("stdin is not piped"); } + return this.#stdin; + } - #stdin = null; - get stdin() { - if (this.#stdin == null) { - throw new TypeError("stdin is not piped"); - } - return this.#stdin; + #stdoutPromiseId; + #stdoutRid; + #stdout = null; + get stdout() { + if (this.#stdout == null) { + throw new TypeError("stdout is not piped"); } + return this.#stdout; + } - #stdoutPromiseId; - #stdoutRid; - #stdout = null; - get stdout() { - if (this.#stdout == null) { - throw new TypeError("stdout is not piped"); - } - return this.#stdout; + #stderrPromiseId; + #stderrRid; + #stderr = null; + get stderr() { + if (this.#stderr == null) { + throw new TypeError("stderr is not piped"); } + return this.#stderr; + } - #stderrPromiseId; - #stderrRid; - #stderr = null; - get stderr() { - if (this.#stderr == null) { - throw new TypeError("stderr is not piped"); - } - return this.#stderr; + constructor(key = null, { + signal, + rid, + pid, + stdinRid, + stdoutRid, + stderrRid, + } = null) { + if (key !== illegalConstructorKey) { + throw new TypeError("Illegal constructor."); } - constructor(key = null, { - signal, - rid, - pid, - stdinRid, - stdoutRid, - stderrRid, - } = null) { - if (key !== illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } + this.#rid = rid; + this.#pid = pid; - this.#rid = rid; - this.#pid = pid; + if (stdinRid !== null) { + this.#stdin = writableStreamForRid(stdinRid); + } - if (stdinRid !== null) { - this.#stdin = writableStreamForRid(stdinRid); - } + if (stdoutRid !== null) { + this.#stdoutRid = stdoutRid; + this.#stdout = readableStreamForRidUnrefable(stdoutRid); + } - if (stdoutRid !== null) { - this.#stdoutRid = stdoutRid; - this.#stdout = readableStreamForRidUnrefable(stdoutRid); - } + if (stderrRid !== null) { + this.#stderrRid = stderrRid; + this.#stderr = readableStreamForRidUnrefable(stderrRid); + } - if (stderrRid !== null) { - this.#stderrRid = stderrRid; - this.#stderr = readableStreamForRidUnrefable(stderrRid); - } + const onAbort = () => this.kill("SIGTERM"); + signal?.[add](onAbort); - const onAbort = () => this.kill("SIGTERM"); - signal?.[add](onAbort); + const waitPromise = core.opAsync("op_spawn_wait", this.#rid); + this.#waitPromiseId = waitPromise[promiseIdSymbol]; + this.#status = PromisePrototypeThen(waitPromise, (res) => { + this.#rid = null; + signal?.[remove](onAbort); + return res; + }); + } - const waitPromise = core.opAsync("op_spawn_wait", this.#rid); - this.#waitPromiseId = waitPromise[promiseIdSymbol]; - this.#status = PromisePrototypeThen(waitPromise, (res) => { - this.#rid = null; - signal?.[remove](onAbort); - return res; - }); - } + #status; + get status() { + return this.#status; + } - #status; - get status() { - return this.#status; + async output() { + if (this.#stdout?.locked) { + throw new TypeError( + "Can't collect output because stdout is locked", + ); + } + if (this.#stderr?.locked) { + throw new TypeError( + "Can't collect output because stderr is locked", + ); } - async output() { - if (this.#stdout?.locked) { - throw new TypeError( - "Can't collect output because stdout is locked", - ); - } - if (this.#stderr?.locked) { - throw new TypeError( - "Can't collect output because stderr is locked", - ); - } + const { 0: status, 1: stdout, 2: stderr } = await SafePromiseAll([ + this.#status, + collectOutput(this.#stdout), + collectOutput(this.#stderr), + ]); + + return { + success: status.success, + code: status.code, + signal: status.signal, + get stdout() { + if (stdout == null) { + throw new TypeError("stdout is not piped"); + } + return stdout; + }, + get stderr() { + if (stderr == null) { + throw new TypeError("stderr is not piped"); + } + return stderr; + }, + }; + } - const { 0: status, 1: stdout, 2: stderr } = await SafePromiseAll([ - this.#status, - collectOutput(this.#stdout), - collectOutput(this.#stderr), - ]); - - return { - success: status.success, - code: status.code, - signal: status.signal, - get stdout() { - if (stdout == null) { - throw new TypeError("stdout is not piped"); - } - return stdout; - }, - get stderr() { - if (stderr == null) { - throw new TypeError("stderr is not piped"); - } - return stderr; - }, - }; + kill(signo = "SIGTERM") { + if (this.#rid === null) { + throw new TypeError("Child process has already terminated."); } + ops.op_kill(this.#pid, signo, "Deno.Child.kill()"); + } - kill(signo = "SIGTERM") { - if (this.#rid === null) { - throw new TypeError("Child process has already terminated."); - } - ops.op_kill(this.#pid, signo, "Deno.Child.kill()"); + ref() { + this.#unrefed = false; + core.refOp(this.#waitPromiseId); + if (this.#stdout) readableStreamForRidUnrefableRef(this.#stdout); + if (this.#stderr) readableStreamForRidUnrefableRef(this.#stderr); + } + + unref() { + this.#unrefed = true; + core.unrefOp(this.#waitPromiseId); + if (this.#stdout) readableStreamForRidUnrefableUnref(this.#stdout); + if (this.#stderr) readableStreamForRidUnrefableUnref(this.#stderr); + } +} + +function createSpawn(opFn) { + return function spawn(command, options) { + if (options?.stdin === "piped") { + throw new TypeError( + "Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead", + ); } + return spawnChildInner(opFn, command, "Deno.Command().output()", options) + .output(); + }; +} - ref() { - this.#unrefed = false; - core.refOp(this.#waitPromiseId); - if (this.#stdout) readableStreamForRidUnrefableRef(this.#stdout); - if (this.#stderr) readableStreamForRidUnrefableRef(this.#stderr); +function createSpawnSync(opFn) { + return function spawnSync(command, { + args = [], + cwd = undefined, + clearEnv = false, + env = {}, + uid = undefined, + gid = undefined, + stdin = "null", + stdout = "piped", + stderr = "piped", + windowsRawArguments = false, + } = {}) { + if (stdin === "piped") { + throw new TypeError( + "Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead", + ); } + const result = opFn({ + cmd: pathFromURL(command), + args: ArrayPrototypeMap(args, String), + cwd: pathFromURL(cwd), + clearEnv, + env: ObjectEntries(env), + uid, + gid, + stdin, + stdout, + stderr, + windowsRawArguments, + }); + return { + success: result.status.success, + code: result.status.code, + signal: result.status.signal, + get stdout() { + if (result.stdout == null) { + throw new TypeError("stdout is not piped"); + } + return result.stdout; + }, + get stderr() { + if (result.stderr == null) { + throw new TypeError("stderr is not piped"); + } + return result.stderr; + }, + }; + }; +} + +function createCommand(spawn, spawnSync, spawnChild) { + return class Command { + #command; + #options; - unref() { - this.#unrefed = true; - core.unrefOp(this.#waitPromiseId); - if (this.#stdout) readableStreamForRidUnrefableUnref(this.#stdout); - if (this.#stderr) readableStreamForRidUnrefableUnref(this.#stderr); + constructor(command, options) { + this.#command = command; + this.#options = options; } - } - function createSpawn(opFn) { - return function spawn(command, options) { - if (options?.stdin === "piped") { + output() { + if (this.#options?.stdin === "piped") { throw new TypeError( - "Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead", + "Piped stdin is not supported for this function, use 'Deno.Command.spawn()' instead", ); } - return spawnChildInner(opFn, command, "Deno.Command().output()", options) - .output(); - }; - } + return spawn(this.#command, this.#options); + } - function createSpawnSync(opFn) { - return function spawnSync(command, { - args = [], - cwd = undefined, - clearEnv = false, - env = {}, - uid = undefined, - gid = undefined, - stdin = "null", - stdout = "piped", - stderr = "piped", - windowsRawArguments = false, - } = {}) { - if (stdin === "piped") { + outputSync() { + if (this.#options?.stdin === "piped") { throw new TypeError( - "Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead", + "Piped stdin is not supported for this function, use 'Deno.Command.spawn()' instead", ); } - const result = opFn({ - cmd: pathFromURL(command), - args: ArrayPrototypeMap(args, String), - cwd: pathFromURL(cwd), - clearEnv, - env: ObjectEntries(env), - uid, - gid, - stdin, - stdout, - stderr, - windowsRawArguments, - }); - return { - success: result.status.success, - code: result.status.code, - signal: result.status.signal, - get stdout() { - if (result.stdout == null) { - throw new TypeError("stdout is not piped"); - } - return result.stdout; - }, - get stderr() { - if (result.stderr == null) { - throw new TypeError("stderr is not piped"); - } - return result.stderr; - }, - }; - }; - } - - function createCommand(spawn, spawnSync, spawnChild) { - return class Command { - #command; - #options; - - constructor(command, options) { - this.#command = command; - this.#options = options; - } - - output() { - if (this.#options?.stdin === "piped") { - throw new TypeError( - "Piped stdin is not supported for this function, use 'Deno.Command.spawn()' instead", - ); - } - return spawn(this.#command, this.#options); - } - - outputSync() { - if (this.#options?.stdin === "piped") { - throw new TypeError( - "Piped stdin is not supported for this function, use 'Deno.Command.spawn()' instead", - ); - } - return spawnSync(this.#command, this.#options); - } - - spawn() { - const options = { - ...(this.#options ?? {}), - stdout: this.#options?.stdout ?? "inherit", - stderr: this.#options?.stderr ?? "inherit", - stdin: this.#options?.stdin ?? "inherit", - }; - return spawnChild(this.#command, options); - } - }; - } + return spawnSync(this.#command, this.#options); + } - window.__bootstrap.spawn = { - Child, - ChildProcess: Child, - createCommand, - createSpawn, - createSpawnChild, - createSpawnSync, + spawn() { + const options = { + ...(this.#options ?? {}), + stdout: this.#options?.stdout ?? "inherit", + stderr: this.#options?.stderr ?? "inherit", + stdin: this.#options?.stdin ?? "inherit", + }; + return spawnChild(this.#command, options); + } }; -})(this); +} + +const ChildProcess = Child; + +export { + Child, + ChildProcess, + createCommand, + createSpawn, + createSpawnChild, + createSpawnSync, +}; diff --git a/runtime/js/40_tty.js b/runtime/js/40_tty.js index 3263dc814..859f49275 100644 --- a/runtime/js/40_tty.js +++ b/runtime/js/40_tty.js @@ -1,28 +1,23 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +const { + Uint32Array, + Uint8Array, +} = primordials; -((window) => { - const { - Uint32Array, - Uint8Array, - } = window.__bootstrap.primordials; - const core = window.Deno.core; - const ops = core.ops; +const size = new Uint32Array(2); - const size = new Uint32Array(2); - function consoleSize() { - ops.op_console_size(size); - return { columns: size[0], rows: size[1] }; - } +function consoleSize() { + ops.op_console_size(size); + return { columns: size[0], rows: size[1] }; +} - const isattyBuffer = new Uint8Array(1); - function isatty(rid) { - ops.op_isatty(rid, isattyBuffer); - return !!isattyBuffer[0]; - } +const isattyBuffer = new Uint8Array(1); +function isatty(rid) { + ops.op_isatty(rid, isattyBuffer); + return !!isattyBuffer[0]; +} - window.__bootstrap.tty = { - consoleSize, - isatty, - }; -})(this); +export { consoleSize, isatty }; diff --git a/runtime/js/40_write_file.js b/runtime/js/40_write_file.js index a32ef441b..a9c870ca3 100644 --- a/runtime/js/40_write_file.js +++ b/runtime/js/40_write_file.js @@ -1,107 +1,100 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.__bootstrap.core; - const ops = core.ops; - const { abortSignal } = window.__bootstrap; - const { pathFromURL } = window.__bootstrap.util; - const { open } = window.__bootstrap.files; - const { ReadableStreamPrototype } = window.__bootstrap.streams; - const { ObjectPrototypeIsPrototypeOf } = window.__bootstrap.primordials; +const core = globalThis.Deno.core; +const ops = core.ops; +const primordials = globalThis.__bootstrap.primordials; +import * as abortSignal from "internal:ext/web/03_abort_signal.js"; +import { pathFromURL } from "internal:runtime/js/06_util.js"; +import { open } from "internal:runtime/js/40_files.js"; +import { ReadableStreamPrototype } from "internal:ext/web/06_streams.js"; +const { ObjectPrototypeIsPrototypeOf } = primordials; - function writeFileSync( - path, +function writeFileSync( + path, + data, + options = {}, +) { + options.signal?.throwIfAborted(); + ops.op_write_file_sync( + pathFromURL(path), + options.mode, + options.append ?? false, + options.create ?? true, + options.createNew ?? false, data, - options = {}, - ) { - options.signal?.throwIfAborted(); - ops.op_write_file_sync( - pathFromURL(path), - options.mode, - options.append ?? false, - options.create ?? true, - options.createNew ?? false, - data, - ); - } + ); +} - async function writeFile( - path, - data, - options = {}, - ) { - let cancelRid; - let abortHandler; - if (options.signal) { - options.signal.throwIfAborted(); - cancelRid = ops.op_cancel_handle(); - abortHandler = () => core.tryClose(cancelRid); - options.signal[abortSignal.add](abortHandler); +async function writeFile( + path, + data, + options = {}, +) { + let cancelRid; + let abortHandler; + if (options.signal) { + options.signal.throwIfAborted(); + cancelRid = ops.op_cancel_handle(); + abortHandler = () => core.tryClose(cancelRid); + options.signal[abortSignal.add](abortHandler); + } + try { + if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) { + const file = await open(path, { + mode: options.mode, + append: options.append ?? false, + create: options.create ?? true, + createNew: options.createNew ?? false, + write: true, + }); + await data.pipeTo(file.writable, { + signal: options.signal, + }); + } else { + await core.opAsync( + "op_write_file_async", + pathFromURL(path), + options.mode, + options.append ?? false, + options.create ?? true, + options.createNew ?? false, + data, + cancelRid, + ); } - try { - if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) { - const file = await open(path, { - mode: options.mode, - append: options.append ?? false, - create: options.create ?? true, - createNew: options.createNew ?? false, - write: true, - }); - await data.pipeTo(file.writable, { - signal: options.signal, - }); - } else { - await core.opAsync( - "op_write_file_async", - pathFromURL(path), - options.mode, - options.append ?? false, - options.create ?? true, - options.createNew ?? false, - data, - cancelRid, - ); - } - } finally { - if (options.signal) { - options.signal[abortSignal.remove](abortHandler); + } finally { + if (options.signal) { + options.signal[abortSignal.remove](abortHandler); - // always throw the abort error when aborted - options.signal.throwIfAborted(); - } + // always throw the abort error when aborted + options.signal.throwIfAborted(); } } +} - function writeTextFileSync( - path, - data, - options = {}, - ) { - const encoder = new TextEncoder(); - return writeFileSync(path, encoder.encode(data), options); - } +function writeTextFileSync( + path, + data, + options = {}, +) { + const encoder = new TextEncoder(); + return writeFileSync(path, encoder.encode(data), options); +} - function writeTextFile( - path, - data, - options = {}, - ) { - if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) { - return writeFile( - path, - data.pipeThrough(new TextEncoderStream()), - options, - ); - } else { - const encoder = new TextEncoder(); - return writeFile(path, encoder.encode(data), options); - } +function writeTextFile( + path, + data, + options = {}, +) { + if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) { + return writeFile( + path, + data.pipeThrough(new TextEncoderStream()), + options, + ); + } else { + const encoder = new TextEncoder(); + return writeFile(path, encoder.encode(data), options); } +} - window.__bootstrap.writeFile = { - writeTextFile, - writeTextFileSync, - writeFile, - writeFileSync, - }; -})(this); +export { writeFile, writeFileSync, writeTextFile, writeTextFileSync }; diff --git a/runtime/js/41_prompt.js b/runtime/js/41_prompt.js index 1d5acc028..441db9a2f 100644 --- a/runtime/js/41_prompt.js +++ b/runtime/js/41_prompt.js @@ -1,82 +1,76 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const { stdin } = window.__bootstrap.files; - const { ArrayPrototypePush, StringPrototypeCharCodeAt, Uint8Array } = - window.__bootstrap.primordials; - const { isatty } = window.__bootstrap.tty; - const LF = StringPrototypeCharCodeAt("\n", 0); - const CR = StringPrototypeCharCodeAt("\r", 0); - const core = window.Deno.core; +const core = globalThis.Deno.core; +const primordials = globalThis.__bootstrap.primordials; +import { isatty } from "internal:runtime/js/40_tty.js"; +import { stdin } from "internal:runtime/js/40_files.js"; +const { ArrayPrototypePush, StringPrototypeCharCodeAt, Uint8Array } = + primordials; +const LF = StringPrototypeCharCodeAt("\n", 0); +const CR = StringPrototypeCharCodeAt("\r", 0); - function alert(message = "Alert") { - if (!isatty(stdin.rid)) { - return; - } - - core.print(`${message} [Enter] `, false); - - readLineFromStdinSync(); +function alert(message = "Alert") { + if (!isatty(stdin.rid)) { + return; } - function confirm(message = "Confirm") { - if (!isatty(stdin.rid)) { - return false; - } - - core.print(`${message} [y/N] `, false); + core.print(`${message} [Enter] `, false); - const answer = readLineFromStdinSync(); + readLineFromStdinSync(); +} - return answer === "Y" || answer === "y"; +function confirm(message = "Confirm") { + if (!isatty(stdin.rid)) { + return false; } - function prompt(message = "Prompt", defaultValue) { - defaultValue ??= null; + core.print(`${message} [y/N] `, false); - if (!isatty(stdin.rid)) { - return null; - } + const answer = readLineFromStdinSync(); - core.print(`${message} `, false); + return answer === "Y" || answer === "y"; +} - if (defaultValue) { - core.print(`[${defaultValue}] `, false); - } +function prompt(message = "Prompt", defaultValue) { + defaultValue ??= null; + + if (!isatty(stdin.rid)) { + return null; + } - return readLineFromStdinSync() || defaultValue; + core.print(`${message} `, false); + + if (defaultValue) { + core.print(`[${defaultValue}] `, false); } - function readLineFromStdinSync() { - const c = new Uint8Array(1); - const buf = []; + return readLineFromStdinSync() || defaultValue; +} + +function readLineFromStdinSync() { + const c = new Uint8Array(1); + const buf = []; - while (true) { + while (true) { + const n = stdin.readSync(c); + if (n === null || n === 0) { + break; + } + if (c[0] === CR) { const n = stdin.readSync(c); - if (n === null || n === 0) { + if (c[0] === LF) { break; } - if (c[0] === CR) { - const n = stdin.readSync(c); - if (c[0] === LF) { - break; - } - ArrayPrototypePush(buf, CR); - if (n === null || n === 0) { - break; - } - } - if (c[0] === LF) { + ArrayPrototypePush(buf, CR); + if (n === null || n === 0) { break; } - ArrayPrototypePush(buf, c[0]); } - return core.decode(new Uint8Array(buf)); + if (c[0] === LF) { + break; + } + ArrayPrototypePush(buf, c[0]); } + return core.decode(new Uint8Array(buf)); +} - window.__bootstrap.prompt = { - alert, - confirm, - prompt, - }; -})(this); +export { alert, confirm, prompt }; diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index d2c76e003..7b791017b 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -1,154 +1,181 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = window.Deno.core; - const __bootstrap = window.__bootstrap; +const core = globalThis.Deno.core; +const ops = core.ops; +import * as timers from "internal:ext/web/02_timers.js"; +import * as httpClient from "internal:ext/fetch/22_http_client.js"; +import * as console from "internal:ext/console/02_console.js"; +import * as ffi from "internal:ext/ffi/00_ffi.js"; +import * as net from "internal:ext/net/01_net.js"; +import * as tls from "internal:ext/net/02_tls.js"; +import * as http from "internal:ext/http/01_http.js"; +import * as flash from "internal:ext/flash/01_http.js"; +import * as build from "internal:runtime/js/01_build.js"; +import * as errors from "internal:runtime/js/01_errors.js"; +import * as version from "internal:runtime/js/01_version.js"; +import * as permissions from "internal:runtime/js/10_permissions.js"; +import * as io from "internal:runtime/js/12_io.js"; +import * as buffer from "internal:runtime/js/13_buffer.js"; +import * as fs from "internal:runtime/js/30_fs.js"; +import * as os from "internal:runtime/js/30_os.js"; +import * as diagnostics from "internal:runtime/js/40_diagnostics.js"; +import * as files from "internal:runtime/js/40_files.js"; +import * as fsEvents from "internal:runtime/js/40_fs_events.js"; +import * as process from "internal:runtime/js/40_process.js"; +import * as readFile from "internal:runtime/js/40_read_file.js"; +import * as signals from "internal:runtime/js/40_signals.js"; +import * as tty from "internal:runtime/js/40_tty.js"; +import * as writeFile from "internal:runtime/js/40_write_file.js"; +import * as spawn from "internal:runtime/js/40_spawn.js"; +// TODO(bartlomieju): this is funky we have two `http` imports +import * as httpRuntime from "internal:runtime/js/40_http.js"; - __bootstrap.denoNs = { - metrics: core.metrics, - Process: __bootstrap.process.Process, - run: __bootstrap.process.run, - isatty: __bootstrap.tty.isatty, - writeFileSync: __bootstrap.writeFile.writeFileSync, - writeFile: __bootstrap.writeFile.writeFile, - writeTextFileSync: __bootstrap.writeFile.writeTextFileSync, - writeTextFile: __bootstrap.writeFile.writeTextFile, - readTextFile: __bootstrap.readFile.readTextFile, - readTextFileSync: __bootstrap.readFile.readTextFileSync, - readFile: __bootstrap.readFile.readFile, - readFileSync: __bootstrap.readFile.readFileSync, - watchFs: __bootstrap.fsEvents.watchFs, - chmodSync: __bootstrap.fs.chmodSync, - chmod: __bootstrap.fs.chmod, - chown: __bootstrap.fs.chown, - chownSync: __bootstrap.fs.chownSync, - copyFileSync: __bootstrap.fs.copyFileSync, - cwd: __bootstrap.fs.cwd, - makeTempDirSync: __bootstrap.fs.makeTempDirSync, - makeTempDir: __bootstrap.fs.makeTempDir, - makeTempFileSync: __bootstrap.fs.makeTempFileSync, - makeTempFile: __bootstrap.fs.makeTempFile, - memoryUsage: () => core.ops.op_runtime_memory_usage(), - mkdirSync: __bootstrap.fs.mkdirSync, - mkdir: __bootstrap.fs.mkdir, - chdir: __bootstrap.fs.chdir, - copyFile: __bootstrap.fs.copyFile, - readDirSync: __bootstrap.fs.readDirSync, - readDir: __bootstrap.fs.readDir, - readLinkSync: __bootstrap.fs.readLinkSync, - readLink: __bootstrap.fs.readLink, - realPathSync: __bootstrap.fs.realPathSync, - realPath: __bootstrap.fs.realPath, - removeSync: __bootstrap.fs.removeSync, - remove: __bootstrap.fs.remove, - renameSync: __bootstrap.fs.renameSync, - rename: __bootstrap.fs.rename, - version: __bootstrap.version.version, - build: __bootstrap.build.build, - statSync: __bootstrap.fs.statSync, - lstatSync: __bootstrap.fs.lstatSync, - stat: __bootstrap.fs.stat, - lstat: __bootstrap.fs.lstat, - truncateSync: __bootstrap.fs.truncateSync, - truncate: __bootstrap.fs.truncate, - ftruncateSync: __bootstrap.fs.ftruncateSync, - ftruncate: __bootstrap.fs.ftruncate, - futime: __bootstrap.fs.futime, - futimeSync: __bootstrap.fs.futimeSync, - errors: __bootstrap.errors.errors, - // TODO(kt3k): Remove this export at v2 - // See https://github.com/denoland/deno/issues/9294 - customInspect: __bootstrap.console.customInspect, - inspect: __bootstrap.console.inspect, - env: __bootstrap.os.env, - exit: __bootstrap.os.exit, - execPath: __bootstrap.os.execPath, - Buffer: __bootstrap.buffer.Buffer, - readAll: __bootstrap.buffer.readAll, - readAllSync: __bootstrap.buffer.readAllSync, - writeAll: __bootstrap.buffer.writeAll, - writeAllSync: __bootstrap.buffer.writeAllSync, - copy: __bootstrap.io.copy, - iter: __bootstrap.io.iter, - iterSync: __bootstrap.io.iterSync, - SeekMode: __bootstrap.io.SeekMode, - read: __bootstrap.io.read, - readSync: __bootstrap.io.readSync, - write: __bootstrap.io.write, - writeSync: __bootstrap.io.writeSync, - File: __bootstrap.files.File, - FsFile: __bootstrap.files.FsFile, - open: __bootstrap.files.open, - openSync: __bootstrap.files.openSync, - create: __bootstrap.files.create, - createSync: __bootstrap.files.createSync, - stdin: __bootstrap.files.stdin, - stdout: __bootstrap.files.stdout, - stderr: __bootstrap.files.stderr, - seek: __bootstrap.files.seek, - seekSync: __bootstrap.files.seekSync, - connect: __bootstrap.net.connect, - listen: __bootstrap.net.listen, - loadavg: __bootstrap.os.loadavg, - connectTls: __bootstrap.tls.connectTls, - listenTls: __bootstrap.tls.listenTls, - startTls: __bootstrap.tls.startTls, - shutdown: __bootstrap.net.shutdown, - fstatSync: __bootstrap.fs.fstatSync, - fstat: __bootstrap.fs.fstat, - fsyncSync: __bootstrap.fs.fsyncSync, - fsync: __bootstrap.fs.fsync, - fdatasyncSync: __bootstrap.fs.fdatasyncSync, - fdatasync: __bootstrap.fs.fdatasync, - symlink: __bootstrap.fs.symlink, - symlinkSync: __bootstrap.fs.symlinkSync, - link: __bootstrap.fs.link, - linkSync: __bootstrap.fs.linkSync, - permissions: __bootstrap.permissions.permissions, - Permissions: __bootstrap.permissions.Permissions, - PermissionStatus: __bootstrap.permissions.PermissionStatus, - serveHttp: __bootstrap.http.serveHttp, - resolveDns: __bootstrap.net.resolveDns, - upgradeWebSocket: __bootstrap.http.upgradeWebSocket, - utime: __bootstrap.fs.utime, - utimeSync: __bootstrap.fs.utimeSync, - kill: __bootstrap.process.kill, - addSignalListener: __bootstrap.signals.addSignalListener, - removeSignalListener: __bootstrap.signals.removeSignalListener, - refTimer: __bootstrap.timers.refTimer, - unrefTimer: __bootstrap.timers.unrefTimer, - osRelease: __bootstrap.os.osRelease, - osUptime: __bootstrap.os.osUptime, - hostname: __bootstrap.os.hostname, - systemMemoryInfo: __bootstrap.os.systemMemoryInfo, - networkInterfaces: __bootstrap.os.networkInterfaces, - consoleSize: __bootstrap.tty.consoleSize, - gid: __bootstrap.os.gid, - uid: __bootstrap.os.uid, - }; +const denoNs = { + metrics: core.metrics, + Process: process.Process, + run: process.run, + isatty: tty.isatty, + writeFileSync: writeFile.writeFileSync, + writeFile: writeFile.writeFile, + writeTextFileSync: writeFile.writeTextFileSync, + writeTextFile: writeFile.writeTextFile, + readTextFile: readFile.readTextFile, + readTextFileSync: readFile.readTextFileSync, + readFile: readFile.readFile, + readFileSync: readFile.readFileSync, + watchFs: fsEvents.watchFs, + chmodSync: fs.chmodSync, + chmod: fs.chmod, + chown: fs.chown, + chownSync: fs.chownSync, + copyFileSync: fs.copyFileSync, + cwd: fs.cwd, + makeTempDirSync: fs.makeTempDirSync, + makeTempDir: fs.makeTempDir, + makeTempFileSync: fs.makeTempFileSync, + makeTempFile: fs.makeTempFile, + memoryUsage: () => ops.op_runtime_memory_usage(), + mkdirSync: fs.mkdirSync, + mkdir: fs.mkdir, + chdir: fs.chdir, + copyFile: fs.copyFile, + readDirSync: fs.readDirSync, + readDir: fs.readDir, + readLinkSync: fs.readLinkSync, + readLink: fs.readLink, + realPathSync: fs.realPathSync, + realPath: fs.realPath, + removeSync: fs.removeSync, + remove: fs.remove, + renameSync: fs.renameSync, + rename: fs.rename, + version: version.version, + build: build.build, + statSync: fs.statSync, + lstatSync: fs.lstatSync, + stat: fs.stat, + lstat: fs.lstat, + truncateSync: fs.truncateSync, + truncate: fs.truncate, + ftruncateSync: fs.ftruncateSync, + ftruncate: fs.ftruncate, + futime: fs.futime, + futimeSync: fs.futimeSync, + errors: errors.errors, + // TODO(kt3k): Remove this export at v2 + // See https://github.com/denoland/deno/issues/9294 + customInspect: console.customInspect, + inspect: console.inspect, + env: os.env, + exit: os.exit, + execPath: os.execPath, + Buffer: buffer.Buffer, + readAll: buffer.readAll, + readAllSync: buffer.readAllSync, + writeAll: buffer.writeAll, + writeAllSync: buffer.writeAllSync, + copy: io.copy, + iter: io.iter, + iterSync: io.iterSync, + SeekMode: io.SeekMode, + read: io.read, + readSync: io.readSync, + write: io.write, + writeSync: io.writeSync, + File: files.File, + FsFile: files.FsFile, + open: files.open, + openSync: files.openSync, + create: files.create, + createSync: files.createSync, + stdin: files.stdin, + stdout: files.stdout, + stderr: files.stderr, + seek: files.seek, + seekSync: files.seekSync, + connect: net.connect, + listen: net.listen, + loadavg: os.loadavg, + connectTls: tls.connectTls, + listenTls: tls.listenTls, + startTls: tls.startTls, + shutdown: net.shutdown, + fstatSync: fs.fstatSync, + fstat: fs.fstat, + fsyncSync: fs.fsyncSync, + fsync: fs.fsync, + fdatasyncSync: fs.fdatasyncSync, + fdatasync: fs.fdatasync, + symlink: fs.symlink, + symlinkSync: fs.symlinkSync, + link: fs.link, + linkSync: fs.linkSync, + permissions: permissions.permissions, + Permissions: permissions.Permissions, + PermissionStatus: permissions.PermissionStatus, + // TODO(bartlomieju): why is this not in one of extensions? + serveHttp: httpRuntime.serveHttp, + resolveDns: net.resolveDns, + upgradeWebSocket: http.upgradeWebSocket, + utime: fs.utime, + utimeSync: fs.utimeSync, + kill: process.kill, + addSignalListener: signals.addSignalListener, + removeSignalListener: signals.removeSignalListener, + refTimer: timers.refTimer, + unrefTimer: timers.unrefTimer, + osRelease: os.osRelease, + osUptime: os.osUptime, + hostname: os.hostname, + systemMemoryInfo: os.systemMemoryInfo, + networkInterfaces: os.networkInterfaces, + consoleSize: tty.consoleSize, + gid: os.gid, + uid: os.uid, +}; - __bootstrap.denoNsUnstable = { - DiagnosticCategory: __bootstrap.diagnostics.DiagnosticCategory, - listenDatagram: __bootstrap.net.listenDatagram, - umask: __bootstrap.fs.umask, - HttpClient: __bootstrap.fetch.HttpClient, - createHttpClient: __bootstrap.fetch.createHttpClient, - http: __bootstrap.http, - dlopen: __bootstrap.ffi.dlopen, - UnsafeCallback: __bootstrap.ffi.UnsafeCallback, - UnsafePointer: __bootstrap.ffi.UnsafePointer, - UnsafePointerView: __bootstrap.ffi.UnsafePointerView, - UnsafeFnPointer: __bootstrap.ffi.UnsafeFnPointer, - flock: __bootstrap.fs.flock, - flockSync: __bootstrap.fs.flockSync, - funlock: __bootstrap.fs.funlock, - funlockSync: __bootstrap.fs.funlockSync, - Child: __bootstrap.spawn.Child, - ChildProcess: __bootstrap.spawn.ChildProcess, - Command: __bootstrap.spawn.Command, - serve: __bootstrap.flash.serve, - upgradeHttp: __bootstrap.http.upgradeHttp, - upgradeHttpRaw: __bootstrap.flash.upgradeHttpRaw, - }; -})(this); +const denoNsUnstable = { + DiagnosticCategory: diagnostics.DiagnosticCategory, + listenDatagram: net.listenDatagram, + umask: fs.umask, + HttpClient: httpClient.HttpClient, + createHttpClient: httpClient.createHttpClient, + // TODO(bartlomieju): why is it needed? + http, + dlopen: ffi.dlopen, + UnsafeCallback: ffi.UnsafeCallback, + UnsafePointer: ffi.UnsafePointer, + UnsafePointerView: ffi.UnsafePointerView, + UnsafeFnPointer: ffi.UnsafeFnPointer, + flock: fs.flock, + flockSync: fs.flockSync, + funlock: fs.funlock, + funlockSync: fs.funlockSync, + Child: spawn.Child, + ChildProcess: spawn.ChildProcess, + Command: spawn.Command, + upgradeHttp: http.upgradeHttp, + upgradeHttpRaw: flash.upgradeHttpRaw, +}; + +export { denoNs, denoNsUnstable }; diff --git a/runtime/js/98_global_scope.js b/runtime/js/98_global_scope.js index 499538a32..dcb3bd486 100644 --- a/runtime/js/98_global_scope.js +++ b/runtime/js/98_global_scope.js @@ -1,335 +1,334 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; -((window) => { - const core = Deno.core; - const { - ObjectDefineProperties, - SymbolFor, - } = window.__bootstrap.primordials; +const core = globalThis.Deno.core; +const primordials = globalThis.__bootstrap.primordials; +const { + ObjectDefineProperties, + SymbolFor, +} = primordials; - const util = window.__bootstrap.util; - const location = window.__bootstrap.location; - const event = window.__bootstrap.event; - const eventTarget = window.__bootstrap.eventTarget; - const timers = window.__bootstrap.timers; - const base64 = window.__bootstrap.base64; - const encoding = window.__bootstrap.encoding; - const Console = window.__bootstrap.console.Console; - const caches = window.__bootstrap.caches; - const compression = window.__bootstrap.compression; - const worker = window.__bootstrap.worker; - const performance = window.__bootstrap.performance; - const crypto = window.__bootstrap.crypto; - const url = window.__bootstrap.url; - const urlPattern = window.__bootstrap.urlPattern; - const headers = window.__bootstrap.headers; - const streams = window.__bootstrap.streams; - const fileReader = window.__bootstrap.fileReader; - const webgpu = window.__bootstrap.webgpu; - const webSocket = window.__bootstrap.webSocket; - const broadcastChannel = window.__bootstrap.broadcastChannel; - const file = window.__bootstrap.file; - const formData = window.__bootstrap.formData; - const fetch = window.__bootstrap.fetch; - const messagePort = window.__bootstrap.messagePort; - const webidl = window.__bootstrap.webidl; - const domException = window.__bootstrap.domException; - const abortSignal = window.__bootstrap.abortSignal; - const globalInterfaces = window.__bootstrap.globalInterfaces; - const webStorage = window.__bootstrap.webStorage; - const prompt = window.__bootstrap.prompt; +import * as util from "internal:runtime/js/06_util.js"; +import * as location from "internal:ext/web/12_location.js"; +import * as event from "internal:ext/web/02_event.js"; +import * as timers from "internal:ext/web/02_timers.js"; +import * as base64 from "internal:ext/web/05_base64.js"; +import * as encoding from "internal:ext/web/08_text_encoding.js"; +import * as console from "internal:ext/console/02_console.js"; +import * as caches from "internal:ext/cache/01_cache.js"; +import * as compression from "internal:ext/web/14_compression.js"; +import * as worker from "internal:runtime/js/11_workers.js"; +import * as performance from "internal:ext/web/15_performance.js"; +import * as crypto from "internal:ext/crypto/00_crypto.js"; +import * as url from "internal:ext/url/00_url.js"; +import * as urlPattern from "internal:ext/url/01_urlpattern.js"; +import * as headers from "internal:ext/fetch/20_headers.js"; +import * as streams from "internal:ext/web/06_streams.js"; +import * as fileReader from "internal:ext/web/10_filereader.js"; +import * as webgpu from "internal:ext/webgpu/01_webgpu.js"; +import * as webSocket from "internal:ext/websocket/01_websocket.js"; +import * as webSocketStream from "internal:ext/websocket/02_websocketstream.js"; +import * as broadcastChannel from "internal:ext/broadcast_channel/01_broadcast_channel.js"; +import * as file from "internal:ext/web/09_file.js"; +import * as formData from "internal:ext/fetch/21_formdata.js"; +import * as request from "internal:ext/fetch/23_request.js"; +import * as response from "internal:ext/fetch/23_response.js"; +import * as fetch from "internal:ext/fetch/26_fetch.js"; +import * as messagePort from "internal:ext/web/13_message_port.js"; +import * as webidl from "internal:ext/webidl/00_webidl.js"; +import DOMException from "internal:ext/web/01_dom_exception.js"; +import * as abortSignal from "internal:ext/web/03_abort_signal.js"; +import * as globalInterfaces from "internal:ext/web/04_global_interfaces.js"; +import * as webStorage from "internal:ext/webstorage/01_webstorage.js"; +import * as prompt from "internal:runtime/js/41_prompt.js"; - // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope - const windowOrWorkerGlobalScope = { - AbortController: util.nonEnumerable(abortSignal.AbortController), - AbortSignal: util.nonEnumerable(abortSignal.AbortSignal), - Blob: util.nonEnumerable(file.Blob), - ByteLengthQueuingStrategy: util.nonEnumerable( - streams.ByteLengthQueuingStrategy, - ), - CloseEvent: util.nonEnumerable(event.CloseEvent), - CompressionStream: util.nonEnumerable(compression.CompressionStream), - CountQueuingStrategy: util.nonEnumerable( - streams.CountQueuingStrategy, - ), - CryptoKey: util.nonEnumerable(crypto.CryptoKey), - CustomEvent: util.nonEnumerable(event.CustomEvent), - DecompressionStream: util.nonEnumerable(compression.DecompressionStream), - DOMException: util.nonEnumerable(domException.DOMException), - ErrorEvent: util.nonEnumerable(event.ErrorEvent), - Event: util.nonEnumerable(event.Event), - EventTarget: util.nonEnumerable(eventTarget.EventTarget), - File: util.nonEnumerable(file.File), - FileReader: util.nonEnumerable(fileReader.FileReader), - FormData: util.nonEnumerable(formData.FormData), - Headers: util.nonEnumerable(headers.Headers), - MessageEvent: util.nonEnumerable(event.MessageEvent), - Performance: util.nonEnumerable(performance.Performance), - PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry), - PerformanceMark: util.nonEnumerable(performance.PerformanceMark), - PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure), - PromiseRejectionEvent: util.nonEnumerable(event.PromiseRejectionEvent), - ProgressEvent: util.nonEnumerable(event.ProgressEvent), - ReadableStream: util.nonEnumerable(streams.ReadableStream), - ReadableStreamDefaultReader: util.nonEnumerable( - streams.ReadableStreamDefaultReader, - ), - Request: util.nonEnumerable(fetch.Request), - Response: util.nonEnumerable(fetch.Response), - TextDecoder: util.nonEnumerable(encoding.TextDecoder), - TextEncoder: util.nonEnumerable(encoding.TextEncoder), - TextDecoderStream: util.nonEnumerable(encoding.TextDecoderStream), - TextEncoderStream: util.nonEnumerable(encoding.TextEncoderStream), - TransformStream: util.nonEnumerable(streams.TransformStream), - URL: util.nonEnumerable(url.URL), - URLPattern: util.nonEnumerable(urlPattern.URLPattern), - URLSearchParams: util.nonEnumerable(url.URLSearchParams), - WebSocket: util.nonEnumerable(webSocket.WebSocket), - MessageChannel: util.nonEnumerable(messagePort.MessageChannel), - MessagePort: util.nonEnumerable(messagePort.MessagePort), - Worker: util.nonEnumerable(worker.Worker), - WritableStream: util.nonEnumerable(streams.WritableStream), - WritableStreamDefaultWriter: util.nonEnumerable( - streams.WritableStreamDefaultWriter, - ), - WritableStreamDefaultController: util.nonEnumerable( - streams.WritableStreamDefaultController, - ), - ReadableByteStreamController: util.nonEnumerable( - streams.ReadableByteStreamController, - ), - ReadableStreamBYOBReader: util.nonEnumerable( - streams.ReadableStreamBYOBReader, - ), - ReadableStreamBYOBRequest: util.nonEnumerable( - streams.ReadableStreamBYOBRequest, - ), - ReadableStreamDefaultController: util.nonEnumerable( - streams.ReadableStreamDefaultController, - ), - TransformStreamDefaultController: util.nonEnumerable( - streams.TransformStreamDefaultController, - ), - atob: util.writable(base64.atob), - btoa: util.writable(base64.btoa), - clearInterval: util.writable(timers.clearInterval), - clearTimeout: util.writable(timers.clearTimeout), - caches: { - enumerable: true, - configurable: true, - get: caches.cacheStorage, - }, - CacheStorage: util.nonEnumerable(caches.CacheStorage), - Cache: util.nonEnumerable(caches.Cache), - console: util.nonEnumerable( - new Console((msg, level) => core.print(msg, level > 1)), - ), - crypto: util.readOnly(crypto.crypto), - Crypto: util.nonEnumerable(crypto.Crypto), - SubtleCrypto: util.nonEnumerable(crypto.SubtleCrypto), - fetch: util.writable(fetch.fetch), - performance: util.writable(performance.performance), - reportError: util.writable(event.reportError), - setInterval: util.writable(timers.setInterval), - setTimeout: util.writable(timers.setTimeout), - structuredClone: util.writable(messagePort.structuredClone), - // Branding as a WebIDL object - [webidl.brand]: util.nonEnumerable(webidl.brand), - }; +// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope +const windowOrWorkerGlobalScope = { + AbortController: util.nonEnumerable(abortSignal.AbortController), + AbortSignal: util.nonEnumerable(abortSignal.AbortSignal), + Blob: util.nonEnumerable(file.Blob), + ByteLengthQueuingStrategy: util.nonEnumerable( + streams.ByteLengthQueuingStrategy, + ), + CloseEvent: util.nonEnumerable(event.CloseEvent), + CompressionStream: util.nonEnumerable(compression.CompressionStream), + CountQueuingStrategy: util.nonEnumerable( + streams.CountQueuingStrategy, + ), + CryptoKey: util.nonEnumerable(crypto.CryptoKey), + CustomEvent: util.nonEnumerable(event.CustomEvent), + DecompressionStream: util.nonEnumerable(compression.DecompressionStream), + DOMException: util.nonEnumerable(DOMException), + ErrorEvent: util.nonEnumerable(event.ErrorEvent), + Event: util.nonEnumerable(event.Event), + EventTarget: util.nonEnumerable(event.EventTarget), + File: util.nonEnumerable(file.File), + FileReader: util.nonEnumerable(fileReader.FileReader), + FormData: util.nonEnumerable(formData.FormData), + Headers: util.nonEnumerable(headers.Headers), + MessageEvent: util.nonEnumerable(event.MessageEvent), + Performance: util.nonEnumerable(performance.Performance), + PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry), + PerformanceMark: util.nonEnumerable(performance.PerformanceMark), + PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure), + PromiseRejectionEvent: util.nonEnumerable(event.PromiseRejectionEvent), + ProgressEvent: util.nonEnumerable(event.ProgressEvent), + ReadableStream: util.nonEnumerable(streams.ReadableStream), + ReadableStreamDefaultReader: util.nonEnumerable( + streams.ReadableStreamDefaultReader, + ), + Request: util.nonEnumerable(request.Request), + Response: util.nonEnumerable(response.Response), + TextDecoder: util.nonEnumerable(encoding.TextDecoder), + TextEncoder: util.nonEnumerable(encoding.TextEncoder), + TextDecoderStream: util.nonEnumerable(encoding.TextDecoderStream), + TextEncoderStream: util.nonEnumerable(encoding.TextEncoderStream), + TransformStream: util.nonEnumerable(streams.TransformStream), + URL: util.nonEnumerable(url.URL), + URLPattern: util.nonEnumerable(urlPattern.URLPattern), + URLSearchParams: util.nonEnumerable(url.URLSearchParams), + WebSocket: util.nonEnumerable(webSocket.WebSocket), + MessageChannel: util.nonEnumerable(messagePort.MessageChannel), + MessagePort: util.nonEnumerable(messagePort.MessagePort), + Worker: util.nonEnumerable(worker.Worker), + WritableStream: util.nonEnumerable(streams.WritableStream), + WritableStreamDefaultWriter: util.nonEnumerable( + streams.WritableStreamDefaultWriter, + ), + WritableStreamDefaultController: util.nonEnumerable( + streams.WritableStreamDefaultController, + ), + ReadableByteStreamController: util.nonEnumerable( + streams.ReadableByteStreamController, + ), + ReadableStreamBYOBReader: util.nonEnumerable( + streams.ReadableStreamBYOBReader, + ), + ReadableStreamBYOBRequest: util.nonEnumerable( + streams.ReadableStreamBYOBRequest, + ), + ReadableStreamDefaultController: util.nonEnumerable( + streams.ReadableStreamDefaultController, + ), + TransformStreamDefaultController: util.nonEnumerable( + streams.TransformStreamDefaultController, + ), + atob: util.writable(base64.atob), + btoa: util.writable(base64.btoa), + clearInterval: util.writable(timers.clearInterval), + clearTimeout: util.writable(timers.clearTimeout), + caches: { + enumerable: true, + configurable: true, + get: caches.cacheStorage, + }, + CacheStorage: util.nonEnumerable(caches.CacheStorage), + Cache: util.nonEnumerable(caches.Cache), + console: util.nonEnumerable( + new console.Console((msg, level) => core.print(msg, level > 1)), + ), + crypto: util.readOnly(crypto.crypto), + Crypto: util.nonEnumerable(crypto.Crypto), + SubtleCrypto: util.nonEnumerable(crypto.SubtleCrypto), + fetch: util.writable(fetch.fetch), + performance: util.writable(performance.performance), + reportError: util.writable(event.reportError), + setInterval: util.writable(timers.setInterval), + setTimeout: util.writable(timers.setTimeout), + structuredClone: util.writable(messagePort.structuredClone), + // Branding as a WebIDL object + [webidl.brand]: util.nonEnumerable(webidl.brand), +}; - const unstableWindowOrWorkerGlobalScope = { - BroadcastChannel: util.nonEnumerable(broadcastChannel.BroadcastChannel), - WebSocketStream: util.nonEnumerable(webSocket.WebSocketStream), +const unstableWindowOrWorkerGlobalScope = { + BroadcastChannel: util.nonEnumerable(broadcastChannel.BroadcastChannel), + WebSocketStream: util.nonEnumerable(webSocketStream.WebSocketStream), - GPU: util.nonEnumerable(webgpu.GPU), - GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), - GPUAdapterInfo: util.nonEnumerable(webgpu.GPUAdapterInfo), - GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits), - GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures), - GPUDeviceLostInfo: util.nonEnumerable(webgpu.GPUDeviceLostInfo), - GPUDevice: util.nonEnumerable(webgpu.GPUDevice), - GPUQueue: util.nonEnumerable(webgpu.GPUQueue), - GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer), - GPUBufferUsage: util.nonEnumerable(webgpu.GPUBufferUsage), - GPUMapMode: util.nonEnumerable(webgpu.GPUMapMode), - GPUTexture: util.nonEnumerable(webgpu.GPUTexture), - GPUTextureUsage: util.nonEnumerable(webgpu.GPUTextureUsage), - GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView), - GPUSampler: util.nonEnumerable(webgpu.GPUSampler), - GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout), - GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout), - GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup), - GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), - GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage), - GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), - GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), - GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite), - GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder), - GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder), - GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder), - GPUCommandBuffer: util.nonEnumerable(webgpu.GPUCommandBuffer), - GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder), - GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), - GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), - GPUError: util.nonEnumerable(webgpu.GPUError), - GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), - GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), - }; + GPU: util.nonEnumerable(webgpu.GPU), + GPUAdapter: util.nonEnumerable(webgpu.GPUAdapter), + GPUAdapterInfo: util.nonEnumerable(webgpu.GPUAdapterInfo), + GPUSupportedLimits: util.nonEnumerable(webgpu.GPUSupportedLimits), + GPUSupportedFeatures: util.nonEnumerable(webgpu.GPUSupportedFeatures), + GPUDeviceLostInfo: util.nonEnumerable(webgpu.GPUDeviceLostInfo), + GPUDevice: util.nonEnumerable(webgpu.GPUDevice), + GPUQueue: util.nonEnumerable(webgpu.GPUQueue), + GPUBuffer: util.nonEnumerable(webgpu.GPUBuffer), + GPUBufferUsage: util.nonEnumerable(webgpu.GPUBufferUsage), + GPUMapMode: util.nonEnumerable(webgpu.GPUMapMode), + GPUTexture: util.nonEnumerable(webgpu.GPUTexture), + GPUTextureUsage: util.nonEnumerable(webgpu.GPUTextureUsage), + GPUTextureView: util.nonEnumerable(webgpu.GPUTextureView), + GPUSampler: util.nonEnumerable(webgpu.GPUSampler), + GPUBindGroupLayout: util.nonEnumerable(webgpu.GPUBindGroupLayout), + GPUPipelineLayout: util.nonEnumerable(webgpu.GPUPipelineLayout), + GPUBindGroup: util.nonEnumerable(webgpu.GPUBindGroup), + GPUShaderModule: util.nonEnumerable(webgpu.GPUShaderModule), + GPUShaderStage: util.nonEnumerable(webgpu.GPUShaderStage), + GPUComputePipeline: util.nonEnumerable(webgpu.GPUComputePipeline), + GPURenderPipeline: util.nonEnumerable(webgpu.GPURenderPipeline), + GPUColorWrite: util.nonEnumerable(webgpu.GPUColorWrite), + GPUCommandEncoder: util.nonEnumerable(webgpu.GPUCommandEncoder), + GPURenderPassEncoder: util.nonEnumerable(webgpu.GPURenderPassEncoder), + GPUComputePassEncoder: util.nonEnumerable(webgpu.GPUComputePassEncoder), + GPUCommandBuffer: util.nonEnumerable(webgpu.GPUCommandBuffer), + GPURenderBundleEncoder: util.nonEnumerable(webgpu.GPURenderBundleEncoder), + GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), + GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), + GPUError: util.nonEnumerable(webgpu.GPUError), + GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), + GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), +}; - class Navigator { - constructor() { - webidl.illegalConstructor(); - } +class Navigator { + constructor() { + webidl.illegalConstructor(); + } - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect({})}`; - } + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${inspect({})}`; } +} - const navigator = webidl.createBranded(Navigator); +const navigator = webidl.createBranded(Navigator); - let numCpus, userAgent, language; +let numCpus, userAgent, language; - function setNumCpus(val) { - numCpus = val; - } +function setNumCpus(val) { + numCpus = val; +} - function setUserAgent(val) { - userAgent = val; - } +function setUserAgent(val) { + userAgent = val; +} - function setLanguage(val) { - language = val; - } +function setLanguage(val) { + language = val; +} - ObjectDefineProperties(Navigator.prototype, { - gpu: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, NavigatorPrototype); - return webgpu.gpu; - }, +ObjectDefineProperties(Navigator.prototype, { + gpu: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return webgpu.gpu; }, - hardwareConcurrency: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, NavigatorPrototype); - return numCpus; - }, + }, + hardwareConcurrency: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return numCpus; }, - userAgent: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, NavigatorPrototype); - return userAgent; - }, + }, + userAgent: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return userAgent; }, - language: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, NavigatorPrototype); - return language; - }, + }, + language: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return language; }, - languages: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, NavigatorPrototype); - return [language]; - }, + }, + languages: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return [language]; }, - }); - const NavigatorPrototype = Navigator.prototype; + }, +}); +const NavigatorPrototype = Navigator.prototype; - class WorkerNavigator { - constructor() { - webidl.illegalConstructor(); - } +class WorkerNavigator { + constructor() { + webidl.illegalConstructor(); + } - [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect({})}`; - } + [SymbolFor("Deno.privateCustomInspect")](inspect) { + return `${this.constructor.name} ${inspect({})}`; } +} - const workerNavigator = webidl.createBranded(WorkerNavigator); +const workerNavigator = webidl.createBranded(WorkerNavigator); - ObjectDefineProperties(WorkerNavigator.prototype, { - gpu: { +ObjectDefineProperties(WorkerNavigator.prototype, { + gpu: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, WorkerNavigatorPrototype); + return webgpu.gpu; + }, + }, + hardwareConcurrency: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, WorkerNavigatorPrototype); + return numCpus; + }, + language: { configurable: true, enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return webgpu.gpu; + return language; }, }, - hardwareConcurrency: { + languages: { configurable: true, enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return numCpus; - }, - language: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, WorkerNavigatorPrototype); - return language; - }, - }, - languages: { - configurable: true, - enumerable: true, - get() { - webidl.assertBranded(this, WorkerNavigatorPrototype); - return [language]; - }, + return [language]; }, }, - }); - const WorkerNavigatorPrototype = WorkerNavigator.prototype; - - const mainRuntimeGlobalProperties = { - Location: location.locationConstructorDescriptor, - location: location.locationDescriptor, - Window: globalInterfaces.windowConstructorDescriptor, - window: util.getterOnly(() => globalThis), - self: util.getterOnly(() => globalThis), - Navigator: util.nonEnumerable(Navigator), - navigator: util.getterOnly(() => navigator), - alert: util.writable(prompt.alert), - confirm: util.writable(prompt.confirm), - prompt: util.writable(prompt.prompt), - localStorage: util.getterOnly(webStorage.localStorage), - sessionStorage: util.getterOnly(webStorage.sessionStorage), - Storage: util.nonEnumerable(webStorage.Storage), - }; + }, +}); +const WorkerNavigatorPrototype = WorkerNavigator.prototype; - const workerRuntimeGlobalProperties = { - WorkerLocation: location.workerLocationConstructorDescriptor, - location: location.workerLocationDescriptor, - WorkerGlobalScope: globalInterfaces.workerGlobalScopeConstructorDescriptor, - DedicatedWorkerGlobalScope: - globalInterfaces.dedicatedWorkerGlobalScopeConstructorDescriptor, - WorkerNavigator: util.nonEnumerable(WorkerNavigator), - navigator: util.getterOnly(() => workerNavigator), - self: util.getterOnly(() => globalThis), - }; +const mainRuntimeGlobalProperties = { + Location: location.locationConstructorDescriptor, + location: location.locationDescriptor, + Window: globalInterfaces.windowConstructorDescriptor, + window: util.getterOnly(() => globalThis), + self: util.getterOnly(() => globalThis), + Navigator: util.nonEnumerable(Navigator), + navigator: util.getterOnly(() => navigator), + alert: util.writable(prompt.alert), + confirm: util.writable(prompt.confirm), + prompt: util.writable(prompt.prompt), + localStorage: util.getterOnly(webStorage.localStorage), + sessionStorage: util.getterOnly(webStorage.sessionStorage), + Storage: util.nonEnumerable(webStorage.Storage), +}; - window.__bootstrap.globalScope = { - windowOrWorkerGlobalScope, - unstableWindowOrWorkerGlobalScope, - mainRuntimeGlobalProperties, - workerRuntimeGlobalProperties, +const workerRuntimeGlobalProperties = { + WorkerLocation: location.workerLocationConstructorDescriptor, + location: location.workerLocationDescriptor, + WorkerGlobalScope: globalInterfaces.workerGlobalScopeConstructorDescriptor, + DedicatedWorkerGlobalScope: + globalInterfaces.dedicatedWorkerGlobalScopeConstructorDescriptor, + WorkerNavigator: util.nonEnumerable(WorkerNavigator), + navigator: util.getterOnly(() => workerNavigator), + self: util.getterOnly(() => globalThis), +}; - setNumCpus, - setUserAgent, - setLanguage, - }; -})(this); +export { + mainRuntimeGlobalProperties, + setLanguage, + setNumCpus, + setUserAgent, + unstableWindowOrWorkerGlobalScope, + windowOrWorkerGlobalScope, + workerRuntimeGlobalProperties, +}; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index e1d089bc5..797007168 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -1,5 +1,4 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; // Removes the `__proto__` for security reasons. // https://tc39.es/ecma262/#sec-get-object.prototype.__proto__ @@ -8,678 +7,677 @@ delete Object.prototype.__proto__; // Remove Intl.v8BreakIterator because it is a non-standard API. delete Intl.v8BreakIterator; -((window) => { - const core = Deno.core; - const ops = core.ops; - const { - ArrayPrototypeIndexOf, - ArrayPrototypePush, - ArrayPrototypeShift, - ArrayPrototypeSplice, - ArrayPrototypeMap, - DateNow, - Error, - ErrorPrototype, - FunctionPrototypeCall, - FunctionPrototypeBind, - ObjectAssign, - ObjectDefineProperty, - ObjectDefineProperties, - ObjectFreeze, - ObjectPrototypeIsPrototypeOf, - ObjectSetPrototypeOf, - PromiseResolve, - Symbol, - SymbolFor, - SymbolIterator, - PromisePrototypeThen, - SafeWeakMap, - TypeError, - WeakMapPrototypeDelete, - WeakMapPrototypeGet, - WeakMapPrototypeSet, - } = window.__bootstrap.primordials; - const util = window.__bootstrap.util; - const event = window.__bootstrap.event; - const eventTarget = window.__bootstrap.eventTarget; - const location = window.__bootstrap.location; - const build = window.__bootstrap.build; - const version = window.__bootstrap.version; - const os = window.__bootstrap.os; - const timers = window.__bootstrap.timers; - const colors = window.__bootstrap.colors; - const inspectArgs = window.__bootstrap.console.inspectArgs; - const quoteString = window.__bootstrap.console.quoteString; - const internals = window.__bootstrap.internals; - const performance = window.__bootstrap.performance; - const url = window.__bootstrap.url; - const fetch = window.__bootstrap.fetch; - const messagePort = window.__bootstrap.messagePort; - const denoNs = window.__bootstrap.denoNs; - const denoNsUnstable = window.__bootstrap.denoNsUnstable; - const errors = window.__bootstrap.errors.errors; - const webidl = window.__bootstrap.webidl; - const domException = window.__bootstrap.domException; - const { defineEventHandler, reportException } = window.__bootstrap.event; - const { deserializeJsMessageData, serializeJsMessageData } = - window.__bootstrap.messagePort; - const { - windowOrWorkerGlobalScope, - unstableWindowOrWorkerGlobalScope, - workerRuntimeGlobalProperties, - mainRuntimeGlobalProperties, - setNumCpus, - setUserAgent, - setLanguage, - } = window.__bootstrap.globalScope; - - let windowIsClosing = false; - - function windowClose() { - if (!windowIsClosing) { - windowIsClosing = true; - // Push a macrotask to exit after a promise resolve. - // This is not perfect, but should be fine for first pass. - PromisePrototypeThen( - PromiseResolve(), - () => - FunctionPrototypeCall(timers.setTimeout, null, () => { - // This should be fine, since only Window/MainWorker has .close() - os.exit(0); - }, 0), - ); - } +const core = globalThis.Deno.core; +const ops = core.ops; +const internals = globalThis.__bootstrap.internals; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayPrototypeIndexOf, + ArrayPrototypePush, + ArrayPrototypeShift, + ArrayPrototypeSplice, + ArrayPrototypeMap, + DateNow, + Error, + ErrorPrototype, + FunctionPrototypeCall, + FunctionPrototypeBind, + ObjectAssign, + ObjectDefineProperty, + ObjectDefineProperties, + ObjectFreeze, + ObjectPrototypeIsPrototypeOf, + ObjectSetPrototypeOf, + PromiseResolve, + Symbol, + SymbolFor, + SymbolIterator, + PromisePrototypeThen, + SafeWeakMap, + TypeError, + WeakMapPrototypeDelete, + WeakMapPrototypeGet, + WeakMapPrototypeSet, +} = primordials; +import * as util from "internal:runtime/js/06_util.js"; +import * as event from "internal:ext/web/02_event.js"; +import * as location from "internal:ext/web/12_location.js"; +import * as build from "internal:runtime/js/01_build.js"; +import * as version from "internal:runtime/js/01_version.js"; +import * as os from "internal:runtime/js/30_os.js"; +import * as timers from "internal:ext/web/02_timers.js"; +import * as colors from "internal:ext/console/01_colors.js"; +import * as net from "internal:ext/net/01_net.js"; +import { + inspectArgs, + quoteString, + wrapConsole, +} from "internal:ext/console/02_console.js"; +import * as performance from "internal:ext/web/15_performance.js"; +import * as url from "internal:ext/url/00_url.js"; +import * as fetch from "internal:ext/fetch/26_fetch.js"; +import * as messagePort from "internal:ext/web/13_message_port.js"; +import { denoNs, denoNsUnstable } from "internal:runtime/js/90_deno_ns.js"; +import { errors } from "internal:runtime/js/01_errors.js"; +import * as webidl from "internal:ext/webidl/00_webidl.js"; +import DOMException from "internal:ext/web/01_dom_exception.js"; +import * as flash from "internal:ext/flash/01_http.js"; +import * as spawn from "internal:runtime/js/40_spawn.js"; +import { + mainRuntimeGlobalProperties, + setLanguage, + setNumCpus, + setUserAgent, + unstableWindowOrWorkerGlobalScope, + windowOrWorkerGlobalScope, + workerRuntimeGlobalProperties, +} from "internal:runtime/js/98_global_scope.js"; + +let windowIsClosing = false; +let globalThis_; + +function windowClose() { + if (!windowIsClosing) { + windowIsClosing = true; + // Push a macrotask to exit after a promise resolve. + // This is not perfect, but should be fine for first pass. + PromisePrototypeThen( + PromiseResolve(), + () => + FunctionPrototypeCall(timers.setTimeout, null, () => { + // This should be fine, since only Window/MainWorker has .close() + os.exit(0); + }, 0), + ); } +} - function workerClose() { - if (isClosing) { - return; - } - - isClosing = true; - ops.op_worker_close(); +function workerClose() { + if (isClosing) { + return; } - function postMessage(message, transferOrOptions = {}) { - const prefix = - "Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - message = webidl.converters.any(message); - let options; - if ( - webidl.type(transferOrOptions) === "Object" && - transferOrOptions !== undefined && - transferOrOptions[SymbolIterator] !== undefined - ) { - const transfer = webidl.converters["sequence<object>"]( - transferOrOptions, - { prefix, context: "Argument 2" }, - ); - options = { transfer }; - } else { - options = webidl.converters.StructuredSerializeOptions( - transferOrOptions, - { - prefix, - context: "Argument 2", - }, - ); - } - const { transfer } = options; - const data = serializeJsMessageData(message, transfer); - ops.op_worker_post_message(data); + isClosing = true; + ops.op_worker_close(); +} + +function postMessage(message, transferOrOptions = {}) { + const prefix = + "Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + message = webidl.converters.any(message); + let options; + if ( + webidl.type(transferOrOptions) === "Object" && + transferOrOptions !== undefined && + transferOrOptions[SymbolIterator] !== undefined + ) { + const transfer = webidl.converters["sequence<object>"]( + transferOrOptions, + { prefix, context: "Argument 2" }, + ); + options = { transfer }; + } else { + options = webidl.converters.StructuredSerializeOptions( + transferOrOptions, + { + prefix, + context: "Argument 2", + }, + ); } + const { transfer } = options; + const data = messagePort.serializeJsMessageData(message, transfer); + ops.op_worker_post_message(data); +} + +let isClosing = false; +let globalDispatchEvent; + +async function pollForMessages() { + if (!globalDispatchEvent) { + globalDispatchEvent = FunctionPrototypeBind( + globalThis.dispatchEvent, + globalThis, + ); + } + while (!isClosing) { + const data = await core.opAsync("op_worker_recv_message"); + if (data === null) break; + const v = messagePort.deserializeJsMessageData(data); + const message = v[0]; + const transferables = v[1]; + + const msgEvent = new event.MessageEvent("message", { + cancelable: false, + data: message, + ports: transferables.filter((t) => + ObjectPrototypeIsPrototypeOf(messagePort.MessagePortPrototype, t) + ), + }); - let isClosing = false; - let globalDispatchEvent; - - async function pollForMessages() { - if (!globalDispatchEvent) { - globalDispatchEvent = FunctionPrototypeBind( - globalThis.dispatchEvent, - globalThis, - ); - } - while (!isClosing) { - const data = await core.opAsync("op_worker_recv_message"); - if (data === null) break; - const v = deserializeJsMessageData(data); - const message = v[0]; - const transferables = v[1]; - - const msgEvent = new event.MessageEvent("message", { - cancelable: false, - data: message, - ports: transferables.filter((t) => - ObjectPrototypeIsPrototypeOf(messagePort.MessagePortPrototype, t) - ), + try { + globalDispatchEvent(msgEvent); + } catch (e) { + const errorEvent = new event.ErrorEvent("error", { + cancelable: true, + message: e.message, + lineno: e.lineNumber ? e.lineNumber + 1 : undefined, + colno: e.columnNumber ? e.columnNumber + 1 : undefined, + filename: e.fileName, + error: e, }); - try { - globalDispatchEvent(msgEvent); - } catch (e) { - const errorEvent = new event.ErrorEvent("error", { - cancelable: true, - message: e.message, - lineno: e.lineNumber ? e.lineNumber + 1 : undefined, - colno: e.columnNumber ? e.columnNumber + 1 : undefined, - filename: e.fileName, - error: e, - }); - - globalDispatchEvent(errorEvent); - if (!errorEvent.defaultPrevented) { - throw e; - } + globalDispatchEvent(errorEvent); + if (!errorEvent.defaultPrevented) { + throw e; } } } +} - let loadedMainWorkerScript = false; - - function importScripts(...urls) { - if (ops.op_worker_get_type() === "module") { - throw new TypeError("Can't import scripts in a module worker."); - } +let loadedMainWorkerScript = false; - const baseUrl = location.getLocationHref(); - const parsedUrls = ArrayPrototypeMap(urls, (scriptUrl) => { - try { - return new url.URL(scriptUrl, baseUrl ?? undefined).href; - } catch { - throw new domException.DOMException( - "Failed to parse URL.", - "SyntaxError", - ); - } - }); +function importScripts(...urls) { + if (ops.op_worker_get_type() === "module") { + throw new TypeError("Can't import scripts in a module worker."); + } - // A classic worker's main script has looser MIME type checks than any - // imported scripts, so we use `loadedMainWorkerScript` to distinguish them. - // TODO(andreubotella) Refactor worker creation so the main script isn't - // loaded with `importScripts()`. - const scripts = ops.op_worker_sync_fetch( - parsedUrls, - !loadedMainWorkerScript, - ); - loadedMainWorkerScript = true; + const baseUrl = location.getLocationHref(); + const parsedUrls = ArrayPrototypeMap(urls, (scriptUrl) => { + try { + return new url.URL(scriptUrl, baseUrl ?? undefined).href; + } catch { + throw new DOMException( + "Failed to parse URL.", + "SyntaxError", + ); + } + }); - for (let i = 0; i < scripts.length; ++i) { - const { url, script } = scripts[i]; - const err = core.evalContext(script, url)[1]; - if (err !== null) { - throw err.thrown; - } + // A classic worker's main script has looser MIME type checks than any + // imported scripts, so we use `loadedMainWorkerScript` to distinguish them. + // TODO(andreubotella) Refactor worker creation so the main script isn't + // loaded with `importScripts()`. + const scripts = ops.op_worker_sync_fetch( + parsedUrls, + !loadedMainWorkerScript, + ); + loadedMainWorkerScript = true; + + for (let i = 0; i < scripts.length; ++i) { + const { url, script } = scripts[i]; + const err = core.evalContext(script, url)[1]; + if (err !== null) { + throw err.thrown; } } - - function opMainModule() { - return ops.op_main_module(); +} + +function opMainModule() { + return ops.op_main_module(); +} + +function formatException(error) { + if (ObjectPrototypeIsPrototypeOf(ErrorPrototype, error)) { + return null; + } else if (typeof error == "string") { + return `Uncaught ${ + inspectArgs([quoteString(error)], { + colors: !colors.getNoColor(), + }) + }`; + } else { + return `Uncaught ${inspectArgs([error], { colors: !colors.getNoColor() })}`; } - - function formatException(error) { - if (ObjectPrototypeIsPrototypeOf(ErrorPrototype, error)) { - return null; - } else if (typeof error == "string") { - return `Uncaught ${ - inspectArgs([quoteString(error)], { - colors: !colors.getNoColor(), - }) - }`; - } else { - return `Uncaught ${ - inspectArgs([error], { colors: !colors.getNoColor() }) - }`; +} + +function runtimeStart(runtimeOptions, source) { + core.setMacrotaskCallback(timers.handleTimerMacrotask); + core.setMacrotaskCallback(promiseRejectMacrotaskCallback); + core.setWasmStreamingCallback(fetch.handleWasmStreaming); + core.setReportExceptionCallback(event.reportException); + ops.op_set_format_exception_callback(formatException); + version.setVersions( + runtimeOptions.denoVersion, + runtimeOptions.v8Version, + runtimeOptions.tsVersion, + ); + build.setBuildInfo(runtimeOptions.target); + util.setLogDebug(runtimeOptions.debugFlag, source); + colors.setNoColor(runtimeOptions.noColor || !runtimeOptions.isTty); + // deno-lint-ignore prefer-primordials + Error.prepareStackTrace = core.prepareStackTrace; + registerErrors(); +} + +function registerErrors() { + core.registerErrorClass("NotFound", errors.NotFound); + core.registerErrorClass("PermissionDenied", errors.PermissionDenied); + core.registerErrorClass("ConnectionRefused", errors.ConnectionRefused); + core.registerErrorClass("ConnectionReset", errors.ConnectionReset); + core.registerErrorClass("ConnectionAborted", errors.ConnectionAborted); + core.registerErrorClass("NotConnected", errors.NotConnected); + core.registerErrorClass("AddrInUse", errors.AddrInUse); + core.registerErrorClass("AddrNotAvailable", errors.AddrNotAvailable); + core.registerErrorClass("BrokenPipe", errors.BrokenPipe); + core.registerErrorClass("AlreadyExists", errors.AlreadyExists); + core.registerErrorClass("InvalidData", errors.InvalidData); + core.registerErrorClass("TimedOut", errors.TimedOut); + core.registerErrorClass("Interrupted", errors.Interrupted); + core.registerErrorClass("WriteZero", errors.WriteZero); + core.registerErrorClass("UnexpectedEof", errors.UnexpectedEof); + core.registerErrorClass("BadResource", errors.BadResource); + core.registerErrorClass("Http", errors.Http); + core.registerErrorClass("Busy", errors.Busy); + core.registerErrorClass("NotSupported", errors.NotSupported); + core.registerErrorBuilder( + "DOMExceptionOperationError", + function DOMExceptionOperationError(msg) { + return new DOMException(msg, "OperationError"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionQuotaExceededError", + function DOMExceptionQuotaExceededError(msg) { + return new DOMException(msg, "QuotaExceededError"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionNotSupportedError", + function DOMExceptionNotSupportedError(msg) { + return new DOMException(msg, "NotSupported"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionNetworkError", + function DOMExceptionNetworkError(msg) { + return new DOMException(msg, "NetworkError"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionAbortError", + function DOMExceptionAbortError(msg) { + return new DOMException(msg, "AbortError"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionInvalidCharacterError", + function DOMExceptionInvalidCharacterError(msg) { + return new DOMException(msg, "InvalidCharacterError"); + }, + ); + core.registerErrorBuilder( + "DOMExceptionDataError", + function DOMExceptionDataError(msg) { + return new DOMException(msg, "DataError"); + }, + ); +} + +const pendingRejections = []; +const pendingRejectionsReasons = new SafeWeakMap(); + +function promiseRejectCallback(type, promise, reason) { + switch (type) { + case 0: { + ops.op_store_pending_promise_rejection(promise, reason); + ArrayPrototypePush(pendingRejections, promise); + WeakMapPrototypeSet(pendingRejectionsReasons, promise, reason); + break; } + case 1: { + ops.op_remove_pending_promise_rejection(promise); + const index = ArrayPrototypeIndexOf(pendingRejections, promise); + if (index > -1) { + ArrayPrototypeSplice(pendingRejections, index, 1); + WeakMapPrototypeDelete(pendingRejectionsReasons, promise); + } + break; + } + default: + return false; } - function runtimeStart(runtimeOptions, source) { - core.setMacrotaskCallback(timers.handleTimerMacrotask); - core.setMacrotaskCallback(promiseRejectMacrotaskCallback); - core.setWasmStreamingCallback(fetch.handleWasmStreaming); - core.setReportExceptionCallback(reportException); - ops.op_set_format_exception_callback(formatException); - version.setVersions( - runtimeOptions.denoVersion, - runtimeOptions.v8Version, - runtimeOptions.tsVersion, - ); - build.setBuildInfo(runtimeOptions.target); - util.setLogDebug(runtimeOptions.debugFlag, source); - colors.setNoColor(runtimeOptions.noColor || !runtimeOptions.isTty); - // deno-lint-ignore prefer-primordials - Error.prepareStackTrace = core.prepareStackTrace; - registerErrors(); - } + return !!globalThis_.onunhandledrejection || + event.listenerCount(globalThis_, "unhandledrejection") > 0; +} - function registerErrors() { - core.registerErrorClass("NotFound", errors.NotFound); - core.registerErrorClass("PermissionDenied", errors.PermissionDenied); - core.registerErrorClass("ConnectionRefused", errors.ConnectionRefused); - core.registerErrorClass("ConnectionReset", errors.ConnectionReset); - core.registerErrorClass("ConnectionAborted", errors.ConnectionAborted); - core.registerErrorClass("NotConnected", errors.NotConnected); - core.registerErrorClass("AddrInUse", errors.AddrInUse); - core.registerErrorClass("AddrNotAvailable", errors.AddrNotAvailable); - core.registerErrorClass("BrokenPipe", errors.BrokenPipe); - core.registerErrorClass("AlreadyExists", errors.AlreadyExists); - core.registerErrorClass("InvalidData", errors.InvalidData); - core.registerErrorClass("TimedOut", errors.TimedOut); - core.registerErrorClass("Interrupted", errors.Interrupted); - core.registerErrorClass("WriteZero", errors.WriteZero); - core.registerErrorClass("UnexpectedEof", errors.UnexpectedEof); - core.registerErrorClass("BadResource", errors.BadResource); - core.registerErrorClass("Http", errors.Http); - core.registerErrorClass("Busy", errors.Busy); - core.registerErrorClass("NotSupported", errors.NotSupported); - core.registerErrorBuilder( - "DOMExceptionOperationError", - function DOMExceptionOperationError(msg) { - return new domException.DOMException(msg, "OperationError"); - }, - ); - core.registerErrorBuilder( - "DOMExceptionQuotaExceededError", - function DOMExceptionQuotaExceededError(msg) { - return new domException.DOMException(msg, "QuotaExceededError"); - }, +function promiseRejectMacrotaskCallback() { + while (pendingRejections.length > 0) { + const promise = ArrayPrototypeShift(pendingRejections); + const hasPendingException = ops.op_has_pending_promise_rejection( + promise, ); - core.registerErrorBuilder( - "DOMExceptionNotSupportedError", - function DOMExceptionNotSupportedError(msg) { - return new domException.DOMException(msg, "NotSupported"); - }, - ); - core.registerErrorBuilder( - "DOMExceptionNetworkError", - function DOMExceptionNetworkError(msg) { - return new domException.DOMException(msg, "NetworkError"); - }, - ); - core.registerErrorBuilder( - "DOMExceptionAbortError", - function DOMExceptionAbortError(msg) { - return new domException.DOMException(msg, "AbortError"); - }, - ); - core.registerErrorBuilder( - "DOMExceptionInvalidCharacterError", - function DOMExceptionInvalidCharacterError(msg) { - return new domException.DOMException(msg, "InvalidCharacterError"); - }, - ); - core.registerErrorBuilder( - "DOMExceptionDataError", - function DOMExceptionDataError(msg) { - return new domException.DOMException(msg, "DataError"); + const reason = WeakMapPrototypeGet(pendingRejectionsReasons, promise); + WeakMapPrototypeDelete(pendingRejectionsReasons, promise); + + if (!hasPendingException) { + continue; + } + + const rejectionEvent = new event.PromiseRejectionEvent( + "unhandledrejection", + { + cancelable: true, + promise, + reason, }, ); - } - - const pendingRejections = []; - const pendingRejectionsReasons = new SafeWeakMap(); - function promiseRejectCallback(type, promise, reason) { - switch (type) { - case 0: { - ops.op_store_pending_promise_rejection(promise, reason); - ArrayPrototypePush(pendingRejections, promise); - WeakMapPrototypeSet(pendingRejectionsReasons, promise, reason); - break; - } - case 1: { + const errorEventCb = (event) => { + if (event.error === reason) { ops.op_remove_pending_promise_rejection(promise); - const index = ArrayPrototypeIndexOf(pendingRejections, promise); - if (index > -1) { - ArrayPrototypeSplice(pendingRejections, index, 1); - WeakMapPrototypeDelete(pendingRejectionsReasons, promise); - } - break; } - default: - return false; + }; + // Add a callback for "error" event - it will be dispatched + // if error is thrown during dispatch of "unhandledrejection" + // event. + globalThis_.addEventListener("error", errorEventCb); + globalThis_.dispatchEvent(rejectionEvent); + globalThis_.removeEventListener("error", errorEventCb); + + // If event was not prevented (or "unhandledrejection" listeners didn't + // throw) we will let Rust side handle it. + if (rejectionEvent.defaultPrevented) { + ops.op_remove_pending_promise_rejection(promise); } + } + return true; +} + +let hasBootstrapped = false; - return !!globalThis.onunhandledrejection || - eventTarget.listenerCount(globalThis, "unhandledrejection") > 0; +function bootstrapMainRuntime(runtimeOptions) { + if (hasBootstrapped) { + throw new Error("Worker runtime already bootstrapped"); } - function promiseRejectMacrotaskCallback() { - while (pendingRejections.length > 0) { - const promise = ArrayPrototypeShift(pendingRejections); - const hasPendingException = ops.op_has_pending_promise_rejection( - promise, - ); - const reason = WeakMapPrototypeGet(pendingRejectionsReasons, promise); - WeakMapPrototypeDelete(pendingRejectionsReasons, promise); + core.initializeAsyncOps(); + performance.setTimeOrigin(DateNow()); + globalThis_ = globalThis; - if (!hasPendingException) { - continue; - } + const consoleFromV8 = globalThis.Deno.core.console; - const rejectionEvent = new event.PromiseRejectionEvent( - "unhandledrejection", - { - cancelable: true, - promise, - reason, - }, - ); + // Remove bootstrapping data from the global scope + delete globalThis.__bootstrap; + delete globalThis.bootstrap; + util.log("bootstrapMainRuntime"); + hasBootstrapped = true; - const errorEventCb = (event) => { - if (event.error === reason) { - ops.op_remove_pending_promise_rejection(promise); - } - }; - // Add a callback for "error" event - it will be dispatched - // if error is thrown during dispatch of "unhandledrejection" - // event. - globalThis.addEventListener("error", errorEventCb); - globalThis.dispatchEvent(rejectionEvent); - globalThis.removeEventListener("error", errorEventCb); - - // If event was not prevented (or "unhandledrejection" listeners didn't - // throw) we will let Rust side handle it. - if (rejectionEvent.defaultPrevented) { - ops.op_remove_pending_promise_rejection(promise); - } - } - return true; + // If the `--location` flag isn't set, make `globalThis.location` `undefined` and + // writable, so that they can mock it themselves if they like. If the flag was + // set, define `globalThis.location`, using the provided value. + if (runtimeOptions.location == null) { + mainRuntimeGlobalProperties.location = { + writable: true, + }; + } else { + location.setLocationHref(runtimeOptions.location); } - let hasBootstrapped = false; + ObjectDefineProperties(globalThis, windowOrWorkerGlobalScope); + if (runtimeOptions.unstableFlag) { + ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope); + } + ObjectDefineProperties(globalThis, mainRuntimeGlobalProperties); + ObjectDefineProperties(globalThis, { + close: util.writable(windowClose), + closed: util.getterOnly(() => windowIsClosing), + }); + ObjectSetPrototypeOf(globalThis, Window.prototype); - function bootstrapMainRuntime(runtimeOptions) { - if (hasBootstrapped) { - throw new Error("Worker runtime already bootstrapped"); - } + if (runtimeOptions.inspectFlag) { + const consoleFromDeno = globalThis.console; + wrapConsole(consoleFromDeno, consoleFromV8); + } - core.initializeAsyncOps(); - performance.setTimeOrigin(DateNow()); - - const consoleFromV8 = window.Deno.core.console; - const wrapConsole = window.__bootstrap.console.wrapConsole; - - // Remove bootstrapping data from the global scope - const __bootstrap = globalThis.__bootstrap; - delete globalThis.__bootstrap; - delete globalThis.bootstrap; - util.log("bootstrapMainRuntime"); - hasBootstrapped = true; - - // If the `--location` flag isn't set, make `globalThis.location` `undefined` and - // writable, so that they can mock it themselves if they like. If the flag was - // set, define `globalThis.location`, using the provided value. - if (runtimeOptions.location == null) { - mainRuntimeGlobalProperties.location = { - writable: true, - }; - } else { - location.setLocationHref(runtimeOptions.location); - } + event.setEventTargetData(globalThis); + event.saveGlobalThisReference(globalThis); - ObjectDefineProperties(globalThis, windowOrWorkerGlobalScope); - if (runtimeOptions.unstableFlag) { - ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope); - } - ObjectDefineProperties(globalThis, mainRuntimeGlobalProperties); - ObjectDefineProperties(globalThis, { - close: util.writable(windowClose), - closed: util.getterOnly(() => windowIsClosing), - }); - ObjectSetPrototypeOf(globalThis, Window.prototype); + event.defineEventHandler(globalThis, "error"); + event.defineEventHandler(globalThis, "load"); + event.defineEventHandler(globalThis, "beforeunload"); + event.defineEventHandler(globalThis, "unload"); + event.defineEventHandler(globalThis, "unhandledrejection"); - if (runtimeOptions.inspectFlag) { - const consoleFromDeno = globalThis.console; - wrapConsole(consoleFromDeno, consoleFromV8); - } + core.setPromiseRejectCallback(promiseRejectCallback); - eventTarget.setEventTargetData(globalThis); + const isUnloadDispatched = SymbolFor("isUnloadDispatched"); + // Stores the flag for checking whether unload is dispatched or not. + // This prevents the recursive dispatches of unload events. + // See https://github.com/denoland/deno/issues/9201. + globalThis[isUnloadDispatched] = false; + globalThis.addEventListener("unload", () => { + globalThis_[isUnloadDispatched] = true; + }); - defineEventHandler(window, "error"); - defineEventHandler(window, "load"); - defineEventHandler(window, "beforeunload"); - defineEventHandler(window, "unload"); - defineEventHandler(window, "unhandledrejection"); + runtimeStart(runtimeOptions); - core.setPromiseRejectCallback(promiseRejectCallback); + setNumCpus(runtimeOptions.cpuCount); + setUserAgent(runtimeOptions.userAgent); + setLanguage(runtimeOptions.locale); - const isUnloadDispatched = SymbolFor("isUnloadDispatched"); - // Stores the flag for checking whether unload is dispatched or not. - // This prevents the recursive dispatches of unload events. - // See https://github.com/denoland/deno/issues/9201. - window[isUnloadDispatched] = false; - window.addEventListener("unload", () => { - window[isUnloadDispatched] = true; - }); + const internalSymbol = Symbol("Deno.internal"); - runtimeStart(runtimeOptions); + // These have to initialized here and not in `90_deno_ns.js` because + // the op function that needs to be passed will be invalidated by creating + // a snapshot + ObjectAssign(internals, { + nodeUnstable: { + Command: spawn.createCommand( + spawn.createSpawn(ops.op_node_unstable_spawn_child), + spawn.createSpawnSync( + ops.op_node_unstable_spawn_sync, + ), + spawn.createSpawnChild( + ops.op_node_unstable_spawn_child, + ), + ), + serve: flash.createServe(ops.op_node_unstable_flash_serve), + upgradeHttpRaw: flash.upgradeHttpRaw, + listenDatagram: net.createListenDatagram( + ops.op_node_unstable_net_listen_udp, + ops.op_node_unstable_net_listen_unixpacket, + ), + osUptime: os.createOsUptime(ops.op_node_unstable_os_uptime), + }, + }); - setNumCpus(runtimeOptions.cpuCount); - setUserAgent(runtimeOptions.userAgent); - setLanguage(runtimeOptions.locale); + // FIXME(bartlomieju): temporarily add whole `Deno.core` to + // `Deno[Deno.internal]` namespace. It should be removed and only necessary + // methods should be left there. + ObjectAssign(internals, { + core, + }); - const internalSymbol = Symbol("Deno.internal"); + const finalDenoNs = { + internal: internalSymbol, + [internalSymbol]: internals, + resources: core.resources, + close: core.close, + ...denoNs, + }; + ObjectDefineProperties(finalDenoNs, { + pid: util.readOnly(runtimeOptions.pid), + ppid: util.readOnly(runtimeOptions.ppid), + noColor: util.readOnly(runtimeOptions.noColor), + args: util.readOnly(ObjectFreeze(runtimeOptions.args)), + mainModule: util.getterOnly(opMainModule), + }); + if (runtimeOptions.unstableFlag) { + ObjectAssign(finalDenoNs, denoNsUnstable); // These have to initialized here and not in `90_deno_ns.js` because // the op function that needs to be passed will be invalidated by creating // a snapshot - ObjectAssign(internals, { - nodeUnstable: { - Command: __bootstrap.spawn.createCommand( - __bootstrap.spawn.createSpawn(ops.op_node_unstable_spawn_child), - __bootstrap.spawn.createSpawnSync( - ops.op_node_unstable_spawn_sync, - ), - __bootstrap.spawn.createSpawnChild( - ops.op_node_unstable_spawn_child, - ), - ), - serve: __bootstrap.flash.createServe(ops.op_node_unstable_flash_serve), - upgradeHttpRaw: __bootstrap.flash.upgradeHttpRaw, - listenDatagram: __bootstrap.net.createListenDatagram( - ops.op_node_unstable_net_listen_udp, - ops.op_node_unstable_net_listen_unixpacket, - ), - osUptime: __bootstrap.os.createOsUptime(ops.op_node_unstable_os_uptime), - }, + ObjectAssign(finalDenoNs, { + Command: spawn.createCommand( + spawn.createSpawn(ops.op_spawn_child), + spawn.createSpawnSync(ops.op_spawn_sync), + spawn.createSpawnChild(ops.op_spawn_child), + ), + serve: flash.createServe(ops.op_flash_serve), + listenDatagram: net.createListenDatagram( + ops.op_net_listen_udp, + ops.op_net_listen_unixpacket, + ), + osUptime: os.createOsUptime(ops.op_os_uptime), }); + } - // FIXME(bartlomieju): temporarily add whole `Deno.core` to - // `Deno[Deno.internal]` namespace. It should be removed and only necessary - // methods should be left there. - ObjectAssign(internals, { - core, - }); + // Setup `Deno` global - we're actually overriding already existing global + // `Deno` with `Deno` namespace from "./deno.ts". + ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); - const finalDenoNs = { - internal: internalSymbol, - [internalSymbol]: internals, - resources: core.resources, - close: core.close, - ...denoNs, - }; - ObjectDefineProperties(finalDenoNs, { - pid: util.readOnly(runtimeOptions.pid), - ppid: util.readOnly(runtimeOptions.ppid), - noColor: util.readOnly(runtimeOptions.noColor), - args: util.readOnly(ObjectFreeze(runtimeOptions.args)), - mainModule: util.getterOnly(opMainModule), - }); + util.log("args", runtimeOptions.args); +} - if (runtimeOptions.unstableFlag) { - ObjectAssign(finalDenoNs, denoNsUnstable); - // These have to initialized here and not in `90_deno_ns.js` because - // the op function that needs to be passed will be invalidated by creating - // a snapshot - ObjectAssign(finalDenoNs, { - Command: __bootstrap.spawn.createCommand( - __bootstrap.spawn.createSpawn(ops.op_spawn_child), - __bootstrap.spawn.createSpawnSync(ops.op_spawn_sync), - __bootstrap.spawn.createSpawnChild(ops.op_spawn_child), - ), - serve: __bootstrap.flash.createServe(ops.op_flash_serve), - listenDatagram: __bootstrap.net.createListenDatagram( - ops.op_net_listen_udp, - ops.op_net_listen_unixpacket, - ), - osUptime: __bootstrap.os.createOsUptime(ops.op_os_uptime), - }); - } +function bootstrapWorkerRuntime( + runtimeOptions, + name, + internalName, +) { + if (hasBootstrapped) { + throw new Error("Worker runtime already bootstrapped"); + } + + core.initializeAsyncOps(); + performance.setTimeOrigin(DateNow()); + globalThis_ = globalThis; - // Setup `Deno` global - we're actually overriding already existing global - // `Deno` with `Deno` namespace from "./deno.ts". - ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); + const consoleFromV8 = globalThis.Deno.core.console; - util.log("args", runtimeOptions.args); + // Remove bootstrapping data from the global scope + delete globalThis.__bootstrap; + delete globalThis.bootstrap; + util.log("bootstrapWorkerRuntime"); + hasBootstrapped = true; + ObjectDefineProperties(globalThis, windowOrWorkerGlobalScope); + if (runtimeOptions.unstableFlag) { + ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope); + } + ObjectDefineProperties(globalThis, workerRuntimeGlobalProperties); + ObjectDefineProperties(globalThis, { + name: util.writable(name), + // TODO(bartlomieju): should be readonly? + close: util.nonEnumerable(workerClose), + postMessage: util.writable(postMessage), + }); + if (runtimeOptions.enableTestingFeaturesFlag) { + ObjectDefineProperty( + globalThis, + "importScripts", + util.writable(importScripts), + ); } + ObjectSetPrototypeOf(globalThis, DedicatedWorkerGlobalScope.prototype); - function bootstrapWorkerRuntime( - runtimeOptions, - name, - internalName, - ) { - if (hasBootstrapped) { - throw new Error("Worker runtime already bootstrapped"); - } + const consoleFromDeno = globalThis.console; + wrapConsole(consoleFromDeno, consoleFromV8); - core.initializeAsyncOps(); - performance.setTimeOrigin(DateNow()); - - const consoleFromV8 = window.Deno.core.console; - const wrapConsole = window.__bootstrap.console.wrapConsole; - - // Remove bootstrapping data from the global scope - const __bootstrap = globalThis.__bootstrap; - delete globalThis.__bootstrap; - delete globalThis.bootstrap; - util.log("bootstrapWorkerRuntime"); - hasBootstrapped = true; - ObjectDefineProperties(globalThis, windowOrWorkerGlobalScope); - if (runtimeOptions.unstableFlag) { - ObjectDefineProperties(globalThis, unstableWindowOrWorkerGlobalScope); - } - ObjectDefineProperties(globalThis, workerRuntimeGlobalProperties); - ObjectDefineProperties(globalThis, { - name: util.writable(name), - // TODO(bartlomieju): should be readonly? - close: util.nonEnumerable(workerClose), - postMessage: util.writable(postMessage), - }); - if (runtimeOptions.enableTestingFeaturesFlag) { - ObjectDefineProperty( - globalThis, - "importScripts", - util.writable(importScripts), - ); - } - ObjectSetPrototypeOf(globalThis, DedicatedWorkerGlobalScope.prototype); + event.setEventTargetData(globalThis); + event.saveGlobalThisReference(globalThis); - const consoleFromDeno = globalThis.console; - wrapConsole(consoleFromDeno, consoleFromV8); + event.defineEventHandler(self, "message"); + event.defineEventHandler(self, "error", undefined, true); + event.defineEventHandler(self, "unhandledrejection"); - eventTarget.setEventTargetData(globalThis); + core.setPromiseRejectCallback(promiseRejectCallback); - defineEventHandler(self, "message"); - defineEventHandler(self, "error", undefined, true); - defineEventHandler(self, "unhandledrejection"); + // `Deno.exit()` is an alias to `self.close()`. Setting and exit + // code using an op in worker context is a no-op. + os.setExitHandler((_exitCode) => { + workerClose(); + }); - core.setPromiseRejectCallback(promiseRejectCallback); + runtimeStart( + runtimeOptions, + internalName ?? name, + ); - // `Deno.exit()` is an alias to `self.close()`. Setting and exit - // code using an op in worker context is a no-op. - os.setExitHandler((_exitCode) => { - workerClose(); - }); + location.setLocationHref(runtimeOptions.location); - runtimeStart( - runtimeOptions, - internalName ?? name, - ); + setNumCpus(runtimeOptions.cpuCount); + setLanguage(runtimeOptions.locale); - location.setLocationHref(runtimeOptions.location); + globalThis.pollForMessages = pollForMessages; - setNumCpus(runtimeOptions.cpuCount); - setLanguage(runtimeOptions.locale); + const internalSymbol = Symbol("Deno.internal"); - globalThis.pollForMessages = pollForMessages; + // These have to initialized here and not in `90_deno_ns.js` because + // the op function that needs to be passed will be invalidated by creating + // a snapshot + ObjectAssign(internals, { + nodeUnstable: { + Command: spawn.createCommand( + spawn.createSpawn(ops.op_node_unstable_spawn_child), + spawn.createSpawnSync( + ops.op_node_unstable_spawn_sync, + ), + spawn.createSpawnChild( + ops.op_node_unstable_spawn_child, + ), + ), + serve: flash.createServe(ops.op_node_unstable_flash_serve), + upgradeHttpRaw: flash.upgradeHttpRaw, + listenDatagram: net.createListenDatagram( + ops.op_node_unstable_net_listen_udp, + ops.op_node_unstable_net_listen_unixpacket, + ), + osUptime: os.createOsUptime(ops.op_node_unstable_os_uptime), + }, + }); - const internalSymbol = Symbol("Deno.internal"); + // FIXME(bartlomieju): temporarily add whole `Deno.core` to + // `Deno[Deno.internal]` namespace. It should be removed and only necessary + // methods should be left there. + ObjectAssign(internals, { + core, + }); + const finalDenoNs = { + internal: internalSymbol, + [internalSymbol]: internals, + resources: core.resources, + close: core.close, + ...denoNs, + }; + if (runtimeOptions.unstableFlag) { + ObjectAssign(finalDenoNs, denoNsUnstable); // These have to initialized here and not in `90_deno_ns.js` because // the op function that needs to be passed will be invalidated by creating // a snapshot - ObjectAssign(internals, { - nodeUnstable: { - Command: __bootstrap.spawn.createCommand( - __bootstrap.spawn.createSpawn(ops.op_node_unstable_spawn_child), - __bootstrap.spawn.createSpawnSync( - ops.op_node_unstable_spawn_sync, - ), - __bootstrap.spawn.createSpawnChild( - ops.op_node_unstable_spawn_child, - ), - ), - serve: __bootstrap.flash.createServe(ops.op_node_unstable_flash_serve), - upgradeHttpRaw: __bootstrap.flash.upgradeHttpRaw, - listenDatagram: __bootstrap.net.createListenDatagram( - ops.op_node_unstable_net_listen_udp, - ops.op_node_unstable_net_listen_unixpacket, - ), - osUptime: __bootstrap.os.createOsUptime(ops.op_node_unstable_os_uptime), - }, - }); - - // FIXME(bartlomieju): temporarily add whole `Deno.core` to - // `Deno[Deno.internal]` namespace. It should be removed and only necessary - // methods should be left there. - ObjectAssign(internals, { - core, - }); - - const finalDenoNs = { - internal: internalSymbol, - [internalSymbol]: internals, - resources: core.resources, - close: core.close, - ...denoNs, - }; - if (runtimeOptions.unstableFlag) { - ObjectAssign(finalDenoNs, denoNsUnstable); - // These have to initialized here and not in `90_deno_ns.js` because - // the op function that needs to be passed will be invalidated by creating - // a snapshot - ObjectAssign(finalDenoNs, { - Command: __bootstrap.spawn.createCommand( - __bootstrap.spawn.createSpawn(ops.op_spawn_child), - __bootstrap.spawn.createSpawnSync(ops.op_spawn_sync), - __bootstrap.spawn.createSpawnChild(ops.op_spawn_child), - ), - serve: __bootstrap.flash.createServe(ops.op_flash_serve), - listenDatagram: __bootstrap.net.createListenDatagram( - ops.op_net_listen_udp, - ops.op_net_listen_unixpacket, - ), - osUptime: __bootstrap.os.createOsUptime(ops.op_os_uptime), - }); - } - ObjectDefineProperties(finalDenoNs, { - pid: util.readOnly(runtimeOptions.pid), - noColor: util.readOnly(runtimeOptions.noColor), - args: util.readOnly(ObjectFreeze(runtimeOptions.args)), + ObjectAssign(finalDenoNs, { + Command: spawn.createCommand( + spawn.createSpawn(ops.op_spawn_child), + spawn.createSpawnSync(ops.op_spawn_sync), + spawn.createSpawnChild(ops.op_spawn_child), + ), + serve: flash.createServe(ops.op_flash_serve), + listenDatagram: net.createListenDatagram( + ops.op_net_listen_udp, + ops.op_net_listen_unixpacket, + ), + osUptime: os.createOsUptime(ops.op_os_uptime), }); - // Setup `Deno` global - we're actually overriding already - // existing global `Deno` with `Deno` namespace from "./deno.ts". - ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); } - - ObjectDefineProperties(globalThis, { - bootstrap: { - value: { - mainRuntime: bootstrapMainRuntime, - workerRuntime: bootstrapWorkerRuntime, - }, - configurable: true, - }, + ObjectDefineProperties(finalDenoNs, { + pid: util.readOnly(runtimeOptions.pid), + noColor: util.readOnly(runtimeOptions.noColor), + args: util.readOnly(ObjectFreeze(runtimeOptions.args)), }); -})(this); + // Setup `Deno` global - we're actually overriding already + // existing global `Deno` with `Deno` namespace from "./deno.ts". + ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); +} + +ObjectDefineProperties(globalThis, { + bootstrap: { + value: { + mainRuntime: bootstrapMainRuntime, + workerRuntime: bootstrapWorkerRuntime, + }, + configurable: true, + }, +}); |