diff options
author | Kenta Moriuchi <moriken@kimamass.com> | 2023-04-03 02:41:41 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-02 19:41:41 +0200 |
commit | 03edd48edd004cec091541e6b71095cfbc4b4c87 (patch) | |
tree | 72aed1dae803334b73479ffebc7ca8c83d10addf /ext/web | |
parent | ad8d0c90d1887beb8a5f2c6d30f9dc71cc63e4fe (diff) |
chore: Turn back on dlintPreferPrimordials (#17715)
Closes #17709
Diffstat (limited to 'ext/web')
-rw-r--r-- | ext/web/02_timers.js | 3 | ||||
-rw-r--r-- | ext/web/06_streams.js | 214 | ||||
-rw-r--r-- | ext/web/08_text_encoding.js | 49 | ||||
-rw-r--r-- | ext/web/09_file.js | 51 | ||||
-rw-r--r-- | ext/web/10_filereader.js | 16 | ||||
-rw-r--r-- | ext/web/13_message_port.js | 6 | ||||
-rw-r--r-- | ext/web/14_compression.js | 6 |
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); } } |