summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenta Moriuchi <moriken@kimamass.com>2023-04-03 02:41:41 +0900
committerGitHub <noreply@github.com>2023-04-02 19:41:41 +0200
commit03edd48edd004cec091541e6b71095cfbc4b4c87 (patch)
tree72aed1dae803334b73479ffebc7ca8c83d10addf
parentad8d0c90d1887beb8a5f2c6d30f9dc71cc63e4fe (diff)
chore: Turn back on dlintPreferPrimordials (#17715)
Closes #17709
-rw-r--r--core/internal.d.ts3
-rw-r--r--ext/console/02_console.js20
-rw-r--r--ext/crypto/00_crypto.js270
-rw-r--r--ext/fetch/22_body.js70
-rw-r--r--ext/ffi/00_ffi.js38
-rw-r--r--ext/flash/01_http.js23
-rw-r--r--ext/fs/30_fs.js5
-rw-r--r--ext/io/12_io.js11
-rw-r--r--ext/web/02_timers.js3
-rw-r--r--ext/web/06_streams.js214
-rw-r--r--ext/web/08_text_encoding.js49
-rw-r--r--ext/web/09_file.js51
-rw-r--r--ext/web/10_filereader.js16
-rw-r--r--ext/web/13_message_port.js6
-rw-r--r--ext/web/14_compression.js6
-rw-r--r--ext/webidl/00_webidl.js26
-rw-r--r--ext/websocket/01_websocket.js53
-rw-r--r--ext/websocket/02_websocketstream.js17
-rw-r--r--runtime/js/13_buffer.js32
-rw-r--r--runtime/js/99_main.js76
-rwxr-xr-xtools/lint.js7
21 files changed, 688 insertions, 308 deletions
diff --git a/core/internal.d.ts b/core/internal.d.ts
index a3e8c9e4d..c78310aeb 100644
--- a/core/internal.d.ts
+++ b/core/internal.d.ts
@@ -588,6 +588,7 @@ declare namespace __bootstrap {
export const MapLength: typeof Map.length;
export const MapName: typeof Map.name;
export const MapPrototype: typeof Map.prototype;
+ export const MapPrototypeGetSize: (map: Map) => number;
export const MapPrototypeGet: UncurryThis<typeof Map.prototype.get>;
export const MapPrototypeSet: UncurryThis<typeof Map.prototype.set>;
export const MapPrototypeHas: UncurryThis<typeof Map.prototype.has>;
@@ -715,6 +716,7 @@ declare namespace __bootstrap {
export const SetLength: typeof Set.length;
export const SetName: typeof Set.name;
export const SetPrototype: typeof Set.prototype;
+ export const SetPrototypeGetSize: (set: Set) => number;
export const SetPrototypeHas: UncurryThis<typeof Set.prototype.has>;
export const SetPrototypeAdd: UncurryThis<typeof Set.prototype.add>;
export const SetPrototypeDelete: UncurryThis<typeof Set.prototype.delete>;
@@ -866,6 +868,7 @@ declare namespace __bootstrap {
export const SymbolLength: typeof Symbol.length;
export const SymbolName: typeof Symbol.name;
export const SymbolPrototype: typeof Symbol.prototype;
+ export const SymbolPrototypeGetDescription: (symbol: symbol) => string;
export const SymbolFor: typeof Symbol.for;
export const SymbolKeyFor: typeof Symbol.keyFor;
export const SymbolAsyncIterator: typeof Symbol.asyncIterator;
diff --git a/ext/console/02_console.js b/ext/console/02_console.js
index 5547dd230..85a0f784f 100644
--- a/ext/console/02_console.js
+++ b/ext/console/02_console.js
@@ -64,6 +64,7 @@ const {
SymbolPrototype,
SymbolPrototypeToString,
SymbolPrototypeValueOf,
+ SymbolPrototypeGetDescription,
SymbolToStringTag,
SymbolHasInstance,
SymbolFor,
@@ -662,7 +663,7 @@ function handleCircular(value, cyan) {
} else {
index = MapPrototypeGet(circular, value);
if (index === undefined) {
- index = circular.size + 1;
+ index = MapPrototypeGetSize(circular) + 1;
MapPrototypeSet(circular, value, index);
}
}
@@ -809,20 +810,17 @@ const QUOTE_SYMBOL_REG = new SafeRegExp(/^[a-zA-Z_][a-zA-Z_.0-9]*$/);
// Surround a symbol's description in quotes when it is required (e.g the description has non printable characters).
function maybeQuoteSymbol(symbol, inspectOptions) {
- if (symbol.description === undefined) {
+ const description = SymbolPrototypeGetDescription(symbol);
+
+ if (description === undefined) {
return SymbolPrototypeToString(symbol);
}
- if (
- RegExpPrototypeTest(
- QUOTE_SYMBOL_REG,
- symbol.description,
- )
- ) {
+ if (RegExpPrototypeTest(QUOTE_SYMBOL_REG, description)) {
return SymbolPrototypeToString(symbol);
}
- return `Symbol(${quoteString(symbol.description, inspectOptions)})`;
+ return `Symbol(${quoteString(description, inspectOptions)})`;
}
const CTX_STACK = [];
@@ -1191,8 +1189,8 @@ function inspectRawObject(
symbolKeys,
(s1, s2) =>
StringPrototypeLocaleCompare(
- s1.description ?? "",
- s2.description ?? "",
+ SymbolPrototypeGetDescription(s1) ?? "",
+ SymbolPrototypeGetDescription(s2) ?? "",
),
);
}
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index a9f37b58f..fe30a4558 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -13,15 +13,15 @@ import * as webidl from "ext:deno_webidl/00_webidl.js";
import DOMException from "ext:deno_web/01_dom_exception.js";
const {
ArrayBufferPrototype,
+ ArrayBufferPrototypeSlice,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypeEvery,
ArrayPrototypeFind,
ArrayPrototypeIncludes,
- BigInt64ArrayPrototype,
- BigUint64ArrayPrototype,
- Int16ArrayPrototype,
- Int32ArrayPrototype,
- Int8ArrayPrototype,
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
JSONParse,
JSONStringify,
MathCeil,
@@ -37,12 +37,12 @@ const {
SymbolFor,
SyntaxError,
TypedArrayPrototypeSlice,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
- Uint16ArrayPrototype,
- Uint32ArrayPrototype,
Uint8Array,
- Uint8ArrayPrototype,
- Uint8ClampedArrayPrototype,
WeakMap,
WeakMapPrototypeGet,
WeakMapPrototypeSet,
@@ -250,13 +250,7 @@ function normalizeAlgorithm(algorithm, op) {
const idlValue = normalizedAlgorithm[member];
// 3.
if (idlType === "BufferSource" && idlValue) {
- normalizedAlgorithm[member] = TypedArrayPrototypeSlice(
- new Uint8Array(
- ArrayBufferIsView(idlValue) ? idlValue.buffer : idlValue,
- idlValue.byteOffset ?? 0,
- idlValue.byteLength,
- ),
- );
+ normalizedAlgorithm[member] = copyBuffer(idlValue);
} else if (idlType === "HashAlgorithmIdentifier") {
normalizedAlgorithm[member] = normalizeAlgorithm(idlValue, "digest");
} else if (idlType === "AlgorithmIdentifier") {
@@ -273,10 +267,34 @@ function normalizeAlgorithm(algorithm, op) {
* @returns {Uint8Array}
*/
function copyBuffer(input) {
+ if (ArrayBufferIsView(input)) {
+ if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
+ // TypedArray
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (input)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (input)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (input)),
+ ),
+ );
+ } else {
+ // DataView
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (input)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)),
+ ),
+ );
+ }
+ }
+ // ArrayBuffer
return TypedArrayPrototypeSlice(
- ArrayBufferIsView(input)
- ? new Uint8Array(input.buffer, input.byteOffset, input.byteLength)
- : new Uint8Array(input),
+ new Uint8Array(
+ input,
+ 0,
+ ArrayBufferPrototypeGetByteLength(input),
+ ),
);
}
@@ -445,7 +463,7 @@ class SubtleCrypto {
/**
* @param {string} algorithm
* @param {BufferSource} data
- * @returns {Promise<Uint8Array>}
+ * @returns {Promise<ArrayBuffer>}
*/
async digest(algorithm, data) {
webidl.assertBranded(this, SubtleCryptoPrototype);
@@ -470,7 +488,7 @@ class SubtleCrypto {
data,
);
- return result.buffer;
+ return TypedArrayPrototypeGetBuffer(result);
}
/**
@@ -596,13 +614,13 @@ class SubtleCrypto {
}, data);
// 6.
- return plainText.buffer;
+ return TypedArrayPrototypeGetBuffer(plainText);
}
case "AES-CBC": {
normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
// 1.
- if (normalizedAlgorithm.iv.byteLength !== 16) {
+ if (TypedArrayPrototypeGetByteLength(normalizedAlgorithm.iv) !== 16) {
throw new DOMException(
"Counter must be 16 bytes",
"OperationError",
@@ -617,13 +635,15 @@ class SubtleCrypto {
}, data);
// 6.
- return plainText.buffer;
+ return TypedArrayPrototypeGetBuffer(plainText);
}
case "AES-CTR": {
normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
// 1.
- if (normalizedAlgorithm.counter.byteLength !== 16) {
+ if (
+ TypedArrayPrototypeGetByteLength(normalizedAlgorithm.counter) !== 16
+ ) {
throw new DOMException(
"Counter vector must be 16 bytes",
"OperationError",
@@ -650,7 +670,7 @@ class SubtleCrypto {
}, data);
// 4.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
case "AES-GCM": {
normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
@@ -671,7 +691,10 @@ class SubtleCrypto {
}
// 2.
- if (data.byteLength < normalizedAlgorithm.tagLength / 8) {
+ if (
+ TypedArrayPrototypeGetByteLength(data) <
+ normalizedAlgorithm.tagLength / 8
+ ) {
throw new DOMException(
"Tag length overflows ciphertext",
"OperationError",
@@ -682,7 +705,7 @@ class SubtleCrypto {
if (
ArrayPrototypeIncludes(
[12, 16],
- normalizedAlgorithm.iv.byteLength,
+ TypedArrayPrototypeGetByteLength(normalizedAlgorithm.iv),
) === undefined
) {
throw new DOMException(
@@ -693,12 +716,13 @@ class SubtleCrypto {
// 4.
if (normalizedAlgorithm.additionalData !== undefined) {
- if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
- throw new DOMException(
- "Additional data too large",
- "OperationError",
- );
- }
+ // NOTE: over the size of Number.MAX_SAFE_INTEGER is not available in V8
+ // if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
+ // throw new DOMException(
+ // "Additional data too large",
+ // "OperationError",
+ // );
+ // }
normalizedAlgorithm.additionalData = copyBuffer(
normalizedAlgorithm.additionalData,
);
@@ -716,7 +740,7 @@ class SubtleCrypto {
}, data);
// 9.
- return plaintext.buffer;
+ return TypedArrayPrototypeGetBuffer(plaintext);
}
default:
throw new DOMException("Not implemented", "NotSupportedError");
@@ -789,7 +813,7 @@ class SubtleCrypto {
hash: hashAlgorithm,
}, data);
- return signature.buffer;
+ return TypedArrayPrototypeGetBuffer(signature);
}
case "RSA-PSS": {
// 1.
@@ -809,7 +833,7 @@ class SubtleCrypto {
saltLength: normalizedAlgorithm.saltLength,
}, data);
- return signature.buffer;
+ return TypedArrayPrototypeGetBuffer(signature);
}
case "ECDSA": {
// 1.
@@ -846,7 +870,7 @@ class SubtleCrypto {
namedCurve,
}, data);
- return signature.buffer;
+ return TypedArrayPrototypeGetBuffer(signature);
}
case "HMAC": {
const hashAlgorithm = key[_algorithm].hash.name;
@@ -857,7 +881,7 @@ class SubtleCrypto {
hash: hashAlgorithm,
}, data);
- return signature.buffer;
+ return TypedArrayPrototypeGetBuffer(signature);
}
case "Ed25519": {
// 1.
@@ -877,7 +901,7 @@ class SubtleCrypto {
"OperationError",
);
}
- return signature.buffer;
+ return TypedArrayPrototypeGetBuffer(signature);
}
}
@@ -1471,7 +1495,7 @@ class SubtleCrypto {
}, bytes);
// 4.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
default: {
throw new DOMException(
@@ -1607,7 +1631,7 @@ class SubtleCrypto {
}, wrappedKey);
// 4.
- key = plainText.buffer;
+ key = TypedArrayPrototypeGetBuffer(plainText);
break;
}
default: {
@@ -2127,7 +2151,7 @@ async function generateKey(normalizedAlgorithm, extractable, usages) {
hash: {
name: normalizedAlgorithm.hash.name,
},
- length: keyData.byteLength * 8,
+ length: TypedArrayPrototypeGetByteLength(keyData) * 8,
};
// 5, 11-13.
@@ -2589,7 +2613,7 @@ function exportKeyAES(
// 1.
const data = innerKey.data;
// 2.
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "jwk": {
// 1-2.
@@ -2664,7 +2688,10 @@ function importKeyAES(
case "raw": {
// 2.
if (
- !ArrayPrototypeIncludes([128, 192, 256], keyData.byteLength * 8)
+ !ArrayPrototypeIncludes(
+ [128, 192, 256],
+ TypedArrayPrototypeGetByteLength(keyData) * 8,
+ )
) {
throw new DOMException("Invalid key length", "Datarror");
}
@@ -2699,7 +2726,7 @@ function importKeyAES(
data = rawData.data;
// 5.
- switch (data.byteLength * 8) {
+ switch (TypedArrayPrototypeGetByteLength(data) * 8) {
case 128:
if (
jwk.alg !== undefined &&
@@ -2789,7 +2816,7 @@ function importKeyAES(
// 4-7.
const algorithm = {
name: algorithmName,
- length: data.byteLength * 8,
+ length: TypedArrayPrototypeGetByteLength(data) * 8,
};
const key = constructKey(
@@ -2956,7 +2983,7 @@ function importKeyHMAC(
}
// 5.
- let length = data.byteLength * 8;
+ let length = TypedArrayPrototypeGetByteLength(data) * 8;
// 6.
if (length === 0) {
throw new DOMException("Key length is zero", "DataError");
@@ -3856,11 +3883,12 @@ function exportKeyHMAC(format, key, innerKey) {
// 3.
case "raw": {
const bits = innerKey.data;
- for (let _i = 7 & (8 - bits.length % 8); _i > 0; _i--) {
- bits.push(0);
- }
+ // TODO(petamoriken): Uint8Array doesn't have push method
+ // for (let _i = 7 & (8 - bits.length % 8); _i > 0; _i--) {
+ // bits.push(0);
+ // }
// 4-5.
- return bits.buffer;
+ return TypedArrayPrototypeGetBuffer(bits);
}
case "jwk": {
// 1-2.
@@ -3929,7 +3957,7 @@ function exportKeyRSA(format, key, innerKey) {
}, innerKey);
// 3.
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "spki": {
// 1.
@@ -3947,7 +3975,7 @@ function exportKeyRSA(format, key, innerKey) {
}, innerKey);
// 3.
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "jwk": {
// 1-2.
@@ -4053,7 +4081,7 @@ function exportKeyEd25519(format, key, innerKey) {
}
// 2-3.
- return innerKey.buffer;
+ return TypedArrayPrototypeGetBuffer(innerKey);
}
case "spki": {
// 1.
@@ -4065,7 +4093,7 @@ function exportKeyEd25519(format, key, innerKey) {
}
const spkiDer = ops.op_export_spki_ed25519(innerKey);
- return spkiDer.buffer;
+ return TypedArrayPrototypeGetBuffer(spkiDer);
}
case "pkcs8": {
// 1.
@@ -4080,7 +4108,7 @@ function exportKeyEd25519(format, key, innerKey) {
new Uint8Array([0x04, 0x22, ...new SafeArrayIterator(innerKey)]),
);
pkcs8Der[15] = 0x20;
- return pkcs8Der.buffer;
+ return TypedArrayPrototypeGetBuffer(pkcs8Der);
}
case "jwk": {
const x = key[_type] === "private"
@@ -4116,7 +4144,7 @@ function exportKeyX25519(format, key, innerKey) {
}
// 2-3.
- return innerKey.buffer;
+ return TypedArrayPrototypeGetBuffer(innerKey);
}
case "spki": {
// 1.
@@ -4128,7 +4156,7 @@ function exportKeyX25519(format, key, innerKey) {
}
const spkiDer = ops.op_export_spki_x25519(innerKey);
- return spkiDer.buffer;
+ return TypedArrayPrototypeGetBuffer(spkiDer);
}
case "pkcs8": {
// 1.
@@ -4143,7 +4171,7 @@ function exportKeyX25519(format, key, innerKey) {
new Uint8Array([0x04, 0x22, ...new SafeArrayIterator(innerKey)]),
);
pkcs8Der[15] = 0x20;
- return pkcs8Der.buffer;
+ return TypedArrayPrototypeGetBuffer(pkcs8Der);
}
case "jwk": {
if (key[_type] === "private") {
@@ -4182,7 +4210,7 @@ function exportKeyEC(format, key, innerKey) {
format: "raw",
}, innerKey);
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "pkcs8": {
// 1.
@@ -4200,7 +4228,7 @@ function exportKeyEC(format, key, innerKey) {
format: "pkcs8",
}, innerKey);
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "spki": {
// 1.
@@ -4218,7 +4246,7 @@ function exportKeyEC(format, key, innerKey) {
format: "spki",
}, innerKey);
- return data.buffer;
+ return TypedArrayPrototypeGetBuffer(data);
}
case "jwk": {
if (key[_algorithm].name == "ECDSA") {
@@ -4370,7 +4398,7 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) {
length,
}, normalizedAlgorithm.salt);
- return buf.buffer;
+ return TypedArrayPrototypeGetBuffer(buf);
}
case "ECDH": {
// 1.
@@ -4421,11 +4449,15 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) {
// 8.
if (length === null) {
- return buf.buffer;
- } else if (buf.buffer.byteLength * 8 < length) {
+ return TypedArrayPrototypeGetBuffer(buf);
+ } else if (TypedArrayPrototypeGetByteLength(buf) * 8 < length) {
throw new DOMException("Invalid length", "OperationError");
} else {
- return buf.buffer.slice(0, MathCeil(length / 8));
+ return ArrayBufferPrototypeSlice(
+ TypedArrayPrototypeGetBuffer(buf),
+ 0,
+ MathCeil(length / 8),
+ );
}
} else {
throw new DOMException("Not implemented", "NotSupportedError");
@@ -4452,7 +4484,7 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) {
length,
}, normalizedAlgorithm.salt);
- return buf.buffer;
+ return TypedArrayPrototypeGetBuffer(buf);
}
case "X25519": {
// 1.
@@ -4490,13 +4522,17 @@ async function deriveBits(normalizedAlgorithm, baseKey, length) {
// 7.
if (length === null) {
- return secret.buffer;
+ return TypedArrayPrototypeGetBuffer(secret);
} else if (
- secret.buffer.byteLength * 8 < length
+ TypedArrayPrototypeGetByteLength(secret) * 8 < length
) {
throw new DOMException("Invalid length", "OperationError");
} else {
- return secret.buffer.slice(0, MathCeil(length / 8));
+ return ArrayBufferPrototypeSlice(
+ TypedArrayPrototypeGetBuffer(secret),
+ 0,
+ MathCeil(length / 8),
+ );
}
}
default:
@@ -4535,13 +4571,13 @@ async function encrypt(normalizedAlgorithm, key, data) {
}, data);
// 6.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
case "AES-CBC": {
normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
// 1.
- if (normalizedAlgorithm.iv.byteLength !== 16) {
+ if (TypedArrayPrototypeGetByteLength(normalizedAlgorithm.iv) !== 16) {
throw new DOMException(
"Initialization vector must be 16 bytes",
"OperationError",
@@ -4557,13 +4593,15 @@ async function encrypt(normalizedAlgorithm, key, data) {
}, data);
// 4.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
case "AES-CTR": {
normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
// 1.
- if (normalizedAlgorithm.counter.byteLength !== 16) {
+ if (
+ TypedArrayPrototypeGetByteLength(normalizedAlgorithm.counter) !== 16
+ ) {
throw new DOMException(
"Counter vector must be 16 bytes",
"OperationError",
@@ -4590,13 +4628,13 @@ async function encrypt(normalizedAlgorithm, key, data) {
}, data);
// 4.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
case "AES-GCM": {
normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
// 1.
- if (data.byteLength > (2 ** 39) - 256) {
+ if (TypedArrayPrototypeGetByteLength(data) > (2 ** 39) - 256) {
throw new DOMException(
"Plaintext too large",
"OperationError",
@@ -4608,7 +4646,7 @@ async function encrypt(normalizedAlgorithm, key, data) {
if (
ArrayPrototypeIncludes(
[12, 16],
- normalizedAlgorithm.iv.byteLength,
+ TypedArrayPrototypeGetByteLength(normalizedAlgorithm.iv),
) === undefined
) {
throw new DOMException(
@@ -4618,14 +4656,15 @@ async function encrypt(normalizedAlgorithm, key, data) {
}
// 3.
- if (normalizedAlgorithm.additionalData !== undefined) {
- if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
- throw new DOMException(
- "Additional data too large",
- "OperationError",
- );
- }
- }
+ // NOTE: over the size of Number.MAX_SAFE_INTEGER is not available in V8
+ // if (normalizedAlgorithm.additionalData !== undefined) {
+ // if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
+ // throw new DOMException(
+ // "Additional data too large",
+ // "OperationError",
+ // );
+ // }
+ // }
// 4.
if (normalizedAlgorithm.tagLength == undefined) {
@@ -4658,7 +4697,7 @@ async function encrypt(normalizedAlgorithm, key, data) {
}, data);
// 8.
- return cipherText.buffer;
+ return TypedArrayPrototypeGetBuffer(cipherText);
}
default:
throw new DOMException("Not implemented", "NotSupportedError");
@@ -4673,50 +4712,43 @@ class Crypto {
webidl.illegalConstructor();
}
- getRandomValues(arrayBufferView) {
+ getRandomValues(typedArray) {
webidl.assertBranded(this, CryptoPrototype);
const prefix = "Failed to execute 'getRandomValues' on 'Crypto'";
webidl.requiredArguments(arguments.length, 1, { prefix });
// Fast path for Uint8Array
- if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, arrayBufferView)) {
- ops.op_crypto_get_random_values(arrayBufferView);
- return arrayBufferView;
+ const tag = TypedArrayPrototypeGetSymbolToStringTag(typedArray);
+ if (tag === "Uint8Array") {
+ ops.op_crypto_get_random_values(typedArray);
+ return typedArray;
}
- arrayBufferView = webidl.converters.ArrayBufferView(arrayBufferView, {
+ typedArray = webidl.converters.ArrayBufferView(typedArray, {
prefix,
context: "Argument 1",
});
- if (
- !(
- ObjectPrototypeIsPrototypeOf(Int8ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(
- Uint8ClampedArrayPrototype,
- arrayBufferView,
- ) ||
- ObjectPrototypeIsPrototypeOf(Int16ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(Uint16ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(Int32ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(Uint32ArrayPrototype, arrayBufferView) ||
- ObjectPrototypeIsPrototypeOf(
- BigInt64ArrayPrototype,
- arrayBufferView,
- ) ||
- ObjectPrototypeIsPrototypeOf(BigUint64ArrayPrototype, arrayBufferView)
- )
- ) {
- throw new DOMException(
- "The provided ArrayBufferView is not an integer array type",
- "TypeMismatchError",
- );
+ switch (tag) {
+ case "Int8Array":
+ case "Uint8ClampedArray":
+ case "Int16Array":
+ case "Uint16Array":
+ case "Int32Array":
+ case "Uint32Array":
+ case "BigInt64Array":
+ case "BigUint64Array":
+ break;
+ default:
+ throw new DOMException(
+ "The provided ArrayBufferView is not an integer array type",
+ "TypeMismatchError",
+ );
}
const ui8 = new Uint8Array(
- arrayBufferView.buffer,
- arrayBufferView.byteOffset,
- arrayBufferView.byteLength,
+ TypedArrayPrototypeGetBuffer(typedArray),
+ TypedArrayPrototypeGetByteOffset(typedArray),
+ TypedArrayPrototypeGetByteLength(typedArray),
);
ops.op_crypto_get_random_values(ui8);
- return arrayBufferView;
+ return typedArray;
}
randomUUID() {
diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js
index dd11df2a2..9dbd58fa4 100644
--- a/ext/fetch/22_body.js
+++ b/ext/fetch/22_body.js
@@ -38,17 +38,24 @@ import {
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypeMap,
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
JSONParse,
ObjectDefineProperties,
ObjectPrototypeIsPrototypeOf,
// TODO(lucacasonato): add SharedArrayBuffer to primordials
// SharedArrayBufferPrototype
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypedArrayPrototypeSlice,
TypeError,
Uint8Array,
- Uint8ArrayPrototype,
} = primordials;
/**
@@ -328,7 +335,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
function packageData(bytes, type, mimeType) {
switch (type) {
case "ArrayBuffer":
- return chunkToU8(bytes).buffer;
+ return TypedArrayPrototypeGetBuffer(chunkToU8(bytes));
case "Blob":
return new Blob([bytes], {
type: mimeType !== null ? mimesniff.serializeMimeType(mimeType) : "",
@@ -385,22 +392,45 @@ function extractBody(object) {
if (object.type.length !== 0) {
contentType = object.type;
}
- } else if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, object)) {
- // Fast(er) path for common case of Uint8Array
- const copy = TypedArrayPrototypeSlice(object, 0, object.byteLength);
- source = copy;
- } else if (
- ArrayBufferIsView(object) ||
- ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, object)
- ) {
- const u8 = ArrayBufferIsView(object)
- ? new Uint8Array(
- object.buffer,
- object.byteOffset,
- object.byteLength,
- )
- : new Uint8Array(object);
- const copy = TypedArrayPrototypeSlice(u8, 0, u8.byteLength);
+ } else if (ArrayBufferIsView(object)) {
+ const tag = TypedArrayPrototypeGetSymbolToStringTag(object);
+ if (tag === "Uint8Array") {
+ // Fast(er) path for common case of Uint8Array
+ const copy = TypedArrayPrototypeSlice(
+ object,
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (object)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (object)),
+ );
+ source = copy;
+ } else if (tag !== undefined) {
+ // TypedArray
+ const copy = TypedArrayPrototypeSlice(
+ new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (object)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (object)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (object)),
+ ),
+ );
+ source = copy;
+ } else {
+ // DataView
+ const copy = TypedArrayPrototypeSlice(
+ new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (object)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (object)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (object)),
+ ),
+ );
+ source = copy;
+ }
+ } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, object)) {
+ const copy = TypedArrayPrototypeSlice(
+ new Uint8Array(
+ object,
+ 0,
+ ArrayBufferPrototypeGetByteLength(object),
+ ),
+ );
source = copy;
} else if (ObjectPrototypeIsPrototypeOf(FormDataPrototype, object)) {
const res = formDataToBlob(object);
@@ -426,9 +456,9 @@ function extractBody(object) {
// no observable side-effect for users so far, but could change
stream = { body: source, consumed: false };
length = null; // NOTE: string length != byte length
- } else if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, source)) {
+ } else if (TypedArrayPrototypeGetSymbolToStringTag(source) === "Uint8Array") {
stream = { body: source, consumed: false };
- length = source.byteLength;
+ length = TypedArrayPrototypeGetByteLength(source);
}
const body = new InnerBody(stream);
body.source = source;
diff --git a/ext/ffi/00_ffi.js b/ext/ffi/00_ffi.js
index 3664ae73b..ea75df65c 100644
--- a/ext/ffi/00_ffi.js
+++ b/ext/ffi/00_ffi.js
@@ -4,13 +4,19 @@ const core = globalThis.Deno.core;
const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials;
const {
+ ArrayBufferIsView,
+ ArrayBufferPrototypeGetByteLength,
ArrayPrototypeMap,
ArrayPrototypeJoin,
+ DataViewPrototypeGetByteLength,
ObjectDefineProperty,
ObjectPrototypeHasOwnProperty,
ObjectPrototypeIsPrototypeOf,
Number,
NumberIsSafeInteger,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint8Array,
Int32Array,
@@ -29,11 +35,27 @@ const {
} = primordials;
import { pathFromURL } from "ext:deno_web/00_infra.js";
+/**
+ * @param {BufferSource} source
+ * @returns {number}
+ */
+function getBufferSourceByteLength(source) {
+ if (ArrayBufferIsView(source)) {
+ if (TypedArrayPrototypeGetSymbolToStringTag(source) !== undefined) {
+ // TypedArray
+ return TypedArrayPrototypeGetByteLength(source);
+ } else {
+ // DataView
+ return DataViewPrototypeGetByteLength(source);
+ }
+ }
+ return ArrayBufferPrototypeGetByteLength(source);
+}
const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId");
const U32_BUFFER = new Uint32Array(2);
-const U64_BUFFER = new BigUint64Array(U32_BUFFER.buffer);
-const I64_BUFFER = new BigInt64Array(U32_BUFFER.buffer);
+const U64_BUFFER = new BigUint64Array(TypedArrayPrototypeGetBuffer(U32_BUFFER));
+const I64_BUFFER = new BigInt64Array(TypedArrayPrototypeGetBuffer(U32_BUFFER));
class UnsafePointerView {
pointer;
@@ -164,7 +186,7 @@ class UnsafePointerView {
this.pointer,
offset,
destination,
- destination.byteLength,
+ getBufferSourceByteLength(destination),
);
}
@@ -173,13 +195,15 @@ class UnsafePointerView {
pointer,
offset,
destination,
- destination.byteLength,
+ getBufferSourceByteLength(destination),
);
}
}
const OUT_BUFFER = new Uint32Array(2);
-const OUT_BUFFER_64 = new BigInt64Array(OUT_BUFFER.buffer);
+const OUT_BUFFER_64 = new BigInt64Array(
+ TypedArrayPrototypeGetBuffer(OUT_BUFFER),
+);
const POINTER_TO_BUFFER_WEAK_MAP = new WeakMap();
class UnsafePointer {
static create(value) {
@@ -492,8 +516,8 @@ class DynamicLibrary {
const call = this.symbols[symbol];
const parameters = symbols[symbol].parameters;
const vi = new Int32Array(2);
- const vui = new Uint32Array(vi.buffer);
- const b = new BigInt64Array(vi.buffer);
+ const vui = new Uint32Array(TypedArrayPrototypeGetBuffer(vi));
+ const b = new BigInt64Array(TypedArrayPrototypeGetBuffer(vi));
const params = ArrayPrototypeJoin(
ArrayPrototypeMap(parameters, (_, index) => `p${index}`),
diff --git a/ext/flash/01_http.js b/ext/flash/01_http.js
index 4d0112c5b..fe503ed05 100644
--- a/ext/flash/01_http.js
+++ b/ext/flash/01_http.js
@@ -31,11 +31,12 @@ const {
PromisePrototypeCatch,
PromisePrototypeThen,
SafePromiseAll,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypedArrayPrototypeSet,
TypedArrayPrototypeSubarray,
TypeError,
Uint8Array,
- Uint8ArrayPrototype,
} = primordials;
const statusCodes = {
@@ -188,9 +189,15 @@ function http1Response(
str += body ?? "";
} else {
const head = core.encode(str);
- const response = new Uint8Array(head.byteLength + bodyLen);
+ const response = new Uint8Array(
+ TypedArrayPrototypeGetByteLength(head) + bodyLen,
+ );
TypedArrayPrototypeSet(response, head, 0);
- TypedArrayPrototypeSet(response, body, head.byteLength);
+ TypedArrayPrototypeSet(
+ response,
+ body,
+ TypedArrayPrototypeGetByteLength(head),
+ );
return response;
}
@@ -303,7 +310,7 @@ async function handleResponse(
}
isStreamingResponseBody = !(
typeof respBody === "string" ||
- ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, respBody)
+ TypedArrayPrototypeGetSymbolToStringTag(respBody) === "Uint8Array"
);
} else {
if (innerResp.body.streamOrStatic.consumed === true) {
@@ -318,7 +325,9 @@ async function handleResponse(
const ws = resp[_ws];
if (isStreamingResponseBody === false) {
- const length = respBody.byteLength || core.byteLength(respBody);
+ const length = typeof respBody === "string"
+ ? core.byteLength(respBody)
+ : TypedArrayPrototypeGetByteLength(respBody);
const responseStr = http1Response(
method,
innerResp.status ?? 200,
@@ -394,8 +403,10 @@ async function handleResponse(
innerResp.status ?? 200,
innerResp.headerList,
null,
+ // deno-lint-ignore prefer-primordials
respBody.byteLength,
),
+ // deno-lint-ignore prefer-primordials
respBody.byteLength,
false,
respondFast,
@@ -722,7 +733,7 @@ function createRequestBodyStream(serverId, token) {
token,
);
if (!firstRead) return null;
- let firstEnqueued = firstRead.byteLength == 0;
+ let firstEnqueued = TypedArrayPrototypeGetByteLength(firstRead) === 0;
return new ReadableStream({
type: "bytes",
diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js
index 500416980..1421de9eb 100644
--- a/ext/fs/30_fs.js
+++ b/ext/fs/30_fs.js
@@ -137,7 +137,10 @@ function readDir(path) {
);
return {
async *[SymbolAsyncIterator]() {
- yield* await array;
+ const dir = await array;
+ for (let i = 0; i < dir.length; ++i) {
+ yield dir[i];
+ }
},
};
}
diff --git a/ext/io/12_io.js b/ext/io/12_io.js
index e17711735..2a825e7f6 100644
--- a/ext/io/12_io.js
+++ b/ext/io/12_io.js
@@ -17,6 +17,8 @@ const {
MathMin,
TypedArrayPrototypeSubarray,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
} = primordials;
const DEFAULT_BUFFER_SIZE = 32 * 1024;
@@ -131,7 +133,10 @@ async function readAllInner(r, options) {
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));
+ ArrayPrototypePush(
+ buffers,
+ new Uint8Array(TypedArrayPrototypeGetBuffer(buf), 0, read),
+ );
} else {
break;
}
@@ -160,7 +165,7 @@ function readAllSync(r) {
function concatBuffers(buffers) {
let totalLen = 0;
for (let i = 0; i < buffers.length; ++i) {
- totalLen += buffers[i].byteLength;
+ totalLen += TypedArrayPrototypeGetByteLength(buffers[i]);
}
const contents = new Uint8Array(totalLen);
@@ -169,7 +174,7 @@ function concatBuffers(buffers) {
for (let i = 0; i < buffers.length; ++i) {
const buf = buffers[i];
TypedArrayPrototypeSet(contents, buf, n);
- n += buf.byteLength;
+ n += TypedArrayPrototypeGetByteLength(buf);
}
return contents;
diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js
index c224be884..753848af1 100644
--- a/ext/web/02_timers.js
+++ b/ext/web/02_timers.js
@@ -19,6 +19,7 @@ const {
PromisePrototypeThen,
SafeArrayIterator,
SymbolFor,
+ TypedArrayPrototypeGetBuffer,
TypeError,
indirectEval,
} = primordials;
@@ -27,7 +28,7 @@ import { reportException } from "ext:deno_web/02_event.js";
import { assert } from "ext:deno_web/00_infra.js";
const hrU8 = new Uint8Array(8);
-const hr = new Uint32Array(hrU8.buffer);
+const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8));
function opNow() {
ops.op_now(hrU8);
return (hr[0] * 1000 + hr[1] / 1e6);
diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js
index 35d8f15e2..135a200ac 100644
--- a/ext/web/06_streams.js
+++ b/ext/web/06_streams.js
@@ -20,6 +20,7 @@ const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBuffer,
ArrayBufferPrototype,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypeMap,
ArrayPrototypePush,
@@ -67,6 +68,7 @@ const {
TypedArrayPrototypeGetByteOffset,
TypedArrayPrototypeGetSymbolToStringTag,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeSlice,
Uint8Array,
Uint16Array,
Uint32Array,
@@ -208,7 +210,12 @@ function uponPromise(promise, onFulfilled, onRejected) {
* @returns {boolean}
*/
function isDetachedBuffer(O) {
- return O.byteLength === 0 && ops.op_arraybuffer_was_detached(O);
+ // deno-lint-ignore prefer-primordials
+ if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) {
+ return false;
+ }
+ return ArrayBufferPrototypeGetByteLength(O) === 0 &&
+ ops.op_arraybuffer_was_detached(O);
}
/**
@@ -238,15 +245,46 @@ function transferArrayBuffer(O) {
}
/**
+ * @param {ArrayBufferLike} O
+ * @returns {number}
+ */
+function getArrayBufferByteLength(O) {
+ // deno-lint-ignore prefer-primordials
+ if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) {
+ // TODO(petamoriken): use primordials
+ // deno-lint-ignore prefer-primordials
+ return O.byteLength;
+ } else {
+ return ArrayBufferPrototypeGetByteLength(O);
+ }
+}
+
+/**
* @param {ArrayBufferView} O
* @returns {Uint8Array}
*/
function cloneAsUint8Array(O) {
assert(typeof O === "object");
assert(ArrayBufferIsView(O));
- assert(!isDetachedBuffer(O.buffer));
- const buffer = O.buffer.slice(O.byteOffset, O.byteOffset + O.byteLength);
- return new Uint8Array(buffer);
+ if (TypedArrayPrototypeGetSymbolToStringTag(O) !== undefined) {
+ // TypedArray
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (O)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (O)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (O)),
+ ),
+ );
+ } else {
+ // DataView
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (O)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (O)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (O)),
+ ),
+ );
+ }
}
const _abortAlgorithm = Symbol("[[abortAlgorithm]]");
@@ -695,7 +733,7 @@ function readableStreamForRid(rid, autoClose = true) {
if (controller[_readAll] === true) {
// fast path for tee'd streams consuming body
const chunk = await core.readAll(rid);
- if (chunk.byteLength > 0) {
+ if (TypedArrayPrototypeGetByteLength(chunk) > 0) {
controller.enqueue(chunk);
}
controller.close();
@@ -870,7 +908,7 @@ async function readableStreamCollectIntoUint8Array(stream) {
}
ArrayPrototypePush(chunks, chunk);
- totalLength += chunk.byteLength;
+ totalLength += TypedArrayPrototypeGetByteLength(chunk);
}
const finalBuffer = new Uint8Array(totalLength);
@@ -878,7 +916,7 @@ async function readableStreamCollectIntoUint8Array(stream) {
for (let i = 0; i < chunks.length; ++i) {
const chunk = chunks[i];
TypedArrayPrototypeSet(finalBuffer, chunk, offset);
- offset += chunk.byteLength;
+ offset += TypedArrayPrototypeGetByteLength(chunk);
}
return finalBuffer;
}
@@ -1092,7 +1130,25 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
return;
}
- const { buffer, byteOffset, byteLength } = chunk;
+ let buffer, byteLength, byteOffset;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ byteOffset = DataViewPrototypeGetByteOffset(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (chunk));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ byteOffset = TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+
if (isDetachedBuffer(buffer)) {
throw new TypeError(
"chunk's buffer is detached and so cannot be enqueued",
@@ -1101,6 +1157,7 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
const transferredBuffer = transferArrayBuffer(buffer);
if (controller[_pendingPullIntos].length !== 0) {
const firstPendingPullInto = controller[_pendingPullIntos][0];
+ // deno-lint-ignore prefer-primordials
if (isDetachedBuffer(firstPendingPullInto.buffer)) {
throw new TypeError(
"The BYOB request's buffer has been detached and so cannot be filled with an enqueued chunk",
@@ -1108,6 +1165,7 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
}
readableByteStreamControllerInvalidateBYOBRequest(controller);
firstPendingPullInto.buffer = transferArrayBuffer(
+ // deno-lint-ignore prefer-primordials
firstPendingPullInto.buffer,
);
if (firstPendingPullInto.readerType === "none") {
@@ -1219,7 +1277,9 @@ function readableByteStreamControllerEnqueueDetachedPullIntoToQueue(
if (pullIntoDescriptor.bytesFilled > 0) {
readableByteStreamControllerEnqueueClonedChunkToQueue(
controller,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
pullIntoDescriptor.bytesFilled,
);
@@ -1238,8 +1298,11 @@ function readableByteStreamControllerGetBYOBRequest(controller) {
) {
const firstDescriptor = controller[_pendingPullIntos][0];
const view = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
firstDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteOffset + firstDescriptor.bytesFilled,
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteLength - firstDescriptor.bytesFilled,
);
const byobRequest = webidl.createBranded(ReadableStreamBYOBRequest);
@@ -1753,7 +1816,7 @@ function readableByteStreamControllerPullInto(
/** @type {PullIntoDescriptor} */
const pullIntoDescriptor = {
buffer,
- bufferByteLength: buffer.byteLength,
+ bufferByteLength: getArrayBufferByteLength(buffer),
byteOffset,
byteLength,
bytesFilled: 0,
@@ -1769,7 +1832,9 @@ function readableByteStreamControllerPullInto(
}
if (stream[_state] === "closed") {
const emptyView = new ctor(
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
0,
);
@@ -1828,11 +1893,13 @@ function readableByteStreamControllerRespond(controller, bytesWritten) {
}
if (
(firstDescriptor.bytesFilled + bytesWritten) >
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteLength
) {
throw new RangeError("bytesWritten out of range");
}
}
+ // deno-lint-ignore prefer-primordials
firstDescriptor.buffer = transferArrayBuffer(firstDescriptor.buffer);
readableByteStreamControllerRespondInternal(controller, bytesWritten);
}
@@ -1850,6 +1917,7 @@ function readableByteStreamControllerRespondInReadableState(
) {
assert(
(pullIntoDescriptor.bytesFilled + bytesWritten) <=
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteLength,
);
readableByteStreamControllerFillHeadPullIntoDescriptor(
@@ -1874,10 +1942,12 @@ function readableByteStreamControllerRespondInReadableState(
const remainderSize = pullIntoDescriptor.bytesFilled %
pullIntoDescriptor.elementSize;
if (remainderSize > 0) {
+ // deno-lint-ignore prefer-primordials
const end = pullIntoDescriptor.byteOffset +
pullIntoDescriptor.bytesFilled;
readableByteStreamControllerEnqueueClonedChunkToQueue(
controller,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
end - remainderSize,
remainderSize,
@@ -1903,6 +1973,7 @@ function readableByteStreamControllerRespondInternal(
bytesWritten,
) {
const firstDescriptor = controller[_pendingPullIntos][0];
+ // deno-lint-ignore prefer-primordials
assert(canTransferArrayBuffer(firstDescriptor.buffer));
readableByteStreamControllerInvalidateBYOBRequest(controller);
const state = controller[_stream][_state];
@@ -1994,47 +2065,57 @@ function readableByteStreamControllerCommitPullIntoDescriptor(
*/
function readableByteStreamControllerRespondWithNewView(controller, view) {
assert(controller[_pendingPullIntos].length !== 0);
- assert(!isDetachedBuffer(view.buffer));
+
+ let buffer, byteLength, byteOffset;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view));
+ byteLength = DataViewPrototypeGetByteLength(/** @type {DataView} */ (view));
+ byteOffset = DataViewPrototypeGetByteOffset(/** @type {DataView} */ (view));
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (view));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (view),
+ );
+ byteOffset = TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (view),
+ );
+ }
+ assert(!isDetachedBuffer(buffer));
const firstDescriptor = controller[_pendingPullIntos][0];
const state = controller[_stream][_state];
if (state === "closed") {
- if (view.byteLength !== 0) {
+ if (byteLength !== 0) {
throw new TypeError(
"The view's length must be 0 when calling respondWithNewView() on a closed stream",
);
}
} else {
assert(state === "readable");
- if (view.byteLength === 0) {
+ if (byteLength === 0) {
throw new TypeError(
"The view's length must be greater than 0 when calling respondWithNewView() on a readable stream",
);
}
}
- if (
- (firstDescriptor.byteOffset + firstDescriptor.bytesFilled) !==
- view.byteOffset
- ) {
+ // deno-lint-ignore prefer-primordials
+ if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== byteOffset) {
throw new RangeError(
"The region specified by view does not match byobRequest",
);
}
- if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) {
+ if (firstDescriptor.bufferByteLength !== getArrayBufferByteLength(buffer)) {
throw new RangeError(
"The buffer of view has different capacity than byobRequest",
);
}
- if (
- (firstDescriptor.bytesFilled + view.byteLength) >
- firstDescriptor.byteLength
- ) {
+ // deno-lint-ignore prefer-primordials
+ if (firstDescriptor.bytesFilled + byteLength > firstDescriptor.byteLength) {
throw new RangeError(
"The region specified by view is larger than byobRequest",
);
}
- const viewByteLength = view.byteLength;
- firstDescriptor.buffer = transferArrayBuffer(view.buffer);
- readableByteStreamControllerRespondInternal(controller, viewByteLength);
+ firstDescriptor.buffer = transferArrayBuffer(buffer);
+ readableByteStreamControllerRespondInternal(controller, byteLength);
}
/**
@@ -2060,6 +2141,7 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue(
(pullIntoDescriptor.bytesFilled % elementSize);
const maxBytesToCopy = MathMin(
controller[_queueTotalSize],
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled,
);
const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
@@ -2076,23 +2158,29 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue(
const headOfQueue = queue[0];
const bytesToCopy = MathMin(
totalBytesToCopyRemaining,
+ // deno-lint-ignore prefer-primordials
headOfQueue.byteLength,
);
+ // deno-lint-ignore prefer-primordials
const destStart = pullIntoDescriptor.byteOffset +
pullIntoDescriptor.bytesFilled;
const destBuffer = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
destStart,
bytesToCopy,
);
const srcBuffer = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
headOfQueue.buffer,
+ // deno-lint-ignore prefer-primordials
headOfQueue.byteOffset,
bytesToCopy,
);
destBuffer.set(srcBuffer);
+ // deno-lint-ignore prefer-primordials
if (headOfQueue.byteLength === bytesToCopy) {
ArrayPrototypeShift(queue);
} else {
@@ -2126,11 +2214,15 @@ function readableByteStreamControllerFillReadRequestFromQueue(
) {
assert(controller[_queueTotalSize] > 0);
const entry = ArrayPrototypeShift(controller[_queue]);
+ // deno-lint-ignore prefer-primordials
controller[_queueTotalSize] -= entry.byteLength;
readableByteStreamControllerHandleQueueDrain(controller);
const view = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
entry.buffer,
+ // deno-lint-ignore prefer-primordials
entry.byteOffset,
+ // deno-lint-ignore prefer-primordials
entry.byteLength,
);
readRequest.chunkSteps(view);
@@ -2164,11 +2256,14 @@ function readableByteStreamControllerConvertPullIntoDescriptor(
) {
const bytesFilled = pullIntoDescriptor.bytesFilled;
const elementSize = pullIntoDescriptor.elementSize;
+ // deno-lint-ignore prefer-primordials
assert(bytesFilled <= pullIntoDescriptor.byteLength);
assert((bytesFilled % elementSize) === 0);
+ // deno-lint-ignore prefer-primordials
const buffer = transferArrayBuffer(pullIntoDescriptor.buffer);
return new pullIntoDescriptor.viewConstructor(
buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
bytesFilled / elementSize,
);
@@ -3029,7 +3124,17 @@ function readableByteStreamTee(stream) {
readableByteStreamControllerClose(otherBranch[_controller]);
}
if (chunk !== undefined) {
- assert(chunk.byteLength === 0);
+ let byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+ assert(byteLength === 0);
if (!byobCanceled) {
readableByteStreamControllerRespondWithNewView(
byobBranch[_controller],
@@ -4644,6 +4749,7 @@ function initializeByteLengthSizeFunction(globalObject) {
if (WeakMapPrototypeHas(byteSizeFunctionWeakMap, globalObject)) {
return;
}
+ // deno-lint-ignore prefer-primordials
const size = (chunk) => chunk.byteLength;
WeakMapPrototypeSet(byteSizeFunctionWeakMap, globalObject, size);
}
@@ -5098,17 +5204,29 @@ class ReadableStreamBYOBReader {
return PromiseReject(err);
}
- if (view.byteLength === 0) {
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (view),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (view));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (view),
+ );
+ }
+ if (byteLength === 0) {
return PromiseReject(
new TypeError("view must have non-zero byteLength"),
);
}
- if (view.buffer.byteLength === 0) {
+ if (getArrayBufferByteLength(buffer) === 0) {
return PromiseReject(
new TypeError("view's buffer must have non-zero byteLength"),
);
}
- if (isDetachedBuffer(view.buffer)) {
+ if (isDetachedBuffer(buffer)) {
return PromiseReject(
new TypeError("view's buffer has been detached"),
);
@@ -5213,13 +5331,22 @@ class ReadableStreamBYOBRequest {
if (this[_controller] === undefined) {
throw new TypeError("This BYOB request has been invalidated");
}
- if (isDetachedBuffer(this[_view].buffer)) {
+
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(this[_view]) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(this[_view]);
+ byteLength = DataViewPrototypeGetByteLength(this[_view]);
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(this[_view]);
+ byteLength = TypedArrayPrototypeGetByteLength(this[_view]);
+ }
+ if (isDetachedBuffer(buffer)) {
throw new TypeError(
"The BYOB request's buffer has been detached and so cannot be used as a response",
);
}
- assert(this[_view].byteLength > 0);
- assert(this[_view].buffer.byteLength > 0);
+ assert(byteLength > 0);
+ assert(getArrayBufferByteLength(buffer) > 0);
readableByteStreamControllerRespond(this[_controller], bytesWritten);
}
@@ -5236,7 +5363,14 @@ class ReadableStreamBYOBRequest {
if (this[_controller] === undefined) {
throw new TypeError("This BYOB request has been invalidated");
}
- if (isDetachedBuffer(view.buffer)) {
+
+ let buffer;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(view);
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(view);
+ }
+ if (isDetachedBuffer(buffer)) {
throw new TypeError(
"The given view's buffer has been detached and so cannot be used as a response",
);
@@ -5320,13 +5454,25 @@ class ReadableByteStreamController {
prefix,
context: arg1,
});
- if (chunk.byteLength === 0) {
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (chunk));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+ if (byteLength === 0) {
throw webidl.makeException(TypeError, "length must be non-zero", {
prefix,
context: arg1,
});
}
- if (chunk.buffer.byteLength === 0) {
+ if (getArrayBufferByteLength(buffer) === 0) {
throw webidl.makeException(
TypeError,
"buffer length must be non-zero",
diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js
index c6c75874a..2e19c3d1f 100644
--- a/ext/web/08_text_encoding.js
+++ b/ext/web/08_text_encoding.js
@@ -14,6 +14,9 @@ const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials;
const {
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
PromiseReject,
PromiseResolve,
// TODO(lucacasonato): add SharedArrayBuffer to primordials
@@ -21,6 +24,10 @@ const {
StringPrototypeCharCodeAt,
StringPrototypeSlice,
TypedArrayPrototypeSubarray,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
Uint8Array,
ObjectPrototypeIsPrototypeOf,
ArrayBufferIsView,
@@ -104,13 +111,27 @@ class TextDecoder {
}
try {
+ /** @type {ArrayBufferLike} */
+ let buffer = input;
+ if (ArrayBufferIsView(input)) {
+ if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
+ // TypedArray
+ buffer = TypedArrayPrototypeGetBuffer(
+ /** @type {Uint8Array} */ (input),
+ );
+ } else {
+ // DataView
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (input));
+ }
+ }
+
// Note from spec: implementations are strongly encouraged to use an implementation strategy that avoids this copy.
// When doing so they will have to make sure that changes to input do not affect future calls to decode().
if (
ObjectPrototypeIsPrototypeOf(
// deno-lint-ignore prefer-primordials
SharedArrayBuffer.prototype,
- input || input.buffer,
+ buffer,
)
) {
// We clone the data into a non-shared ArrayBuffer so we can pass it
@@ -118,13 +139,27 @@ class TextDecoder {
// `input` is now a Uint8Array, and calling the TypedArray constructor
// with a TypedArray argument copies the data.
if (ArrayBufferIsView(input)) {
- input = new Uint8Array(
- input.buffer,
- input.byteOffset,
- input.byteLength,
- );
+ if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
+ // TypedArray
+ input = new Uint8Array(
+ buffer,
+ TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (input),
+ ),
+ TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (input),
+ ),
+ );
+ } else {
+ // DataView
+ input = new Uint8Array(
+ buffer,
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)),
+ );
+ }
} else {
- input = new Uint8Array(input);
+ input = new Uint8Array(buffer);
}
}
diff --git a/ext/web/09_file.js b/ext/web/09_file.js
index 5ebef8f9d..1ecebe8a8 100644
--- a/ext/web/09_file.js
+++ b/ext/web/09_file.js
@@ -18,9 +18,13 @@ const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
ArrayBufferPrototypeSlice,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypePush,
AsyncGeneratorPrototypeNext,
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
Date,
DatePrototypeGetTime,
FinalizationRegistry,
@@ -37,6 +41,10 @@ const {
Symbol,
SymbolFor,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint8Array,
} = primordials;
@@ -100,6 +108,7 @@ function convertLineEndingsToNative(s) {
/** @param {(BlobReference | Blob)[]} parts */
async function* toIterator(parts) {
for (let i = 0; i < parts.length; ++i) {
+ // deno-lint-ignore prefer-primordials
yield* parts[i].stream();
}
}
@@ -120,15 +129,31 @@ function processBlobParts(parts, endings) {
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, element)) {
const chunk = new Uint8Array(ArrayBufferPrototypeSlice(element, 0));
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
- size += element.byteLength;
+ size += ArrayBufferPrototypeGetByteLength(element);
} else if (ArrayBufferIsView(element)) {
- const chunk = new Uint8Array(
- element.buffer,
- element.byteOffset,
- element.byteLength,
- );
- size += element.byteLength;
- ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ if (TypedArrayPrototypeGetSymbolToStringTag(element) !== undefined) {
+ // TypedArray
+ const chunk = new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (element)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (element)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (element)),
+ );
+ size += TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (element),
+ );
+ ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ } else {
+ // DataView
+ const chunk = new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (element)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (element)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (element)),
+ );
+ size += DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (element),
+ );
+ ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ }
} else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, element)) {
ArrayPrototypePush(processedParts, element);
size += element.size;
@@ -136,7 +161,7 @@ function processBlobParts(parts, endings) {
const chunk = core.encode(
endings == "native" ? convertLineEndingsToNative(element) : element,
);
- size += chunk.byteLength;
+ size += TypedArrayPrototypeGetByteLength(chunk);
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
} else {
throw new TypeError("Unreachable code (invalid element type)");
@@ -341,7 +366,7 @@ class Blob {
partIterator,
);
if (done) return controller.close();
- if (value.byteLength > 0) {
+ if (TypedArrayPrototypeGetByteLength(value) > 0) {
return controller.enqueue(value);
}
}
@@ -368,7 +393,7 @@ class Blob {
partIterator,
);
if (done) break;
- const byteLength = value.byteLength;
+ const byteLength = TypedArrayPrototypeGetByteLength(value);
if (byteLength > 0) {
TypedArrayPrototypeSet(bytes, value, offset);
offset += byteLength;
@@ -383,7 +408,7 @@ class Blob {
async arrayBuffer() {
webidl.assertBranded(this, BlobPrototype);
const buf = await this.#u8Array(this.size);
- return buf.buffer;
+ return TypedArrayPrototypeGetBuffer(buf);
}
[SymbolFor("Deno.customInspect")](inspect) {
@@ -554,7 +579,7 @@ class BlobReference {
*/
static fromUint8Array(data) {
const id = ops.op_blob_create_part(data);
- return new BlobReference(id, data.byteLength);
+ return new BlobReference(id, TypedArrayPrototypeGetByteLength(data));
}
/**
diff --git a/ext/web/10_filereader.js b/ext/web/10_filereader.js
index 5dd2d5c3a..524a3fe51 100644
--- a/ext/web/10_filereader.js
+++ b/ext/web/10_filereader.js
@@ -27,14 +27,15 @@ const {
MapPrototypeGet,
MapPrototypeSet,
ObjectDefineProperty,
- ObjectPrototypeIsPrototypeOf,
queueMicrotask,
SafeArrayIterator,
Symbol,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint8Array,
- Uint8ArrayPrototype,
} = primordials;
const state = Symbol("[[state]]");
@@ -119,7 +120,8 @@ class FileReader extends EventTarget {
// and whose value property is a Uint8Array object, run these steps:
if (
!chunk.done &&
- ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk.value)
+ TypedArrayPrototypeGetSymbolToStringTag(chunk.value) ===
+ "Uint8Array"
) {
ArrayPrototypePush(chunks, chunk.value);
@@ -127,7 +129,7 @@ class FileReader extends EventTarget {
{
const size = ArrayPrototypeReduce(
chunks,
- (p, i) => p + i.byteLength,
+ (p, i) => p + TypedArrayPrototypeGetByteLength(i),
0,
);
const ev = new ProgressEvent("progress", {
@@ -151,7 +153,7 @@ class FileReader extends EventTarget {
// 2. Let result be the result of package data given bytes, type, blob's type, and encodingName.
const size = ArrayPrototypeReduce(
chunks,
- (p, i) => p + i.byteLength,
+ (p, i) => p + TypedArrayPrototypeGetByteLength(i),
0,
);
const bytes = new Uint8Array(size);
@@ -159,11 +161,11 @@ class FileReader extends EventTarget {
for (let i = 0; i < chunks.length; ++i) {
const chunk = chunks[i];
TypedArrayPrototypeSet(bytes, chunk, offs);
- offs += chunk.byteLength;
+ offs += TypedArrayPrototypeGetByteLength(chunk);
}
switch (readtype.kind) {
case "ArrayBuffer": {
- this[result] = bytes.buffer;
+ this[result] = TypedArrayPrototypeGetBuffer(bytes);
break;
}
case "BinaryString":
diff --git a/ext/web/13_message_port.js b/ext/web/13_message_port.js
index f50d14d1a..6227bf92b 100644
--- a/ext/web/13_message_port.js
+++ b/ext/web/13_message_port.js
@@ -19,6 +19,7 @@ import DOMException from "ext:deno_web/01_dom_exception.js";
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
+ ArrayBufferPrototypeGetByteLength,
ArrayPrototypeFilter,
ArrayPrototypeIncludes,
ArrayPrototypePush,
@@ -249,7 +250,10 @@ function serializeJsMessageData(data, transferables) {
for (let i = 0, j = 0; i < transferables.length; i++) {
const ab = transferables[i];
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, ab)) {
- if (ab.byteLength === 0 && ops.op_arraybuffer_was_detached(ab)) {
+ if (
+ ArrayBufferPrototypeGetByteLength(ab) === 0 &&
+ ops.op_arraybuffer_was_detached(ab)
+ ) {
throw new DOMException(
`ArrayBuffer at index ${j} is already detached`,
"DataCloneError",
diff --git a/ext/web/14_compression.js b/ext/web/14_compression.js
index a3bca50e5..f6f22bed3 100644
--- a/ext/web/14_compression.js
+++ b/ext/web/14_compression.js
@@ -7,6 +7,10 @@
const core = globalThis.Deno.core;
const ops = core.ops;
+const primordials = globalThis.__bootstrap.primordials;
+const {
+ TypedArrayPrototypeGetByteLength,
+} = primordials;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { TransformStream } from "ext:deno_web/06_streams.js";
@@ -113,7 +117,7 @@ class DecompressionStream {
}
function maybeEnqueue(controller, output) {
- if (output && output.byteLength > 0) {
+ if (output && TypedArrayPrototypeGetByteLength(output) > 0) {
controller.enqueue(output);
}
}
diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js
index 124c81c73..43c0cb621 100644
--- a/ext/webidl/00_webidl.js
+++ b/ext/webidl/00_webidl.js
@@ -18,6 +18,7 @@ const {
BigInt,
BigIntAsIntN,
BigIntAsUintN,
+ DataViewPrototypeGetBuffer,
Float32Array,
Float64Array,
FunctionPrototypeBind,
@@ -76,6 +77,7 @@ const {
Symbol,
SymbolIterator,
SymbolToStringTag,
+ TypedArrayPrototypeGetBuffer,
TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint16Array,
@@ -476,7 +478,7 @@ converters.DataView = (V, opts = {}) => {
throw makeException(TypeError, "is not a DataView", opts);
}
- if (!opts.allowShared && isSharedArrayBuffer(V.buffer)) {
+ if (!opts.allowShared && isSharedArrayBuffer(DataViewPrototypeGetBuffer(V))) {
throw makeException(
TypeError,
"is backed by a SharedArrayBuffer, which is not allowed",
@@ -512,7 +514,10 @@ ArrayPrototypeForEach(
opts,
);
}
- if (!opts.allowShared && isSharedArrayBuffer(V.buffer)) {
+ if (
+ !opts.allowShared &&
+ isSharedArrayBuffer(TypedArrayPrototypeGetBuffer(V))
+ ) {
throw makeException(
TypeError,
"is a view on a SharedArrayBuffer, which is not allowed",
@@ -535,8 +540,13 @@ converters.ArrayBufferView = (V, opts = {}) => {
opts,
);
}
-
- if (!opts.allowShared && isSharedArrayBuffer(V.buffer)) {
+ let buffer;
+ if (TypedArrayPrototypeGetSymbolToStringTag(V) !== undefined) {
+ buffer = TypedArrayPrototypeGetBuffer(V);
+ } else {
+ buffer = DataViewPrototypeGetBuffer(V);
+ }
+ if (!opts.allowShared && isSharedArrayBuffer(buffer)) {
throw makeException(
TypeError,
"is a view on a SharedArrayBuffer, which is not allowed",
@@ -549,7 +559,13 @@ converters.ArrayBufferView = (V, opts = {}) => {
converters.BufferSource = (V, opts = {}) => {
if (ArrayBufferIsView(V)) {
- if (!opts.allowShared && isSharedArrayBuffer(V.buffer)) {
+ let buffer;
+ if (TypedArrayPrototypeGetSymbolToStringTag(V) !== undefined) {
+ buffer = TypedArrayPrototypeGetBuffer(V);
+ } else {
+ buffer = DataViewPrototypeGetBuffer(V);
+ }
+ if (!opts.allowShared && isSharedArrayBuffer(buffer)) {
throw makeException(
TypeError,
"is a view on a SharedArrayBuffer, which is not allowed",
diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js
index cadd35a50..5105df24d 100644
--- a/ext/websocket/01_websocket.js
+++ b/ext/websocket/01_websocket.js
@@ -22,16 +22,19 @@ const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
ArrayBufferIsView,
+ ArrayBufferPrototypeGetByteLength,
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypeSome,
DataView,
+ DataViewPrototypeGetByteLength,
ErrorPrototypeToString,
ObjectDefineProperties,
ObjectPrototypeIsPrototypeOf,
PromisePrototypeThen,
RegExpPrototypeTest,
Set,
+ SetPrototypeGetSize,
// TODO(lucacasonato): add SharedArrayBuffer to primordials
// SharedArrayBufferPrototype
String,
@@ -41,6 +44,8 @@ const {
SymbolIterator,
PromisePrototypeCatch,
SymbolFor,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetSymbolToStringTag,
} = primordials;
webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
@@ -211,9 +216,11 @@ class WebSocket extends EventTarget {
if (
protocols.length !==
- new Set(
- ArrayPrototypeMap(protocols, (p) => StringPrototypeToLowerCase(p)),
- ).size
+ SetPrototypeGetSize(
+ new Set(
+ ArrayPrototypeMap(protocols, (p) => StringPrototypeToLowerCase(p)),
+ ),
+ )
) {
throw new DOMException(
"Can't supply multiple times the same protocol.",
@@ -298,12 +305,16 @@ class WebSocket extends EventTarget {
throw new DOMException("readyState not OPEN", "InvalidStateError");
}
- const sendTypedArray = (ta) => {
- this[_bufferedAmount] += ta.byteLength;
+ /**
+ * @param {ArrayBufferView} view
+ * @param {number} byteLength
+ */
+ const sendTypedArray = (view, byteLength) => {
+ this[_bufferedAmount] += byteLength;
PromisePrototypeThen(
- core.opAsync2("op_ws_send_binary", this[_rid], ta),
+ core.opAsync2("op_ws_send_binary", this[_rid], view),
() => {
- this[_bufferedAmount] -= ta.byteLength;
+ this[_bufferedAmount] -= byteLength;
},
);
};
@@ -311,20 +322,33 @@ class WebSocket extends EventTarget {
if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) {
PromisePrototypeThen(
data.slice().arrayBuffer(),
- (ab) => sendTypedArray(new DataView(ab)),
+ (ab) =>
+ sendTypedArray(
+ new DataView(ab),
+ ArrayBufferPrototypeGetByteLength(ab),
+ ),
);
} else if (ArrayBufferIsView(data)) {
- sendTypedArray(data);
+ if (TypedArrayPrototypeGetSymbolToStringTag(data) === undefined) {
+ // DataView
+ sendTypedArray(data, DataViewPrototypeGetByteLength(data));
+ } else {
+ // TypedArray
+ sendTypedArray(data, TypedArrayPrototypeGetByteLength(data));
+ }
} else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) {
- sendTypedArray(new DataView(data));
+ sendTypedArray(
+ new DataView(data),
+ ArrayBufferPrototypeGetByteLength(data),
+ );
} else {
const string = String(data);
const d = core.encode(string);
- this[_bufferedAmount] += d.byteLength;
+ this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d);
PromisePrototypeThen(
core.opAsync2("op_ws_send_text", this[_rid], string),
() => {
- this[_bufferedAmount] -= d.byteLength;
+ this[_bufferedAmount] -= TypedArrayPrototypeGetByteLength(d);
},
);
}
@@ -361,7 +385,10 @@ class WebSocket extends EventTarget {
}
}
- if (reason !== undefined && core.encode(reason).byteLength > 123) {
+ if (
+ reason !== undefined &&
+ TypedArrayPrototypeGetByteLength(core.encode(reason)) > 123
+ ) {
throw new DOMException(
"The close reason may not be longer than 123 bytes.",
"SyntaxError",
diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js
index 6e487f0b7..46bd7deae 100644
--- a/ext/websocket/02_websocketstream.js
+++ b/ext/websocket/02_websocketstream.js
@@ -22,10 +22,12 @@ const {
PromisePrototypeCatch,
PromisePrototypeThen,
Set,
+ SetPrototypeGetSize,
StringPrototypeEndsWith,
StringPrototypeToLowerCase,
Symbol,
SymbolFor,
+ TypedArrayPrototypeGetByteLength,
TypeError,
Uint8ArrayPrototype,
} = primordials;
@@ -115,12 +117,14 @@ class WebSocketStream {
if (
options.protocols.length !==
- new Set(
- ArrayPrototypeMap(
- options.protocols,
- (p) => StringPrototypeToLowerCase(p),
+ SetPrototypeGetSize(
+ new Set(
+ ArrayPrototypeMap(
+ options.protocols,
+ (p) => StringPrototypeToLowerCase(p),
+ ),
),
- ).size
+ )
) {
throw new DOMException(
"Can't supply multiple times the same protocol.",
@@ -394,7 +398,8 @@ class WebSocketStream {
const encoder = new TextEncoder();
if (
- closeInfo.reason && encoder.encode(closeInfo.reason).byteLength > 123
+ closeInfo.reason &&
+ TypedArrayPrototypeGetByteLength(encoder.encode(closeInfo.reason)) > 123
) {
throw new DOMException(
"The close reason may not be longer than 123 bytes.",
diff --git a/runtime/js/13_buffer.js b/runtime/js/13_buffer.js
index 4534152f3..907b07128 100644
--- a/runtime/js/13_buffer.js
+++ b/runtime/js/13_buffer.js
@@ -7,9 +7,12 @@
import { assert } from "ext:deno_web/00_infra.js";
const primordials = globalThis.__bootstrap.primordials;
const {
+ ArrayBufferPrototypeGetByteLength,
TypedArrayPrototypeSubarray,
TypedArrayPrototypeSlice,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
MathFloor,
MathMin,
PromiseResolve,
@@ -28,12 +31,12 @@ const MAX_SIZE = 2 ** 32 - 2;
// from `src`.
// Returns the number of bytes copied.
function copyBytes(src, dst, off = 0) {
- const r = dst.byteLength - off;
- if (src.byteLength > r) {
+ const r = TypedArrayPrototypeGetByteLength(dst) - off;
+ if (TypedArrayPrototypeGetByteLength(src) > r) {
src = TypedArrayPrototypeSubarray(src, 0, r);
}
TypedArrayPrototypeSet(dst, src, off);
- return src.byteLength;
+ return TypedArrayPrototypeGetByteLength(src);
}
class Buffer {
@@ -57,15 +60,17 @@ class Buffer {
}
empty() {
- return this.#buf.byteLength <= this.#off;
+ return TypedArrayPrototypeGetByteLength(this.#buf) <= this.#off;
}
get length() {
- return this.#buf.byteLength - this.#off;
+ return TypedArrayPrototypeGetByteLength(this.#buf) - this.#off;
}
get capacity() {
- return this.#buf.buffer.byteLength;
+ return ArrayBufferPrototypeGetByteLength(
+ TypedArrayPrototypeGetBuffer(this.#buf),
+ );
}
truncate(n) {
@@ -85,7 +90,7 @@ class Buffer {
}
#tryGrowByReslice(n) {
- const l = this.#buf.byteLength;
+ const l = TypedArrayPrototypeGetByteLength(this.#buf);
if (n <= this.capacity - l) {
this.#reslice(l + n);
return l;
@@ -94,15 +99,16 @@ class Buffer {
}
#reslice(len) {
- assert(len <= this.#buf.buffer.byteLength);
- this.#buf = new Uint8Array(this.#buf.buffer, 0, len);
+ const ab = TypedArrayPrototypeGetBuffer(this.#buf);
+ assert(len <= ArrayBufferPrototypeGetByteLength(ab));
+ this.#buf = new Uint8Array(ab, 0, len);
}
readSync(p) {
if (this.empty()) {
// Buffer is empty, reset to recover space.
this.reset();
- if (p.byteLength === 0) {
+ if (TypedArrayPrototypeGetByteLength(p) === 0) {
// this edge case is tested in 'bufferReadEmptyAtEOF' test
return 0;
}
@@ -122,7 +128,7 @@ class Buffer {
}
writeSync(p) {
- const m = this.#grow(p.byteLength);
+ const m = this.#grow(TypedArrayPrototypeGetByteLength(p));
return copyBytes(p, this.#buf, m);
}
@@ -180,7 +186,7 @@ class Buffer {
// otherwise read directly into the internal buffer
const buf = shouldGrow
? tmp
- : new Uint8Array(this.#buf.buffer, this.length);
+ : new Uint8Array(TypedArrayPrototypeGetBuffer(this.#buf), this.length);
const nread = await r.read(buf);
if (nread === null) {
@@ -205,7 +211,7 @@ class Buffer {
// otherwise read directly into the internal buffer
const buf = shouldGrow
? tmp
- : new Uint8Array(this.#buf.buffer, this.length);
+ : new Uint8Array(TypedArrayPrototypeGetBuffer(this.#buf), this.length);
const nread = r.readSync(buf);
if (nread === null) {
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index 956f35d0a..fa16cc1f4 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -411,25 +411,25 @@ function bootstrapMainRuntime(runtimeOptions) {
throw new Error("Worker runtime already bootstrapped");
}
- const [
- args,
- cpuCount,
- debugFlag,
- denoVersion,
- locale,
- location_,
- noColor,
- isTty,
- tsVersion,
- unstableFlag,
- pid,
- ppid,
- target,
- v8Version,
- userAgent,
- inspectFlag,
- _,
- ] = runtimeOptions;
+ const {
+ 0: args,
+ 1: cpuCount,
+ 2: debugFlag,
+ 3: denoVersion,
+ 4: locale,
+ 5: location_,
+ 6: noColor,
+ 7: isTty,
+ 8: tsVersion,
+ 9: unstableFlag,
+ 10: pid,
+ 11: ppid,
+ 12: target,
+ 13: v8Version,
+ 14: userAgent,
+ 15: inspectFlag,
+ // 16: enableTestingFeaturesFlag
+ } = runtimeOptions;
performance.setTimeOrigin(DateNow());
globalThis_ = globalThis;
@@ -519,25 +519,25 @@ function bootstrapWorkerRuntime(
throw new Error("Worker runtime already bootstrapped");
}
- const [
- args,
- cpuCount,
- debugFlag,
- denoVersion,
- locale,
- location_,
- noColor,
- isTty,
- tsVersion,
- unstableFlag,
- pid,
- _ppid,
- target,
- v8Version,
- _userAgent,
- _inspectFlag,
- enableTestingFeaturesFlag,
- ] = runtimeOptions;
+ const {
+ 0: args,
+ 1: cpuCount,
+ 2: debugFlag,
+ 3: denoVersion,
+ 4: locale,
+ 5: location_,
+ 6: noColor,
+ 7: isTty,
+ 8: tsVersion,
+ 9: unstableFlag,
+ 10: pid,
+ // 11: ppid,
+ 12: target,
+ 13: v8Version,
+ // 14: userAgent,
+ // 15: inspectFlag,
+ 16: enableTestingFeaturesFlag,
+ } = runtimeOptions;
performance.setTimeOrigin(DateNow());
globalThis_ = globalThis;
diff --git a/tools/lint.js b/tools/lint.js
index f77ddbaf7..bdaa01562 100755
--- a/tools/lint.js
+++ b/tools/lint.js
@@ -25,8 +25,7 @@ if (Deno.args.includes("--rs")) {
if (!didLint) {
await Promise.all([
dlint(),
- // todo(dsherret): re-enable
- // dlintPreferPrimordials(),
+ dlintPreferPrimordials(),
checkCopyright(),
clippy(),
]);
@@ -96,6 +95,10 @@ async function dlintPreferPrimordials() {
const sourceFiles = await getSources(ROOT_PATH, [
"runtime/**/*.js",
"ext/**/*.js",
+ // TODO(petamoriken): enable for node polyfills
+ // "ext/node/polyfills/*.mjs",
+ // "ext/node/polyfills/*.ts",
+ // ":!:ext/node/polyfills/*.d.ts",
"core/*.js",
":!:core/*_test.js",
":!:core/examples/**",