aboutsummaryrefslogtreecommitdiff
path: root/src/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript')
-rw-r--r--src/javascript/jsc/base.zig61
-rw-r--r--src/javascript/jsc/bindings/BunBuiltinNames.h4
-rw-r--r--src/javascript/jsc/bindings/ReadableByteStreamControllerBuiltins.cpp15
-rw-r--r--src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp114
-rw-r--r--src/javascript/jsc/bindings/ReadableStreamBYOBReaderBuiltins.cpp8
-rw-r--r--src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp87
-rw-r--r--src/javascript/jsc/bindings/ReadableStreamBuiltins.h2
-rw-r--r--src/javascript/jsc/bindings/ReadableStreamDefaultReaderBuiltins.cpp65
-rw-r--r--src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp57
-rw-r--r--src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp129
-rw-r--r--src/javascript/jsc/bindings/StreamInternalsBuiltins.h8
-rw-r--r--src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp31
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.cpp20
-rw-r--r--src/javascript/jsc/bindings/bindings.zig10
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableByteStreamController.js13
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js76
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableStream.js84
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableStreamBYOBReader.js4
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableStreamDefaultReader.js59
-rw-r--r--src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js39
-rw-r--r--src/javascript/jsc/bindings/builtins/js/StreamInternals.js114
-rw-r--r--src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js19
-rw-r--r--src/javascript/jsc/event_loop.zig4
-rw-r--r--src/javascript/jsc/webcore/response.zig329
24 files changed, 711 insertions, 641 deletions
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig
index 0b895ed82..777a5d6ef 100644
--- a/src/javascript/jsc/base.zig
+++ b/src/javascript/jsc/base.zig
@@ -2306,61 +2306,6 @@ pub const ArrayBuffer = extern struct {
return this.toJSUnchecked(ctx, exception);
}
- pub fn toJSAutoAllocator(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue {
- if (!this.value.isEmpty()) {
- return this.value;
- }
-
- if (this.byte_len >= bun.huge_allocator_threshold) {
- if (this.typed_array_type == .ArrayBuffer) {
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
- ctx,
- this.ptr,
- this.byte_len,
- MmapArrayBuffer_deallocator,
- @intToPtr(*anyopaque, this.byte_len),
- exception,
- ));
- }
-
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.typed_array_type.toC(),
- this.ptr,
- this.byte_len,
- MmapArrayBuffer_deallocator,
- @intToPtr(*anyopaque, this.byte_len),
- exception,
- ));
- }
-
- // If it's not a mimalloc heap buffer, we're not going to call a deallocator
- if (!bun.Global.Mimalloc.mi_is_in_heap_region(this.ptr)) {
- if (this.typed_array_type == .ArrayBuffer) {
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
- ctx,
- this.ptr,
- this.byte_len,
- null,
- null,
- exception,
- ));
- }
-
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.typed_array_type.toC(),
- this.ptr,
- this.byte_len,
- null,
- null,
- exception,
- ));
- }
-
- return this.toJSUnchecked(ctx, exception);
- }
-
pub fn toJSWithContext(
this: ArrayBuffer,
ctx: JSC.C.JSContextRef,
@@ -2609,12 +2554,6 @@ pub export fn MarkedArrayBuffer_deallocator(bytes_: *anyopaque, _: *anyopaque) v
mimalloc.mi_free(bytes_);
}
-pub export fn MmapArrayBuffer_deallocator(bytes: *anyopaque, length_as_ptr: *anyopaque) void {
- const length = @ptrToInt(length_as_ptr);
- var ptr = @ptrCast([*]u8, bytes);
-
- bun.auto_allocator.free(ptr[0..length]);
-}
pub export fn BlobArrayBuffer_deallocator(_: *anyopaque, blob: *anyopaque) void {
// zig's memory allocator interface won't work here
// mimalloc knows the size of things
diff --git a/src/javascript/jsc/bindings/BunBuiltinNames.h b/src/javascript/jsc/bindings/BunBuiltinNames.h
index 0acfb0bb5..e849f914d 100644
--- a/src/javascript/jsc/bindings/BunBuiltinNames.h
+++ b/src/javascript/jsc/bindings/BunBuiltinNames.h
@@ -67,8 +67,10 @@ using namespace JSC;
macro(controlledReadableStream) \
macro(controller) \
macro(cork) \
- macro(createReadableStream) \
+ macro(createFIFO) \
macro(createNativeReadableStream) \
+ macro(createReadableStream) \
+ macro(createUninitializedArrayBuffer) \
macro(createWritableStreamFromInternal) \
macro(cwd) \
macro(dataView) \
diff --git a/src/javascript/jsc/bindings/ReadableByteStreamControllerBuiltins.cpp b/src/javascript/jsc/bindings/ReadableByteStreamControllerBuiltins.cpp
index 2532f608b..b09754494 100644
--- a/src/javascript/jsc/bindings/ReadableByteStreamControllerBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableByteStreamControllerBuiltins.cpp
@@ -131,7 +131,7 @@ const char* const s_readableByteStreamControllerCloseCode =
const JSC::ConstructAbility s_readableByteStreamControllerByobRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamControllerByobRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamControllerByobRequestCodeLength = 759;
+const int s_readableByteStreamControllerByobRequestCodeLength = 817;
static const JSC::Intrinsic s_readableByteStreamControllerByobRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamControllerByobRequestCode =
"(function ()\n" \
@@ -141,12 +141,17 @@ const char* const s_readableByteStreamControllerByobRequestCode =
" if (!@isReadableByteStreamController(this))\n" \
" throw @makeGetterTypeError(\"ReadableByteStreamController\", \"byobRequest\");\n" \
"\n" \
- " if (@getByIdDirectPrivate(this, \"byobRequest\") === @undefined && @getByIdDirectPrivate(this, \"pendingPullIntos\").length) {\n" \
- " const firstDescriptor = @getByIdDirectPrivate(this, \"pendingPullIntos\")[0];\n" \
- " const view = new @Uint8Array(firstDescriptor.buffer,\n" \
+ " \n" \
+ " var request = @getByIdDirectPrivate(this, \"byobRequest\");\n" \
+ " if (request === @undefined) {\n" \
+ " var pending = @getByIdDirectPrivate(this, \"pendingPullIntos\");\n" \
+ " const firstDescriptor = pending.peek();\n" \
+ " if (firstDescriptor) {\n" \
+ " const view = new @Uint8Array(firstDescriptor.buffer,\n" \
" firstDescriptor.byteOffset + firstDescriptor.bytesFilled,\n" \
" firstDescriptor.byteLength - firstDescriptor.bytesFilled);\n" \
- " @putByIdDirectPrivate(this, \"byobRequest\", new @ReadableStreamBYOBRequest(this, view, @isReadableStream));\n" \
+ " @putByIdDirectPrivate(this, \"byobRequest\", new @ReadableStreamBYOBRequest(this, view, @isReadableStream));\n" \
+ " }\n" \
" }\n" \
"\n" \
" return @getByIdDirectPrivate(this, \"byobRequest\");\n" \
diff --git a/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp
index f8faa0b4a..97dd3ba81 100644
--- a/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
const JSC::ConstructAbility s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeLength = 2333;
+const int s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeLength = 2344;
static const JSC::Intrinsic s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCode =
"(function (stream, underlyingByteSource, highWaterMark)\n" \
@@ -84,7 +84,7 @@ const char* const s_readableByteStreamInternalsPrivateInitializeReadableByteStre
" @throwRangeError(\"autoAllocateChunkSize value is negative or equal to positive or negative infinity\");\n" \
" }\n" \
" @putByIdDirectPrivate(this, \"autoAllocateChunkSize\", autoAllocateChunkSize);\n" \
- " @putByIdDirectPrivate(this, \"pendingPullIntos\", []);\n" \
+ " @putByIdDirectPrivate(this, \"pendingPullIntos\", @createFIFO());\n" \
"\n" \
" const controller = this;\n" \
" const startResult = @promiseInvokeOrNoopNoCatch(underlyingByteSource, \"start\", [this]).@then(() => {\n" \
@@ -166,7 +166,7 @@ const char* const s_readableByteStreamInternalsIsReadableStreamBYOBReaderCode =
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeLength = 392;
+const int s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeLength = 398;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerCancelCode =
"(function (controller, reason)\n" \
@@ -174,8 +174,10 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerCance
" \"use strict\";\n" \
"\n" \
" var pendingPullIntos = @getByIdDirectPrivate(controller, \"pendingPullIntos\");\n" \
- " if (pendingPullIntos.length > 0)\n" \
- " pendingPullIntos[0].bytesFilled = 0;\n" \
+ " var first = pendingPullIntos.peek();\n" \
+ " if (first)\n" \
+ " first.bytesFilled = 0;\n" \
+ "\n" \
" @putByIdDirectPrivate(controller, \"queue\", @newQueue());\n" \
" return @promiseInvokeOrNoop(@getByIdDirectPrivate(controller, \"underlyingByteSource\"), \"cancel\", [reason]);\n" \
"})\n" \
@@ -199,7 +201,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerError
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeLength = 848;
+const int s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeLength = 809;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerCloseCode =
"(function (controller)\n" \
@@ -214,9 +216,9 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerClose
" return;\n" \
" }\n" \
"\n" \
- " var pendingPullIntos = @getByIdDirectPrivate(controller, \"pendingPullIntos\");\n" \
- " if (pendingPullIntos.length > 0) {\n" \
- " if (pendingPullIntos[0].bytesFilled > 0) {\n" \
+ " var first = @getByIdDirectPrivate(controller, \"pendingPullIntos\")?.peek();\n" \
+ " if (first) {\n" \
+ " if (first.bytesFilled > 0) {\n" \
" const e = @makeTypeError(\"Close requested while there remain pending bytes\");\n" \
" @readableByteStreamControllerError(controller, e);\n" \
" throw e;\n" \
@@ -229,7 +231,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerClose
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeLength = 178;
+const int s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeLength = 347;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCode =
"(function (controller)\n" \
@@ -237,7 +239,12 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerClear
" \"use strict\";\n" \
"\n" \
" @readableByteStreamControllerInvalidateBYOBRequest(controller);\n" \
- " @putByIdDirectPrivate(controller, \"pendingPullIntos\", []);\n" \
+ " var existing = @getByIdDirectPrivate(controller, \"pendingPullIntos\");\n" \
+ " if (existing !== @undefined) {\n" \
+ " existing.clear();\n" \
+ " } else {\n" \
+ " @putByIdDirectPrivate(controller, \"pendingPullIntos\", @createFIFO());\n" \
+ " }\n" \
"})\n" \
;
@@ -309,7 +316,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerHandl
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerPullCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerPullCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerPullCodeLength = 1701;
+const int s_readableByteStreamInternalsReadableByteStreamControllerPullCodeLength = 1706;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerPullCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullCode =
"(function (controller)\n" \
@@ -320,8 +327,8 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullC
" @assert(@readableStreamHasDefaultReader(stream));\n" \
"\n" \
" if (@getByIdDirectPrivate(controller, \"queue\").size > 0) {\n" \
- " @assert(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length === 0);\n" \
- " const entry = @getByIdDirectPrivate(controller, \"queue\").content.@shift();\n" \
+ " @assert(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isEmpty());\n" \
+ " const entry = @getByIdDirectPrivate(controller, \"queue\").content.shift();\n" \
" @getByIdDirectPrivate(controller, \"queue\").size -= entry.byteLength;\n" \
" @readableByteStreamControllerHandleQueueDrain(controller);\n" \
" let view;\n" \
@@ -336,7 +343,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullC
" if (@getByIdDirectPrivate(controller, \"autoAllocateChunkSize\") !== @undefined) {\n" \
" let buffer;\n" \
" try {\n" \
- " buffer = new @ArrayBuffer(@getByIdDirectPrivate(controller, \"autoAllocateChunkSize\"));\n" \
+ " buffer = @createUninitializedArrayBuffer(@getByIdDirectPrivate(controller, \"autoAllocateChunkSize\"));\n" \
" } catch (error) {\n" \
" return @Promise.@reject(error);\n" \
" }\n" \
@@ -349,7 +356,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullC
" ctor: @Uint8Array,\n" \
" readerType: 'default'\n" \
" };\n" \
- " @arrayPush(@getByIdDirectPrivate(controller, \"pendingPullIntos\"), pullIntoDescriptor);\n" \
+ " @getByIdDirectPrivate(controller, \"pendingPullIntos\").push(pullIntoDescriptor);\n" \
" }\n" \
"\n" \
" const promise = @readableStreamAddReadRequest(stream);\n" \
@@ -360,7 +367,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullC
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength = 868;
+const int s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength = 874;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCode =
"(function (controller)\n" \
@@ -375,9 +382,9 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerShoul
" return false;\n" \
" if (!@getByIdDirectPrivate(controller, \"started\"))\n" \
" return false;\n" \
- " if (@readableStreamHasDefaultReader(stream) && (@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length > 0 || !!@getByIdDirectPrivate(reader, \"bunNativePtr\")))\n" \
+ " if (@readableStreamHasDefaultReader(stream) && (@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isNotEmpty() || !!@getByIdDirectPrivate(reader, \"bunNativePtr\")))\n" \
" return true;\n" \
- " if (@readableStreamHasBYOBReader(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\").length > 0)\n" \
+ " if (@readableStreamHasBYOBReader(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\")?.isNotEmpty())\n" \
" return true;\n" \
" if (@readableByteStreamControllerGetDesiredSize(controller) > 0)\n" \
" return true;\n" \
@@ -455,7 +462,7 @@ const char* const s_readableByteStreamInternalsReadableStreamReaderKindCode =
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength = 1642;
+const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength = 1649;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCode =
"(function (controller, chunk)\n" \
@@ -471,10 +478,10 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnque
" switch (reader ? @readableStreamReaderKind(reader) : 0) {\n" \
" \n" \
" case 1: {\n" \
- " if (!@getByIdDirectPrivate(reader, \"readRequests\").length)\n" \
+ " if (!@getByIdDirectPrivate(reader, \"readRequests\")?.isNotEmpty())\n" \
" @readableByteStreamControllerEnqueueChunk(controller, @transferBufferToCurrentRealm(chunk.buffer), chunk.byteOffset, chunk.byteLength);\n" \
" else {\n" \
- " @assert(!@getByIdDirectPrivate(controller, \"queue\").content.length);\n" \
+ " @assert(!@getByIdDirectPrivate(controller, \"queue\").content.size());\n" \
" const transferredView = chunk.constructor === @Uint8Array ? chunk : new @Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n" \
" @readableStreamFulfillReadRequest(stream, transferredView, false);\n" \
" }\n" \
@@ -506,14 +513,14 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnque
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeLength = 310;
+const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeLength = 303;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCode =
"(function (controller, buffer, byteOffset, byteLength)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " @arrayPush(@getByIdDirectPrivate(controller, \"queue\").content, {\n" \
+ " @getByIdDirectPrivate(controller, \"queue\").content.push({\n" \
" buffer: buffer,\n" \
" byteOffset: byteOffset,\n" \
" byteLength: byteLength\n" \
@@ -524,17 +531,17 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnque
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeLength = 609;
+const int s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeLength = 619;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCode =
"(function (controller, view)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").length > 0);\n" \
- "\n" \
- " let firstDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\")[0];\n" \
+ " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").isNotEmpty());\n" \
"\n" \
+ " let firstDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\").peek();\n" \
+ " \n" \
" if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset)\n" \
" @throwRangeError(\"Invalid value for view.byteOffset\");\n" \
"\n" \
@@ -548,7 +555,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeLength = 409;
+const int s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeLength = 411;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondCode =
"(function (controller, bytesWritten)\n" \
@@ -560,7 +567,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
" if (@isNaN(bytesWritten) || bytesWritten === @Infinity || bytesWritten < 0 )\n" \
" @throwRangeError(\"bytesWritten has an incorrect value\");\n" \
"\n" \
- " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").length > 0);\n" \
+ " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").isNotEmpty());\n" \
"\n" \
" @readableByteStreamControllerRespondInternal(controller, bytesWritten);\n" \
"})\n" \
@@ -568,14 +575,14 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeLength = 708;
+const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeLength = 712;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCode =
"(function (controller, bytesWritten)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " let firstDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\")[0];\n" \
+ " let firstDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\").peek();\n" \
" let stream = @getByIdDirectPrivate(controller, \"controlledReadableStream\");\n" \
"\n" \
" if (@getByIdDirectPrivate(stream, \"state\") === @streamClosed) {\n" \
@@ -591,7 +598,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeLength = 1439;
+const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeLength = 1440;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCode =
"(function (controller, bytesWritten, pullIntoDescriptor)\n" \
@@ -601,7 +608,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
" if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength)\n" \
" @throwRangeError(\"bytesWritten value is too great\");\n" \
"\n" \
- " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").length === 0 || @getByIdDirectPrivate(controller, \"pendingPullIntos\")[0] === pullIntoDescriptor);\n" \
+ " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").isEmpty() || @getByIdDirectPrivate(controller, \"pendingPullIntos\").peek() === pullIntoDescriptor);\n" \
" @readableByteStreamControllerInvalidateBYOBRequest(controller);\n" \
" pullIntoDescriptor.bytesFilled += bytesWritten;\n" \
"\n" \
@@ -626,7 +633,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeLength = 727;
+const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeLength = 730;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCode =
"(function (controller, firstDescriptor)\n" \
@@ -637,7 +644,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
" @assert(firstDescriptor.bytesFilled === 0);\n" \
"\n" \
" if (@readableStreamHasBYOBReader(@getByIdDirectPrivate(controller, \"controlledReadableStream\"))) {\n" \
- " while (@getByIdDirectPrivate(@getByIdDirectPrivate(@getByIdDirectPrivate(controller, \"controlledReadableStream\"), \"reader\"), \"readIntoRequests\").length > 0) {\n" \
+ " while (@getByIdDirectPrivate(@getByIdDirectPrivate(@getByIdDirectPrivate(controller, \"controlledReadableStream\"), \"reader\"), \"readIntoRequests\")?.isNotEmpty()) {\n" \
" let pullIntoDescriptor = @readableByteStreamControllerShiftPendingDescriptor(controller);\n" \
" @readableByteStreamControllerCommitDescriptor(@getByIdDirectPrivate(controller, \"controlledReadableStream\"), pullIntoDescriptor);\n" \
" }\n" \
@@ -647,7 +654,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespo
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeLength = 706;
+const int s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeLength = 712;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCode =
"(function (controller)\n" \
@@ -655,10 +662,10 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerProce
" \"use strict\";\n" \
"\n" \
" @assert(!@getByIdDirectPrivate(controller, \"closeRequested\"));\n" \
- " while (@getByIdDirectPrivate(controller, \"pendingPullIntos\").length > 0) {\n" \
+ " while (@getByIdDirectPrivate(controller, \"pendingPullIntos\").isNotEmpty()) {\n" \
" if (@getByIdDirectPrivate(controller, \"queue\").size === 0)\n" \
" return;\n" \
- " let pullIntoDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\")[0];\n" \
+ " let pullIntoDescriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\").peek();\n" \
" if (@readableByteStreamControllerFillDescriptorFromQueue(controller, pullIntoDescriptor)) {\n" \
" @readableByteStreamControllerShiftPendingDescriptor(controller);\n" \
" @readableByteStreamControllerCommitDescriptor(@getByIdDirectPrivate(controller, \"controlledReadableStream\"), pullIntoDescriptor);\n" \
@@ -669,7 +676,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerProce
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeLength = 2355;
+const int s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeLength = 2359;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCode =
"(function (controller, pullIntoDescriptor)\n" \
@@ -690,7 +697,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerFillD
" }\n" \
"\n" \
" while (totalBytesToCopyRemaining > 0) {\n" \
- " let headOfQueue = @getByIdDirectPrivate(controller, \"queue\").content[0];\n" \
+ " let headOfQueue = @getByIdDirectPrivate(controller, \"queue\").content.peek();\n" \
" const bytesToCopy = totalBytesToCopyRemaining < headOfQueue.byteLength ? totalBytesToCopyRemaining : headOfQueue.byteLength;\n" \
" //\n" \
" //\n" \
@@ -701,14 +708,14 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerFillD
" new @Uint8Array(pullIntoDescriptor.buffer).set(new @Uint8Array(headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy), destStart);\n" \
"\n" \
" if (headOfQueue.byteLength === bytesToCopy)\n" \
- " @getByIdDirectPrivate(controller, \"queue\").content.@shift();\n" \
+ " @getByIdDirectPrivate(controller, \"queue\").content.shift();\n" \
" else {\n" \
" headOfQueue.byteOffset += bytesToCopy;\n" \
" headOfQueue.byteLength -= bytesToCopy;\n" \
" }\n" \
"\n" \
" @getByIdDirectPrivate(controller, \"queue\").size -= bytesToCopy;\n" \
- " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").length === 0 || @getByIdDirectPrivate(controller, \"pendingPullIntos\")[0] === pullIntoDescriptor);\n" \
+ " @assert(@getByIdDirectPrivate(controller, \"pendingPullIntos\").isEmpty() || @getByIdDirectPrivate(controller, \"pendingPullIntos\").peek() === pullIntoDescriptor);\n" \
" @readableByteStreamControllerInvalidateBYOBRequest(controller);\n" \
" pullIntoDescriptor.bytesFilled += bytesToCopy;\n" \
" totalBytesToCopyRemaining -= bytesToCopy;\n" \
@@ -726,14 +733,14 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerFillD
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeLength = 223;
+const int s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeLength = 222;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCode =
"(function (controller)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " let descriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\").@shift();\n" \
+ " let descriptor = @getByIdDirectPrivate(controller, \"pendingPullIntos\").shift();\n" \
" @readableByteStreamControllerInvalidateBYOBRequest(controller);\n" \
" return descriptor;\n" \
"})\n" \
@@ -800,13 +807,13 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerConve
const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeLength = 244;
+const int s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeLength = 243;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCode =
"(function (stream, chunk, done)\n" \
"{\n" \
" \"use strict\";\n" \
- " const readIntoRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\").@shift();\n" \
+ " const readIntoRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\").shift();\n" \
" @fulfillPromise(readIntoRequest, { value: chunk, done: done });\n" \
"})\n" \
;
@@ -833,7 +840,7 @@ const char* const s_readableByteStreamInternalsReadableStreamBYOBReaderReadCode
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeLength = 2216;
+const int s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeLength = 2190;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCode =
"(function (controller, view)\n" \
@@ -873,9 +880,10 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullI
" readerType: 'byob'\n" \
" };\n" \
"\n" \
- " if (@getByIdDirectPrivate(controller, \"pendingPullIntos\").length) {\n" \
+ " var pending = @getByIdDirectPrivate(controller, \"pendingPullIntos\");\n" \
+ " if (pending?.isNotEmpty()) {\n" \
" pullIntoDescriptor.buffer = @transferBufferToCurrentRealm(pullIntoDescriptor.buffer);\n" \
- " @arrayPush(@getByIdDirectPrivate(controller, \"pendingPullIntos\"), pullIntoDescriptor);\n" \
+ " pending.push(pullIntoDescriptor);\n" \
" return @readableStreamAddReadIntoRequest(stream);\n" \
" }\n" \
"\n" \
@@ -898,7 +906,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullI
" }\n" \
"\n" \
" pullIntoDescriptor.buffer = @transferBufferToCurrentRealm(pullIntoDescriptor.buffer);\n" \
- " @arrayPush(@getByIdDirectPrivate(controller, \"pendingPullIntos\"), pullIntoDescriptor);\n" \
+ " @getByIdDirectPrivate(controller, \"pendingPullIntos\").push(pullIntoDescriptor);\n" \
" const promise = @readableStreamAddReadIntoRequest(stream);\n" \
" @readableByteStreamControllerCallPullIfNeeded(controller);\n" \
" return promise;\n" \
@@ -907,7 +915,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullI
const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeLength = 437;
+const int s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeLength = 430;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCode =
"(function (stream)\n" \
@@ -918,7 +926,7 @@ const char* const s_readableByteStreamInternalsReadableStreamAddReadIntoRequestC
" @assert(@getByIdDirectPrivate(stream, \"state\") === @streamReadable || @getByIdDirectPrivate(stream, \"state\") === @streamClosed);\n" \
"\n" \
" const readRequest = @newPromise();\n" \
- " @arrayPush(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\"), readRequest);\n" \
+ " @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\").push(readRequest);\n" \
"\n" \
" return readRequest;\n" \
"})\n" \
diff --git a/src/javascript/jsc/bindings/ReadableStreamBYOBReaderBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamBYOBReaderBuiltins.cpp
index c6514f616..81486dffe 100644
--- a/src/javascript/jsc/bindings/ReadableStreamBYOBReaderBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableStreamBYOBReaderBuiltins.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
const JSC::ConstructAbility s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeLength = 574;
+const int s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeLength = 585;
static const JSC::Intrinsic s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCode =
"(function (stream)\n" \
@@ -64,7 +64,7 @@ const char* const s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCo
" @throwTypeError(\"ReadableStream is locked\");\n" \
"\n" \
" @readableStreamReaderGenericInitialize(this, stream);\n" \
- " @putByIdDirectPrivate(this, \"readIntoRequests\", []);\n" \
+ " @putByIdDirectPrivate(this, \"readIntoRequests\", @createFIFO());\n" \
"\n" \
" return this;\n" \
"})\n" \
@@ -119,7 +119,7 @@ const char* const s_readableStreamBYOBReaderReadCode =
const JSC::ConstructAbility s_readableStreamBYOBReaderReleaseLockCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamBYOBReaderReleaseLockCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamBYOBReaderReleaseLockCodeLength = 440;
+const int s_readableStreamBYOBReaderReleaseLockCodeLength = 447;
static const JSC::Intrinsic s_readableStreamBYOBReaderReleaseLockCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamBYOBReaderReleaseLockCode =
"(function ()\n" \
@@ -132,7 +132,7 @@ const char* const s_readableStreamBYOBReaderReleaseLockCode =
" if (!@getByIdDirectPrivate(this, \"ownerReadableStream\"))\n" \
" return;\n" \
"\n" \
- " if (@getByIdDirectPrivate(this, \"readIntoRequests\").length)\n" \
+ " if (@getByIdDirectPrivate(this, \"readIntoRequests\")?.isNotEmpty())\n" \
" @throwTypeError(\"There are still pending read requests, cannot release the lock\");\n" \
"\n" \
" @readableStreamReaderGenericRelease(this);\n" \
diff --git a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp
index a268cf2ce..68155a460 100644
--- a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp
@@ -119,82 +119,73 @@ const char* const s_readableStreamInitializeReadableStreamCode =
const JSC::ConstructAbility s_readableStreamCreateNativeReadableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamCreateNativeReadableStreamCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamCreateNativeReadableStreamCodeLength = 2905;
+const int s_readableStreamCreateNativeReadableStreamCodeLength = 3152;
static const JSC::Intrinsic s_readableStreamCreateNativeReadableStreamCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamCreateNativeReadableStreamCode =
- "(function (nativePtr, nativeType) {\n" \
+ "(function (nativePtr, nativeType, autoAllocateChunkSize) {\n" \
" \"use strict\";\n" \
" var cached = globalThis[Symbol.for(\"Bun.nativeReadableStreamPrototype\")] ||= new @Map;\n" \
" var Prototype = cached.@get(nativeType);\n" \
" if (Prototype === @undefined) {\n" \
" var [pull, start, cancel, setClose, deinit] = globalThis[Symbol.for(\"Bun.lazy\")](nativeType);\n" \
" var closer = [false];\n" \
- "\n" \
+ "var handleResult;\n" \
" function handleNativeReadableStreamPromiseResult(val) {\n" \
" \"use strict\";\n" \
- " var {r, c} = this;\n" \
- " this.r = @undefined;\n" \
+ " var {c, v} = this;\n" \
" this.c = @undefined;\n" \
- " r(val, c);\n" \
+ " this.v = @undefined;\n" \
+ " closer[0] = false;\n" \
+ " handleResult(val, c, v);\n" \
" }\n" \
" \n" \
- " function closeNativeReadableStreamOnNextTick(controller) {\n" \
- " \"use strict\";\n" \
- " controller.close();\n" \
- " controller = @undefined;\n" \
- " } \n" \
- "\n" \
- " var handleResult = function handleResult(result, controller) {\n" \
+ " \n" \
+ " handleResult = function handleResult(result, controller, view) {\n" \
" \"use strict\";\n" \
"\n" \
" if (result && @isPromise(result)) {\n" \
- " return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, r: handleResult}), controller.error);\n" \
+ " return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, v: view}), (err) => controller.error(err));\n" \
" } else if (result !== false) {\n" \
- " controller.enqueue(result);\n" \
+ " if (view && view.byteLength === result) {\n" \
+ " controller.byobRequest.respondWithNewView(view);\n" \
+ " } else {\n" \
+ " controller.byobRequest.respond(result);\n" \
+ " }\n" \
" }\n" \
"\n" \
" if (closer[0] || result === false) {\n" \
- " @enqueueJob(closeNativeReadableStreamOnNextTick, controller);\n" \
+ " @enqueueJob(() => controller.close());\n" \
" closer[0] = false;\n" \
" }\n" \
- " }\n" \
+ " };\n" \
"\n" \
" Prototype = class NativeReadableStreamSource {\n" \
- " constructor(tag) {\n" \
+ " constructor(tag, autoAllocateChunkSize) {\n" \
" this.pull = this.pull_.bind(tag);\n" \
- " this.start = this.start_.bind(tag);\n" \
" this.cancel = this.cancel_.bind(tag);\n" \
+ " this.autoAllocateChunkSize = autoAllocateChunkSize;\n" \
" }\n" \
"\n" \
" pull;\n" \
- " start;\n" \
" cancel;\n" \
- " \n" \
- " pull_(controller) {\n" \
- " closer[0] = false;\n" \
- " var result;\n" \
- "\n" \
- " try {\n" \
- " result = pull(this, closer);\n" \
- " } catch(err) {\n" \
- " return controller.error(err);\n" \
- " }\n" \
"\n" \
- " return handleResult(result, controller);\n" \
- " }\n" \
+ " type = \"bytes\";\n" \
+ " autoAllocateChunkSize = 0;\n" \
"\n" \
- " start_(controller) {\n" \
- " setClose(this, controller.close);\n" \
+ " static startSync = start;\n" \
+ " \n" \
+ " pull_(controller) {\n" \
" closer[0] = false;\n" \
" var result;\n" \
"\n" \
+ " const view = controller.byobRequest.view;\n" \
" try {\n" \
- " result = start(this, closer);\n" \
+ " result = pull(this, view, closer);\n" \
" } catch(err) {\n" \
" return controller.error(err);\n" \
" }\n" \
"\n" \
- " return handleResult(result, controller);\n" \
+ " return handleResult(result, controller, view);\n" \
" }\n" \
"\n" \
" cancel_(reason) {\n" \
@@ -206,7 +197,29 @@ const char* const s_readableStreamCreateNativeReadableStreamCode =
" cached.@set(nativeType, Prototype);\n" \
" }\n" \
" \n" \
- " var instance = new Prototype(nativePtr);\n" \
+ " //\n" \
+ " //\n" \
+ " //\n" \
+ " const chunkSize = Prototype.startSync(nativePtr, autoAllocateChunkSize);\n" \
+ "\n" \
+ " //\n" \
+ " if (chunkSize === 0) {\n" \
+ " return new @ReadableStream({\n" \
+ " start(controller) {\n" \
+ " controller.close();\n" \
+ " },\n" \
+ "\n" \
+ " pull() {\n" \
+ "\n" \
+ " },\n" \
+ "\n" \
+ " cancel() {\n" \
+ "\n" \
+ " },\n" \
+ " });\n" \
+ " }\n" \
+ "\n" \
+ " var instance = new Prototype(nativePtr, chunkSize);\n" \
" Prototype.registry.register(instance, nativePtr);\n" \
" var stream = new @ReadableStream(instance);\n" \
" @putByIdDirectPrivate(stream, \"bunNativeType\", nativeType);\n" \
diff --git a/src/javascript/jsc/bindings/ReadableStreamBuiltins.h b/src/javascript/jsc/bindings/ReadableStreamBuiltins.h
index ccf3e9b7c..2cd7f6b6e 100644
--- a/src/javascript/jsc/bindings/ReadableStreamBuiltins.h
+++ b/src/javascript/jsc/bindings/ReadableStreamBuiltins.h
@@ -82,7 +82,7 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind;
#define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_DATA(macro) \
macro(initializeReadableStream, readableStreamInitializeReadableStream, 2) \
- macro(createNativeReadableStream, readableStreamCreateNativeReadableStream, 2) \
+ macro(createNativeReadableStream, readableStreamCreateNativeReadableStream, 3) \
macro(cancel, readableStreamCancel, 1) \
macro(getReader, readableStreamGetReader, 1) \
macro(pipeThrough, readableStreamPipeThrough, 2) \
diff --git a/src/javascript/jsc/bindings/ReadableStreamDefaultReaderBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamDefaultReaderBuiltins.cpp
index e1933d425..f488ffea0 100644
--- a/src/javascript/jsc/bindings/ReadableStreamDefaultReaderBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableStreamDefaultReaderBuiltins.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
const JSC::ConstructAbility s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeLength = 382;
+const int s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeLength = 393;
static const JSC::Intrinsic s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCode =
"(function (stream)\n" \
@@ -62,7 +62,7 @@ const char* const s_readableStreamDefaultReaderInitializeReadableStreamDefaultRe
" @throwTypeError(\"ReadableStream is locked\");\n" \
"\n" \
" @readableStreamReaderGenericInitialize(this, stream);\n" \
- " @putByIdDirectPrivate(this, \"readRequests\", []);\n" \
+ " @putByIdDirectPrivate(this, \"readRequests\", @createFIFO());\n" \
"\n" \
" return this;\n" \
"})\n" \
@@ -89,7 +89,7 @@ const char* const s_readableStreamDefaultReaderCancelCode =
const JSC::ConstructAbility s_readableStreamDefaultReaderReadManyCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamDefaultReaderReadManyCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamDefaultReaderReadManyCodeLength = 3797;
+const int s_readableStreamDefaultReaderReadManyCodeLength = 2136;
static const JSC::Intrinsic s_readableStreamDefaultReaderReadManyCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamDefaultReaderReadManyCode =
"(function ()\n" \
@@ -111,30 +111,14 @@ const char* const s_readableStreamDefaultReaderReadManyCode =
" throw @getByIdDirectPrivate(stream, \"storedError\");\n" \
" }\n" \
"\n" \
- " const controller = @getByIdDirectPrivate(stream, \"readableStreamController\");\n" \
+ " var controller = @getByIdDirectPrivate(stream, \"readableStreamController\");\n" \
" \n" \
" const content = @getByIdDirectPrivate(controller, \"queue\").content;\n" \
" var size = @getByIdDirectPrivate(controller, \"queue\").size;\n" \
+ " var values = content.toArray(false);\n" \
+ " var length = values.length;\n" \
"\n" \
- " var values = new @Array(content.length);\n" \
- "\n" \
- " if (content.length > 0) {\n" \
- " if (\"buffer\" in content[0]) {\n" \
- " values[0] = new @Uint8Array(content[0].buffer, content[0].byteOffset, content[0].byteLength);\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, new @Uint8Array(content[i].buffer, content[i].byteOffset, content[i].byteLength));\n" \
- " }\n" \
- " } else if (typeof content[0] === 'object' && content[0] && \"byteLength\" in content[0]) {\n" \
- " size = 0;\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, content[i].value);\n" \
- " size += content[i].value.byteLength;\n" \
- " }\n" \
- " } else {\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, content[i].value);\n" \
- " }\n" \
- " }\n" \
+ " if (length > 0) {\n" \
" @resetQueue(@getByIdDirectPrivate(controller, \"queue\"));\n" \
"\n" \
" if (@getByIdDirectPrivate(controller, \"closeRequested\"))\n" \
@@ -146,44 +130,23 @@ const char* const s_readableStreamDefaultReaderReadManyCode =
" if (done) {\n" \
" return {value: [], size: 0, done: true};\n" \
" }\n" \
- "\n" \
- " const content = queue.content;\n" \
- " var values = new @Array(content.length + 1);\n" \
- " \n" \
+ " var queue = @getByIdDirectPrivate(controller, \"queue\");\n" \
+ " const content = [value].concat(queue.content.toArray(false));\n" \
" var size = queue.size;\n" \
- "\n" \
- " if (\"buffer\" in content[0]) {\n" \
- " values[0] = new @Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, new @Uint8Array(content[i].buffer, content[i].byteOffset, content[i].byteLength));\n" \
- " }\n" \
- " size += value.byteLength;\n" \
- " } else if (typeof value === 'object' && value && \"byteLength\" in value) {\n" \
- " size += value.byteLength;\n" \
- " values[0] = value;\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, content[i].value);\n" \
- " size += content[i].value.byteLength;\n" \
- " }\n" \
- "\n" \
- " } else {\n" \
- " values[0] = value;\n" \
- " for (var i = 0; i < content.length; ++i) {\n" \
- " @putByValDirect(values, i+1, content[i].value);\n" \
- " }\n" \
- " }\n" \
- "\n" \
" @resetQueue(queue);\n" \
"\n" \
" if (@getByIdDirectPrivate(controller, \"closeRequested\"))\n" \
" @readableStreamClose(@getByIdDirectPrivate(controller, \"controlledReadableStream\"));\n" \
" else\n" \
" @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \
+ " controller = @undefined;\n" \
"\n" \
" return {value: values, size: size, done: false};\n" \
" });\n" \
" }\n" \
"\n" \
+ " controller = @undefined;\n" \
+ "\n" \
" return {value: values, size, done: false};\n" \
"})\n" \
;
@@ -208,7 +171,7 @@ const char* const s_readableStreamDefaultReaderReadCode =
const JSC::ConstructAbility s_readableStreamDefaultReaderReleaseLockCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamDefaultReaderReleaseLockCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamDefaultReaderReleaseLockCodeLength = 442;
+const int s_readableStreamDefaultReaderReleaseLockCodeLength = 449;
static const JSC::Intrinsic s_readableStreamDefaultReaderReleaseLockCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamDefaultReaderReleaseLockCode =
"(function ()\n" \
@@ -221,7 +184,7 @@ const char* const s_readableStreamDefaultReaderReleaseLockCode =
" if (!@getByIdDirectPrivate(this, \"ownerReadableStream\"))\n" \
" return;\n" \
"\n" \
- " if (@getByIdDirectPrivate(this, \"readRequests\").length)\n" \
+ " if (@getByIdDirectPrivate(this, \"readRequests\")?.isNotEmpty())\n" \
" @throwTypeError(\"There are still pending read requests, cannot release the lock\");\n" \
"\n" \
" @readableStreamReaderGenericRelease(this);\n" \
diff --git a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp
index 99ef5176a..b7ae6f1df 100644
--- a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp
+++ b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp
@@ -688,7 +688,7 @@ const char* const s_readableStreamInternalsIsReadableStreamDefaultControllerCode
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamErrorCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamErrorCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamErrorCodeLength = 1283;
+const int s_readableStreamInternalsReadableStreamErrorCodeLength = 1295;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamErrorCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamErrorCode =
"(function (stream, error)\n" \
@@ -707,15 +707,15 @@ const char* const s_readableStreamInternalsReadableStreamErrorCode =
"\n" \
" if (@isReadableStreamDefaultReader(reader)) {\n" \
" const requests = @getByIdDirectPrivate(reader, \"readRequests\");\n" \
- " @putByIdDirectPrivate(reader, \"readRequests\", []);\n" \
- " for (let index = 0, length = requests.length; index < length; ++index)\n" \
- " @rejectPromise(requests[index], error);\n" \
+ " @putByIdDirectPrivate(reader, \"readRequests\", @createFIFO());\n" \
+ " for (var request = requests.shift(); request; request = requests.shift())\n" \
+ " @rejectPromise(request, error);\n" \
" } else {\n" \
" @assert(@isReadableStreamBYOBReader(reader));\n" \
" const requests = @getByIdDirectPrivate(reader, \"readIntoRequests\");\n" \
- " @putByIdDirectPrivate(reader, \"readIntoRequests\", []);\n" \
- " for (let index = 0, length = requests.length; index < length; ++index)\n" \
- " @rejectPromise(requests[index], error);\n" \
+ " @putByIdDirectPrivate(reader, \"readIntoRequests\", @createFIFO());\n" \
+ " for (var request = requests.shift(); request; request = requests.shift())\n" \
+ " @rejectPromise(request, error);\n" \
" }\n" \
"\n" \
" @getByIdDirectPrivate(reader, \"closedPromiseCapability\").@reject.@call(@undefined, error);\n" \
@@ -726,7 +726,7 @@ const char* const s_readableStreamInternalsReadableStreamErrorCode =
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength = 652;
+const int s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength = 659;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCode =
"(function (controller)\n" \
@@ -737,7 +737,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerShould
" return false;\n" \
" if (!@getByIdDirectPrivate(controller, \"started\"))\n" \
" return false;\n" \
- " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \
+ " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \
" return false;\n" \
" const desiredSize = @readableStreamDefaultControllerGetDesiredSize(controller);\n" \
" @assert(desiredSize !== null);\n" \
@@ -747,7 +747,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerShould
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength = 1239;
+const int s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength = 1246;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCode =
"(function (controller)\n" \
@@ -761,7 +761,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPu
" return;\n" \
" if (!@getByIdDirectPrivate(controller, \"started\"))\n" \
" return;\n" \
- " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \
+ " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \
" return;\n" \
"\n" \
" if (@getByIdDirectPrivate(controller, \"pulling\")) {\n" \
@@ -870,16 +870,17 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCancel
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerPullCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerPullCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamDefaultControllerPullCodeLength = 805;
+const int s_readableStreamInternalsReadableStreamDefaultControllerPullCodeLength = 742;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerPullCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamDefaultControllerPullCode =
"(function (controller)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " if (@getByIdDirectPrivate(controller, \"queue\").content.length) {\n" \
- " const chunk = @dequeueValue(@getByIdDirectPrivate(controller, \"queue\"));\n" \
- " if (@getByIdDirectPrivate(controller, \"closeRequested\") && @getByIdDirectPrivate(controller, \"queue\").content.length === 0)\n" \
+ " var queue = @getByIdDirectPrivate(controller, \"queue\");\n" \
+ " if (queue.isNotEmpty()) {\n" \
+ " const chunk = @dequeueValue(queue);\n" \
+ " if (@getByIdDirectPrivate(controller, \"closeRequested\") && queue.isEmpty())\n" \
" @readableStreamClose(@getByIdDirectPrivate(controller, \"controlledReadableStream\"));\n" \
" else\n" \
" @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \
@@ -894,7 +895,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerPullCo
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeLength = 352;
+const int s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeLength = 346;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamDefaultControllerCloseCode =
"(function (controller)\n" \
@@ -903,14 +904,14 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCloseC
"\n" \
" @assert(@readableStreamDefaultControllerCanCloseOrEnqueue(controller));\n" \
" @putByIdDirectPrivate(controller, \"closeRequested\", true);\n" \
- " if (@getByIdDirectPrivate(controller, \"queue\").content.length === 0)\n" \
+ " if (!@getByIdDirectPrivate(controller, \"queue\")?.isNotEmpty())\n" \
" @readableStreamClose(@getByIdDirectPrivate(controller, \"controlledReadableStream\"));\n" \
"})\n" \
;
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamCloseCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamCloseCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamCloseCodeLength = 697;
+const int s_readableStreamInternalsReadableStreamCloseCodeLength = 712;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamCloseCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamCloseCode =
"(function (stream)\n" \
@@ -926,9 +927,10 @@ const char* const s_readableStreamInternalsReadableStreamCloseCode =
"\n" \
" if (@isReadableStreamDefaultReader(reader)) {\n" \
" const requests = @getByIdDirectPrivate(reader, \"readRequests\");\n" \
- " @putByIdDirectPrivate(reader, \"readRequests\", []);\n" \
- " for (let index = 0, length = requests.length; index < length; ++index)\n" \
- " @fulfillPromise(requests[index], { value: @undefined, done: true });\n" \
+ " @putByIdDirectPrivate(reader, \"readRequests\", @createFIFO());\n" \
+ " \n" \
+ " for (var request = requests.shift(); request; request = requests.shift())\n" \
+ " @fulfillPromise(request, { value: @undefined, done: true });\n" \
" }\n" \
"\n" \
" @getByIdDirectPrivate(reader, \"closedPromiseCapability\").@resolve.@call();\n" \
@@ -937,20 +939,20 @@ const char* const s_readableStreamInternalsReadableStreamCloseCode =
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamFulfillReadRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamFulfillReadRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamFulfillReadRequestCodeLength = 232;
+const int s_readableStreamInternalsReadableStreamFulfillReadRequestCodeLength = 231;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamFulfillReadRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamFulfillReadRequestCode =
"(function (stream, chunk, done)\n" \
"{\n" \
" \"use strict\";\n" \
- " const readRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").@shift();\n" \
+ " const readRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").shift();\n" \
" @fulfillPromise(readRequest, { value: chunk, done: done });\n" \
"})\n" \
;
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeLength = 986;
+const int s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeLength = 990;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCode =
"(function (controller, chunk)\n" \
@@ -961,7 +963,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerEnqueu
" //\n" \
" @assert(@readableStreamDefaultControllerCanCloseOrEnqueue(controller));\n" \
"\n" \
- " if (@isReadableStreamLocked(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length) {\n" \
+ " if (@isReadableStreamLocked(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").isNotEmpty) {\n" \
" @readableStreamFulfillReadRequest(stream, chunk, false);\n" \
" @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \
" return;\n" \
@@ -1007,7 +1009,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultReaderReadCode =
const JSC::ConstructAbility s_readableStreamInternalsReadableStreamAddReadRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamInternalsReadableStreamAddReadRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_readableStreamInternalsReadableStreamAddReadRequestCodeLength = 375;
+const int s_readableStreamInternalsReadableStreamAddReadRequestCodeLength = 373;
static const JSC::Intrinsic s_readableStreamInternalsReadableStreamAddReadRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamInternalsReadableStreamAddReadRequestCode =
"(function (stream)\n" \
@@ -1018,7 +1020,8 @@ const char* const s_readableStreamInternalsReadableStreamAddReadRequestCode =
" @assert(@getByIdDirectPrivate(stream, \"state\") == @streamReadable);\n" \
"\n" \
" const readRequest = @newPromise();\n" \
- " @arrayPush(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\"), readRequest);\n" \
+ " \n" \
+ " @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").push(readRequest);\n" \
"\n" \
" return readRequest;\n" \
"})\n" \
diff --git a/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp
index 41b6a4532..2203ed2f2 100644
--- a/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp
+++ b/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp
@@ -183,29 +183,135 @@ const char* const s_streamInternalsValidateAndNormalizeQueuingStrategyCode =
"})\n" \
;
+const JSC::ConstructAbility s_streamInternalsCreateFIFOCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
+const JSC::ConstructorKind s_streamInternalsCreateFIFOCodeConstructorKind = JSC::ConstructorKind::None;
+const int s_streamInternalsCreateFIFOCodeLength = 2764;
+static const JSC::Intrinsic s_streamInternalsCreateFIFOCodeIntrinsic = JSC::NoIntrinsic;
+const char* const s_streamInternalsCreateFIFOCode =
+ "(function () {\n" \
+ " \"use strict\";\n" \
+ " class Denqueue {\n" \
+ " constructor() {\n" \
+ " this._head = 0;\n" \
+ " this._tail = 0;\n" \
+ " //\n" \
+ " this._capacityMask = 0x3;\n" \
+ " this._list = @newArrayWithSize(4);\n" \
+ " }\n" \
+ " \n" \
+ " size() {\n" \
+ " if (this._head === this._tail) return 0;\n" \
+ " if (this._head < this._tail) return this._tail - this._head;\n" \
+ " else return this._capacityMask + 1 - (this._head - this._tail);\n" \
+ " }\n" \
+ "\n" \
+ " isEmpty() {\n" \
+ " return this.size() == 0;\n" \
+ " }\n" \
+ "\n" \
+ " isNotEmpty() {\n" \
+ " return this.size() > 0;\n" \
+ " }\n" \
+ " \n" \
+ " shift() {\n" \
+ " var head = this._head;\n" \
+ " if (head === this._tail) return @undefined;\n" \
+ " var item = this._list[head];\n" \
+ " @putByValDirect(this._list, head, @undefined);\n" \
+ " this._head = (head + 1) & this._capacityMask;\n" \
+ " if (head < 2 && this._tail > 10000 && this._tail <= this._list.length >>> 2) this._shrinkArray();\n" \
+ " return item;\n" \
+ " }\n" \
+ "\n" \
+ " peek() {\n" \
+ " if (this._head === this._tail) return @undefined;\n" \
+ " return this._list[this._head];\n" \
+ " }\n" \
+ " \n" \
+ " push(item) {\n" \
+ " var tail = this._tail;\n" \
+ " @putByValDirect(this._list, tail, item);\n" \
+ " this._tail = (tail + 1) & this._capacityMask;\n" \
+ " if (this._tail === this._head) {\n" \
+ " this._growArray();\n" \
+ " }\n" \
+ " //\n" \
+ " //\n" \
+ " //\n" \
+ " }\n" \
+ " \n" \
+ " toArray(fullCopy) {\n" \
+ " var list = this._list;\n" \
+ " var len = @toLength(list.length);\n" \
+ " \n" \
+ " if (fullCopy || this._head > this._tail) {\n" \
+ " var _head = @toLength(this._head);\n" \
+ " var _tail = @toLength(this._tail);\n" \
+ " var total = @toLength((len - _head) + _tail);\n" \
+ " var array = @newArrayWithSize(total);\n" \
+ " var j = 0;\n" \
+ " for (var i = _head; i < len; i++) @putByValDirect(array, j++, list[i]);\n" \
+ " for (var i = 0; i < _tail; i++) @putByValDirect(array, j++, list[i]);\n" \
+ " return array;\n" \
+ " } else {\n" \
+ " return @Array.prototype.slice.@call(list, this._head, this._tail);\n" \
+ " }\n" \
+ " }\n" \
+ " \n" \
+ " clear() {\n" \
+ " this._head = 0;\n" \
+ " this._tail = 0;\n" \
+ " this._list.fill(undefined);\n" \
+ " }\n" \
+ "\n" \
+ " _growArray() {\n" \
+ " if (this._head) {\n" \
+ " //\n" \
+ " this._list = this.toArray(true);\n" \
+ " this._head = 0;\n" \
+ " }\n" \
+ " \n" \
+ " //\n" \
+ " this._tail = @toLength(this._list.length);\n" \
+ " \n" \
+ " this._list.length <<= 1;\n" \
+ " this._capacityMask = (this._capacityMask << 1) | 1;\n" \
+ " }\n" \
+ " \n" \
+ " shrinkArray() {\n" \
+ " this._list.length >>>= 1;\n" \
+ " this._capacityMask >>>= 1;\n" \
+ " }\n" \
+ " }\n" \
+ "\n" \
+ " \n" \
+ " return new Denqueue();\n" \
+ "})\n" \
+;
+
const JSC::ConstructAbility s_streamInternalsNewQueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_streamInternalsNewQueueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_streamInternalsNewQueueCodeLength = 74;
+const int s_streamInternalsNewQueueCodeLength = 85;
static const JSC::Intrinsic s_streamInternalsNewQueueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_streamInternalsNewQueueCode =
"(function ()\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " return { content: [], size: 0 };\n" \
+ " return { content: @createFIFO(), size: 0 };\n" \
"})\n" \
;
const JSC::ConstructAbility s_streamInternalsDequeueValueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_streamInternalsDequeueValueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_streamInternalsDequeueValueCodeLength = 196;
+const int s_streamInternalsDequeueValueCodeLength = 195;
static const JSC::Intrinsic s_streamInternalsDequeueValueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_streamInternalsDequeueValueCode =
"(function (queue)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " const record = queue.content.@shift();\n" \
+ " const record = queue.content.shift();\n" \
" queue.size -= record.size;\n" \
" //\n" \
" if (queue.size < 0)\n" \
@@ -216,7 +322,7 @@ const char* const s_streamInternalsDequeueValueCode =
const JSC::ConstructAbility s_streamInternalsEnqueueValueWithSizeCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_streamInternalsEnqueueValueWithSizeCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_streamInternalsEnqueueValueWithSizeCodeLength = 250;
+const int s_streamInternalsEnqueueValueWithSizeCodeLength = 248;
static const JSC::Intrinsic s_streamInternalsEnqueueValueWithSizeCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_streamInternalsEnqueueValueWithSizeCode =
"(function (queue, value, size)\n" \
@@ -226,29 +332,30 @@ const char* const s_streamInternalsEnqueueValueWithSizeCode =
" size = @toNumber(size);\n" \
" if (!@isFinite(size) || size < 0)\n" \
" @throwRangeError(\"size has an incorrect value\");\n" \
- " @arrayPush(queue.content, { value, size });\n" \
+ " \n" \
+ " queue.content.push({ value, size });\n" \
" queue.size += size;\n" \
"})\n" \
;
const JSC::ConstructAbility s_streamInternalsPeekQueueValueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_streamInternalsPeekQueueValueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_streamInternalsPeekQueueValueCodeLength = 117;
+const int s_streamInternalsPeekQueueValueCodeLength = 115;
static const JSC::Intrinsic s_streamInternalsPeekQueueValueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_streamInternalsPeekQueueValueCode =
"(function (queue)\n" \
"{\n" \
" \"use strict\";\n" \
"\n" \
- " @assert(queue.content.length > 0);\n" \
+ " @assert(queue.content.isNotEmpty());\n" \
"\n" \
- " return queue.content[0].value;\n" \
+ " return queue.peek().value;\n" \
"})\n" \
;
const JSC::ConstructAbility s_streamInternalsResetQueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_streamInternalsResetQueueCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_streamInternalsResetQueueCodeLength = 149;
+const int s_streamInternalsResetQueueCodeLength = 152;
static const JSC::Intrinsic s_streamInternalsResetQueueCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_streamInternalsResetQueueCode =
"(function (queue)\n" \
@@ -257,7 +364,7 @@ const char* const s_streamInternalsResetQueueCode =
"\n" \
" @assert(\"content\" in queue);\n" \
" @assert(\"size\" in queue);\n" \
- " queue.content = [];\n" \
+ " queue.content.clear();\n" \
" queue.size = 0;\n" \
"})\n" \
;
diff --git a/src/javascript/jsc/bindings/StreamInternalsBuiltins.h b/src/javascript/jsc/bindings/StreamInternalsBuiltins.h
index 20c41ddb9..61fb36b0e 100644
--- a/src/javascript/jsc/bindings/StreamInternalsBuiltins.h
+++ b/src/javascript/jsc/bindings/StreamInternalsBuiltins.h
@@ -79,6 +79,10 @@ extern const char* const s_streamInternalsValidateAndNormalizeQueuingStrategyCod
extern const int s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength;
extern const JSC::ConstructAbility s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructAbility;
extern const JSC::ConstructorKind s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructorKind;
+extern const char* const s_streamInternalsCreateFIFOCode;
+extern const int s_streamInternalsCreateFIFOCodeLength;
+extern const JSC::ConstructAbility s_streamInternalsCreateFIFOCodeConstructAbility;
+extern const JSC::ConstructorKind s_streamInternalsCreateFIFOCodeConstructorKind;
extern const char* const s_streamInternalsNewQueueCode;
extern const int s_streamInternalsNewQueueCodeLength;
extern const JSC::ConstructAbility s_streamInternalsNewQueueCodeConstructAbility;
@@ -129,6 +133,7 @@ extern const JSC::ConstructorKind s_streamInternalsToDictionaryCodeConstructorKi
macro(promiseInvokeOrNoop, streamInternalsPromiseInvokeOrNoop, 3) \
macro(promiseInvokeOrFallbackOrNoop, streamInternalsPromiseInvokeOrFallbackOrNoop, 5) \
macro(validateAndNormalizeQueuingStrategy, streamInternalsValidateAndNormalizeQueuingStrategy, 2) \
+ macro(createFIFO, streamInternalsCreateFIFO, 0) \
macro(newQueue, streamInternalsNewQueue, 0) \
macro(dequeueValue, streamInternalsDequeueValue, 1) \
macro(enqueueValueWithSize, streamInternalsEnqueueValueWithSize, 3) \
@@ -148,6 +153,7 @@ extern const JSC::ConstructorKind s_streamInternalsToDictionaryCodeConstructorKi
#define WEBCORE_BUILTIN_STREAMINTERNALS_PROMISEINVOKEORNOOP 1
#define WEBCORE_BUILTIN_STREAMINTERNALS_PROMISEINVOKEORFALLBACKORNOOP 1
#define WEBCORE_BUILTIN_STREAMINTERNALS_VALIDATEANDNORMALIZEQUEUINGSTRATEGY 1
+#define WEBCORE_BUILTIN_STREAMINTERNALS_CREATEFIFO 1
#define WEBCORE_BUILTIN_STREAMINTERNALS_NEWQUEUE 1
#define WEBCORE_BUILTIN_STREAMINTERNALS_DEQUEUEVALUE 1
#define WEBCORE_BUILTIN_STREAMINTERNALS_ENQUEUEVALUEWITHSIZE 1
@@ -168,6 +174,7 @@ extern const JSC::ConstructorKind s_streamInternalsToDictionaryCodeConstructorKi
macro(streamInternalsPromiseInvokeOrNoopCode, promiseInvokeOrNoop, ASCIILiteral(), s_streamInternalsPromiseInvokeOrNoopCodeLength) \
macro(streamInternalsPromiseInvokeOrFallbackOrNoopCode, promiseInvokeOrFallbackOrNoop, ASCIILiteral(), s_streamInternalsPromiseInvokeOrFallbackOrNoopCodeLength) \
macro(streamInternalsValidateAndNormalizeQueuingStrategyCode, validateAndNormalizeQueuingStrategy, ASCIILiteral(), s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength) \
+ macro(streamInternalsCreateFIFOCode, createFIFO, ASCIILiteral(), s_streamInternalsCreateFIFOCodeLength) \
macro(streamInternalsNewQueueCode, newQueue, ASCIILiteral(), s_streamInternalsNewQueueCodeLength) \
macro(streamInternalsDequeueValueCode, dequeueValue, ASCIILiteral(), s_streamInternalsDequeueValueCodeLength) \
macro(streamInternalsEnqueueValueWithSizeCode, enqueueValueWithSize, ASCIILiteral(), s_streamInternalsEnqueueValueWithSizeCodeLength) \
@@ -180,6 +187,7 @@ extern const JSC::ConstructorKind s_streamInternalsToDictionaryCodeConstructorKi
macro(streamInternalsToDictionaryCode, toDictionary, ASCIILiteral(), s_streamInternalsToDictionaryCodeLength) \
#define WEBCORE_FOREACH_STREAMINTERNALS_BUILTIN_FUNCTION_NAME(macro) \
+ macro(createFIFO) \
macro(createFulfilledPromise) \
macro(dequeueValue) \
macro(enqueueValueWithSize) \
diff --git a/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp
index 2e0a4b1df..98674f442 100644
--- a/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp
+++ b/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp
@@ -160,7 +160,7 @@ const char* const s_writableStreamInternalsCreateInternalWritableStreamFromUnder
const JSC::ConstructAbility s_writableStreamInternalsInitializeWritableStreamSlotsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsInitializeWritableStreamSlotsCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsInitializeWritableStreamSlotsCodeLength = 734;
+const int s_writableStreamInternalsInitializeWritableStreamSlotsCodeLength = 745;
static const JSC::Intrinsic s_writableStreamInternalsInitializeWritableStreamSlotsCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsInitializeWritableStreamSlotsCode =
"(function (stream, underlyingSink)\n" \
@@ -173,7 +173,7 @@ const char* const s_writableStreamInternalsInitializeWritableStreamSlotsCode =
" @putByIdDirectPrivate(stream, \"closeRequest\", @undefined);\n" \
" @putByIdDirectPrivate(stream, \"inFlightCloseRequest\", @undefined);\n" \
" @putByIdDirectPrivate(stream, \"pendingAbortRequest\", @undefined);\n" \
- " @putByIdDirectPrivate(stream, \"writeRequests\", []);\n" \
+ " @putByIdDirectPrivate(stream, \"writeRequests\", @createFIFO());\n" \
" @putByIdDirectPrivate(stream, \"backpressure\", false);\n" \
" @putByIdDirectPrivate(stream, \"underlyingSink\", underlyingSink);\n" \
"})\n" \
@@ -320,7 +320,7 @@ const char* const s_writableStreamInternalsWritableStreamCloseCode =
const JSC::ConstructAbility s_writableStreamInternalsWritableStreamAddWriteRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsWritableStreamAddWriteRequestCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsWritableStreamAddWriteRequestCodeLength = 379;
+const int s_writableStreamInternalsWritableStreamAddWriteRequestCodeLength = 372;
static const JSC::Intrinsic s_writableStreamInternalsWritableStreamAddWriteRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsWritableStreamAddWriteRequestCode =
"(function (stream)\n" \
@@ -330,7 +330,7 @@ const char* const s_writableStreamInternalsWritableStreamAddWriteRequestCode =
"\n" \
" const writePromiseCapability = @newPromiseCapability(@Promise);\n" \
" const writeRequests = @getByIdDirectPrivate(stream, \"writeRequests\");\n" \
- " @arrayPush(writeRequests, writePromiseCapability);\n" \
+ " writeRequests.push(writePromiseCapability);\n" \
" return writePromiseCapability.@promise;\n" \
"})\n" \
;
@@ -366,7 +366,7 @@ const char* const s_writableStreamInternalsWritableStreamDealWithRejectionCode =
const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishErroringCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishErroringCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsWritableStreamFinishErroringCodeLength = 1543;
+const int s_writableStreamInternalsWritableStreamFinishErroringCodeLength = 1556;
static const JSC::Intrinsic s_writableStreamInternalsWritableStreamFinishErroringCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsWritableStreamFinishErroringCode =
"(function (stream)\n" \
@@ -381,10 +381,11 @@ const char* const s_writableStreamInternalsWritableStreamFinishErroringCode =
"\n" \
" const storedError = @getByIdDirectPrivate(stream, \"storedError\");\n" \
" const requests = @getByIdDirectPrivate(stream, \"writeRequests\");\n" \
- " for (let index = 0, length = requests.length; index < length; ++index)\n" \
- " requests[index].@reject.@call(@undefined, storedError);\n" \
+ " for (var request = requests.shift(); request; request = requests.shift())\n" \
+ " request.@reject.@call(@undefined, storedError);\n" \
"\n" \
- " @putByIdDirectPrivate(stream, \"writeRequests\", []);\n" \
+ " //\n" \
+ " @putByIdDirectPrivate(stream, \"writeRequests\", @createFIFO());\n" \
"\n" \
" const abortRequest = @getByIdDirectPrivate(stream, \"pendingAbortRequest\");\n" \
" if (abortRequest === @undefined) {\n" \
@@ -534,16 +535,16 @@ const char* const s_writableStreamInternalsWritableStreamMarkCloseRequestInFligh
const JSC::ConstructAbility s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeLength = 343;
+const int s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeLength = 344;
static const JSC::Intrinsic s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCode =
"(function (stream)\n" \
"{\n" \
" const writeRequests = @getByIdDirectPrivate(stream, \"writeRequests\");\n" \
" @assert(@getByIdDirectPrivate(stream, \"inFlightWriteRequest\") === @undefined);\n" \
- " @assert(writeRequests.length > 0);\n" \
+ " @assert(writeRequests.isNotEmpty());\n" \
"\n" \
- " const writeRequest = writeRequests.@shift();\n" \
+ " const writeRequest = writeRequests.shift();\n" \
" @putByIdDirectPrivate(stream, \"inFlightWriteRequest\", writeRequest);\n" \
"})\n" \
;
@@ -869,7 +870,7 @@ const char* const s_writableStreamInternalsSetUpWritableStreamDefaultControllerF
const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeLength = 865;
+const int s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeLength = 872;
static const JSC::Intrinsic s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCode =
"(function (controller)\n" \
@@ -890,7 +891,7 @@ const char* const s_writableStreamInternalsWritableStreamDefaultControllerAdvanc
" return;\n" \
" }\n" \
"\n" \
- " if (@getByIdDirectPrivate(controller, \"queue\").content.length === 0)\n" \
+ " if (@getByIdDirectPrivate(controller, \"queue\").content?.isEmpty() ?? false)\n" \
" return;\n" \
"\n" \
" const value = @peekQueueValue(@getByIdDirectPrivate(controller, \"queue\"));\n" \
@@ -1007,7 +1008,7 @@ const char* const s_writableStreamInternalsWritableStreamDefaultControllerGetDes
const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeLength = 630;
+const int s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeLength = 628;
static const JSC::Intrinsic s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCode =
"(function (controller)\n" \
@@ -1017,7 +1018,7 @@ const char* const s_writableStreamInternalsWritableStreamDefaultControllerProces
" @writableStreamMarkCloseRequestInFlight(stream);\n" \
" @dequeueValue(@getByIdDirectPrivate(controller, \"queue\"));\n" \
"\n" \
- " @assert(@getByIdDirectPrivate(controller, \"queue\").content.length === 0);\n" \
+ " @assert(@getByIdDirectPrivate(controller, \"queue\").content?.isEmpty());\n" \
"\n" \
" const sinkClosePromise = @getByIdDirectPrivate(controller, \"closeAlgorithm\").@call();\n" \
" @writableStreamDefaultControllerClearAlgorithms(controller);\n" \
diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
index 8da658526..c3ba74cf4 100644
--- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp
+++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
@@ -871,6 +871,22 @@ static JSC_DEFINE_HOST_FUNCTION(functionReportError,
return JSC::JSValue::encode(JSC::jsUndefined());
}
+JSC_DECLARE_HOST_FUNCTION(functionCreateUninitializedArrayBuffer);
+JSC_DEFINE_HOST_FUNCTION(functionCreateUninitializedArrayBuffer,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ size_t len = static_cast<size_t>(JSC__JSValue__toInt64(JSC::JSValue::encode(callFrame->argument(0))));
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ auto arrayBuffer = JSC::ArrayBuffer::tryCreateUninitialized(len, 1);
+
+ if (UNLIKELY(!arrayBuffer)) {
+ JSC::throwOutOfMemoryError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ RELEASE_AND_RETURN(scope, JSValue::encode(JSC::JSArrayBuffer::create(globalObject->vm(), globalObject->arrayBufferStructure(JSC::ArrayBufferSharingMode::Default), WTFMove(arrayBuffer))));
+}
+
JSC_DEFINE_HOST_FUNCTION(functionNoop, (JSC::JSGlobalObject*, JSC::CallFrame*))
{
return JSC::JSValue::encode(JSC::jsUndefined());
@@ -1250,7 +1266,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
auto& builtinNames = WebCore::builtinNames(vm);
WTF::Vector<GlobalPropertyInfo> extraStaticGlobals;
- extraStaticGlobals.reserveCapacity(26);
+ extraStaticGlobals.reserveCapacity(27);
JSC::Identifier queueMicrotaskIdentifier = JSC::Identifier::fromString(vm, "queueMicrotask"_s);
extraStaticGlobals.uncheckedAppend(
@@ -1336,6 +1352,8 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
extraStaticGlobals.releaseBuffer();
+ putDirectBuiltinFunction(vm, this, builtinNames.createFIFOPrivateName(), streamInternalsCreateFIFOCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
putDirectBuiltinFunction(vm, this, builtinNames.createNativeReadableStreamPrivateName(), readableStreamCreateNativeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "process"_s), JSC::CustomGetterSetter::create(vm, property_lazyProcessGetter, property_lazyProcessSetter),
diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig
index 1f4a62939..e421bfd89 100644
--- a/src/javascript/jsc/bindings/bindings.zig
+++ b/src/javascript/jsc/bindings/bindings.zig
@@ -2259,6 +2259,16 @@ pub const JSValue = enum(i64) {
return JSC.GetJSPrivateData(ZigType, value.asObjectRef());
}
+ pub fn protect(this: JSValue) void {
+ if (this.isEmptyOrUndefinedOrNull() or this.isNumber()) return;
+ JSC.C.JSValueProtect(JSC.VirtualMachine.vm.global, this.asObjectRef());
+ }
+
+ pub fn unprotect(this: JSValue) void {
+ if (this.isEmptyOrUndefinedOrNull() or this.isNumber()) return;
+ JSC.C.JSValueUnprotect(JSC.VirtualMachine.vm.global, this.asObjectRef());
+ }
+
/// Create an object with exactly two properties
pub fn createObject2(global: *JSGlobalObject, key1: *const ZigString, key2: *const ZigString, value1: JSValue, value2: JSValue) JSValue {
return cppFn("createObject2", .{ global, key1, key2, value1, value2 });
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamController.js b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamController.js
index fac5c864c..0b47d730c 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamController.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamController.js
@@ -89,12 +89,17 @@ function byobRequest()
if (!@isReadableByteStreamController(this))
throw @makeGetterTypeError("ReadableByteStreamController", "byobRequest");
- if (@getByIdDirectPrivate(this, "byobRequest") === @undefined && @getByIdDirectPrivate(this, "pendingPullIntos").length) {
- const firstDescriptor = @getByIdDirectPrivate(this, "pendingPullIntos")[0];
- const view = new @Uint8Array(firstDescriptor.buffer,
+
+ var request = @getByIdDirectPrivate(this, "byobRequest");
+ if (request === @undefined) {
+ var pending = @getByIdDirectPrivate(this, "pendingPullIntos");
+ const firstDescriptor = pending.peek();
+ if (firstDescriptor) {
+ const view = new @Uint8Array(firstDescriptor.buffer,
firstDescriptor.byteOffset + firstDescriptor.bytesFilled,
firstDescriptor.byteLength - firstDescriptor.bytesFilled);
- @putByIdDirectPrivate(this, "byobRequest", new @ReadableStreamBYOBRequest(this, view, @isReadableStream));
+ @putByIdDirectPrivate(this, "byobRequest", new @ReadableStreamBYOBRequest(this, view, @isReadableStream));
+ }
}
return @getByIdDirectPrivate(this, "byobRequest");
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js
index 45af990cd..5806ba48c 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js
@@ -56,7 +56,7 @@ function privateInitializeReadableByteStreamController(stream, underlyingByteSou
@throwRangeError("autoAllocateChunkSize value is negative or equal to positive or negative infinity");
}
@putByIdDirectPrivate(this, "autoAllocateChunkSize", autoAllocateChunkSize);
- @putByIdDirectPrivate(this, "pendingPullIntos", []);
+ @putByIdDirectPrivate(this, "pendingPullIntos", @createFIFO());
const controller = this;
const startResult = @promiseInvokeOrNoopNoCatch(underlyingByteSource, "start", [this]).@then(() => {
@@ -116,8 +116,10 @@ function readableByteStreamControllerCancel(controller, reason)
"use strict";
var pendingPullIntos = @getByIdDirectPrivate(controller, "pendingPullIntos");
- if (pendingPullIntos.length > 0)
- pendingPullIntos[0].bytesFilled = 0;
+ var first = pendingPullIntos.peek();
+ if (first)
+ first.bytesFilled = 0;
+
@putByIdDirectPrivate(controller, "queue", @newQueue());
return @promiseInvokeOrNoop(@getByIdDirectPrivate(controller, "underlyingByteSource"), "cancel", [reason]);
}
@@ -144,9 +146,9 @@ function readableByteStreamControllerClose(controller)
return;
}
- var pendingPullIntos = @getByIdDirectPrivate(controller, "pendingPullIntos");
- if (pendingPullIntos.length > 0) {
- if (pendingPullIntos[0].bytesFilled > 0) {
+ var first = @getByIdDirectPrivate(controller, "pendingPullIntos")?.peek();
+ if (first) {
+ if (first.bytesFilled > 0) {
const e = @makeTypeError("Close requested while there remain pending bytes");
@readableByteStreamControllerError(controller, e);
throw e;
@@ -161,7 +163,12 @@ function readableByteStreamControllerClearPendingPullIntos(controller)
"use strict";
@readableByteStreamControllerInvalidateBYOBRequest(controller);
- @putByIdDirectPrivate(controller, "pendingPullIntos", []);
+ var existing = @getByIdDirectPrivate(controller, "pendingPullIntos");
+ if (existing !== @undefined) {
+ existing.clear();
+ } else {
+ @putByIdDirectPrivate(controller, "pendingPullIntos", @createFIFO());
+ }
}
function readableByteStreamControllerGetDesiredSize(controller)
@@ -214,8 +221,8 @@ function readableByteStreamControllerPull(controller)
@assert(@readableStreamHasDefaultReader(stream));
if (@getByIdDirectPrivate(controller, "queue").size > 0) {
- @assert(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").length === 0);
- const entry = @getByIdDirectPrivate(controller, "queue").content.@shift();
+ @assert(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isEmpty());
+ const entry = @getByIdDirectPrivate(controller, "queue").content.shift();
@getByIdDirectPrivate(controller, "queue").size -= entry.byteLength;
@readableByteStreamControllerHandleQueueDrain(controller);
let view;
@@ -230,7 +237,7 @@ function readableByteStreamControllerPull(controller)
if (@getByIdDirectPrivate(controller, "autoAllocateChunkSize") !== @undefined) {
let buffer;
try {
- buffer = new @ArrayBuffer(@getByIdDirectPrivate(controller, "autoAllocateChunkSize"));
+ buffer = @createUninitializedArrayBuffer(@getByIdDirectPrivate(controller, "autoAllocateChunkSize"));
} catch (error) {
return @Promise.@reject(error);
}
@@ -243,7 +250,7 @@ function readableByteStreamControllerPull(controller)
ctor: @Uint8Array,
readerType: 'default'
};
- @arrayPush(@getByIdDirectPrivate(controller, "pendingPullIntos"), pullIntoDescriptor);
+ @getByIdDirectPrivate(controller, "pendingPullIntos").push(pullIntoDescriptor);
}
const promise = @readableStreamAddReadRequest(stream);
@@ -263,9 +270,9 @@ function readableByteStreamControllerShouldCallPull(controller)
return false;
if (!@getByIdDirectPrivate(controller, "started"))
return false;
- if (@readableStreamHasDefaultReader(stream) && (@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").length > 0 || !!@getByIdDirectPrivate(reader, "bunNativePtr")))
+ if (@readableStreamHasDefaultReader(stream) && (@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isNotEmpty() || !!@getByIdDirectPrivate(reader, "bunNativePtr")))
return true;
- if (@readableStreamHasBYOBReader(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests").length > 0)
+ if (@readableStreamHasBYOBReader(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests")?.isNotEmpty())
return true;
if (@readableByteStreamControllerGetDesiredSize(controller) > 0)
return true;
@@ -334,10 +341,10 @@ function readableByteStreamControllerEnqueue(controller, chunk)
switch (reader ? @readableStreamReaderKind(reader) : 0) {
/* default reader */
case 1: {
- if (!@getByIdDirectPrivate(reader, "readRequests").length)
+ if (!@getByIdDirectPrivate(reader, "readRequests")?.isNotEmpty())
@readableByteStreamControllerEnqueueChunk(controller, @transferBufferToCurrentRealm(chunk.buffer), chunk.byteOffset, chunk.byteLength);
else {
- @assert(!@getByIdDirectPrivate(controller, "queue").content.length);
+ @assert(!@getByIdDirectPrivate(controller, "queue").content.size());
const transferredView = chunk.constructor === @Uint8Array ? chunk : new @Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
@readableStreamFulfillReadRequest(stream, transferredView, false);
}
@@ -371,7 +378,7 @@ function readableByteStreamControllerEnqueueChunk(controller, buffer, byteOffset
{
"use strict";
- @arrayPush(@getByIdDirectPrivate(controller, "queue").content, {
+ @getByIdDirectPrivate(controller, "queue").content.push({
buffer: buffer,
byteOffset: byteOffset,
byteLength: byteLength
@@ -383,10 +390,10 @@ function readableByteStreamControllerRespondWithNewView(controller, view)
{
"use strict";
- @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").length > 0);
-
- let firstDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos")[0];
+ @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").isNotEmpty());
+ let firstDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos").peek();
+
if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset)
@throwRangeError("Invalid value for view.byteOffset");
@@ -406,7 +413,7 @@ function readableByteStreamControllerRespond(controller, bytesWritten)
if (@isNaN(bytesWritten) || bytesWritten === @Infinity || bytesWritten < 0 )
@throwRangeError("bytesWritten has an incorrect value");
- @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").length > 0);
+ @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").isNotEmpty());
@readableByteStreamControllerRespondInternal(controller, bytesWritten);
}
@@ -415,7 +422,7 @@ function readableByteStreamControllerRespondInternal(controller, bytesWritten)
{
"use strict";
- let firstDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos")[0];
+ let firstDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos").peek();
let stream = @getByIdDirectPrivate(controller, "controlledReadableStream");
if (@getByIdDirectPrivate(stream, "state") === @streamClosed) {
@@ -435,7 +442,7 @@ function readableByteStreamControllerRespondInReadableState(controller, bytesWri
if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength)
@throwRangeError("bytesWritten value is too great");
- @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").length === 0 || @getByIdDirectPrivate(controller, "pendingPullIntos")[0] === pullIntoDescriptor);
+ @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").isEmpty() || @getByIdDirectPrivate(controller, "pendingPullIntos").peek() === pullIntoDescriptor);
@readableByteStreamControllerInvalidateBYOBRequest(controller);
pullIntoDescriptor.bytesFilled += bytesWritten;
@@ -465,7 +472,7 @@ function readableByteStreamControllerRespondInClosedState(controller, firstDescr
@assert(firstDescriptor.bytesFilled === 0);
if (@readableStreamHasBYOBReader(@getByIdDirectPrivate(controller, "controlledReadableStream"))) {
- while (@getByIdDirectPrivate(@getByIdDirectPrivate(@getByIdDirectPrivate(controller, "controlledReadableStream"), "reader"), "readIntoRequests").length > 0) {
+ while (@getByIdDirectPrivate(@getByIdDirectPrivate(@getByIdDirectPrivate(controller, "controlledReadableStream"), "reader"), "readIntoRequests")?.isNotEmpty()) {
let pullIntoDescriptor = @readableByteStreamControllerShiftPendingDescriptor(controller);
@readableByteStreamControllerCommitDescriptor(@getByIdDirectPrivate(controller, "controlledReadableStream"), pullIntoDescriptor);
}
@@ -478,10 +485,10 @@ function readableByteStreamControllerProcessPullDescriptors(controller)
"use strict";
@assert(!@getByIdDirectPrivate(controller, "closeRequested"));
- while (@getByIdDirectPrivate(controller, "pendingPullIntos").length > 0) {
+ while (@getByIdDirectPrivate(controller, "pendingPullIntos").isNotEmpty()) {
if (@getByIdDirectPrivate(controller, "queue").size === 0)
return;
- let pullIntoDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos")[0];
+ let pullIntoDescriptor = @getByIdDirectPrivate(controller, "pendingPullIntos").peek();
if (@readableByteStreamControllerFillDescriptorFromQueue(controller, pullIntoDescriptor)) {
@readableByteStreamControllerShiftPendingDescriptor(controller);
@readableByteStreamControllerCommitDescriptor(@getByIdDirectPrivate(controller, "controlledReadableStream"), pullIntoDescriptor);
@@ -508,7 +515,7 @@ function readableByteStreamControllerFillDescriptorFromQueue(controller, pullInt
}
while (totalBytesToCopyRemaining > 0) {
- let headOfQueue = @getByIdDirectPrivate(controller, "queue").content[0];
+ let headOfQueue = @getByIdDirectPrivate(controller, "queue").content.peek();
const bytesToCopy = totalBytesToCopyRemaining < headOfQueue.byteLength ? totalBytesToCopyRemaining : headOfQueue.byteLength;
// Copy appropriate part of pullIntoDescriptor.buffer to headOfQueue.buffer.
// Remark: this implementation is not completely aligned on the definition of CopyDataBlockBytes
@@ -519,14 +526,14 @@ function readableByteStreamControllerFillDescriptorFromQueue(controller, pullInt
new @Uint8Array(pullIntoDescriptor.buffer).set(new @Uint8Array(headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy), destStart);
if (headOfQueue.byteLength === bytesToCopy)
- @getByIdDirectPrivate(controller, "queue").content.@shift();
+ @getByIdDirectPrivate(controller, "queue").content.shift();
else {
headOfQueue.byteOffset += bytesToCopy;
headOfQueue.byteLength -= bytesToCopy;
}
@getByIdDirectPrivate(controller, "queue").size -= bytesToCopy;
- @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").length === 0 || @getByIdDirectPrivate(controller, "pendingPullIntos")[0] === pullIntoDescriptor);
+ @assert(@getByIdDirectPrivate(controller, "pendingPullIntos").isEmpty() || @getByIdDirectPrivate(controller, "pendingPullIntos").peek() === pullIntoDescriptor);
@readableByteStreamControllerInvalidateBYOBRequest(controller);
pullIntoDescriptor.bytesFilled += bytesToCopy;
totalBytesToCopyRemaining -= bytesToCopy;
@@ -546,7 +553,7 @@ function readableByteStreamControllerShiftPendingDescriptor(controller)
{
"use strict";
- let descriptor = @getByIdDirectPrivate(controller, "pendingPullIntos").@shift();
+ let descriptor = @getByIdDirectPrivate(controller, "pendingPullIntos").shift();
@readableByteStreamControllerInvalidateBYOBRequest(controller);
return descriptor;
}
@@ -597,7 +604,7 @@ function readableByteStreamControllerConvertDescriptor(pullIntoDescriptor)
function readableStreamFulfillReadIntoRequest(stream, chunk, done)
{
"use strict";
- const readIntoRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests").@shift();
+ const readIntoRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests").shift();
@fulfillPromise(readIntoRequest, { value: chunk, done: done });
}
@@ -652,9 +659,10 @@ function readableByteStreamControllerPullInto(controller, view)
readerType: 'byob'
};
- if (@getByIdDirectPrivate(controller, "pendingPullIntos").length) {
+ var pending = @getByIdDirectPrivate(controller, "pendingPullIntos");
+ if (pending?.isNotEmpty()) {
pullIntoDescriptor.buffer = @transferBufferToCurrentRealm(pullIntoDescriptor.buffer);
- @arrayPush(@getByIdDirectPrivate(controller, "pendingPullIntos"), pullIntoDescriptor);
+ pending.push(pullIntoDescriptor);
return @readableStreamAddReadIntoRequest(stream);
}
@@ -677,7 +685,7 @@ function readableByteStreamControllerPullInto(controller, view)
}
pullIntoDescriptor.buffer = @transferBufferToCurrentRealm(pullIntoDescriptor.buffer);
- @arrayPush(@getByIdDirectPrivate(controller, "pendingPullIntos"), pullIntoDescriptor);
+ @getByIdDirectPrivate(controller, "pendingPullIntos").push(pullIntoDescriptor);
const promise = @readableStreamAddReadIntoRequest(stream);
@readableByteStreamControllerCallPullIfNeeded(controller);
return promise;
@@ -691,7 +699,7 @@ function readableStreamAddReadIntoRequest(stream)
@assert(@getByIdDirectPrivate(stream, "state") === @streamReadable || @getByIdDirectPrivate(stream, "state") === @streamClosed);
const readRequest = @newPromise();
- @arrayPush(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests"), readRequest);
+ @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readIntoRequests").push(readRequest);
return readRequest;
}
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js
index 5a5ea4094..4d7113888 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js
@@ -89,79 +89,69 @@ function initializeReadableStream(underlyingSource, strategy)
}
@globalPrivate
-function createNativeReadableStream(nativePtr, nativeType) {
+function createNativeReadableStream(nativePtr, nativeType, autoAllocateChunkSize) {
"use strict";
var cached = globalThis[Symbol.for("Bun.nativeReadableStreamPrototype")] ||= new @Map;
var Prototype = cached.@get(nativeType);
if (Prototype === @undefined) {
var [pull, start, cancel, setClose, deinit] = globalThis[Symbol.for("Bun.lazy")](nativeType);
var closer = [false];
-
+var handleResult;
function handleNativeReadableStreamPromiseResult(val) {
"use strict";
- var {r, c} = this;
- this.r = @undefined;
+ var {c, v} = this;
this.c = @undefined;
- r(val, c);
+ this.v = @undefined;
+ handleResult(val, c, v);
}
- function closeNativeReadableStreamOnNextTick(controller) {
- "use strict";
- controller.close();
- controller = @undefined;
- }
-
- var handleResult = function handleResult(result, controller) {
+
+ handleResult = function handleResult(result, controller, view) {
"use strict";
if (result && @isPromise(result)) {
- return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, r: handleResult}), controller.error);
+ return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, v: view}), (err) => controller.error(err));
} else if (result !== false) {
- controller.enqueue(result);
+ if (view && view.byteLength === result) {
+ controller.byobRequest.respondWithNewView(view);
+ } else {
+ controller.byobRequest.respond(result);
+ }
}
if (closer[0] || result === false) {
- @enqueueJob(closeNativeReadableStreamOnNextTick, controller);
+ @enqueueJob(() => controller.close());
closer[0] = false;
}
- }
+ };
Prototype = class NativeReadableStreamSource {
- constructor(tag) {
+ constructor(tag, autoAllocateChunkSize) {
this.pull = this.pull_.bind(tag);
- this.start = this.start_.bind(tag);
this.cancel = this.cancel_.bind(tag);
+ this.autoAllocateChunkSize = autoAllocateChunkSize;
}
pull;
- start;
cancel;
-
- pull_(controller) {
- closer[0] = false;
- var result;
-
- try {
- result = pull(this, closer);
- } catch(err) {
- return controller.error(err);
- }
- return handleResult(result, controller);
- }
+ type = "bytes";
+ autoAllocateChunkSize = 0;
- start_(controller) {
- setClose(this, controller.close);
+ static startSync = start;
+
+ pull_(controller) {
closer[0] = false;
var result;
+ const view = controller.byobRequest.view;
try {
- result = start(this, closer);
+ result = pull(this, view, closer);
} catch(err) {
return controller.error(err);
}
- return handleResult(result, controller);
+ return handleResult(result, controller, view);
}
cancel_(reason) {
@@ -173,7 +163,29 @@ function createNativeReadableStream(nativePtr, nativeType) {
cached.@set(nativeType, Prototype);
}
- var instance = new Prototype(nativePtr);
+ // either returns the chunk size
+ // or throws an error
+ // should never return a Promise
+ const chunkSize = Prototype.startSync(nativePtr, autoAllocateChunkSize);
+
+ // empty file, no need for native back-and-forth on this
+ if (chunkSize === 0) {
+ return new @ReadableStream({
+ start(controller) {
+ controller.close();
+ },
+
+ pull() {
+
+ },
+
+ cancel() {
+
+ },
+ });
+ }
+
+ var instance = new Prototype(nativePtr, chunkSize);
Prototype.registry.register(instance, nativePtr);
var stream = new @ReadableStream(instance);
@putByIdDirectPrivate(stream, "bunNativeType", nativeType);
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStreamBYOBReader.js b/src/javascript/jsc/bindings/builtins/js/ReadableStreamBYOBReader.js
index f4bc203c8..16e4ebce5 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableStreamBYOBReader.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableStreamBYOBReader.js
@@ -34,7 +34,7 @@ function initializeReadableStreamBYOBReader(stream)
@throwTypeError("ReadableStream is locked");
@readableStreamReaderGenericInitialize(this, stream);
- @putByIdDirectPrivate(this, "readIntoRequests", []);
+ @putByIdDirectPrivate(this, "readIntoRequests", @createFIFO());
return this;
}
@@ -84,7 +84,7 @@ function releaseLock()
if (!@getByIdDirectPrivate(this, "ownerReadableStream"))
return;
- if (@getByIdDirectPrivate(this, "readIntoRequests").length)
+ if (@getByIdDirectPrivate(this, "readIntoRequests")?.isNotEmpty())
@throwTypeError("There are still pending read requests, cannot release the lock");
@readableStreamReaderGenericRelease(this);
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStreamDefaultReader.js b/src/javascript/jsc/bindings/builtins/js/ReadableStreamDefaultReader.js
index 3e7438a62..9766d150e 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableStreamDefaultReader.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableStreamDefaultReader.js
@@ -33,7 +33,7 @@ function initializeReadableStreamDefaultReader(stream)
@throwTypeError("ReadableStream is locked");
@readableStreamReaderGenericInitialize(this, stream);
- @putByIdDirectPrivate(this, "readRequests", []);
+ @putByIdDirectPrivate(this, "readRequests", @createFIFO());
return this;
}
@@ -70,30 +70,14 @@ function readMany()
throw @getByIdDirectPrivate(stream, "storedError");
}
- const controller = @getByIdDirectPrivate(stream, "readableStreamController");
+ var controller = @getByIdDirectPrivate(stream, "readableStreamController");
const content = @getByIdDirectPrivate(controller, "queue").content;
var size = @getByIdDirectPrivate(controller, "queue").size;
+ var values = content.toArray(false);
+ var length = values.length;
- var values = new @Array(content.length);
-
- if (content.length > 0) {
- if ("buffer" in content[0]) {
- values[0] = new @Uint8Array(content[0].buffer, content[0].byteOffset, content[0].byteLength);
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, new @Uint8Array(content[i].buffer, content[i].byteOffset, content[i].byteLength));
- }
- } else if (typeof content[0] === 'object' && content[0] && "byteLength" in content[0]) {
- size = 0;
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, content[i].value);
- size += content[i].value.byteLength;
- }
- } else {
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, content[i].value);
- }
- }
+ if (length > 0) {
@resetQueue(@getByIdDirectPrivate(controller, "queue"));
if (@getByIdDirectPrivate(controller, "closeRequested"))
@@ -105,44 +89,23 @@ function readMany()
if (done) {
return {value: [], size: 0, done: true};
}
-
- const content = queue.content;
- var values = new @Array(content.length + 1);
-
+ var queue = @getByIdDirectPrivate(controller, "queue");
+ const content = [value].concat(queue.content.toArray(false));
var size = queue.size;
-
- if ("buffer" in content[0]) {
- values[0] = new @Uint8Array(value.buffer, value.byteOffset, value.byteLength);
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, new @Uint8Array(content[i].buffer, content[i].byteOffset, content[i].byteLength));
- }
- size += value.byteLength;
- } else if (typeof value === 'object' && value && "byteLength" in value) {
- size += value.byteLength;
- values[0] = value;
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, content[i].value);
- size += content[i].value.byteLength;
- }
-
- } else {
- values[0] = value;
- for (var i = 0; i < content.length; ++i) {
- @putByValDirect(values, i+1, content[i].value);
- }
- }
-
@resetQueue(queue);
if (@getByIdDirectPrivate(controller, "closeRequested"))
@readableStreamClose(@getByIdDirectPrivate(controller, "controlledReadableStream"));
else
@readableStreamDefaultControllerCallPullIfNeeded(controller);
+ controller = @undefined;
return {value: values, size: size, done: false};
});
}
+ controller = @undefined;
+
return {value: values, size, done: false};
}
@@ -168,7 +131,7 @@ function releaseLock()
if (!@getByIdDirectPrivate(this, "ownerReadableStream"))
return;
- if (@getByIdDirectPrivate(this, "readRequests").length)
+ if (@getByIdDirectPrivate(this, "readRequests")?.isNotEmpty())
@throwTypeError("There are still pending read requests, cannot release the lock");
@readableStreamReaderGenericRelease(this);
diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js
index 7c2384330..f441858cc 100644
--- a/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js
+++ b/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js
@@ -547,15 +547,15 @@ function readableStreamError(stream, error)
if (@isReadableStreamDefaultReader(reader)) {
const requests = @getByIdDirectPrivate(reader, "readRequests");
- @putByIdDirectPrivate(reader, "readRequests", []);
- for (let index = 0, length = requests.length; index < length; ++index)
- @rejectPromise(requests[index], error);
+ @putByIdDirectPrivate(reader, "readRequests", @createFIFO());
+ for (var request = requests.shift(); request; request = requests.shift())
+ @rejectPromise(request, error);
} else {
@assert(@isReadableStreamBYOBReader(reader));
const requests = @getByIdDirectPrivate(reader, "readIntoRequests");
- @putByIdDirectPrivate(reader, "readIntoRequests", []);
- for (let index = 0, length = requests.length; index < length; ++index)
- @rejectPromise(requests[index], error);
+ @putByIdDirectPrivate(reader, "readIntoRequests", @createFIFO());
+ for (var request = requests.shift(); request; request = requests.shift())
+ @rejectPromise(request, error);
}
@getByIdDirectPrivate(reader, "closedPromiseCapability").@reject.@call(@undefined, error);
@@ -571,7 +571,7 @@ function readableStreamDefaultControllerShouldCallPull(controller)
return false;
if (!@getByIdDirectPrivate(controller, "started"))
return false;
- if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").length) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)
+ if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)
return false;
const desiredSize = @readableStreamDefaultControllerGetDesiredSize(controller);
@assert(desiredSize !== null);
@@ -589,7 +589,7 @@ function readableStreamDefaultControllerCallPullIfNeeded(controller)
return;
if (!@getByIdDirectPrivate(controller, "started"))
return;
- if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").length) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)
+ if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)
return;
if (@getByIdDirectPrivate(controller, "pulling")) {
@@ -670,9 +670,10 @@ function readableStreamDefaultControllerPull(controller)
{
"use strict";
- if (@getByIdDirectPrivate(controller, "queue").content.length) {
- const chunk = @dequeueValue(@getByIdDirectPrivate(controller, "queue"));
- if (@getByIdDirectPrivate(controller, "closeRequested") && @getByIdDirectPrivate(controller, "queue").content.length === 0)
+ var queue = @getByIdDirectPrivate(controller, "queue");
+ if (queue.isNotEmpty()) {
+ const chunk = @dequeueValue(queue);
+ if (@getByIdDirectPrivate(controller, "closeRequested") && queue.isEmpty())
@readableStreamClose(@getByIdDirectPrivate(controller, "controlledReadableStream"));
else
@readableStreamDefaultControllerCallPullIfNeeded(controller);
@@ -690,7 +691,7 @@ function readableStreamDefaultControllerClose(controller)
@assert(@readableStreamDefaultControllerCanCloseOrEnqueue(controller));
@putByIdDirectPrivate(controller, "closeRequested", true);
- if (@getByIdDirectPrivate(controller, "queue").content.length === 0)
+ if (!@getByIdDirectPrivate(controller, "queue")?.isNotEmpty())
@readableStreamClose(@getByIdDirectPrivate(controller, "controlledReadableStream"));
}
@@ -707,9 +708,10 @@ function readableStreamClose(stream)
if (@isReadableStreamDefaultReader(reader)) {
const requests = @getByIdDirectPrivate(reader, "readRequests");
- @putByIdDirectPrivate(reader, "readRequests", []);
- for (let index = 0, length = requests.length; index < length; ++index)
- @fulfillPromise(requests[index], { value: @undefined, done: true });
+ @putByIdDirectPrivate(reader, "readRequests", @createFIFO());
+
+ for (var request = requests.shift(); request; request = requests.shift())
+ @fulfillPromise(request, { value: @undefined, done: true });
}
@getByIdDirectPrivate(reader, "closedPromiseCapability").@resolve.@call();
@@ -718,7 +720,7 @@ function readableStreamClose(stream)
function readableStreamFulfillReadRequest(stream, chunk, done)
{
"use strict";
- const readRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").@shift();
+ const readRequest = @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").shift();
@fulfillPromise(readRequest, { value: chunk, done: done });
}
@@ -730,7 +732,7 @@ function readableStreamDefaultControllerEnqueue(controller, chunk)
// this is checked by callers
@assert(@readableStreamDefaultControllerCanCloseOrEnqueue(controller));
- if (@isReadableStreamLocked(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").length) {
+ if (@isReadableStreamLocked(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").isNotEmpty) {
@readableStreamFulfillReadRequest(stream, chunk, false);
@readableStreamDefaultControllerCallPullIfNeeded(controller);
return;
@@ -775,7 +777,8 @@ function readableStreamAddReadRequest(stream)
@assert(@getByIdDirectPrivate(stream, "state") == @streamReadable);
const readRequest = @newPromise();
- @arrayPush(@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests"), readRequest);
+
+ @getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests").push(readRequest);
return readRequest;
}
diff --git a/src/javascript/jsc/bindings/builtins/js/StreamInternals.js b/src/javascript/jsc/bindings/builtins/js/StreamInternals.js
index 9c2103293..c2ca3f5b5 100644
--- a/src/javascript/jsc/bindings/builtins/js/StreamInternals.js
+++ b/src/javascript/jsc/bindings/builtins/js/StreamInternals.js
@@ -114,18 +114,119 @@ function validateAndNormalizeQueuingStrategy(size, highWaterMark)
return { size: size, highWaterMark: newHighWaterMark };
}
+@globalPrivate
+function createFIFO() {
+ "use strict";
+ class Denqueue {
+ constructor() {
+ this._head = 0;
+ this._tail = 0;
+ // this._capacity = 0;
+ this._capacityMask = 0x3;
+ this._list = @newArrayWithSize(4);
+ }
+
+ size() {
+ if (this._head === this._tail) return 0;
+ if (this._head < this._tail) return this._tail - this._head;
+ else return this._capacityMask + 1 - (this._head - this._tail);
+ }
+
+ isEmpty() {
+ return this.size() == 0;
+ }
+
+ isNotEmpty() {
+ return this.size() > 0;
+ }
+
+ shift() {
+ var head = this._head;
+ if (head === this._tail) return @undefined;
+ var item = this._list[head];
+ @putByValDirect(this._list, head, @undefined);
+ this._head = (head + 1) & this._capacityMask;
+ if (head < 2 && this._tail > 10000 && this._tail <= this._list.length >>> 2) this._shrinkArray();
+ return item;
+ }
+
+ peek() {
+ if (this._head === this._tail) return @undefined;
+ return this._list[this._head];
+ }
+
+ push(item) {
+ var tail = this._tail;
+ @putByValDirect(this._list, tail, item);
+ this._tail = (tail + 1) & this._capacityMask;
+ if (this._tail === this._head) {
+ this._growArray();
+ }
+ // if (this._capacity && this.size() > this._capacity) {
+ // this.shift();
+ // }
+ }
+
+ toArray(fullCopy) {
+ var list = this._list;
+ var len = @toLength(list.length);
+
+ if (fullCopy || this._head > this._tail) {
+ var _head = @toLength(this._head);
+ var _tail = @toLength(this._tail);
+ var total = @toLength((len - _head) + _tail);
+ var array = @newArrayWithSize(total);
+ var j = 0;
+ for (var i = _head; i < len; i++) @putByValDirect(array, j++, list[i]);
+ for (var i = 0; i < _tail; i++) @putByValDirect(array, j++, list[i]);
+ return array;
+ } else {
+ return @Array.prototype.slice.@call(list, this._head, this._tail);
+ }
+ }
+
+ clear() {
+ this._head = 0;
+ this._tail = 0;
+ this._list.fill(undefined);
+ }
+
+ _growArray() {
+ if (this._head) {
+ // copy existing data, head to end, then beginning to tail.
+ this._list = this.toArray(true);
+ this._head = 0;
+ }
+
+ // head is at 0 and array is now full, safe to extend
+ this._tail = @toLength(this._list.length);
+
+ this._list.length <<= 1;
+ this._capacityMask = (this._capacityMask << 1) | 1;
+ }
+
+ shrinkArray() {
+ this._list.length >>>= 1;
+ this._capacityMask >>>= 1;
+ }
+ }
+
+
+ return new Denqueue();
+}
+
function newQueue()
{
"use strict";
- return { content: [], size: 0 };
+ return { content: @createFIFO(), size: 0 };
}
function dequeueValue(queue)
{
"use strict";
- const record = queue.content.@shift();
+ const record = queue.content.shift();
queue.size -= record.size;
// As described by spec, below case may occur due to rounding errors.
if (queue.size < 0)
@@ -140,7 +241,8 @@ function enqueueValueWithSize(queue, value, size)
size = @toNumber(size);
if (!@isFinite(size) || size < 0)
@throwRangeError("size has an incorrect value");
- @arrayPush(queue.content, { value, size });
+
+ queue.content.push({ value, size });
queue.size += size;
}
@@ -148,9 +250,9 @@ function peekQueueValue(queue)
{
"use strict";
- @assert(queue.content.length > 0);
+ @assert(queue.content.isNotEmpty());
- return queue.content[0].value;
+ return queue.peek().value;
}
function resetQueue(queue)
@@ -159,7 +261,7 @@ function resetQueue(queue)
@assert("content" in queue);
@assert("size" in queue);
- queue.content = [];
+ queue.content.clear();
queue.size = 0;
}
diff --git a/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js
index 406b9ea48..6b2b3cf90 100644
--- a/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js
+++ b/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js
@@ -118,7 +118,7 @@ function initializeWritableStreamSlots(stream, underlyingSink)
@putByIdDirectPrivate(stream, "closeRequest", @undefined);
@putByIdDirectPrivate(stream, "inFlightCloseRequest", @undefined);
@putByIdDirectPrivate(stream, "pendingAbortRequest", @undefined);
- @putByIdDirectPrivate(stream, "writeRequests", []);
+ @putByIdDirectPrivate(stream, "writeRequests", @createFIFO());
@putByIdDirectPrivate(stream, "backpressure", false);
@putByIdDirectPrivate(stream, "underlyingSink", underlyingSink);
}
@@ -233,7 +233,7 @@ function writableStreamAddWriteRequest(stream)
const writePromiseCapability = @newPromiseCapability(@Promise);
const writeRequests = @getByIdDirectPrivate(stream, "writeRequests");
- @arrayPush(writeRequests, writePromiseCapability);
+ writeRequests.push(writePromiseCapability);
return writePromiseCapability.@promise;
}
@@ -266,10 +266,11 @@ function writableStreamFinishErroring(stream)
const storedError = @getByIdDirectPrivate(stream, "storedError");
const requests = @getByIdDirectPrivate(stream, "writeRequests");
- for (let index = 0, length = requests.length; index < length; ++index)
- requests[index].@reject.@call(@undefined, storedError);
+ for (var request = requests.shift(); request; request = requests.shift())
+ request.@reject.@call(@undefined, storedError);
- @putByIdDirectPrivate(stream, "writeRequests", []);
+ // TODO: is this still necessary?
+ @putByIdDirectPrivate(stream, "writeRequests", @createFIFO());
const abortRequest = @getByIdDirectPrivate(stream, "pendingAbortRequest");
if (abortRequest === @undefined) {
@@ -384,9 +385,9 @@ function writableStreamMarkFirstWriteRequestInFlight(stream)
{
const writeRequests = @getByIdDirectPrivate(stream, "writeRequests");
@assert(@getByIdDirectPrivate(stream, "inFlightWriteRequest") === @undefined);
- @assert(writeRequests.length > 0);
+ @assert(writeRequests.isNotEmpty());
- const writeRequest = writeRequests.@shift();
+ const writeRequest = writeRequests.shift();
@putByIdDirectPrivate(stream, "inFlightWriteRequest", writeRequest);
}
@@ -649,7 +650,7 @@ function writableStreamDefaultControllerAdvanceQueueIfNeeded(controller)
return;
}
- if (@getByIdDirectPrivate(controller, "queue").content.length === 0)
+ if (@getByIdDirectPrivate(controller, "queue").content?.isEmpty() ?? false)
return;
const value = @peekQueueValue(@getByIdDirectPrivate(controller, "queue"));
@@ -722,7 +723,7 @@ function writableStreamDefaultControllerProcessClose(controller)
@writableStreamMarkCloseRequestInFlight(stream);
@dequeueValue(@getByIdDirectPrivate(controller, "queue"));
- @assert(@getByIdDirectPrivate(controller, "queue").content.length === 0);
+ @assert(@getByIdDirectPrivate(controller, "queue").content?.isEmpty());
const sinkClosePromise = @getByIdDirectPrivate(controller, "closeAlgorithm").@call();
@writableStreamDefaultControllerClearAlgorithms(controller);
diff --git a/src/javascript/jsc/event_loop.zig b/src/javascript/jsc/event_loop.zig
index 88bc9af4e..209e9071d 100644
--- a/src/javascript/jsc/event_loop.zig
+++ b/src/javascript/jsc/event_loop.zig
@@ -19,8 +19,8 @@ const napi_async_work = JSC.napi.napi_async_work;
const FetchTasklet = Fetch.FetchTasklet;
const JSValue = JSC.JSValue;
const js = JSC.C;
-const WorkPool = @import("../../work_pool.zig").WorkPool;
-const WorkPoolTask = @import("../../work_pool.zig").Task;
+pub const WorkPool = @import("../../work_pool.zig").WorkPool;
+pub const WorkPoolTask = @import("../../work_pool.zig").Task;
const NetworkThread = @import("http").NetworkThread;
pub fn ConcurrentPromiseTask(comptime Context: type) type {
diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig
index 137ce35b8..3e42c174a 100644
--- a/src/javascript/jsc/webcore/response.zig
+++ b/src/javascript/jsc/webcore/response.zig
@@ -1557,7 +1557,7 @@ pub const Blob = struct {
is_all_ascii: ?bool = null,
allocator: std.mem.Allocator,
- // 8 MB ought to be enough
+ // 2 MB ought to be enough
pub const max_chunk_size = 1024 * 1024 * 2;
pub export fn BlobStore__ref(ptr: *anyopaque) void {
@@ -4988,6 +4988,12 @@ pub const FetchEvent = struct {
}
};
+pub const StreamStart = union(enum) {
+ empty: void,
+ err: JSC.Node.Syscall.Error,
+ chunk_size: Blob.SizeType,
+};
+
pub const StreamResult = union(enum) {
owned: bun.ByteList,
owned_and_done: bun.ByteList,
@@ -5000,8 +5006,8 @@ pub const StreamResult = union(enum) {
done: void,
pub const IntoArray = struct {
- value: JSValue,
- len: usize = std.math.maxInt(usize),
+ value: JSValue = JSValue.zero,
+ len: Blob.SizeType = std.math.maxInt(Blob.SizeType),
};
pub const Pending = struct {
@@ -5010,6 +5016,13 @@ pub const StreamResult = union(enum) {
used: bool = false,
};
+ pub fn isDone(this: *const StreamResult) bool {
+ return switch (this.*) {
+ .owned_and_done, .temporary_and_done, .into_array_and_done, .done, .err => true,
+ else => false,
+ };
+ }
+
fn toPromisedWrap(globalThis: *JSGlobalObject, promise: *JSPromise, pending: *Pending) void {
suspend {}
@@ -5038,10 +5051,10 @@ pub const StreamResult = union(enum) {
pub fn toJS(this: *const StreamResult, globalThis: *JSGlobalObject) JSValue {
switch (this.*) {
.owned => |list| {
- return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJSAutoAllocator(globalThis.ref(), null);
+ return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJS(globalThis.ref(), null);
},
.owned_and_done => |list| {
- return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJSAutoAllocator(globalThis.ref(), null);
+ return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJS(globalThis.ref(), null);
},
.temporary => |temp| {
var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len);
@@ -5056,10 +5069,10 @@ pub const StreamResult = union(enum) {
return array;
},
.into_array => |array| {
- return array.value;
+ return JSC.JSValue.jsNumberFromInt64(array.len);
},
.into_array_and_done => |array| {
- return array.value;
+ return JSC.JSValue.jsNumberFromInt64(array.len);
},
.pending => |pending| {
var promise = JSC.JSPromise.create(globalThis);
@@ -5115,7 +5128,7 @@ pub fn WritableStreamSink(
return onWrite(&this.context, bytes);
}
- pub fn start(this: *This) StreamResult {
+ pub fn start(this: *This) StreamStart {
return onStart(&this.context);
}
@@ -5291,21 +5304,21 @@ pub fn ReadableStreamSource(
const This = @This();
const ReadableStreamSourceType = @This();
- pub fn pull(this: *This) StreamResult {
- return onPull(&this.context);
+ pub fn pull(this: *This, buf: []u8) StreamResult {
+ return onPull(&this.context, buf, JSValue.zero);
}
pub fn start(
this: *This,
- ) StreamResult {
+ ) StreamStart {
return onStart(&this.context);
}
- pub fn pullFromJS(this: *This) StreamResult {
- return onPull(&this.context);
+ pub fn pullFromJS(this: *This, buf: []u8, view: JSValue) StreamResult {
+ return onPull(&this.context, buf, view);
}
- pub fn startFromJS(this: *This) StreamResult {
+ pub fn startFromJS(this: *This) StreamStart {
return onStart(&this.context);
}
@@ -5356,19 +5369,24 @@ pub fn ReadableStreamSource(
pub fn pull(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue {
var this = callFrame.argument(0).asPtr(ReadableStreamSourceType);
+ const view = callFrame.argument(1);
+ view.ensureStillAlive();
+ var buffer = view.asArrayBuffer(globalThis) orelse return JSC.JSValue.jsUndefined();
return processResult(
globalThis,
callFrame,
- this.pullFromJS(),
+ this.pullFromJS(buffer.slice(), view),
);
}
pub fn start(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue {
var this = callFrame.argument(0).asPtr(ReadableStreamSourceType);
- return processResult(
- globalThis,
- callFrame,
- this.startFromJS(),
- );
+ switch (this.startFromJS()) {
+ .empty => return JSValue.jsNumber(0),
+ .chunk_size => |size| return JSValue.jsNumber(size),
+ .err => |err| {
+ return err.toJSC(globalThis);
+ },
+ }
}
pub fn processResult(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame, result: StreamResult) JSC.JSValue {
@@ -5475,30 +5493,35 @@ pub const ByteBlobLoader = struct {
};
}
- pub fn onStart(this: *ByteBlobLoader) StreamResult {
- return this.onPull();
+ pub fn onStart(this: *ByteBlobLoader) StreamStart {
+ return .{ .chunk_size = this.chunk_size };
}
- pub fn onPull(this: *ByteBlobLoader) StreamResult {
+ pub fn onPull(this: *ByteBlobLoader, buffer: []u8, array: JSC.JSValue) StreamResult {
if (this.done) {
return .{ .done = {} };
}
var temporary = this.store.sharedView();
temporary = temporary[this.offset..];
- temporary = temporary[0..@minimum(this.chunk_size, @minimum(temporary.len, this.remain))];
+
+ temporary = temporary[0..@minimum(buffer.len, @minimum(temporary.len, this.remain))];
if (temporary.len == 0) {
this.store.deref();
this.done = true;
return .{ .done = {} };
}
- this.remain -|= @intCast(Blob.SizeType, temporary.len);
- this.offset +|= @intCast(Blob.SizeType, temporary.len);
+ const copied = @intCast(Blob.SizeType, temporary.len);
- return .{
- .temporary = bun.ByteList.init(temporary),
- };
+ this.remain -|= copied;
+ this.offset +|= copied;
+ @memcpy(temporary.ptr, buffer.ptr, temporary.len);
+ if (this.remain == 0) {
+ return .{ .into_array_and_done = .{ .value = array, .len = copied } };
+ }
+
+ return .{ .into_array = .{ .value = array, .len = copied } };
}
pub fn onCancel(_: *ByteBlobLoader) void {}
@@ -5517,7 +5540,7 @@ pub const ByteBlobLoader = struct {
pub const FileBlobLoader = struct {
buf: []u8 = &[_]u8{},
- uint8array: JSC.JSValue = JSC.JSValue.zero,
+ protected_view: JSC.JSValue = JSC.JSValue.zero,
fd: JSC.Node.FileDescriptor = 0,
auto_close: bool = false,
loop: *JSC.EventLoop = undefined,
@@ -5538,7 +5561,7 @@ pub const FileBlobLoader = struct {
const FileReader = @This();
- const run_on_different_thread_size = 1024 * 512;
+ const run_on_different_thread_size = bun.huge_allocator_threshold;
pub const tag = ReadableStream.Tag.File;
@@ -5635,40 +5658,23 @@ pub const FileBlobLoader = struct {
scheduleMainThreadTask(this);
return;
}
+ }
- AsyncIO.global.read(
- *FileBlobLoader,
- this,
- onRead,
- &this.concurrent.completion,
- this.fd,
- this.buf[this.concurrent.read..],
- null,
- );
-
- suspend {
- var _frame = @frame();
- var this_frame = HTTPClient.getAllocator().create(std.meta.Child(@TypeOf(_frame))) catch unreachable;
- this_frame.* = _frame.*;
- this.concurrent.read_frame = this_frame;
- }
- } else {
- AsyncIO.global.read(
- *FileBlobLoader,
- this,
- onRead,
- &this.concurrent.completion,
- this.fd,
- this.buf[this.concurrent.read..],
- null,
- );
+ AsyncIO.global.read(
+ *FileBlobLoader,
+ this,
+ onRead,
+ &this.concurrent.completion,
+ this.fd,
+ this.buf[this.concurrent.read..],
+ null,
+ );
- suspend {
- var _frame = @frame();
- var this_frame = HTTPClient.getAllocator().create(std.meta.Child(@TypeOf(_frame))) catch unreachable;
- this_frame.* = _frame.*;
- this.concurrent.read_frame = this_frame;
- }
+ suspend {
+ var _frame = @frame();
+ var this_frame = HTTPClient.getAllocator().create(std.meta.Child(@TypeOf(_frame))) catch unreachable;
+ this_frame.* = _frame.*;
+ this.concurrent.read_frame = this_frame;
}
scheduleMainThreadTask(this);
@@ -5676,12 +5682,16 @@ pub const FileBlobLoader = struct {
pub fn onJSThread(task_ctx: *anyopaque) void {
var this: *FileBlobLoader = bun.cast(*FileBlobLoader, task_ctx);
+ const protected_view = this.protected_view;
+ defer protected_view.unprotect();
+ this.protected_view = JSC.JSValue.zero;
if (this.finalized and this.scheduled_count == 0) {
if (!this.pending.used) {
resume this.pending.frame;
}
this.scheduled_count -= 1;
+
this.deinit();
return;
@@ -5702,9 +5712,12 @@ pub const FileBlobLoader = struct {
return;
}
- this.pending.result = this.handleReadChunk(this.buf, @as(usize, this.concurrent.read));
+ this.pending.result = this.handleReadChunk(@as(usize, this.concurrent.read));
resume this.pending.frame;
this.scheduled_count -= 1;
+ if (this.pending.result.isDone()) {
+ this.finalize();
+ }
}
pub fn scheduleMainThreadTask(this: *FileBlobLoader) void {
@@ -5714,14 +5727,6 @@ pub const FileBlobLoader = struct {
fn runAsync(this: *FileBlobLoader) void {
this.concurrent.read = 0;
- this.buf = bun.auto_allocator.alloc(u8, this.concurrent.chunk_size) catch {
- this.pending.result = .{ .err = JSC.Node.Syscall.Error.oom };
- this.concurrent.read = 0;
- scheduleMainThreadTask(this);
-
- return;
- };
- _ = bun.C.posix_madvise(this.buf.ptr, this.buf.len, 2);
Concurrent.scheduleRead(this);
@@ -5742,7 +5747,7 @@ pub const FileBlobLoader = struct {
const default_fifo_chunk_size = 1024;
const default_file_chunk_size = 1024 * 1024 * 2;
- pub fn onStart(this: *FileBlobLoader) StreamResult {
+ pub fn onStart(this: *FileBlobLoader) StreamStart {
var file = &this.store.data.file;
var file_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var auto_close = this.auto_close;
@@ -5800,15 +5805,6 @@ pub const FileBlobLoader = struct {
return .{ .err = err };
}
- // if (comptime Environment.isMac) {
- // if (std.os.S.ISSOCK(stat.mode)) {
- // // darwin doesn't support os.MSG.NOSIGNAL,
- // // but instead a socket option to avoid SIGPIPE.
- // const _bytes = &std.mem.toBytes(@as(c_int, 1));
- // _ = std.os.darwin.setsockopt(fd, std.os.SOL.SOCKET, std.os.SO.NOSIGPIPE, _bytes, @intCast(std.os.socklen_t, _bytes.len));
- // }
- // }
-
file.seekable = std.os.S.ISREG(stat.mode);
file.mode = @intCast(JSC.Node.Mode, stat.mode);
this.mode = file.mode;
@@ -5821,45 +5817,14 @@ pub const FileBlobLoader = struct {
_ = JSC.Node.Syscall.close(fd);
}
this.deinit();
- return .{ .done = {} };
+ return .{ .empty = {} };
}
this.fd = fd;
this.auto_close = auto_close;
const chunk_size = this.calculateChunkSize(std.math.maxInt(usize));
-
- if (chunk_size >= run_on_different_thread_size) {
- // should never be reached
- this.pending.result = .{
- .err = JSC.Node.Syscall.Error.todo,
- };
-
- this.scheduleAsync(@truncate(Blob.SizeType, chunk_size));
-
- return .{ .pending = &this.pending };
- }
-
- if (this.allocateBuffer(chunk_size)) |err| {
- this.deinit();
- return .{ .err = err };
- }
-
- return this.read(this.buf);
- }
-
- // Disabled because it's not fully implemented
- // Maybe we should allocate as an ArrayBuffer instead of a Uint8Array?
- fn shouldUseJSCHeap(this: *const FileBlobLoader, chunk_size: Blob.SizeType) bool {
- _ = this;
- _ = chunk_size;
- return false;
- // const file = &this.store.data.file;
-
- // if (!(file.seekable orelse false))
- // return false;
-
- // return file.max_size - this.total_read >= chunk_size;
+ return .{ .chunk_size = @truncate(Blob.SizeType, chunk_size) };
}
fn calculateChunkSize(this: *FileBlobLoader, available_to_read: usize) usize {
@@ -5878,55 +5843,32 @@ pub const FileBlobLoader = struct {
@minimum(available_to_read, chunk_size);
}
- fn allocateBuffer(this: *FileBlobLoader, chunk_size: usize) ?JSC.Node.Syscall.Error {
- var file = &this.store.data.file;
-
- if (this.shouldUseJSCHeap(@intCast(Blob.SizeType, chunk_size))) {
- this.uint8array = JSValue.createUninitializedUint8Array(this.loop.global, chunk_size);
- this.uint8array.ensureStillAlive();
- this.buf = this.uint8array.asArrayBuffer(this.loop.global).?.slice();
- } else {
- this.buf = bun.auto_allocator.alloc(
- u8,
- chunk_size,
- ) catch {
- this.maybeAutoClose();
- return JSC.Node.Syscall.Error.oom.withPath(if (file.pathlike.path.slice().len > 0) file.pathlike.path.slice() else "");
- };
- }
-
- return null;
- }
-
- pub fn onPull(this: *FileBlobLoader) StreamResult {
- if (this.buf.len == 0) {
- const chunk_size = this.calculateChunkSize(std.math.maxInt(usize));
+ pub fn onPull(this: *FileBlobLoader, buffer: []u8, view: JSC.JSValue) StreamResult {
+ const chunk_size = this.calculateChunkSize(std.math.maxInt(usize));
- switch (chunk_size) {
- 0 => {
- std.debug.assert(this.store.data.file.seekable orelse false);
- this.finalize();
- return .{ .done = {} };
- },
- run_on_different_thread_size...std.math.maxInt(@TypeOf(chunk_size)) => {
- // should never be reached
- this.pending.result = .{
- .err = JSC.Node.Syscall.Error.todo,
- };
+ switch (chunk_size) {
+ 0 => {
+ std.debug.assert(this.store.data.file.seekable orelse false);
+ this.finalize();
+ return .{ .done = {} };
+ },
+ run_on_different_thread_size...std.math.maxInt(@TypeOf(chunk_size)) => {
+ this.protected_view = view;
+ this.protected_view.protect();
+ // should never be reached
+ this.pending.result = .{
+ .err = JSC.Node.Syscall.Error.todo,
+ };
+ this.buf = buffer;
- this.scheduleAsync(@truncate(Blob.SizeType, chunk_size));
+ this.scheduleAsync(@truncate(Blob.SizeType, chunk_size));
- return .{ .pending = &this.pending };
- },
- else => {
- if (this.allocateBuffer(chunk_size)) |err| {
- return .{ .err = err };
- }
- },
- }
+ return .{ .pending = &this.pending };
+ },
+ else => {},
}
- return this.read(this.buf);
+ return this.read(buffer, view);
}
fn maybeAutoClose(this: *FileBlobLoader) void {
@@ -5936,7 +5878,7 @@ pub const FileBlobLoader = struct {
}
}
- fn handleReadChunk(this: *FileBlobLoader, read_buf: []u8, result: usize) StreamResult {
+ fn handleReadChunk(this: *FileBlobLoader, result: usize) StreamResult {
this.total_read += @intCast(Blob.SizeType, result);
const remaining: Blob.SizeType = if (this.store.data.file.seekable orelse false)
this.store.data.file.max_size -| this.total_read
@@ -5954,52 +5896,16 @@ pub const FileBlobLoader = struct {
const has_more = remaining > 0;
if (!has_more) {
- this.uint8array.ensureStillAlive();
-
- defer {
- this.uint8array.ensureStillAlive();
- this.buf = &.{};
- this.uint8array = JSValue.zero;
- this.finalize();
- }
-
- if (this.uint8array.isEmpty()) {
- return .{
- .owned_and_done = bun.ByteList.init(read_buf[0..result]),
- };
- } else {
- return .{
- .into_array_and_done = .{
- .value = this.uint8array,
- .len = result,
- },
- };
- }
+ return .{ .into_array_and_done = .{ .len = @truncate(Blob.SizeType, result) } };
}
- if (this.uint8array.isEmpty()) {
- defer this.buf = &.{};
- return .{
- .owned = bun.ByteList.init(read_buf[0..result]),
- };
- } else {
- defer {
- this.buf = &.{};
- this.uint8array = JSValue.zero;
- }
-
- return .{
- .into_array = .{
- .value = this.uint8array,
- .len = result,
- },
- };
- }
+ return .{ .into_array = .{ .len = @truncate(Blob.SizeType, result) } };
}
pub fn read(
this: *FileBlobLoader,
read_buf: []u8,
+ view: JSC.JSValue,
) StreamResult {
const rc =
JSC.Node.Syscall.read(this.fd, read_buf);
@@ -6013,6 +5919,9 @@ pub const FileBlobLoader = struct {
switch (err.getErrno()) {
retry => {
+ this.protected_view = view;
+ this.protected_view.protect();
+ this.buf = read_buf;
this.watch();
return .{
.pending = &this.pending,
@@ -6029,7 +5938,7 @@ pub const FileBlobLoader = struct {
return .{ .err = sys };
},
.result => |result| {
- return this.handleReadChunk(read_buf, result);
+ return this.handleReadChunk(result);
},
}
}
@@ -6037,6 +5946,9 @@ pub const FileBlobLoader = struct {
pub fn callback(task: ?*anyopaque, sizeOrOffset: i64, _: u16) void {
var this: *FileReader = bun.cast(*FileReader, task.?);
this.scheduled_count -= 1;
+ const protected_view = this.protected_view;
+ defer protected_view.unprotect();
+ this.protected_view = JSValue.zero;
var available_to_read: usize = std.math.maxInt(usize);
if (comptime Environment.isMac) {
@@ -6064,16 +5976,12 @@ pub const FileBlobLoader = struct {
return;
if (this.buf.len == 0) {
- if (this.allocateBuffer(available_to_read)) |err| {
- this.pending.result = .{ .err = err };
- resume this.pending.frame;
- return;
- }
+ return;
} else {
this.buf.len = @minimum(this.buf.len, available_to_read);
}
- this.pending.result = this.read(this.buf);
+ this.pending.result = this.read(this.buf, this.protected_view);
resume this.pending.frame;
}
@@ -6081,15 +5989,6 @@ pub const FileBlobLoader = struct {
if (this.finalized)
return;
this.finalized = true;
- if (this.buf.len > 0) {
- if (this.uint8array.isEmpty()) {
- bun.default_allocator.free(this.buf);
- this.buf = &.{};
- } else {
- this.buf = &.{};
- this.uint8array = JSValue.zero;
- }
- }
this.maybeAutoClose();