mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
parent
ad8d0c90d1
commit
03edd48edd
21 changed files with 688 additions and 308 deletions
3
core/internal.d.ts
vendored
3
core/internal.d.ts
vendored
|
@ -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;
|
||||
|
|
|
@ -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) ?? "",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
ArrayBufferIsView(input)
|
||||
? new Uint8Array(input.buffer, input.byteOffset, input.byteLength)
|
||||
: new Uint8Array(input),
|
||||
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(
|
||||
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)
|
||||
)
|
||||
) {
|
||||
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() {
|
||||
|
|
|
@ -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)) {
|
||||
} else if (ArrayBufferIsView(object)) {
|
||||
const tag = TypedArrayPrototypeGetSymbolToStringTag(object);
|
||||
if (tag === "Uint8Array") {
|
||||
// Fast(er) path for common case of Uint8Array
|
||||
const copy = TypedArrayPrototypeSlice(object, 0, object.byteLength);
|
||||
const copy = TypedArrayPrototypeSlice(
|
||||
object,
|
||||
TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (object)),
|
||||
TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (object)),
|
||||
);
|
||||
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 (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;
|
||||
|
|
|
@ -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}`),
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)) {
|
||||
if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
|
||||
// TypedArray
|
||||
input = new Uint8Array(
|
||||
input.buffer,
|
||||
input.byteOffset,
|
||||
input.byteLength,
|
||||
buffer,
|
||||
TypedArrayPrototypeGetByteOffset(
|
||||
/** @type {Uint8Array} */ (input),
|
||||
),
|
||||
TypedArrayPrototypeGetByteLength(
|
||||
/** @type {Uint8Array} */ (input),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
input = new Uint8Array(input);
|
||||
// DataView
|
||||
input = new Uint8Array(
|
||||
buffer,
|
||||
DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)),
|
||||
DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
input = new Uint8Array(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
if (TypedArrayPrototypeGetSymbolToStringTag(element) !== undefined) {
|
||||
// TypedArray
|
||||
const chunk = new Uint8Array(
|
||||
element.buffer,
|
||||
element.byteOffset,
|
||||
element.byteLength,
|
||||
TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (element)),
|
||||
TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (element)),
|
||||
TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (element)),
|
||||
);
|
||||
size += TypedArrayPrototypeGetByteLength(
|
||||
/** @type {Uint8Array} */ (element),
|
||||
);
|
||||
size += element.byteLength;
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 !==
|
||||
SetPrototypeGetSize(
|
||||
new Set(
|
||||
ArrayPrototypeMap(protocols, (p) => StringPrototypeToLowerCase(p)),
|
||||
).size
|
||||
),
|
||||
)
|
||||
) {
|
||||
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",
|
||||
|
|
|
@ -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 !==
|
||||
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.",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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/**",
|
||||
|
|
Loading…
Reference in a new issue