From 1aac47720b8dad6826d59263f8e825c221f2a328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 6 Jul 2021 14:38:12 +0200 Subject: [PATCH] refactor: use primordials in extensions/web (#11273) Co-authored-by: Divy Srivastava --- core/internal.d.ts | 4 ++ extensions/web/02_structured_clone.js | 17 +++++++-- extensions/web/03_abort_signal.js | 23 ++++++++--- extensions/web/04_global_interfaces.js | 15 ++++++-- extensions/web/05_base64.js | 23 +++++++---- extensions/web/08_text_encoding.js | 53 +++++++++++++++++--------- extensions/web/12_location.js | 50 +++++++++++++++--------- 7 files changed, 131 insertions(+), 54 deletions(-) diff --git a/core/internal.d.ts b/core/internal.d.ts index e582eb359c..6697f47155 100644 --- a/core/internal.d.ts +++ b/core/internal.d.ts @@ -834,6 +834,10 @@ declare namespace __bootstrap { export const TypeErrorLength: typeof TypeError.length; export const TypeErrorName: typeof TypeError.name; export const TypeErrorPrototype: typeof TypeError.prototype; + export const TypedArrayFrom: ( + constructor: Uint8ArrayConstructor, + arrayLike: ArrayLike, + ) => Uint8Array; export const TypedArrayPrototypeCopyWithin: UncurryThis< typeof Uint8Array.prototype.copyWithin >; diff --git a/extensions/web/02_structured_clone.js b/extensions/web/02_structured_clone.js index 265d89247d..4845c6508d 100644 --- a/extensions/web/02_structured_clone.js +++ b/extensions/web/02_structured_clone.js @@ -2,6 +2,7 @@ // @ts-check /// +/// /// /// @@ -10,6 +11,15 @@ ((window) => { const core = window.Deno.core; const { DOMException } = window.__bootstrap.domException; + const { + ArrayBuffer, + ArrayBufferIsView, + DataView, + TypedArrayPrototypeSlice, + TypeError, + WeakMap, + WeakMapPrototypeSet, + } = window.__bootstrap.primordials; const objectCloneMemo = new WeakMap(); @@ -20,7 +30,8 @@ _cloneConstructor, ) { // this function fudges the return type but SharedArrayBuffer is disabled for a while anyway - return srcBuffer.slice( + return TypedArrayPrototypeSlice( + srcBuffer, srcByteOffset, srcByteOffset + srcLength, ); @@ -38,10 +49,10 @@ value.byteLength, ArrayBuffer, ); - objectCloneMemo.set(value, cloned); + WeakMapPrototypeSet(objectCloneMemo, value, cloned); return cloned; } - if (ArrayBuffer.isView(value)) { + if (ArrayBufferIsView(value)) { const clonedBuffer = structuredClone(value.buffer); // Use DataViewConstructor type purely for type-checking, can be a // DataView or TypedArray. They use the same constructor signature, diff --git a/extensions/web/03_abort_signal.js b/extensions/web/03_abort_signal.js index 54a485dab1..d67bfef268 100644 --- a/extensions/web/03_abort_signal.js +++ b/extensions/web/03_abort_signal.js @@ -1,9 +1,22 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. "use strict"; +// @ts-check +/// + ((window) => { const webidl = window.__bootstrap.webidl; const { setIsTrusted, defineEventHandler } = window.__bootstrap.event; + const { + Boolean, + Set, + SetPrototypeAdd, + SetPrototypeClear, + SetPrototypeDelete, + Symbol, + SymbolToStringTag, + TypeError, + } = window.__bootstrap.primordials; const add = Symbol("add"); const signalAbort = Symbol("signalAbort"); @@ -22,7 +35,7 @@ } [add](algorithm) { - this.#abortAlgorithms.add(algorithm); + SetPrototypeAdd(this.#abortAlgorithms, algorithm); } [signalAbort]() { @@ -33,14 +46,14 @@ for (const algorithm of this.#abortAlgorithms) { algorithm(); } - this.#abortAlgorithms.clear(); + SetPrototypeClear(this.#abortAlgorithms); const event = new Event("abort"); setIsTrusted(event, true); this.dispatchEvent(event); } [remove](algorithm) { - this.#abortAlgorithms.delete(algorithm); + SetPrototypeDelete(this.#abortAlgorithms, algorithm); } constructor(key = null) { @@ -55,7 +68,7 @@ return Boolean(this.#aborted); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "AbortSignal"; } } @@ -74,7 +87,7 @@ this.#signal[signalAbort](); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "AbortController"; } } diff --git a/extensions/web/04_global_interfaces.js b/extensions/web/04_global_interfaces.js index c3181fb666..8117bface2 100644 --- a/extensions/web/04_global_interfaces.js +++ b/extensions/web/04_global_interfaces.js @@ -1,7 +1,16 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. "use strict"; + +// @ts-check +/// + ((window) => { const { EventTarget } = window; + const { + Symbol, + SymbolToStringTag, + TypeError, + } = window.__bootstrap.primordials; const illegalConstructorKey = Symbol("illegalConstructorKey"); @@ -13,7 +22,7 @@ super(); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "Window"; } } @@ -26,7 +35,7 @@ super(); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "WorkerGlobalScope"; } } @@ -39,7 +48,7 @@ super(); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "DedicatedWorkerGlobalScope"; } } diff --git a/extensions/web/05_base64.js b/extensions/web/05_base64.js index f0490f240b..818815ecde 100644 --- a/extensions/web/05_base64.js +++ b/extensions/web/05_base64.js @@ -1,6 +1,7 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. // @ts-check +/// /// /// /// @@ -14,6 +15,13 @@ forgivingBase64Decode, } = window.__bootstrap.infra; const { DOMException } = window.__bootstrap.domException; + const { + ArrayPrototypeMap, + StringPrototypeCharCodeAt, + ArrayPrototypeJoin, + StringFromCharCode, + TypedArrayFrom, + } = window.__bootstrap.primordials; /** * @param {string} data @@ -26,10 +34,11 @@ }); const uint8Array = forgivingBase64Decode(data); - const result = [...uint8Array] - .map((byte) => String.fromCharCode(byte)) - .join(""); - return result; + const result = ArrayPrototypeMap( + [...uint8Array], + (byte) => StringFromCharCode(byte), + ); + return ArrayPrototypeJoin(result, ""); } /** @@ -43,8 +52,8 @@ prefix, context: "Argument 1", }); - const byteArray = [...data].map((char) => { - const charCode = char.charCodeAt(0); + const byteArray = ArrayPrototypeMap([...data], (char) => { + const charCode = StringPrototypeCharCodeAt(char, 0); if (charCode > 0xff) { throw new DOMException( "The string to be encoded contains characters outside of the Latin1 range.", @@ -53,7 +62,7 @@ } return charCode; }); - return forgivingBase64Encode(Uint8Array.from(byteArray)); + return forgivingBase64Encode(TypedArrayFrom(Uint8Array, byteArray)); } window.__bootstrap.base64 = { diff --git a/extensions/web/08_text_encoding.js b/extensions/web/08_text_encoding.js index 0918cee64c..9be4aa7539 100644 --- a/extensions/web/08_text_encoding.js +++ b/extensions/web/08_text_encoding.js @@ -2,6 +2,7 @@ // @ts-check /// +/// /// /// /// @@ -13,6 +14,17 @@ ((window) => { const core = Deno.core; const webidl = window.__bootstrap.webidl; + const { + ArrayBufferIsView, + PromiseReject, + PromiseResolve, + StringPrototypeCharCodeAt, + StringPrototypeSlice, + SymbolToStringTag, + TypedArrayPrototypeSubarray, + TypedArrayPrototypeSlice, + Uint8Array, + } = window.__bootstrap.primordials; class TextDecoder { /** @type {string} */ @@ -95,7 +107,7 @@ } try { - if (ArrayBuffer.isView(input)) { + if (ArrayBufferIsView(input)) { input = new Uint8Array( input.buffer, input.byteOffset, @@ -116,7 +128,7 @@ } } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "TextDecoder"; } } @@ -172,7 +184,7 @@ return core.opSync("op_encoding_encode_into", source, destination); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "TextEncoder"; } } @@ -213,9 +225,9 @@ if (decoded) { controller.enqueue(decoded); } - return Promise.resolve(); + return PromiseResolve(); } catch (err) { - return Promise.reject(err); + return PromiseReject(err); } }, flush: (controller) => { @@ -224,9 +236,9 @@ if (final) { controller.enqueue(final); } - return Promise.resolve(); + return PromiseResolve(); } catch (err) { - return Promise.reject(err); + return PromiseReject(err); } }, }); @@ -263,7 +275,7 @@ return this.#transform.writable; } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "TextDecoderStream"; } } @@ -286,19 +298,22 @@ if (this.#pendingHighSurrogate !== null) { chunk = this.#pendingHighSurrogate + chunk; } - const lastCodeUnit = chunk.charCodeAt(chunk.length - 1); + const lastCodeUnit = StringPrototypeCharCodeAt( + chunk, + chunk.length - 1, + ); if (0xD800 <= lastCodeUnit && lastCodeUnit <= 0xDBFF) { - this.#pendingHighSurrogate = chunk.slice(-1); - chunk = chunk.slice(0, -1); + this.#pendingHighSurrogate = StringPrototypeSlice(chunk, -1); + chunk = StringPrototypeSlice(chunk, 0, -1); } else { this.#pendingHighSurrogate = null; } if (chunk) { controller.enqueue(core.encode(chunk)); } - return Promise.resolve(); + return PromiseResolve(); } catch (err) { - return Promise.reject(err); + return PromiseReject(err); } }, flush: (controller) => { @@ -306,9 +321,9 @@ if (this.#pendingHighSurrogate !== null) { controller.enqueue(new Uint8Array([0xEF, 0xBF, 0xBD])); } - return Promise.resolve(); + return PromiseResolve(); } catch (err) { - return Promise.reject(err); + return PromiseReject(err); } }, }); @@ -333,7 +348,7 @@ return this.#transform.writable; } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "TextEncoderStream"; } } @@ -377,14 +392,16 @@ if (BOMEncoding === "UTF-8") start = 3; else start = 2; } - return new TextDecoder(encoding).decode(bytes.slice(start)); + return new TextDecoder(encoding).decode( + TypedArrayPrototypeSlice(bytes, start), + ); } /** * @param {Uint8Array} bytes */ function BOMSniff(bytes) { - const BOM = bytes.subarray(0, 3); + const BOM = TypedArrayPrototypeSubarray(bytes, 0, 3); if (BOM[0] === 0xEF && BOM[1] === 0xBB && BOM[2] === 0xBF) { return "UTF-8"; } diff --git a/extensions/web/12_location.js b/extensions/web/12_location.js index dd56fb47b7..40dd545fe1 100644 --- a/extensions/web/12_location.js +++ b/extensions/web/12_location.js @@ -1,9 +1,23 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. "use strict"; +/// + ((window) => { const { URL } = window.__bootstrap.url; const { DOMException } = window.__bootstrap.domException; + const { + Error, + ObjectDefineProperties, + ReferenceError, + Symbol, + SymbolFor, + SymbolToStringTag, + TypeError, + WeakMap, + WeakMapPrototypeGet, + WeakMapPrototypeSet, + } = window.__bootstrap.primordials; const locationConstructorKey = Symbol("locationConstuctorKey"); @@ -20,7 +34,7 @@ const url = new URL(href); url.username = ""; url.password = ""; - Object.defineProperties(this, { + ObjectDefineProperties(this, { hash: { get() { return url.hash; @@ -167,7 +181,7 @@ }, enumerable: true, }, - [Symbol.for("Deno.privateCustomInspect")]: { + [SymbolFor("Deno.privateCustomInspect")]: { value: function (inspect) { const object = { hash: this.hash, @@ -187,8 +201,8 @@ } } - Object.defineProperties(Location.prototype, { - [Symbol.toStringTag]: { + ObjectDefineProperties(Location.prototype, { + [SymbolToStringTag]: { value: "Location", configurable: true, }, @@ -204,14 +218,14 @@ const url = new URL(href); url.username = ""; url.password = ""; - workerLocationUrls.set(this, url); + WeakMapPrototypeSet(workerLocationUrls, this, url); } } - Object.defineProperties(WorkerLocation.prototype, { + ObjectDefineProperties(WorkerLocation.prototype, { hash: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -222,7 +236,7 @@ }, host: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -233,7 +247,7 @@ }, hostname: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -244,7 +258,7 @@ }, href: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -255,7 +269,7 @@ }, origin: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -266,7 +280,7 @@ }, pathname: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -277,7 +291,7 @@ }, port: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -288,7 +302,7 @@ }, protocol: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -299,7 +313,7 @@ }, search: { get() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -310,7 +324,7 @@ }, toString: { value: function toString() { - const url = workerLocationUrls.get(this); + const url = WeakMapPrototypeGet(workerLocationUrls, this); if (url == null) { throw new TypeError("Illegal invocation."); } @@ -320,11 +334,11 @@ enumerable: true, writable: true, }, - [Symbol.toStringTag]: { + [SymbolToStringTag]: { value: "WorkerLocation", configurable: true, }, - [Symbol.for("Deno.privateCustomInspect")]: { + [SymbolFor("Deno.privateCustomInspect")]: { value: function (inspect) { const object = { hash: this.hash,