chore: Turn back on dlintPreferPrimordials (#17715)

Closes #17709
This commit is contained in:
Kenta Moriuchi 2023-04-03 02:41:41 +09:00 committed by GitHub
parent ad8d0c90d1
commit 03edd48edd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 688 additions and 308 deletions

3
core/internal.d.ts vendored
View file

@ -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;

View file

@ -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) ?? "",
),
);
}

View file

@ -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() {

View file

@ -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;

View file

@ -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}`),

View file

@ -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",

View file

@ -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];
}
},
};
}

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
/**
@ -237,6 +244,21 @@ function transferArrayBuffer(O) {
return ops.op_transfer_arraybuffer(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}
@ -244,9 +266,25 @@ function transferArrayBuffer(O) {
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",

View file

@ -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);
}
}

View file

@ -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));
}
/**

View file

@ -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":

View file

@ -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",

View file

@ -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);
}
}

View file

@ -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",

View file

@ -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",

View file

@ -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.",

View file

@ -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) {

View file

@ -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;

View file

@ -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/**",