summaryrefslogtreecommitdiff
path: root/ext/web
diff options
context:
space:
mode:
authorKenta Moriuchi <moriken@kimamass.com>2023-04-03 02:41:41 +0900
committerGitHub <noreply@github.com>2023-04-02 19:41:41 +0200
commit03edd48edd004cec091541e6b71095cfbc4b4c87 (patch)
tree72aed1dae803334b73479ffebc7ca8c83d10addf /ext/web
parentad8d0c90d1887beb8a5f2c6d30f9dc71cc63e4fe (diff)
chore: Turn back on dlintPreferPrimordials (#17715)
Closes #17709
Diffstat (limited to 'ext/web')
-rw-r--r--ext/web/02_timers.js3
-rw-r--r--ext/web/06_streams.js214
-rw-r--r--ext/web/08_text_encoding.js49
-rw-r--r--ext/web/09_file.js51
-rw-r--r--ext/web/10_filereader.js16
-rw-r--r--ext/web/13_message_port.js6
-rw-r--r--ext/web/14_compression.js6
7 files changed, 281 insertions, 64 deletions
diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js
index c224be884..753848af1 100644
--- a/ext/web/02_timers.js
+++ b/ext/web/02_timers.js
@@ -19,6 +19,7 @@ const {
PromisePrototypeThen,
SafeArrayIterator,
SymbolFor,
+ TypedArrayPrototypeGetBuffer,
TypeError,
indirectEval,
} = primordials;
@@ -27,7 +28,7 @@ import { reportException } from "ext:deno_web/02_event.js";
import { assert } from "ext:deno_web/00_infra.js";
const hrU8 = new Uint8Array(8);
-const hr = new Uint32Array(hrU8.buffer);
+const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8));
function opNow() {
ops.op_now(hrU8);
return (hr[0] * 1000 + hr[1] / 1e6);
diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js
index 35d8f15e2..135a200ac 100644
--- a/ext/web/06_streams.js
+++ b/ext/web/06_streams.js
@@ -20,6 +20,7 @@ const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBuffer,
ArrayBufferPrototype,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypeMap,
ArrayPrototypePush,
@@ -67,6 +68,7 @@ const {
TypedArrayPrototypeGetByteOffset,
TypedArrayPrototypeGetSymbolToStringTag,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeSlice,
Uint8Array,
Uint16Array,
Uint32Array,
@@ -208,7 +210,12 @@ function uponPromise(promise, onFulfilled, onRejected) {
* @returns {boolean}
*/
function isDetachedBuffer(O) {
- return O.byteLength === 0 && ops.op_arraybuffer_was_detached(O);
+ // deno-lint-ignore prefer-primordials
+ if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) {
+ return false;
+ }
+ return ArrayBufferPrototypeGetByteLength(O) === 0 &&
+ ops.op_arraybuffer_was_detached(O);
}
/**
@@ -238,15 +245,46 @@ function transferArrayBuffer(O) {
}
/**
+ * @param {ArrayBufferLike} O
+ * @returns {number}
+ */
+function getArrayBufferByteLength(O) {
+ // deno-lint-ignore prefer-primordials
+ if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) {
+ // TODO(petamoriken): use primordials
+ // deno-lint-ignore prefer-primordials
+ return O.byteLength;
+ } else {
+ return ArrayBufferPrototypeGetByteLength(O);
+ }
+}
+
+/**
* @param {ArrayBufferView} O
* @returns {Uint8Array}
*/
function cloneAsUint8Array(O) {
assert(typeof O === "object");
assert(ArrayBufferIsView(O));
- assert(!isDetachedBuffer(O.buffer));
- const buffer = O.buffer.slice(O.byteOffset, O.byteOffset + O.byteLength);
- return new Uint8Array(buffer);
+ if (TypedArrayPrototypeGetSymbolToStringTag(O) !== undefined) {
+ // TypedArray
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (O)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (O)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (O)),
+ ),
+ );
+ } else {
+ // DataView
+ return TypedArrayPrototypeSlice(
+ new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (O)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (O)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (O)),
+ ),
+ );
+ }
}
const _abortAlgorithm = Symbol("[[abortAlgorithm]]");
@@ -695,7 +733,7 @@ function readableStreamForRid(rid, autoClose = true) {
if (controller[_readAll] === true) {
// fast path for tee'd streams consuming body
const chunk = await core.readAll(rid);
- if (chunk.byteLength > 0) {
+ if (TypedArrayPrototypeGetByteLength(chunk) > 0) {
controller.enqueue(chunk);
}
controller.close();
@@ -870,7 +908,7 @@ async function readableStreamCollectIntoUint8Array(stream) {
}
ArrayPrototypePush(chunks, chunk);
- totalLength += chunk.byteLength;
+ totalLength += TypedArrayPrototypeGetByteLength(chunk);
}
const finalBuffer = new Uint8Array(totalLength);
@@ -878,7 +916,7 @@ async function readableStreamCollectIntoUint8Array(stream) {
for (let i = 0; i < chunks.length; ++i) {
const chunk = chunks[i];
TypedArrayPrototypeSet(finalBuffer, chunk, offset);
- offset += chunk.byteLength;
+ offset += TypedArrayPrototypeGetByteLength(chunk);
}
return finalBuffer;
}
@@ -1092,7 +1130,25 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
return;
}
- const { buffer, byteOffset, byteLength } = chunk;
+ let buffer, byteLength, byteOffset;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ byteOffset = DataViewPrototypeGetByteOffset(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (chunk));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ byteOffset = TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+
if (isDetachedBuffer(buffer)) {
throw new TypeError(
"chunk's buffer is detached and so cannot be enqueued",
@@ -1101,6 +1157,7 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
const transferredBuffer = transferArrayBuffer(buffer);
if (controller[_pendingPullIntos].length !== 0) {
const firstPendingPullInto = controller[_pendingPullIntos][0];
+ // deno-lint-ignore prefer-primordials
if (isDetachedBuffer(firstPendingPullInto.buffer)) {
throw new TypeError(
"The BYOB request's buffer has been detached and so cannot be filled with an enqueued chunk",
@@ -1108,6 +1165,7 @@ function readableByteStreamControllerEnqueue(controller, chunk) {
}
readableByteStreamControllerInvalidateBYOBRequest(controller);
firstPendingPullInto.buffer = transferArrayBuffer(
+ // deno-lint-ignore prefer-primordials
firstPendingPullInto.buffer,
);
if (firstPendingPullInto.readerType === "none") {
@@ -1219,7 +1277,9 @@ function readableByteStreamControllerEnqueueDetachedPullIntoToQueue(
if (pullIntoDescriptor.bytesFilled > 0) {
readableByteStreamControllerEnqueueClonedChunkToQueue(
controller,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
pullIntoDescriptor.bytesFilled,
);
@@ -1238,8 +1298,11 @@ function readableByteStreamControllerGetBYOBRequest(controller) {
) {
const firstDescriptor = controller[_pendingPullIntos][0];
const view = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
firstDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteOffset + firstDescriptor.bytesFilled,
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteLength - firstDescriptor.bytesFilled,
);
const byobRequest = webidl.createBranded(ReadableStreamBYOBRequest);
@@ -1753,7 +1816,7 @@ function readableByteStreamControllerPullInto(
/** @type {PullIntoDescriptor} */
const pullIntoDescriptor = {
buffer,
- bufferByteLength: buffer.byteLength,
+ bufferByteLength: getArrayBufferByteLength(buffer),
byteOffset,
byteLength,
bytesFilled: 0,
@@ -1769,7 +1832,9 @@ function readableByteStreamControllerPullInto(
}
if (stream[_state] === "closed") {
const emptyView = new ctor(
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
0,
);
@@ -1828,11 +1893,13 @@ function readableByteStreamControllerRespond(controller, bytesWritten) {
}
if (
(firstDescriptor.bytesFilled + bytesWritten) >
+ // deno-lint-ignore prefer-primordials
firstDescriptor.byteLength
) {
throw new RangeError("bytesWritten out of range");
}
}
+ // deno-lint-ignore prefer-primordials
firstDescriptor.buffer = transferArrayBuffer(firstDescriptor.buffer);
readableByteStreamControllerRespondInternal(controller, bytesWritten);
}
@@ -1850,6 +1917,7 @@ function readableByteStreamControllerRespondInReadableState(
) {
assert(
(pullIntoDescriptor.bytesFilled + bytesWritten) <=
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteLength,
);
readableByteStreamControllerFillHeadPullIntoDescriptor(
@@ -1874,10 +1942,12 @@ function readableByteStreamControllerRespondInReadableState(
const remainderSize = pullIntoDescriptor.bytesFilled %
pullIntoDescriptor.elementSize;
if (remainderSize > 0) {
+ // deno-lint-ignore prefer-primordials
const end = pullIntoDescriptor.byteOffset +
pullIntoDescriptor.bytesFilled;
readableByteStreamControllerEnqueueClonedChunkToQueue(
controller,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
end - remainderSize,
remainderSize,
@@ -1903,6 +1973,7 @@ function readableByteStreamControllerRespondInternal(
bytesWritten,
) {
const firstDescriptor = controller[_pendingPullIntos][0];
+ // deno-lint-ignore prefer-primordials
assert(canTransferArrayBuffer(firstDescriptor.buffer));
readableByteStreamControllerInvalidateBYOBRequest(controller);
const state = controller[_stream][_state];
@@ -1994,47 +2065,57 @@ function readableByteStreamControllerCommitPullIntoDescriptor(
*/
function readableByteStreamControllerRespondWithNewView(controller, view) {
assert(controller[_pendingPullIntos].length !== 0);
- assert(!isDetachedBuffer(view.buffer));
+
+ let buffer, byteLength, byteOffset;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view));
+ byteLength = DataViewPrototypeGetByteLength(/** @type {DataView} */ (view));
+ byteOffset = DataViewPrototypeGetByteOffset(/** @type {DataView} */ (view));
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (view));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (view),
+ );
+ byteOffset = TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (view),
+ );
+ }
+ assert(!isDetachedBuffer(buffer));
const firstDescriptor = controller[_pendingPullIntos][0];
const state = controller[_stream][_state];
if (state === "closed") {
- if (view.byteLength !== 0) {
+ if (byteLength !== 0) {
throw new TypeError(
"The view's length must be 0 when calling respondWithNewView() on a closed stream",
);
}
} else {
assert(state === "readable");
- if (view.byteLength === 0) {
+ if (byteLength === 0) {
throw new TypeError(
"The view's length must be greater than 0 when calling respondWithNewView() on a readable stream",
);
}
}
- if (
- (firstDescriptor.byteOffset + firstDescriptor.bytesFilled) !==
- view.byteOffset
- ) {
+ // deno-lint-ignore prefer-primordials
+ if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== byteOffset) {
throw new RangeError(
"The region specified by view does not match byobRequest",
);
}
- if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) {
+ if (firstDescriptor.bufferByteLength !== getArrayBufferByteLength(buffer)) {
throw new RangeError(
"The buffer of view has different capacity than byobRequest",
);
}
- if (
- (firstDescriptor.bytesFilled + view.byteLength) >
- firstDescriptor.byteLength
- ) {
+ // deno-lint-ignore prefer-primordials
+ if (firstDescriptor.bytesFilled + byteLength > firstDescriptor.byteLength) {
throw new RangeError(
"The region specified by view is larger than byobRequest",
);
}
- const viewByteLength = view.byteLength;
- firstDescriptor.buffer = transferArrayBuffer(view.buffer);
- readableByteStreamControllerRespondInternal(controller, viewByteLength);
+ firstDescriptor.buffer = transferArrayBuffer(buffer);
+ readableByteStreamControllerRespondInternal(controller, byteLength);
}
/**
@@ -2060,6 +2141,7 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue(
(pullIntoDescriptor.bytesFilled % elementSize);
const maxBytesToCopy = MathMin(
controller[_queueTotalSize],
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled,
);
const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
@@ -2076,23 +2158,29 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue(
const headOfQueue = queue[0];
const bytesToCopy = MathMin(
totalBytesToCopyRemaining,
+ // deno-lint-ignore prefer-primordials
headOfQueue.byteLength,
);
+ // deno-lint-ignore prefer-primordials
const destStart = pullIntoDescriptor.byteOffset +
pullIntoDescriptor.bytesFilled;
const destBuffer = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.buffer,
destStart,
bytesToCopy,
);
const srcBuffer = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
headOfQueue.buffer,
+ // deno-lint-ignore prefer-primordials
headOfQueue.byteOffset,
bytesToCopy,
);
destBuffer.set(srcBuffer);
+ // deno-lint-ignore prefer-primordials
if (headOfQueue.byteLength === bytesToCopy) {
ArrayPrototypeShift(queue);
} else {
@@ -2126,11 +2214,15 @@ function readableByteStreamControllerFillReadRequestFromQueue(
) {
assert(controller[_queueTotalSize] > 0);
const entry = ArrayPrototypeShift(controller[_queue]);
+ // deno-lint-ignore prefer-primordials
controller[_queueTotalSize] -= entry.byteLength;
readableByteStreamControllerHandleQueueDrain(controller);
const view = new Uint8Array(
+ // deno-lint-ignore prefer-primordials
entry.buffer,
+ // deno-lint-ignore prefer-primordials
entry.byteOffset,
+ // deno-lint-ignore prefer-primordials
entry.byteLength,
);
readRequest.chunkSteps(view);
@@ -2164,11 +2256,14 @@ function readableByteStreamControllerConvertPullIntoDescriptor(
) {
const bytesFilled = pullIntoDescriptor.bytesFilled;
const elementSize = pullIntoDescriptor.elementSize;
+ // deno-lint-ignore prefer-primordials
assert(bytesFilled <= pullIntoDescriptor.byteLength);
assert((bytesFilled % elementSize) === 0);
+ // deno-lint-ignore prefer-primordials
const buffer = transferArrayBuffer(pullIntoDescriptor.buffer);
return new pullIntoDescriptor.viewConstructor(
buffer,
+ // deno-lint-ignore prefer-primordials
pullIntoDescriptor.byteOffset,
bytesFilled / elementSize,
);
@@ -3029,7 +3124,17 @@ function readableByteStreamTee(stream) {
readableByteStreamControllerClose(otherBranch[_controller]);
}
if (chunk !== undefined) {
- assert(chunk.byteLength === 0);
+ let byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+ assert(byteLength === 0);
if (!byobCanceled) {
readableByteStreamControllerRespondWithNewView(
byobBranch[_controller],
@@ -4644,6 +4749,7 @@ function initializeByteLengthSizeFunction(globalObject) {
if (WeakMapPrototypeHas(byteSizeFunctionWeakMap, globalObject)) {
return;
}
+ // deno-lint-ignore prefer-primordials
const size = (chunk) => chunk.byteLength;
WeakMapPrototypeSet(byteSizeFunctionWeakMap, globalObject, size);
}
@@ -5098,17 +5204,29 @@ class ReadableStreamBYOBReader {
return PromiseReject(err);
}
- if (view.byteLength === 0) {
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (view),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (view));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (view),
+ );
+ }
+ if (byteLength === 0) {
return PromiseReject(
new TypeError("view must have non-zero byteLength"),
);
}
- if (view.buffer.byteLength === 0) {
+ if (getArrayBufferByteLength(buffer) === 0) {
return PromiseReject(
new TypeError("view's buffer must have non-zero byteLength"),
);
}
- if (isDetachedBuffer(view.buffer)) {
+ if (isDetachedBuffer(buffer)) {
return PromiseReject(
new TypeError("view's buffer has been detached"),
);
@@ -5213,13 +5331,22 @@ class ReadableStreamBYOBRequest {
if (this[_controller] === undefined) {
throw new TypeError("This BYOB request has been invalidated");
}
- if (isDetachedBuffer(this[_view].buffer)) {
+
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(this[_view]) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(this[_view]);
+ byteLength = DataViewPrototypeGetByteLength(this[_view]);
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(this[_view]);
+ byteLength = TypedArrayPrototypeGetByteLength(this[_view]);
+ }
+ if (isDetachedBuffer(buffer)) {
throw new TypeError(
"The BYOB request's buffer has been detached and so cannot be used as a response",
);
}
- assert(this[_view].byteLength > 0);
- assert(this[_view].buffer.byteLength > 0);
+ assert(byteLength > 0);
+ assert(getArrayBufferByteLength(buffer) > 0);
readableByteStreamControllerRespond(this[_controller], bytesWritten);
}
@@ -5236,7 +5363,14 @@ class ReadableStreamBYOBRequest {
if (this[_controller] === undefined) {
throw new TypeError("This BYOB request has been invalidated");
}
- if (isDetachedBuffer(view.buffer)) {
+
+ let buffer;
+ if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(view);
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(view);
+ }
+ if (isDetachedBuffer(buffer)) {
throw new TypeError(
"The given view's buffer has been detached and so cannot be used as a response",
);
@@ -5320,13 +5454,25 @@ class ReadableByteStreamController {
prefix,
context: arg1,
});
- if (chunk.byteLength === 0) {
+ let buffer, byteLength;
+ if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) {
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk));
+ byteLength = DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (chunk),
+ );
+ } else {
+ buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (chunk));
+ byteLength = TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (chunk),
+ );
+ }
+ if (byteLength === 0) {
throw webidl.makeException(TypeError, "length must be non-zero", {
prefix,
context: arg1,
});
}
- if (chunk.buffer.byteLength === 0) {
+ if (getArrayBufferByteLength(buffer) === 0) {
throw webidl.makeException(
TypeError,
"buffer length must be non-zero",
diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js
index c6c75874a..2e19c3d1f 100644
--- a/ext/web/08_text_encoding.js
+++ b/ext/web/08_text_encoding.js
@@ -14,6 +14,9 @@ const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials;
const {
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
PromiseReject,
PromiseResolve,
// TODO(lucacasonato): add SharedArrayBuffer to primordials
@@ -21,6 +24,10 @@ const {
StringPrototypeCharCodeAt,
StringPrototypeSlice,
TypedArrayPrototypeSubarray,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
Uint8Array,
ObjectPrototypeIsPrototypeOf,
ArrayBufferIsView,
@@ -104,13 +111,27 @@ class TextDecoder {
}
try {
+ /** @type {ArrayBufferLike} */
+ let buffer = input;
+ if (ArrayBufferIsView(input)) {
+ if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
+ // TypedArray
+ buffer = TypedArrayPrototypeGetBuffer(
+ /** @type {Uint8Array} */ (input),
+ );
+ } else {
+ // DataView
+ buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (input));
+ }
+ }
+
// Note from spec: implementations are strongly encouraged to use an implementation strategy that avoids this copy.
// When doing so they will have to make sure that changes to input do not affect future calls to decode().
if (
ObjectPrototypeIsPrototypeOf(
// deno-lint-ignore prefer-primordials
SharedArrayBuffer.prototype,
- input || input.buffer,
+ buffer,
)
) {
// We clone the data into a non-shared ArrayBuffer so we can pass it
@@ -118,13 +139,27 @@ class TextDecoder {
// `input` is now a Uint8Array, and calling the TypedArray constructor
// with a TypedArray argument copies the data.
if (ArrayBufferIsView(input)) {
- input = new Uint8Array(
- input.buffer,
- input.byteOffset,
- input.byteLength,
- );
+ if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) {
+ // TypedArray
+ input = new Uint8Array(
+ buffer,
+ TypedArrayPrototypeGetByteOffset(
+ /** @type {Uint8Array} */ (input),
+ ),
+ TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (input),
+ ),
+ );
+ } else {
+ // DataView
+ input = new Uint8Array(
+ buffer,
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)),
+ );
+ }
} else {
- input = new Uint8Array(input);
+ input = new Uint8Array(buffer);
}
}
diff --git a/ext/web/09_file.js b/ext/web/09_file.js
index 5ebef8f9d..1ecebe8a8 100644
--- a/ext/web/09_file.js
+++ b/ext/web/09_file.js
@@ -18,9 +18,13 @@ const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
ArrayBufferPrototypeSlice,
+ ArrayBufferPrototypeGetByteLength,
ArrayBufferIsView,
ArrayPrototypePush,
AsyncGeneratorPrototypeNext,
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
Date,
DatePrototypeGetTime,
FinalizationRegistry,
@@ -37,6 +41,10 @@ const {
Symbol,
SymbolFor,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint8Array,
} = primordials;
@@ -100,6 +108,7 @@ function convertLineEndingsToNative(s) {
/** @param {(BlobReference | Blob)[]} parts */
async function* toIterator(parts) {
for (let i = 0; i < parts.length; ++i) {
+ // deno-lint-ignore prefer-primordials
yield* parts[i].stream();
}
}
@@ -120,15 +129,31 @@ function processBlobParts(parts, endings) {
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, element)) {
const chunk = new Uint8Array(ArrayBufferPrototypeSlice(element, 0));
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
- size += element.byteLength;
+ size += ArrayBufferPrototypeGetByteLength(element);
} else if (ArrayBufferIsView(element)) {
- const chunk = new Uint8Array(
- element.buffer,
- element.byteOffset,
- element.byteLength,
- );
- size += element.byteLength;
- ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ if (TypedArrayPrototypeGetSymbolToStringTag(element) !== undefined) {
+ // TypedArray
+ const chunk = new Uint8Array(
+ TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (element)),
+ TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (element)),
+ TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (element)),
+ );
+ size += TypedArrayPrototypeGetByteLength(
+ /** @type {Uint8Array} */ (element),
+ );
+ ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ } else {
+ // DataView
+ const chunk = new Uint8Array(
+ DataViewPrototypeGetBuffer(/** @type {DataView} */ (element)),
+ DataViewPrototypeGetByteOffset(/** @type {DataView} */ (element)),
+ DataViewPrototypeGetByteLength(/** @type {DataView} */ (element)),
+ );
+ size += DataViewPrototypeGetByteLength(
+ /** @type {DataView} */ (element),
+ );
+ ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
+ }
} else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, element)) {
ArrayPrototypePush(processedParts, element);
size += element.size;
@@ -136,7 +161,7 @@ function processBlobParts(parts, endings) {
const chunk = core.encode(
endings == "native" ? convertLineEndingsToNative(element) : element,
);
- size += chunk.byteLength;
+ size += TypedArrayPrototypeGetByteLength(chunk);
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
} else {
throw new TypeError("Unreachable code (invalid element type)");
@@ -341,7 +366,7 @@ class Blob {
partIterator,
);
if (done) return controller.close();
- if (value.byteLength > 0) {
+ if (TypedArrayPrototypeGetByteLength(value) > 0) {
return controller.enqueue(value);
}
}
@@ -368,7 +393,7 @@ class Blob {
partIterator,
);
if (done) break;
- const byteLength = value.byteLength;
+ const byteLength = TypedArrayPrototypeGetByteLength(value);
if (byteLength > 0) {
TypedArrayPrototypeSet(bytes, value, offset);
offset += byteLength;
@@ -383,7 +408,7 @@ class Blob {
async arrayBuffer() {
webidl.assertBranded(this, BlobPrototype);
const buf = await this.#u8Array(this.size);
- return buf.buffer;
+ return TypedArrayPrototypeGetBuffer(buf);
}
[SymbolFor("Deno.customInspect")](inspect) {
@@ -554,7 +579,7 @@ class BlobReference {
*/
static fromUint8Array(data) {
const id = ops.op_blob_create_part(data);
- return new BlobReference(id, data.byteLength);
+ return new BlobReference(id, TypedArrayPrototypeGetByteLength(data));
}
/**
diff --git a/ext/web/10_filereader.js b/ext/web/10_filereader.js
index 5dd2d5c3a..524a3fe51 100644
--- a/ext/web/10_filereader.js
+++ b/ext/web/10_filereader.js
@@ -27,14 +27,15 @@ const {
MapPrototypeGet,
MapPrototypeSet,
ObjectDefineProperty,
- ObjectPrototypeIsPrototypeOf,
queueMicrotask,
SafeArrayIterator,
Symbol,
TypedArrayPrototypeSet,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetSymbolToStringTag,
TypeError,
Uint8Array,
- Uint8ArrayPrototype,
} = primordials;
const state = Symbol("[[state]]");
@@ -119,7 +120,8 @@ class FileReader extends EventTarget {
// and whose value property is a Uint8Array object, run these steps:
if (
!chunk.done &&
- ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk.value)
+ TypedArrayPrototypeGetSymbolToStringTag(chunk.value) ===
+ "Uint8Array"
) {
ArrayPrototypePush(chunks, chunk.value);
@@ -127,7 +129,7 @@ class FileReader extends EventTarget {
{
const size = ArrayPrototypeReduce(
chunks,
- (p, i) => p + i.byteLength,
+ (p, i) => p + TypedArrayPrototypeGetByteLength(i),
0,
);
const ev = new ProgressEvent("progress", {
@@ -151,7 +153,7 @@ class FileReader extends EventTarget {
// 2. Let result be the result of package data given bytes, type, blob's type, and encodingName.
const size = ArrayPrototypeReduce(
chunks,
- (p, i) => p + i.byteLength,
+ (p, i) => p + TypedArrayPrototypeGetByteLength(i),
0,
);
const bytes = new Uint8Array(size);
@@ -159,11 +161,11 @@ class FileReader extends EventTarget {
for (let i = 0; i < chunks.length; ++i) {
const chunk = chunks[i];
TypedArrayPrototypeSet(bytes, chunk, offs);
- offs += chunk.byteLength;
+ offs += TypedArrayPrototypeGetByteLength(chunk);
}
switch (readtype.kind) {
case "ArrayBuffer": {
- this[result] = bytes.buffer;
+ this[result] = TypedArrayPrototypeGetBuffer(bytes);
break;
}
case "BinaryString":
diff --git a/ext/web/13_message_port.js b/ext/web/13_message_port.js
index f50d14d1a..6227bf92b 100644
--- a/ext/web/13_message_port.js
+++ b/ext/web/13_message_port.js
@@ -19,6 +19,7 @@ import DOMException from "ext:deno_web/01_dom_exception.js";
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
+ ArrayBufferPrototypeGetByteLength,
ArrayPrototypeFilter,
ArrayPrototypeIncludes,
ArrayPrototypePush,
@@ -249,7 +250,10 @@ function serializeJsMessageData(data, transferables) {
for (let i = 0, j = 0; i < transferables.length; i++) {
const ab = transferables[i];
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, ab)) {
- if (ab.byteLength === 0 && ops.op_arraybuffer_was_detached(ab)) {
+ if (
+ ArrayBufferPrototypeGetByteLength(ab) === 0 &&
+ ops.op_arraybuffer_was_detached(ab)
+ ) {
throw new DOMException(
`ArrayBuffer at index ${j} is already detached`,
"DataCloneError",
diff --git a/ext/web/14_compression.js b/ext/web/14_compression.js
index a3bca50e5..f6f22bed3 100644
--- a/ext/web/14_compression.js
+++ b/ext/web/14_compression.js
@@ -7,6 +7,10 @@
const core = globalThis.Deno.core;
const ops = core.ops;
+const primordials = globalThis.__bootstrap.primordials;
+const {
+ TypedArrayPrototypeGetByteLength,
+} = primordials;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { TransformStream } from "ext:deno_web/06_streams.js";
@@ -113,7 +117,7 @@ class DecompressionStream {
}
function maybeEnqueue(controller, output) {
- if (output && output.byteLength > 0) {
+ if (output && TypedArrayPrototypeGetByteLength(output) > 0) {
controller.enqueue(output);
}
}