From 56e88fb4dd06e07569ddc3861e2e8e21f71e45b8 Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Wed, 15 Jun 2022 07:17:42 -0700 Subject: direct streams mostly work --- integration/bunjs-only-snippets/ffi.test.js | 1 - integration/bunjs-only-snippets/streams.test.js | 27 + src/javascript/jsc/base.zig | 9 +- src/javascript/jsc/bindings/BunBuiltinNames.h | 6 +- src/javascript/jsc/bindings/JSSink.cpp | 227 +++++--- src/javascript/jsc/bindings/JSSink.h | 323 +++++------ .../ReadableByteStreamInternalsBuiltins.cpp | 16 +- .../jsc/bindings/ReadableStreamBuiltins.cpp | 158 ++---- .../bindings/ReadableStreamInternalsBuiltins.cpp | 629 ++++++++++++++++++--- .../jsc/bindings/ReadableStreamInternalsBuiltins.h | 116 +++- .../bindings/WritableStreamInternalsBuiltins.cpp | 7 +- src/javascript/jsc/bindings/ZigGlobalObject.cpp | 14 + src/javascript/jsc/bindings/ZigGlobalObject.h | 2 + src/javascript/jsc/bindings/bindings.zig | 49 +- .../builtins/js/ReadableByteStreamInternals.js | 11 +- .../jsc/bindings/builtins/js/ReadableStream.js | 444 +-------------- .../builtins/js/ReadableStreamInternals.js | 500 ++++++++++++++-- .../builtins/js/WritableStreamInternals.js | 1 - src/javascript/jsc/bindings/exports.zig | 2 +- src/javascript/jsc/bindings/headers-cpp.h | 2 +- src/javascript/jsc/bindings/headers.h | 6 +- src/javascript/jsc/bindings/headers.zig | 1 - .../jsc/bindings/webcore/DOMClientIsoSubspaces.h | 1 + .../jsc/bindings/webcore/DOMIsoSubspaces.h | 1 + src/javascript/jsc/generate-jssink.js | 339 ++++++----- src/javascript/jsc/webcore/streams.zig | 57 +- 26 files changed, 1782 insertions(+), 1167 deletions(-) diff --git a/integration/bunjs-only-snippets/ffi.test.js b/integration/bunjs-only-snippets/ffi.test.js index 6698ae51b..b8d79887b 100644 --- a/integration/bunjs-only-snippets/ffi.test.js +++ b/integration/bunjs-only-snippets/ffi.test.js @@ -383,7 +383,6 @@ function ffiRunner(types) { var bigArray = new BigUint64Array(8); new Uint8Array(bigArray.buffer).fill(255); var bigIntArray = new BigInt64Array(bigArray.buffer); - expect(identity_uint64_t(bigArray[0])).toBe(bigArray[0]); expect(identity_uint64_t(bigArray[0] - BigInt(1))).toBe( bigArray[0] - BigInt(1) diff --git a/integration/bunjs-only-snippets/streams.test.js b/integration/bunjs-only-snippets/streams.test.js index a3d4965ee..929f4a29b 100644 --- a/integration/bunjs-only-snippets/streams.test.js +++ b/integration/bunjs-only-snippets/streams.test.js @@ -22,15 +22,37 @@ it("exists globally", () => { expect(typeof CountQueuingStrategy).toBe("function"); }); +it("ReadableStream (direct)", async () => { + var stream = new ReadableStream({ + pull(controller) { + controller.write("hello"); + controller.write("world"); + controller.close(); + }, + cancel() {}, + type: "direct", + }); + console.log("hello"); + const chunks = []; + const chunk = await stream.getReader().read(); + console.log("it's me"); + chunks.push(chunk.value); + expect(chunks[0].join("")).toBe(Buffer.from("helloworld").join("")); +}); + it("ReadableStream (bytes)", async () => { + console.trace(); + var stream = new ReadableStream({ start(controller) { + console.log("there"); controller.enqueue(Buffer.from("abdefgh")); }, pull(controller) {}, cancel() {}, type: "bytes", }); + console.log("here"); const chunks = []; const chunk = await stream.getReader().read(); chunks.push(chunk.value); @@ -38,6 +60,7 @@ it("ReadableStream (bytes)", async () => { }); it("ReadableStream (default)", async () => { + console.trace(); var stream = new ReadableStream({ start(controller) { controller.enqueue(Buffer.from("abdefgh")); @@ -53,6 +76,7 @@ it("ReadableStream (default)", async () => { }); it("readableStreamToArray", async () => { + console.trace(); var queue = [Buffer.from("abdefgh")]; var stream = new ReadableStream({ pull(controller) { @@ -73,6 +97,7 @@ it("readableStreamToArray", async () => { }); it("readableStreamToArrayBuffer (bytes)", async () => { + console.trace(); var queue = [Buffer.from("abdefgh")]; var stream = new ReadableStream({ pull(controller) { @@ -109,6 +134,7 @@ it("readableStreamToArrayBuffer (default)", async () => { }); it("ReadableStream for Blob", async () => { + console.trace(); var blob = new Blob(["abdefgh", "ijklmnop"]); expect(await blob.text()).toBe("abdefghijklmnop"); var stream = blob.stream(); @@ -125,6 +151,7 @@ it("ReadableStream for Blob", async () => { }); it("ReadableStream for File", async () => { + console.trace(); var blob = file(import.meta.dir + "/fetch.js.txt"); var stream = blob.stream(24); const chunks = []; diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig index 22011aeab..eaf15beba 100644 --- a/src/javascript/jsc/base.zig +++ b/src/javascript/jsc/base.zig @@ -2246,15 +2246,16 @@ pub const ArrayBuffer = extern struct { } pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSC.JSValue.JSType) JSValue { + JSC.markBinding(); return switch (comptime kind) { - .Uint8Array => Bun__createUninitializedUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len), - .ArrayBuffer => Bun__createUninitializedArrayBufferForCopy(globalThis, bytes.ptr, bytes.len), + .Uint8Array => Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len), + .ArrayBuffer => Bun__createArrayBufferForCopy(globalThis, bytes.ptr, bytes.len), else => @compileError("Not implemented yet"), }; } - extern "C" fn Bun__createUninitializedArrayBufferForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue; - extern "C" fn Bun__createUninitializedUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue; + extern "C" fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue; + extern "C" fn Bun__createArrayBufferForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue; pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue, _: JSC.C.ExceptionRef) ArrayBuffer { var out = std.mem.zeroes(ArrayBuffer); diff --git a/src/javascript/jsc/bindings/BunBuiltinNames.h b/src/javascript/jsc/bindings/BunBuiltinNames.h index e825b0765..917f0bf09 100644 --- a/src/javascript/jsc/bindings/BunBuiltinNames.h +++ b/src/javascript/jsc/bindings/BunBuiltinNames.h @@ -40,9 +40,9 @@ using namespace JSC; macro(addEventListener) \ macro(appendFromJS) \ macro(argv) \ + macro(assignDirectStream) \ macro(associatedReadableByteStreamController) \ macro(autoAllocateChunkSize) \ - macro(startDirectStream) \ macro(backpressure) \ macro(backpressureChangePromise) \ macro(basename) \ @@ -79,8 +79,8 @@ using namespace JSC; macro(delimiter) \ macro(destroy) \ macro(dir) \ - macro(dirname) \ macro(direct) \ + macro(dirname) \ macro(disturbed) \ macro(document) \ macro(encode) \ @@ -124,6 +124,7 @@ using namespace JSC; macro(isWindows) \ macro(join) \ macro(kind) \ + macro(lazy) \ macro(localStreams) \ macro(makeDOMException) \ macro(makeGetterTypeError) \ @@ -186,6 +187,7 @@ using namespace JSC; macro(start) \ macro(startAlgorithm) \ macro(startConsumingStream) \ + macro(startDirectStream) \ macro(started) \ macro(startedPromise) \ macro(state) \ diff --git a/src/javascript/jsc/bindings/JSSink.cpp b/src/javascript/jsc/bindings/JSSink.cpp index 3e659deb0..60227464c 100644 --- a/src/javascript/jsc/bindings/JSSink.cpp +++ b/src/javascript/jsc/bindings/JSSink.cpp @@ -1,9 +1,9 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by /Users/jarred/Code/bun/src/javascript/jsc/generate-JSSink.js at 2022-06-14T08:19:26.544Z +// Generated by /Users/jarred/Code/bun/src/javascript/jsc/generate-jssink.js at 2022-06-15T10:28:21.211Z // To regenerate this file, run: // -// bun src/javascript/jsc/generate-JSSink.js +// bun src/javascript/jsc/generate-jssink.js // #include "root.h" #include "JSSink.h" @@ -49,56 +49,125 @@ // #include "JavaScriptCore/JSTypedArrayViewPrototype.h" #include "JavaScriptCore/JSArrayBufferViewInlines.h" +#include "JSReadableStream.h" +#include "BunClientData.h" +#include "JavaScriptCore/Weak.h" +#include "JavaScriptCore/WeakInlines.h" + namespace WebCore { using namespace JSC; -JSC_DEFINE_CUSTOM_GETTER(functionArrayBufferSink__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) +JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) { + auto& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); - return JSC::JSValue::encode(globalObject->ArrayBufferSink()); + JSC::JSValue readableStream = callFrame->argument(0); + JSC::JSValue onPull = callFrame->argument(1); + JSC::JSValue onClose = callFrame->argument(2); + if (!readableStream.isObject()) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected ReadableStream"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + if (!onPull.isObject() || !onPull.isCallable()) { + onPull = JSC::jsUndefined(); + } + + if (!onClose.isObject() || !onClose.isCallable()) { + onClose = JSC::jsUndefined(); + } + + JSC::JSFunction* onPullFunction = JSC::jsDynamicCast(onPull); + JSC::JSFunction* onCloseFunction = JSC::jsDynamicCast(onClose); + + if (WebCore::JSReadableArrayBufferSinkController* ArrayBufferSinkController = JSC::jsDynamicCast(callFrame->thisValue())) { + if (ArrayBufferSinkController->wrapped() == nullptr) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + ArrayBufferSinkController->start(globalObject, readableStream, onPullFunction, onCloseFunction); + } + + else { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Unknown direct controller. This is a bug in Bun."_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsUndefined())); } -JSC_DEFINE_CUSTOM_GETTER(functionReadableArrayBufferSinkController__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) +JSC_DEFINE_CUSTOM_GETTER(functionArrayBufferSink__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) { auto& vm = lexicalGlobalObject->vm(); Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); - return JSC::JSValue::encode(globalObject->ArrayBufferSinkController()); + return JSC::JSValue::encode(globalObject->ArrayBufferSink()); } -JSC_DECLARE_HOST_FUNCTION(functionReadableArrayBufferSinkController__run); -JSC_DEFINE_HOST_FUNCTION(functionReadableArrayBufferSinkController__run, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +JSC_DECLARE_HOST_FUNCTION(JSReadableArrayBufferSinkController__close); +JSC_DEFINE_HOST_FUNCTION(JSReadableArrayBufferSinkController__close, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) { + auto& vm = lexicalGlobalObject->vm(); - Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); auto scope = DECLARE_THROW_SCOPE(vm); + Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); + WebCore::JSReadableArrayBufferSinkController* controller = JSC::jsDynamicCast(callFrame->thisValue()); + if (!controller) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected JSReadableArrayBufferSinkController"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } - if (callFrame->argumentCount() < 6) { - throwException(callFrame, scope, createNotEnoughArgumentsError(callFrame)); + void* ptr = controller->wrapped(); + if (ptr == nullptr) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } - WebCore::JSReadableStream* readableStream = JSC::jsDynamicCast(vm, callFrame->argument(0)); - if (!readableStream) { - throwException(callFrame, scope, createTypeError(callFrame, "first argument is not a ReadableStream")); + controller->detach(); + ArrayBufferSink__close(lexicalGlobalObject, ptr); + return JSC::JSValue::encode(JSC::jsUndefined()); +} + +JSC_DECLARE_HOST_FUNCTION(ArrayBufferSink__doClose); +JSC_DEFINE_HOST_FUNCTION(ArrayBufferSink__doClose, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + + auto& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); + WebCore::JSArrayBufferSink* sink = JSC::jsDynamicCast(callFrame->thisValue()); + if (!sink) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected ArrayBufferSink"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } - void* sinkPtr = reinterpret_cast(bitwise_cast(callFrame->argument(1).toDouble(globalObject))); - JSObject* startFunctionObj = callFrame->argument(2).getObject(); - JSObject* pullFunctionObj = callFrame->argument(3).getObject(); - JSObject* cancelFunctionObj = callFrame->argument(4).getObject(); + void* ptr = sink->wrapped(); + if (ptr == nullptr) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } - JSFunction* pullFunction = pullFunctionObj != nullptr && startFunctionObj->isCallbable() ? JSC::jsCast(pullFunctionObj) : nullptr; - JSFunction* cancelFunction = cancelFunctionObj != nullptr && startFunctionObj->isCallbable() ? JSC::jsCast(cancelFunctionObj) : nullptr; + sink->detach(); + ArrayBufferSink__close(lexicalGlobalObject, ptr); + return JSC::JSValue::encode(JSC::jsUndefined()); } static const HashTableValue JSArrayBufferSinkPrototypeTableValues[] = { - { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__close), (intptr_t)(0) } }, - { "closeWithError"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__closeWithError), (intptr_t)(1) } }, + { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__doClose), (intptr_t)(0) } }, + { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__drain), (intptr_t)(1) } }, + { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__end), (intptr_t)(0) } }, + { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__start), (intptr_t)(1) } }, + { "write"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__write), (intptr_t)(1) } }, + }; + +static const HashTableValue JSReadableArrayBufferSinkControllerPrototypeTableValues[] + = { + { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(JSReadableArrayBufferSinkController__close), (intptr_t)(0) } }, { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__drain), (intptr_t)(1) } }, { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__end), (intptr_t)(0) } }, { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(ArrayBufferSink__start), (intptr_t)(1) } }, @@ -171,15 +240,12 @@ private: }; STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableArrayBufferSinkControllerPrototype, JSReadableArrayBufferSinkControllerPrototype::Base); -// Classes without streams const ClassInfo JSArrayBufferSinkPrototype::s_info = { "ArrayBufferSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArrayBufferSinkPrototype) }; const ClassInfo JSArrayBufferSink::s_info = { "ArrayBufferSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArrayBufferSink) }; const ClassInfo JSArrayBufferSinkConstructor::s_info = { "ArrayBufferSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArrayBufferSinkConstructor) }; -// Classes with streams const ClassInfo JSReadableArrayBufferSinkControllerPrototype::s_info = { "ReadableArrayBufferSinkController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableArrayBufferSinkControllerPrototype) }; const ClassInfo JSReadableArrayBufferSinkController::s_info = { "ReadableArrayBufferSinkController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableArrayBufferSinkController) }; -const ClassInfo JSReadableArrayBufferSinkControllerConstructor::s_info = { "ReadableArrayBufferSinkController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableArrayBufferSinkControllerConstructor) }; JSArrayBufferSink::~JSArrayBufferSink() { @@ -191,7 +257,7 @@ JSArrayBufferSink::~JSArrayBufferSink() JSReadableArrayBufferSinkController::~JSReadableArrayBufferSinkController() { if (m_sinkPtr) { - ArrayBufferSink__finalizeController(m_sinkPtr); + ArrayBufferSink__finalize(m_sinkPtr); } } @@ -202,13 +268,6 @@ JSArrayBufferSinkConstructor* JSArrayBufferSinkConstructor::create(JSC::VM& vm, return ptr; } -JSReadableArrayBufferSinkControllerConstructor* JSReadableArrayBufferSinkControllerConstructor::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSObject* prototype) -{ - JSReadableArrayBufferSinkControllerConstructor* ptr = new (NotNull, JSC::allocateCell(vm)) JSReadableArrayBufferSinkControllerConstructor(vm, structure, ArrayBufferSink__constructController); - ptr->finishCreation(vm, globalObject, prototype); - return ptr; -} - JSArrayBufferSink* JSArrayBufferSink::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr) { JSArrayBufferSink* ptr = new (NotNull, JSC::allocateCell(vm)) JSArrayBufferSink(vm, structure, sinkPtr); @@ -230,23 +289,11 @@ void JSArrayBufferSinkConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* g initializeProperties(vm, globalObject, prototype); } -void JSReadableArrayBufferSinkControllerConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSObject* prototype) -{ - Base::finishCreation(vm); - ASSERT(inherits(info())); - initializeProperties(vm, globalObject, prototype); -} - JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSArrayBufferSinkConstructor::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { return ArrayBufferSink__construct(globalObject, callFrame); } -JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSReadableArrayBufferSinkController::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -{ - return ArrayBufferSink__constructController(globalObject, callFrame); -} - void JSArrayBufferSinkConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSObject* prototype) { putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); @@ -255,14 +302,6 @@ void JSArrayBufferSinkConstructor::initializeProperties(VM& vm, JSC::JSGlobalObj putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); } -void JSReadableArrayBufferSinkControllerConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSObject* prototype) -{ - putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); - JSString* nameString = jsNontrivialString(vm, "ArrayBufferSink"_s); - m_originalName.set(vm, this, nameString); - putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); -} - void JSArrayBufferSinkPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) { Base::finishCreation(vm); @@ -273,7 +312,7 @@ void JSArrayBufferSinkPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject void JSReadableArrayBufferSinkControllerPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) { Base::finishCreation(vm); - reifyStaticProperties(vm, JSReadableArrayBufferSinkControllerPrototype::info(), ReadableArrayBufferSinkControllerPrototypeTableValues, *this); + reifyStaticProperties(vm, JSReadableArrayBufferSinkController::info(), JSReadableArrayBufferSinkControllerPrototypeTableValues, *this); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); } @@ -283,25 +322,12 @@ void JSArrayBufferSink::finishCreation(VM& vm) ASSERT(inherits(info())); } -void ReadableArrayBufferSinkController::finishCreation(VM& vm) +void JSReadableArrayBufferSinkController::finishCreation(VM& vm) { Base::finishCreation(vm); ASSERT(inherits(info())); } -template -void JSReadableArrayBufferSinkController::visitChildrenImpl(JSCell* cell, Visitor& visitor) -{ - auto* thisObject = jsCast(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, info()); - Base::visitChildren(thisObject, visitor); - visitor.append(thisObject->m_pull); - visitor.append(thisObject->m_close); - visitor.append(thisObject->m_start); -} - -DEFINE_VISIT_CHILDREN(JSReadableArrayBufferSinkController); - void JSArrayBufferSink::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) { auto* thisObject = jsCast(cell); @@ -324,6 +350,26 @@ void JSReadableArrayBufferSinkController::analyzeHeap(JSCell* cell, HeapAnalyzer Base::analyzeHeap(cell, analyzer); } +template +void JSReadableArrayBufferSinkController::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + JSReadableArrayBufferSinkController* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.append(thisObject->m_onPull); + visitor.append(thisObject->m_onClose); + visitor.append(thisObject->m_weakReadableStream); +} + +DEFINE_VISIT_CHILDREN(JSReadableArrayBufferSinkController); + +void JSReadableArrayBufferSinkController::start(JSC::JSGlobalObject* globalObject, JSC::JSValue readableStream, JSC::JSFunction* onPull, JSC::JSFunction* onClose) +{ + this->m_weakReadableStream = JSC::Weak(readableStream.getObject()); + this->m_onPull.set(globalObject->vm(), this, onPull); + this->m_onClose.set(globalObject->vm(), this, onClose); +} + void JSArrayBufferSink::destroy(JSCell* cell) { static_cast(cell)->JSArrayBufferSink::~JSArrayBufferSink(); @@ -367,29 +413,46 @@ extern "C" JSC__JSValue ArrayBufferSink__createObject(JSC__JSGlobalObject* arg0, return JSC::JSValue::encode(WebCore::JSArrayBufferSink::create(vm, globalObject, structure, sinkPtr)); } -extern "C" JSC__JSValue ArrayBufferSink__setStreamController(JSC__JSGlobalObject* arg0, JSC__JSValue readableStream, void* sinkPtr) -{ - auto& vm = arg0->vm(); - Zig::GlobalObject* globalObject = reinterpret_cast(arg0); - JSC::JSValue prototype = globalObject->ArrayBufferSinkControllerPrototype(); - JSC::Structure* structure = WebCore::JSReadableArrayBufferSinkController::createStructure(vm, globalObject, prototype); - return JSC::JSValue::encode(WebCore::JSReadableArrayBufferSinkController::create(vm, globalObject, structure, sinkPtr)); -} - extern "C" void* ArrayBufferSink__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1) { JSC::VM& vm = WebCore::getVM(arg0); if (auto* sink = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) return sink->wrapped(); + if (auto* controller = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) + return controller->wrapped(); + return nullptr; } -extern "C" void* JSReadableArrayBufferSinkController__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1) +extern "C" JSC__JSValue ArrayBufferSink__assignToStream(JSC__JSGlobalObject* arg0, JSC__JSValue stream, void* sinkPtr, int32_t* bunNativeTag, void** bunNativePtr) { - JSC::VM& vm = WebCore::getVM(arg0); - if (auto* sink = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) - return sink->wrapped(); + auto& vm = arg0->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast(arg0); + auto clientData = WebCore::clientData(vm); + JSC::JSObject* readableStream = JSC::JSValue::decode(stream).getObject(); + + if (JSC::JSValue tag = readableStream->get(globalObject, clientData->builtinNames().bunNativeTypePrivateName())) { + if (tag.isInt32()) { + int32_t tagNumber = tag.toInt32(arg0); + if (tagNumber > 0 && tagNumber < 5) { + *bunNativeTag = tagNumber; + *bunNativePtr = reinterpret_cast(bitwise_cast(readableStream->get(globalObject, clientData->builtinNames().bunNativePtrPrivateName()).asNumber())); + return JSC::JSValue::encode(JSC::jsNull()); + } + } + } - return nullptr; + JSC::JSValue prototype = globalObject->JSReadableArrayBufferSinkControllerPrototype(); + JSC::Structure* structure = WebCore::JSReadableArrayBufferSinkController::createStructure(vm, globalObject, prototype); + WebCore::JSReadableArrayBufferSinkController* controller = WebCore::JSReadableArrayBufferSinkController::create(vm, globalObject, structure, sinkPtr); + + JSC::JSObject* function = globalObject->getDirect(vm, clientData->builtinNames().assignDirectStreamPrivateName()).getObject(); + auto callData = JSC::getCallData(function); + JSC::MarkedArgumentBuffer arguments; + arguments.append(JSC::JSValue::decode(stream)); + arguments.append(controller); + + auto result = JSC::call(arg0, function, callData, JSC::jsUndefined(), arguments); + return JSC::JSValue::encode(result); } diff --git a/src/javascript/jsc/bindings/JSSink.h b/src/javascript/jsc/bindings/JSSink.h index a9085cbf4..cc4f667e0 100644 --- a/src/javascript/jsc/bindings/JSSink.h +++ b/src/javascript/jsc/bindings/JSSink.h @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by /Users/jarred/Code/bun/src/javascript/jsc/generate-JSSink.js at 2022-06-14T08:19:26.543Z +// Generated by /Users/jarred/Code/bun/src/javascript/jsc/generate-jssink.js at 2022-06-15T10:28:21.209Z // #pragma once @@ -15,184 +15,153 @@ extern "C" bool JSSink_isSink(JSC::JSGlobalObject*, JSC::EncodedJSValue); namespace WebCore { using namespace JSC; -class JSArrayBufferSinkConstructor final : public JSC::InternalFunction { -public: - using Base = JSC::InternalFunction; - static JSArrayBufferSinkConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype); - static constexpr SinkID Sink = SinkID::ArrayBufferSink; - - static constexpr unsigned StructureFlags = Base::StructureFlags; - static constexpr bool needsDestruction = false; - - DECLARE_EXPORT_INFO; - template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - if constexpr (mode == JSC::SubspaceAccess::Concurrently) - return nullptr; - return WebCore::subspaceForImpl( - vm, - [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkConstructor.get(); }, - [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkConstructor = WTFMove(space); }, - [](auto& spaces) { return spaces.m_subspaceForJSSinkConstructor.get(); }, - [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkConstructor = WTFMove(space); }); - } - - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); - } - void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); - - // Must be defined for each specialization class. - static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); - -private: - JSArrayBufferSinkConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) - : Base(vm, structure, nativeFunction, nativeFunction) - - { - } - - void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); -}; - -class JSReadableArrayBufferSinkControllerConstructor final : public JSC::InternalFunction { -public: - using Base = JSC::InternalFunction; - static JSReadableArrayBufferSinkControllerConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype); - static constexpr SinkID Sink = SinkID::ArrayBufferSink; - - static constexpr unsigned StructureFlags = Base::StructureFlags; - static constexpr bool needsDestruction = false; - - DECLARE_EXPORT_INFO; - template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - if constexpr (mode == JSC::SubspaceAccess::Concurrently) - return nullptr; - return WebCore::subspaceForImpl( - vm, - [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkConstructor.get(); }, - [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkConstructor = WTFMove(space); }, - [](auto& spaces) { return spaces.m_subspaceForJSSinkConstructor.get(); }, - [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkConstructor = WTFMove(space); }); - } - - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); - } - void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); - - // Must be defined for each specialization class. - static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); - -private: - JSReadableArrayBufferSinkControllerConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) - : Base(vm, structure, nativeFunction, nativeFunction) - - { - } - - void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); -}; - -class JSArrayBufferSink final : public JSC::JSDestructibleObject { -public: - using Base = JSC::JSDestructibleObject; - static JSArrayBufferSink* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); - static constexpr SinkID Sink = SinkID::ArrayBufferSink; - - DECLARE_EXPORT_INFO; - template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - if constexpr (mode == JSC::SubspaceAccess::Concurrently) - return nullptr; - return WebCore::subspaceForImpl( - vm, - [](auto& spaces) { return spaces.m_clientSubspaceForJSSink.get(); }, - [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSink = WTFMove(space); }, - [](auto& spaces) { return spaces.m_subspaceForJSSink.get(); }, - [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSink = WTFMove(space); }); - } - - static void destroy(JSC::JSCell*); - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); - } - - ~JSArrayBufferSink(); - - void* wrapped() const { return m_sinkPtr; } - - static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); - - void* m_sinkPtr; - - JSArrayBufferSink(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) - : Base(vm, structure) - { - m_sinkPtr = sinkPtr; - } - - void finishCreation(JSC::VM&); -}; - -class JSReadableArrayBufferSinkController final : public JSC::JSDestructibleObject { -public: - using Base = JSC::JSDestructibleObject; - static JSReadableArrayBufferSinkController* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr, JSC::JSFunction* pullFunction, JSC::JSFunction* cancelFunction); - static constexpr SinkID Sink = SinkID::ArrayBufferSink; - - DECLARE_EXPORT_INFO; - template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - if constexpr (mode == JSC::SubspaceAccess::Concurrently) - return nullptr; - return WebCore::subspaceForImpl( - vm, - [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkController.get(); }, - [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkController = WTFMove(space); }, - [](auto& spaces) { return spaces.m_subspaceForJSSinkController.get(); }, - [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkController = WTFMove(space); }); - } - - static void destroy(JSC::JSCell*); - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); - } - - ~JSReadableArrayBufferSinkController(); - - void* wrapped() const { return m_sinkPtr; } - - static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); - - void* m_sinkPtr; - mutable WriteBarrier m_pull; - mutable WriteBarrier m_cancel; - // start is not stored because it doesn't need to be - - DECLARE_VISIT_CHILDREN; - - JSReadableArrayBufferSinkController(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr, JSC::JSFunction* pullFunction, JSC::JSFunction* cancelFunction) - : Base(vm, structure) - { - if (pullFunction != nullptr) - m_pull.set(vm, this, pullFunction); - if (cancelFunction != nullptr) - m_cancel.set(vm, this, cancelFunction); - - m_sinkPtr = sinkPtr; - } - - void finishCreation(JSC::VM&); -}; + +JSC_DECLARE_HOST_FUNCTION(functionStartDirectStream); +class JSArrayBufferSinkConstructor final : public JSC::InternalFunction { + public: + using Base = JSC::InternalFunction; + static JSArrayBufferSinkConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype); + static constexpr SinkID Sink = SinkID::ArrayBufferSink; + + static constexpr unsigned StructureFlags = Base::StructureFlags; + static constexpr bool needsDestruction = false; + + DECLARE_EXPORT_INFO; + template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkConstructor.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkConstructor = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForJSSinkConstructor.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkConstructor = WTFMove(space); }); + } + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); + } + void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); + + + // Must be defined for each specialization class. + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); + + private: + JSArrayBufferSinkConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) + : Base(vm, structure, nativeFunction, nativeFunction) + + { + } + + void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); + }; + + class JSArrayBufferSink final : public JSC::JSDestructibleObject { + public: + using Base = JSC::JSDestructibleObject; + static JSArrayBufferSink* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); + static constexpr SinkID Sink = SinkID::ArrayBufferSink; + + DECLARE_EXPORT_INFO; + template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForJSSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSink = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForJSSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSink = WTFMove(space); }); + } + + static void destroy(JSC::JSCell*); + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + ~JSArrayBufferSink(); + + void* wrapped() const { return m_sinkPtr; } + + void detach() { + m_sinkPtr = nullptr; + } + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + void* m_sinkPtr; + + JSArrayBufferSink(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + : Base(vm, structure) + { + m_sinkPtr = sinkPtr; + } + + void finishCreation(JSC::VM&); + }; + + class JSReadableArrayBufferSinkController final : public JSC::JSDestructibleObject { + public: + using Base = JSC::JSDestructibleObject; + static JSReadableArrayBufferSinkController* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); + static constexpr SinkID Sink = SinkID::ArrayBufferSink; + + DECLARE_EXPORT_INFO; + template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkController = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForJSSinkController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkController = WTFMove(space); }); + } + + static void destroy(JSC::JSCell*); + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + ~JSReadableArrayBufferSinkController(); + + + void* wrapped() const { return m_sinkPtr; } + void detach() { + m_sinkPtr = nullptr; + } + + void start(JSC::JSGlobalObject *globalObject, JSC::JSValue readableStream, JSC::JSFunction *onPull, JSC::JSFunction *onClose); + DECLARE_VISIT_CHILDREN; + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + void* m_sinkPtr; + mutable WriteBarrier m_onPull; + mutable WriteBarrier m_onClose; + mutable JSC::Weak m_weakReadableStream; + + JSReadableArrayBufferSinkController(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + : Base(vm, structure) + { + m_sinkPtr = sinkPtr; + } + + void finishCreation(JSC::VM&); + }; JSC_DECLARE_CUSTOM_GETTER(functionArrayBufferSink__getter); -JSC_DECLARE_CUSTOM_GETTER(functionArrayBufferSinkController__getter); + + + + JSObject* createJSSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WebCore::SinkID sinkID); JSObject* createJSSinkControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WebCore::SinkID sinkID); diff --git a/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp index 938efa620..97bcc0e25 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 = 1782; +const int s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeLength = 2089; static const JSC::Intrinsic s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCode = "(function (stream, underlyingByteSource, highWaterMark)\n" \ @@ -89,23 +89,31 @@ const char* const s_readableByteStreamInternalsPrivateInitializeReadableByteStre " @putByIdDirectPrivate(this, \"cancel\", @readableByteStreamControllerCancel);\n" \ " @putByIdDirectPrivate(this, \"pull\", @readableByteStreamControllerPull);\n" \ "\n" \ + " if (@getByIdDirectPrivate(underlyingByteSource, \"lazy\") === true) {\n" \ + " @putByIdDirectPrivate(this, \"start\", () => @readableStreamByteStreamControllerStart(this));\n" \ + " } else {\n" \ + " @putByIdDirectPrivate(this, \"start\", @undefined); \n" \ + " @readableStreamByteStreamControllerStart(this);\n" \ + " }\n" \ + "\n" \ " return this;\n" \ "})\n" \ ; const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeLength = 829; +const int s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeLength = 972; static const JSC::Intrinsic s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCode = "(function (controller) {\n" \ " \"use strict\";\n" \ - "\n" \ + " @putByIdDirectPrivate(controller, \"start\", @undefined);\n" \ + " \n" \ " if (@getByIdDirectPrivate(controller, \"started\") !== -1)\n" \ " return;\n" \ "\n" \ " @putByIdDirectPrivate(controller, \"started\", 0);\n" \ - "\n" \ + " var stream = @getByIdDirectPrivate(controller, \"controlledReadableStream\");\n" \ " return @promiseInvokeOrNoopNoCatch(@getByIdDirectPrivate(controller, \"underlyingByteSource\"), \"start\", [controller]).@then(() => {\n" \ " @putByIdDirectPrivate(controller, \"started\", 1);\n" \ " @assert(!@getByIdDirectPrivate(controller, \"pulling\"));\n" \ diff --git a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp index f11b743bf..b7692a601 100644 --- a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp +++ b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp @@ -49,7 +49,7 @@ namespace WebCore { const JSC::ConstructAbility s_readableStreamInitializeReadableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInitializeReadableStreamCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInitializeReadableStreamCodeLength = 2367; +const int s_readableStreamInitializeReadableStreamCodeLength = 2262; static const JSC::Intrinsic s_readableStreamInitializeReadableStreamCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInitializeReadableStreamCode = "(function (underlyingSource, strategy)\n" \ @@ -70,7 +70,6 @@ const char* const s_readableStreamInitializeReadableStreamCode = " @putByIdDirectPrivate(this, \"state\", @streamReadable);\n" \ " \n" \ " @putByIdDirectPrivate(this, \"reader\", @undefined);\n" \ - " @putByIdDirectPrivate(this, \"sink\", @undefined);\n" \ " \n" \ " @putByIdDirectPrivate(this, \"storedError\", @undefined);\n" \ " \n" \ @@ -78,39 +77,34 @@ const char* const s_readableStreamInitializeReadableStreamCode = " \n" \ " //\n" \ " @putByIdDirectPrivate(this, \"readableStreamController\", null);\n" \ - " \n" \ "\n" \ + " const isDirect = underlyingSource.type === \"direct\";\n" \ " //\n" \ + " const isUnderlyingSourceLazy = !!underlyingSource.@lazy;\n" \ + " const isLazy = isDirect || isUnderlyingSourceLazy;\n" \ + " \n" \ " //\n" \ - " if (@getByIdDirectPrivate(underlyingSource, \"pull\") !== @undefined) {\n" \ - " \n" \ + " //\n" \ + " if (@getByIdDirectPrivate(underlyingSource, \"pull\") !== @undefined && !isLazy) {\n" \ " const size = @getByIdDirectPrivate(strategy, \"size\");\n" \ " const highWaterMark = @getByIdDirectPrivate(strategy, \"highWaterMark\");\n" \ " @setupReadableStreamDefaultController(this, underlyingSource, size, highWaterMark !== @undefined ? highWaterMark : 1, @getByIdDirectPrivate(underlyingSource, \"start\"), @getByIdDirectPrivate(underlyingSource, \"pull\"), @getByIdDirectPrivate(underlyingSource, \"cancel\"));\n" \ " \n" \ " return this;\n" \ " }\n" \ - "\n" \ - " const type = underlyingSource.type;\n" \ - " const typeString = @toString(type);\n" \ - "\n" \ - " if (typeString === \"bytes\") {\n" \ - " //\n" \ - " //\n" \ - "\n" \ - " if (strategy.highWaterMark === @undefined)\n" \ - " strategy.highWaterMark = 0;\n" \ - " if (strategy.size !== @undefined)\n" \ - " @throwRangeError(\"Strategy for a ReadableByteStreamController cannot have a size\");\n" \ - "\n" \ - " @putByIdDirectPrivate(this, \"readableStreamController\", new @ReadableByteStreamController(this, underlyingSource, strategy.highWaterMark, @isReadableStream));\n" \ - " } else if (type === @undefined) {\n" \ - " if (strategy.highWaterMark === @undefined)\n" \ - " strategy.highWaterMark = 1;\n" \ - " \n" \ - " @setupReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, underlyingSource.start, underlyingSource.pull, underlyingSource.cancel);\n" \ - " } else\n" \ - " @throwRangeError(\"Invalid type for underlying source\");\n" \ + " if (isDirect) {\n" \ + " if (\"start\" in underlyingSource && typeof underlyingSource.start === \"function\")\n" \ + " @throwTypeError(\"\\\"start\\\" for direct streams are not implemented yet\");\n" \ + " \n" \ + " @putByIdDirectPrivate(this, \"start\", () => @createReadableStreamController.@call(this, underlyingSource, strategy, true));\n" \ + " } else if (isLazy) {\n" \ + " const autoAllocateChunkSize = underlyingSource.autoAllocateChunkSize;\n" \ + " @putByIdDirectPrivate(this, \"start\", () => @lazyLoadStream(this, autoAllocateChunkSize));\n" \ + " } else {\n" \ + " @putByIdDirectPrivate(this, \"start\", @undefined);\n" \ + " @createReadableStreamController.@call(this, underlyingSource, strategy, false);\n" \ + " }\n" \ + " \n" \ "\n" \ " return this;\n" \ "})\n" \ @@ -267,19 +261,19 @@ const char* const s_readableStreamReadableStreamToArrayPublicCode = const JSC::ConstructAbility s_readableStreamConsumeReadableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamConsumeReadableStreamCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamConsumeReadableStreamCodeLength = 3696; +const int s_readableStreamConsumeReadableStreamCodeLength = 3718; static const JSC::Intrinsic s_readableStreamConsumeReadableStreamCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamConsumeReadableStreamCode = "(function (nativePtr, nativeType, inputStream) {\n" \ " \"use strict\";\n" \ - " const symbol = Symbol.for(\"Bun.consumeReadableStreamPrototype\");\n" \ + " const symbol = globalThis.Symbol.for(\"Bun.consumeReadableStreamPrototype\");\n" \ " var cached = globalThis[symbol];\n" \ " if (!cached) {\n" \ " cached = globalThis[symbol] = [];\n" \ " }\n" \ " var Prototype = cached[nativeType];\n" \ " if (Prototype === @undefined) {\n" \ - " var [doRead, doError, doReadMany, doClose, onClose, deinit] = globalThis[Symbol.for(\"Bun.lazy\")](nativeType);\n" \ + " var [doRead, doError, doReadMany, doClose, onClose, deinit] = globalThis[globalThis.Symbol.for(\"Bun.lazy\")](nativeType);\n" \ "\n" \ " Prototype = class NativeReadableStreamSink {\n" \ " constructor(reader, ptr) {\n" \ @@ -403,95 +397,15 @@ const char* const s_readableStreamCreateEmptyReadableStreamCode = const JSC::ConstructAbility s_readableStreamCreateNativeReadableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamCreateNativeReadableStreamCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamCreateNativeReadableStreamCodeLength = 2955; +const int s_readableStreamCreateNativeReadableStreamCodeLength = 343; static const JSC::Intrinsic s_readableStreamCreateNativeReadableStreamCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamCreateNativeReadableStreamCode = "(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" \ - " var handleResult;\n" \ - " function handleNativeReadableStreamPromiseResult(val) {\n" \ - " \"use strict\";\n" \ - " var {c, v} = this;\n" \ - " this.c = @undefined;\n" \ - " this.v = @undefined;\n" \ - " handleResult(val, c, v);\n" \ - " }\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, v: view}), (err) => controller.error(err));\n" \ - " } else if (result !== false) {\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(() => controller.close());\n" \ - " closer[0] = false;\n" \ - " }\n" \ - " };\n" \ - "\n" \ - " Prototype = class NativeReadableStreamSource {\n" \ - " constructor(tag, autoAllocateChunkSize) {\n" \ - " this.pull = this.pull_.bind(tag);\n" \ - " this.cancel = this.cancel_.bind(tag);\n" \ - " this.autoAllocateChunkSize = autoAllocateChunkSize;\n" \ - " }\n" \ - "\n" \ - " pull;\n" \ - " cancel;\n" \ - "\n" \ - " type = \"bytes\";\n" \ - " autoAllocateChunkSize = 0;\n" \ - "\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 = pull(this, view, closer);\n" \ - " } catch(err) {\n" \ - " return controller.error(err);\n" \ - " }\n" \ - "\n" \ - " return handleResult(result, controller, view);\n" \ - " }\n" \ - "\n" \ - " cancel_(reason) {\n" \ - " cancel(this, reason);\n" \ - " }\n" \ - "\n" \ - " static registry = new FinalizationRegistry(deinit);\n" \ - " }\n" \ - " cached.@set(nativeType, Prototype);\n" \ - " }\n" \ - " \n" \ - " //\n" \ - " //\n" \ - " //\n" \ - " const chunkSize = Prototype.startSync(nativePtr, autoAllocateChunkSize);\n" \ - "\n" \ - " //\n" \ - " if (chunkSize === 0) {\n" \ - " return @createEmptyReadableStream();\n" \ - " }\n" \ - "\n" \ - " var instance = new Prototype(nativePtr, chunkSize);\n" \ - " Prototype.registry.register(instance, nativePtr);\n" \ - " var stream = new @ReadableStream(instance);\n" \ + " stream = new @ReadableStream({\n" \ + " @lazy: true,\n" \ + " autoAllocateChunkSize: autoAllocateChunkSize,\n" \ + " });\n" \ " @putByIdDirectPrivate(stream, \"bunNativeType\", nativeType);\n" \ " @putByIdDirectPrivate(stream, \"bunNativePtr\", nativePtr);\n" \ " return stream;\n" \ @@ -519,7 +433,7 @@ const char* const s_readableStreamCancelCode = const JSC::ConstructAbility s_readableStreamGetReaderCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamGetReaderCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamGetReaderCodeLength = 759; +const int s_readableStreamGetReaderCodeLength = 619; static const JSC::Intrinsic s_readableStreamGetReaderCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamGetReaderCode = "(function (options)\n" \ @@ -530,17 +444,15 @@ const char* const s_readableStreamGetReaderCode = " throw @makeThisTypeError(\"ReadableStream\", \"getReader\");\n" \ "\n" \ " const mode = @toDictionary(options, { }, \"ReadableStream.getReader takes an object as first argument\").mode;\n" \ - " if (mode === @undefined)\n" \ + " if (mode === @undefined) {\n" \ + " var start_ = @getByIdDirectPrivate(this, \"start\");\n" \ + " if (start_) {\n" \ + " start_.@call(this);\n" \ + " }\n" \ " return new @ReadableStreamDefaultReader(this);\n" \ - "\n" \ + " }\n" \ " //\n" \ " if (mode == 'byob') {\n" \ - " var controller = @getByIdDirectPrivate(this, \"controller\");\n" \ - " if (@isReadableStreamDefaultController(controller))\n" \ - " @readableStreamDefaultControllerStart(controller)\n" \ - " else\n" \ - " @readableStreamByteStreamControllerStart(controller);\n" \ - "\n" \ " return new @ReadableStreamBYOBReader(this);\n" \ " }\n" \ "\n" \ diff --git a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp index 2151d538a..6bc61fd96 100644 --- a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp +++ b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.cpp @@ -71,7 +71,7 @@ const char* const s_readableStreamInternalsReadableStreamReaderGenericInitialize const JSC::ConstructAbility s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength = 910; +const int s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength = 899; static const JSC::Intrinsic s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCode = "(function (stream, underlyingSource, size, highWaterMark)\n" \ @@ -95,66 +95,14 @@ const char* const s_readableStreamInternalsPrivateInitializeReadableStreamDefaul " @putByIdDirectPrivate(this, \"pullAgain\", false);\n" \ " @putByIdDirectPrivate(this, \"pulling\", false);\n" \ " @putByIdDirectPrivate(this, \"strategy\", @validateAndNormalizeQueuingStrategy(size, highWaterMark));\n" \ - " \n" \ - " \n" \ - "\n" \ "\n" \ " return this;\n" \ "})\n" \ ; -const JSC::ConstructAbility s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; -const JSC::ConstructorKind s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength = 876; -static const JSC::Intrinsic s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeIntrinsic = JSC::NoIntrinsic; -const char* const s_readableStreamInternalsSetupReadableStreamDefaultControllerCode = - "(function (stream, underlyingSource, size, highWaterMark, startMethod, pullMethod, cancelMethod)\n" \ - "{\n" \ - " \"use strict\";\n" \ - " \n" \ - " const controller = new @ReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, @isReadableStream);\n" \ - " \n" \ - " const pullAlgorithm = () => @promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]);\n" \ - " const cancelAlgorithm = (reason) => @promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]);\n" \ - " \n" \ - " @putByIdDirectPrivate(controller, \"pullAlgorithm\", pullAlgorithm);\n" \ - " @putByIdDirectPrivate(controller, \"cancelAlgorithm\", cancelAlgorithm);\n" \ - " @putByIdDirectPrivate(controller, \"pull\", @readableStreamDefaultControllerPull);\n" \ - " @putByIdDirectPrivate(controller, \"cancel\", @readableStreamDefaultControllerCancel);\n" \ - " @putByIdDirectPrivate(stream, \"readableStreamController\", controller);\n" \ - "\n" \ - " \n" \ - "})\n" \ -; - -const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; -const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength = 782; -static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerStartCodeIntrinsic = JSC::NoIntrinsic; -const char* const s_readableStreamInternalsReadableStreamDefaultControllerStartCode = - "(function (controller) {\n" \ - " if (@getByIdDirectPrivate(controller, \"started\") !== -1)\n" \ - " return;\n" \ - "\n" \ - " const underlyingSource = @getByIdDirectPrivate(controller, \"underlyingSource\");\n" \ - " const startMethod = @getByIdDirectPrivate(underlyingSource, \"start\");\n" \ - " @putByIdDirectPrivate(controller, \"started\", 0);\n" \ - "\n" \ - " return @promiseInvokeOrNoopMethodNoCatch(underlyingSource, startMethod, [controller]).@then(() => {\n" \ - " @putByIdDirectPrivate(controller, \"started\", 1);\n" \ - " @assert(!@getByIdDirectPrivate(controller, \"pulling\"));\n" \ - " @assert(!@getByIdDirectPrivate(controller, \"pullAgain\"));\n" \ - " @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \ - " \n" \ - " }, (error) => {\n" \ - " @readableStreamDefaultControllerError(controller, error);\n" \ - " });\n" \ - "})\n" \ -; - const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength = 322; +const int s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength = 327; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamDefaultControllerErrorCode = "(function (controller, error)\n" \ @@ -165,6 +113,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerErrorC " if (@getByIdDirectPrivate(stream, \"state\") !== @streamReadable)\n" \ " return;\n" \ " @putByIdDirectPrivate(controller, \"queue\", @newQueue());\n" \ + " \n" \ " @readableStreamError(stream, error);\n" \ "})\n" \ ; @@ -206,29 +155,120 @@ const char* const s_readableStreamInternalsReadableStreamPipeToCode = const JSC::ConstructAbility s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength = 356; +const int s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength = 204; static const JSC::Intrinsic s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsAcquireReadableStreamDefaultReaderCode = "(function (stream)\n" \ "{\n" \ - " var controller = @getByIdDirectPrivate(stream, \"readableStreamController\");\n" \ - " if (@isReadableStreamDefaultController(controller)) {\n" \ - " @readableStreamDefaultControllerStart(controller);\n" \ - " } else {\n" \ - " @readableStreamByteStreamControllerStart(controller);\n" \ + " \"use strict\";\n" \ + " var start = @getByIdDirectPrivate(stream, \"start\");\n" \ + " if (start) {\n" \ + " start.@call(stream);\n" \ " }\n" \ "\n" \ " return new @ReadableStreamDefaultReader(stream);\n" \ "})\n" \ ; +const JSC::ConstructAbility s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength = 931; +static const JSC::Intrinsic s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsSetupReadableStreamDefaultControllerCode = + "(function (stream, underlyingSource, size, highWaterMark, startMethod, pullMethod, cancelMethod)\n" \ + "{\n" \ + " \"use strict\";\n" \ + " \n" \ + " const controller = new @ReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, @isReadableStream);\n" \ + " \n" \ + " const pullAlgorithm = () => @promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]);\n" \ + " const cancelAlgorithm = (reason) => @promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]);\n" \ + " \n" \ + " @putByIdDirectPrivate(controller, \"pullAlgorithm\", pullAlgorithm);\n" \ + " @putByIdDirectPrivate(controller, \"cancelAlgorithm\", cancelAlgorithm);\n" \ + " @putByIdDirectPrivate(controller, \"pull\", @readableStreamDefaultControllerPull);\n" \ + " @putByIdDirectPrivate(controller, \"cancel\", @readableStreamDefaultControllerCancel);\n" \ + " @putByIdDirectPrivate(stream, \"readableStreamController\", controller);\n" \ + "\n" \ + " @readableStreamDefaultControllerStart(controller);\n" \ + " \n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsCreateReadableStreamControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsCreateReadableStreamControllerCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsCreateReadableStreamControllerCodeLength = 1256; +static const JSC::Intrinsic s_readableStreamInternalsCreateReadableStreamControllerCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsCreateReadableStreamControllerCode = + "(function (underlyingSource, strategy, fromLazy) {\n" \ + " if (fromLazy) {\n" \ + " @putByIdDirectPrivate(this, \"start\", @undefined);\n" \ + " }\n" \ + "\n" \ + " const type = underlyingSource.type;\n" \ + " const typeString = @toString(type);\n" \ + "\n" \ + " if (typeString === \"bytes\") {\n" \ + " //\n" \ + " //\n" \ + "\n" \ + " if (strategy.highWaterMark === @undefined)\n" \ + " strategy.highWaterMark = 0;\n" \ + " if (strategy.size !== @undefined)\n" \ + " @throwRangeError(\"Strategy for a ReadableByteStreamController cannot have a size\");\n" \ + "\n" \ + " @putByIdDirectPrivate(this, \"readableStreamController\", new @ReadableByteStreamController(this, underlyingSource, strategy.highWaterMark, @isReadableStream));\n" \ + " } else if (typeString === \"direct\") {\n" \ + " var highWaterMark = strategy?.highWaterMark;\n" \ + " @initializeArrayBufferStream.@call(this, underlyingSource, highWaterMark); \n" \ + " } else if (type === @undefined) {\n" \ + " if (strategy.highWaterMark === @undefined)\n" \ + " strategy.highWaterMark = 1;\n" \ + " \n" \ + " @setupReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, underlyingSource.start, underlyingSource.pull, underlyingSource.cancel);\n" \ + " } else\n" \ + " @throwRangeError(\"Invalid type for underlying source\");\n" \ + "\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength = 765; +static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerStartCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsReadableStreamDefaultControllerStartCode = + "(function (controller) {\n" \ + " \"use strict\";\n" \ + "\n" \ + " \n" \ + "\n" \ + " if (@getByIdDirectPrivate(controller, \"started\") !== -1)\n" \ + " return;\n" \ + "\n" \ + " const underlyingSource = @getByIdDirectPrivate(controller, \"underlyingSource\");\n" \ + " const startMethod = underlyingSource.start;\n" \ + " @putByIdDirectPrivate(controller, \"started\", 0);\n" \ + "\n" \ + " @promiseInvokeOrNoopMethodNoCatch(underlyingSource, startMethod, [controller]).@then(() => {\n" \ + " @putByIdDirectPrivate(controller, \"started\", 1);\n" \ + " @assert(!@getByIdDirectPrivate(controller, \"pulling\"));\n" \ + " @assert(!@getByIdDirectPrivate(controller, \"pullAgain\"));\n" \ + " @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \ + " }, (error) => {\n" \ + " @readableStreamDefaultControllerError(controller, error);\n" \ + " });\n" \ + "})\n" \ +; + const JSC::ConstructAbility s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength = 3213; +const int s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength = 3232; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamPipeToWritableStreamCode = "(function (source, destination, preventClose, preventAbort, preventCancel, signal)\n" \ "{\n" \ + " \"use strict\";\n" \ + "\n" \ " @assert(@isReadableStream(source));\n" \ " @assert(@isWritableStream(destination));\n" \ " @assert(!@isReadableStreamLocked(source));\n" \ @@ -300,11 +340,12 @@ const char* const s_readableStreamInternalsReadableStreamPipeToWritableStreamCod const JSC::ConstructAbility s_readableStreamInternalsPipeToLoopCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToLoopCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToLoopCodeLength = 194; +const int s_readableStreamInternalsPipeToLoopCodeLength = 212; static const JSC::Intrinsic s_readableStreamInternalsPipeToLoopCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToLoopCode = "(function (pipeState)\n" \ "{\n" \ + " \"use strict\";\n" \ " if (pipeState.shuttingDown)\n" \ " return;\n" \ "\n" \ @@ -317,11 +358,12 @@ const char* const s_readableStreamInternalsPipeToLoopCode = const JSC::ConstructAbility s_readableStreamInternalsPipeToDoReadWriteCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToDoReadWriteCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToDoReadWriteCodeLength = 1108; +const int s_readableStreamInternalsPipeToDoReadWriteCodeLength = 1126; static const JSC::Intrinsic s_readableStreamInternalsPipeToDoReadWriteCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToDoReadWriteCode = "(function (pipeState)\n" \ "{\n" \ + " \"use strict\";\n" \ " @assert(!pipeState.shuttingDown);\n" \ "\n" \ " pipeState.pendingReadPromiseCapability = @newPromiseCapability(@Promise);\n" \ @@ -376,11 +418,12 @@ const char* const s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCo const JSC::ConstructAbility s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeLength = 584; +const int s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeLength = 602; static const JSC::Intrinsic s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCode = "(function (pipeState)\n" \ "{\n" \ + " \"use strict\";\n" \ " const action = () => {\n" \ " const error = @getByIdDirectPrivate(pipeState.destination, \"storedError\");\n" \ " if (!pipeState.preventCancel) {\n" \ @@ -444,11 +487,13 @@ const char* const s_readableStreamInternalsPipeToClosingMustBePropagatedBackward const JSC::ConstructAbility s_readableStreamInternalsPipeToShutdownWithActionCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToShutdownWithActionCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToShutdownWithActionCodeLength = 882; +const int s_readableStreamInternalsPipeToShutdownWithActionCodeLength = 901; static const JSC::Intrinsic s_readableStreamInternalsPipeToShutdownWithActionCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToShutdownWithActionCode = "(function (pipeState, action)\n" \ "{\n" \ + " \"use strict\";\n" \ + "\n" \ " if (pipeState.shuttingDown)\n" \ " return;\n" \ "\n" \ @@ -481,11 +526,13 @@ const char* const s_readableStreamInternalsPipeToShutdownWithActionCode = const JSC::ConstructAbility s_readableStreamInternalsPipeToShutdownCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToShutdownCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToShutdownCodeLength = 717; +const int s_readableStreamInternalsPipeToShutdownCodeLength = 740; static const JSC::Intrinsic s_readableStreamInternalsPipeToShutdownCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToShutdownCode = "(function (pipeState)\n" \ "{\n" \ + " \"use strict\";\n" \ + " \n" \ " if (pipeState.shuttingDown)\n" \ " return;\n" \ "\n" \ @@ -512,11 +559,13 @@ const char* const s_readableStreamInternalsPipeToShutdownCode = const JSC::ConstructAbility s_readableStreamInternalsPipeToFinalizeCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsPipeToFinalizeCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsPipeToFinalizeCodeLength = 356; +const int s_readableStreamInternalsPipeToFinalizeCodeLength = 375; static const JSC::Intrinsic s_readableStreamInternalsPipeToFinalizeCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsPipeToFinalizeCode = "(function (pipeState)\n" \ "{\n" \ + " \"use strict\";\n" \ + "\n" \ " @writableStreamDefaultWriterRelease(pipeState.writer);\n" \ " @readableStreamReaderGenericRelease(pipeState.reader);\n" \ "\n" \ @@ -711,6 +760,332 @@ const char* const s_readableStreamInternalsIsReadableStreamDefaultControllerCode "})\n" \ ; +const JSC::ConstructAbility s_readableStreamInternalsAssignDirectStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsAssignDirectStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsAssignDirectStreamCodeLength = 60; +static const JSC::Intrinsic s_readableStreamInternalsAssignDirectStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsAssignDirectStreamCode = + "(function () {\n" \ + " \"use strict\";\n" \ + "\n" \ + " var stream = this;\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsHandleDirectStreamErrorCodeLength = 840; +static const JSC::Intrinsic s_readableStreamInternalsHandleDirectStreamErrorCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsHandleDirectStreamErrorCode = + "(function (e) {\n" \ + " \"use strict\";\n" \ + "\n" \ + " var controller = this;\n" \ + " var sink = controller.@sink;\n" \ + " if (sink) {\n" \ + " @putByIdDirectPrivate(controller, \"sink\", @undefined);\n" \ + " try {\n" \ + " sink.close(e);\n" \ + " } catch (f) {}\n" \ + " }\n" \ + "\n" \ + " this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed;\n" \ + "\n" \ + " if (typeof this.@underlyingSource.close === 'function') {\n" \ + " try {\n" \ + " this.@underlyingSource.close.@call(this.@underlyingSource, e);\n" \ + " } catch (e) {\n" \ + " }\n" \ + " }\n" \ + "\n" \ + " try {\n" \ + " var pend = controller._pendingRead;\n" \ + " if (pend) {\n" \ + " controller._pendingRead = @undefined;\n" \ + " @rejectPromise(pend, e);\n" \ + " }\n" \ + " } catch (f) {}\n" \ + " var stream = controller.@controlledReadableStream;\n" \ + " if (stream) @readableStreamError(stream, e);\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsHandleDirectStreamErrorRejectCodeLength = 96; +static const JSC::Intrinsic s_readableStreamInternalsHandleDirectStreamErrorRejectCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsHandleDirectStreamErrorRejectCode = + "(function (e) {\n" \ + " @handleDirectStreamError.@call(this, e);\n" \ + " return @Promise.@reject(e);\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsOnPullDirectStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsOnPullDirectStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsOnPullDirectStreamCodeLength = 1701; +static const JSC::Intrinsic s_readableStreamInternalsOnPullDirectStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsOnPullDirectStreamCode = + "(function (controller)\n" \ + "{\n" \ + " \n" \ + " \"use strict\";\n" \ + "\n" \ + " var stream = controller.@controlledReadableStream;\n" \ + " if (!stream || @getByIdDirectPrivate(stream, \"state\") !== @streamReadable)\n" \ + " return;\n" \ + "\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " if (controller._deferClose === -1) {\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " \n" \ + " controller._deferClose = -1;\n" \ + " controller._deferDrain = -1;\n" \ + " var deferClose;\n" \ + " var deferDrain;\n" \ + "\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " try {\n" \ + " var result = controller.@underlyingSource.pull(\n" \ + " controller,\n" \ + " );\n" \ + "\n" \ + " if (result && @isPromise(result)) {\n" \ + " if (controller._handleError === @undefined) {\n" \ + " controller._handleError = @handleDirectStreamErrorReject.bind(controller);\n" \ + " }\n" \ + "\n" \ + " @Promise.prototype.catch.@call(result, controller._handleError);\n" \ + " }\n" \ + " } catch(e) {\n" \ + " return @handleDirectStreamErrorReject.@call(controller, e);\n" \ + " } finally {\n" \ + " deferClose = controller._deferClose;\n" \ + " deferDrain = controller._deferDrain;\n" \ + " controller._deferDrain = controller._deferClose = 0;\n" \ + " }\n" \ + " \n" \ + " \n" \ + " var promiseToReturn;\n" \ + " \n" \ + "\n" \ + " if (controller._pendingRead === @undefined) {\n" \ + " controller._pendingRead = promiseToReturn = @newPromise();\n" \ + " } else {\n" \ + " promiseToReturn = @readableStreamAddReadRequest(stream);\n" \ + " }\n" \ + "\n" \ + "\n" \ + " //\n" \ + " //\n" \ + " if (deferClose === 1) {\n" \ + " var reason = controller._deferCloseReason;\n" \ + " controller._deferCloseReason = @undefined;\n" \ + " @onCloseDirectStream.@call(controller, reason);\n" \ + " return promiseToReturn;\n" \ + " }\n" \ + "\n" \ + " //\n" \ + " if (deferDrain === 1) {\n" \ + " @onDrainDirectStream.@call(controller);\n" \ + " }\n" \ + " \n" \ + "\n" \ + " return promiseToReturn;\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsNoopDoneFunctionCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsNoopDoneFunctionCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsNoopDoneFunctionCodeLength = 81; +static const JSC::Intrinsic s_readableStreamInternalsNoopDoneFunctionCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsNoopDoneFunctionCode = + "(function () {\n" \ + " return @Promise.@resolve({value: @undefined, done: true});\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeLength = 111; +static const JSC::Intrinsic s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsOnReadableStreamDirectControllerClosedCode = + "(function (reason)\n" \ + "{\n" \ + " \"use strict\";\n" \ + " @throwTypeError(\"ReadableStreamDirectController is now closed\");\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsOnCloseDirectStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsOnCloseDirectStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsOnCloseDirectStreamCodeLength = 2405; +static const JSC::Intrinsic s_readableStreamInternalsOnCloseDirectStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsOnCloseDirectStreamCode = + "(function (reason)\n" \ + "{\n" \ + " \"use strict\";\n" \ + " var stream = this.@controlledReadableStream;\n" \ + " if (!stream || @getByIdDirectPrivate(stream, \"state\") !== @streamReadable)\n" \ + " return;\n" \ + "\n" \ + " if (this._deferClose !== 0) {\n" \ + " this._deferClose = 1;\n" \ + " this._deferCloseReason = reason;\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " @putByIdDirectPrivate(stream, \"state\", @streamClosing);\n" \ + " if (typeof this.@underlyingSource.close === 'function') {\n" \ + " try {\n" \ + " this.@underlyingSource.close.@call(this.@underlyingSource, reason);\n" \ + " } catch (e) {\n" \ + " \n" \ + " }\n" \ + " }\n" \ + "\n" \ + " var drained;\n" \ + " try {\n" \ + " drained = this.@sink.end();\n" \ + " @putByIdDirectPrivate(this, \"sink\", @undefined);\n" \ + " } catch (e) {\n" \ + " if (this._pendingRead) {\n" \ + " var read = this._pendingRead;\n" \ + " this._pendingRead = @undefined;\n" \ + " @rejectPromise(read, e);\n" \ + " }\n" \ + " @readableStreamError(stream, e);\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed;\n" \ + "\n" \ + " var reader = @getByIdDirectPrivate(stream, \"reader\");\n" \ + "\n" \ + " if (reader && @isReadableStreamDefaultReader(reader)) {\n" \ + " var _pendingRead = this._pendingRead;\n" \ + " if (_pendingRead && @isPromise(_pendingRead) && drained?.byteLength) {\n" \ + " this._pendingRead = @undefined;\n" \ + " @fulfillPromise(_pendingRead, {value: drained, done: false});\n" \ + " @readableStreamClose(stream);\n" \ + " return;\n" \ + " }\n" \ + " }\n" \ + "\n" \ + " if (drained?.byteLength) {\n" \ + " var requests = @getByIdDirectPrivate(reader, \"readRequests\");\n" \ + " if (requests?.isNotEmpty()) {\n" \ + " @readableStreamFulfillReadRequest(stream, drained, false);\n" \ + " @readableStreamClose(stream);\n" \ + " return;\n" \ + " }\n" \ + " \n" \ + " @putByIdDirectPrivate(stream, \"state\", @streamReadable);\n" \ + " this.@pull = () => {\n" \ + " var thisResult = @createFulfilledPromise({value: drained, done: false});\n" \ + " drained = @undefined;\n" \ + " @readableStreamClose(stream);\n" \ + " stream = @undefined;\n" \ + " return thisResult;\n" \ + " };\n" \ + " } else if (this._pendingRead) {\n" \ + " var read = this._pendingRead;\n" \ + " this._pendingRead = @undefined;\n" \ + " @putByIdDirectPrivate(this, \"pull\", @noopDoneFunction);\n" \ + " @fulfillPromise(read, {value: @undefined, done: true});\n" \ + " }\n" \ + "\n" \ + " @readableStreamClose(stream);\n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsOnDrainDirectStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsOnDrainDirectStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsOnDrainDirectStreamCodeLength = 990; +static const JSC::Intrinsic s_readableStreamInternalsOnDrainDirectStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsOnDrainDirectStreamCode = + "(function ()\n" \ + "{\n" \ + " \"use strict\";\n" \ + "\n" \ + " var stream = this.@controlledReadableStream;\n" \ + " var reader = @getByIdDirectPrivate(stream, \"reader\");\n" \ + " if (!reader || !@isReadableStreamDefaultReader(reader)) {\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " var _pendingRead = this._pendingRead;\n" \ + " this._pendingRead = @undefined;\n" \ + " if (_pendingRead && @isPromise(_pendingRead)) {\n" \ + " var drained = this.@sink.drain();\n" \ + " if (drained?.byteLength) {\n" \ + " this._pendingRead = @getByIdDirectPrivate(stream, \"readRequests\")?.shift();\n" \ + " @fulfillPromise(_pendingRead, {value: drained, done: false});\n" \ + " } else {\n" \ + " this._pendingRead = _pendingRead;\n" \ + " }\n" \ + " } else if (@getByIdDirectPrivate(stream, \"readRequests\")?.isNotEmpty()) {\n" \ + " var drained = this.@sink.drain();\n" \ + " if (drained?.byteLength) {\n" \ + " @readableStreamFulfillReadRequest(stream, drained, false);\n" \ + " }\n" \ + " } else if (this._deferDrain === -1) {\n" \ + " this._deferDrain = 1;\n" \ + " }\n" \ + " \n" \ + "})\n" \ +; + +const JSC::ConstructAbility s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsInitializeArrayBufferStreamCodeLength = 930; +static const JSC::Intrinsic s_readableStreamInternalsInitializeArrayBufferStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsInitializeArrayBufferStreamCode = + "(function (underlyingSource, highWaterMark)\n" \ + "{\n" \ + " \"use strict\";\n" \ + "\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " \n" \ + " var opts = highWaterMark ? {highWaterMark, stream: true, asUint8Array: true} : {stream: true, asUint8Array: true};\n" \ + " var sink = new globalThis.Bun.ArrayBufferSink();\n" \ + " sink.start(opts);\n" \ + "\n" \ + " var controller = {\n" \ + " @underlyingSource: underlyingSource,\n" \ + " @pull: @onPullDirectStream,\n" \ + " @controlledReadableStream: this,\n" \ + " @sink: sink,\n" \ + " close: @onCloseDirectStream,\n" \ + " write: sink.write.bind(sink),\n" \ + " error: @handleDirectStreamError,\n" \ + " end: @onCloseDirectStream,\n" \ + " @close: @onCloseDirectStream,\n" \ + " drain: @onDrainDirectStream,\n" \ + " _pendingRead: @undefined,\n" \ + " _deferClose: 0,\n" \ + " _deferDrain: 0,\n" \ + " _deferCloseReason: @undefined,\n" \ + " _handleError: @undefined,\n" \ + " };\n" \ + " \n" \ + " \n" \ + " @putByIdDirectPrivate(this, \"readableStreamController\", controller);\n" \ + " \n" \ + "})\n" \ +; + const JSC::ConstructAbility s_readableStreamInternalsReadableStreamErrorCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsReadableStreamErrorCodeConstructorKind = JSC::ConstructorKind::None; const int s_readableStreamInternalsReadableStreamErrorCodeLength = 1266; @@ -751,16 +1126,18 @@ 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 = 665; +const int s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength = 690; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCode = "(function (controller)\n" \ "{\n" \ - " const stream = @getByIdDirectPrivate(controller, \"controlledReadableStream\");\n" \ + " \"use strict\";\n" \ "\n" \ + " const stream = @getByIdDirectPrivate(controller, \"controlledReadableStream\");\n" \ + " \n" \ " if (!@readableStreamDefaultControllerCanCloseOrEnqueue(controller))\n" \ " return false;\n" \ - " if (!(@getByIdDirectPrivate(controller, \"started\") > 0))\n" \ + " if (!(@getByIdDirectPrivate(controller, \"started\") === 1))\n" \ " return false;\n" \ " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \ " return false;\n" \ @@ -772,7 +1149,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 = 1252; +const int s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength = 1272; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCode = "(function (controller)\n" \ @@ -784,7 +1161,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPu "\n" \ " if (!@readableStreamDefaultControllerCanCloseOrEnqueue(controller))\n" \ " return;\n" \ - " if (!(@getByIdDirectPrivate(controller, \"started\") > 0))\n" \ + " if (!(@getByIdDirectPrivate(controller, \"started\") === 1))\n" \ " return;\n" \ " if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)\n" \ " return;\n" \ @@ -794,6 +1171,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPu " return;\n" \ " }\n" \ "\n" \ + " \n" \ " @assert(!@getByIdDirectPrivate(controller, \"pullAgain\"));\n" \ " @putByIdDirectPrivate(controller, \"pulling\", true);\n" \ "\n" \ @@ -801,6 +1179,7 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPu " @putByIdDirectPrivate(controller, \"pulling\", false);\n" \ " if (@getByIdDirectPrivate(controller, \"pullAgain\")) {\n" \ " @putByIdDirectPrivate(controller, \"pullAgain\", false);\n" \ + " \n" \ " @readableStreamDefaultControllerCallPullIfNeeded(controller);\n" \ " }\n" \ " }, function(error) {\n" \ @@ -861,7 +1240,7 @@ const char* const s_readableStreamInternalsReadableStreamReaderGenericCancelCode const JSC::ConstructAbility s_readableStreamInternalsReadableStreamCancelCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsReadableStreamCancelCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableStreamInternalsReadableStreamCancelCodeLength = 547; +const int s_readableStreamInternalsReadableStreamCancelCodeLength = 534; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamCancelCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamCancelCode = "(function (stream, reason)\n" \ @@ -875,7 +1254,9 @@ const char* const s_readableStreamInternalsReadableStreamCancelCode = " if (state === @streamErrored)\n" \ " return @Promise.@reject(@getByIdDirectPrivate(stream, \"storedError\"));\n" \ " @readableStreamClose(stream);\n" \ - " return @getByIdDirectPrivate(stream, \"readableStreamController\").@cancel(@getByIdDirectPrivate(stream, \"readableStreamController\"), reason).@then(function() { });\n" \ + "\n" \ + " var controller = @getByIdDirectPrivate(stream, \"readableStreamController\");\n" \ + " return controller.@cancel(controller, reason).@then(function() { });\n" \ "})\n" \ ; @@ -1103,6 +1484,106 @@ const char* const s_readableStreamInternalsReadableStreamDefaultControllerCanClo "})\n" \ ; +const JSC::ConstructAbility s_readableStreamInternalsLazyLoadStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamInternalsLazyLoadStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamInternalsLazyLoadStreamCodeLength = 3053; +static const JSC::Intrinsic s_readableStreamInternalsLazyLoadStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamInternalsLazyLoadStreamCode = + "(function (stream, autoAllocateChunkSize) {\n" \ + " \"use strict\";\n" \ + "\n" \ + " @putByIdDirectPrivate(stream, \"start\", @undefined);\n" \ + " var bunNativeType = @getByIdDirectPrivate(stream, \"bunNativeType\");\n" \ + " var bunNativePtr = @getByIdDirectPrivate(stream, \"bunNativePtr\");\n" \ + "\n" \ + " var cached = globalThis[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[globalThis.Symbol.for(\"Bun.lazy\")](nativeType);\n" \ + " var closer = [false];\n" \ + " var handleResult;\n" \ + " function handleNativeReadableStreamPromiseResult(val) {\n" \ + " \"use strict\";\n" \ + " var {c, v} = this;\n" \ + " this.c = @undefined;\n" \ + " this.v = @undefined;\n" \ + " handleResult(val, c, v);\n" \ + " }\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, v: view}), (err) => controller.error(err));\n" \ + " } else if (result !== false) {\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(() => controller.close());\n" \ + " closer[0] = false;\n" \ + " }\n" \ + " };\n" \ + "\n" \ + " Prototype = class NativeReadableStreamSource {\n" \ + " constructor(tag, autoAllocateChunkSize) {\n" \ + " this.pull = this.pull_.bind(tag);\n" \ + " this.cancel = this.cancel_.bind(tag);\n" \ + " this.autoAllocateChunkSize = autoAllocateChunkSize;\n" \ + " }\n" \ + "\n" \ + " pull;\n" \ + " cancel;\n" \ + "\n" \ + " type = \"bytes\";\n" \ + " autoAllocateChunkSize = 0;\n" \ + "\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 = pull(this, view, closer);\n" \ + " } catch(err) {\n" \ + " return controller.error(err);\n" \ + " }\n" \ + "\n" \ + " return handleResult(result, controller, view);\n" \ + " }\n" \ + "\n" \ + " cancel_(reason) {\n" \ + " cancel(this, reason);\n" \ + " }\n" \ + "\n" \ + " static registry = new FinalizationRegistry(deinit);\n" \ + " }\n" \ + " cached.@set(nativeType, Prototype);\n" \ + " }\n" \ + "\n" \ + " //\n" \ + " //\n" \ + " //\n" \ + " const chunkSize = Prototype.startSync(nativePtr, autoAllocateChunkSize);\n" \ + "\n" \ + " //\n" \ + " if (chunkSize === 0) {\n" \ + " @readableStreamClose(stream);\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " var instance = new Prototype(nativePtr, chunkSize);\n" \ + " Prototype.registry.register(instance, nativePtr);\n" \ + " @createReadableStreamController.@call(stream, instance, @undefined, true);\n" \ + "})\n" \ +; + #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \ diff --git a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.h b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.h index 01c8635cc..a17ea08bb 100644 --- a/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.h +++ b/src/javascript/jsc/bindings/ReadableStreamInternalsBuiltins.h @@ -55,14 +55,6 @@ extern const char* const s_readableStreamInternalsPrivateInitializeReadableStrea extern const int s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructAbility; extern const JSC::ConstructorKind s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructorKind; -extern const char* const s_readableStreamInternalsSetupReadableStreamDefaultControllerCode; -extern const int s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength; -extern const JSC::ConstructAbility s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructAbility; -extern const JSC::ConstructorKind s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructorKind; -extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerStartCode; -extern const int s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength; -extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructAbility; -extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructorKind; extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerErrorCode; extern const int s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeConstructAbility; @@ -75,6 +67,18 @@ extern const char* const s_readableStreamInternalsAcquireReadableStreamDefaultRe extern const int s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructAbility; extern const JSC::ConstructorKind s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructorKind; +extern const char* const s_readableStreamInternalsSetupReadableStreamDefaultControllerCode; +extern const int s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsCreateReadableStreamControllerCode; +extern const int s_readableStreamInternalsCreateReadableStreamControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsCreateReadableStreamControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsCreateReadableStreamControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerStartCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructorKind; extern const char* const s_readableStreamInternalsReadableStreamPipeToWritableStreamCode; extern const int s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeConstructAbility; @@ -143,6 +147,42 @@ extern const char* const s_readableStreamInternalsIsReadableStreamDefaultControl extern const int s_readableStreamInternalsIsReadableStreamDefaultControllerCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamDefaultControllerCodeConstructAbility; extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsAssignDirectStreamCode; +extern const int s_readableStreamInternalsAssignDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsAssignDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsAssignDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsHandleDirectStreamErrorCode; +extern const int s_readableStreamInternalsHandleDirectStreamErrorCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorCodeConstructorKind; +extern const char* const s_readableStreamInternalsHandleDirectStreamErrorRejectCode; +extern const int s_readableStreamInternalsHandleDirectStreamErrorRejectCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnPullDirectStreamCode; +extern const int s_readableStreamInternalsOnPullDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnPullDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnPullDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsNoopDoneFunctionCode; +extern const int s_readableStreamInternalsNoopDoneFunctionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsNoopDoneFunctionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsNoopDoneFunctionCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnReadableStreamDirectControllerClosedCode; +extern const int s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnCloseDirectStreamCode; +extern const int s_readableStreamInternalsOnCloseDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnCloseDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnCloseDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnDrainDirectStreamCode; +extern const int s_readableStreamInternalsOnDrainDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnDrainDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnDrainDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsInitializeArrayBufferStreamCode; +extern const int s_readableStreamInternalsInitializeArrayBufferStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructorKind; extern const char* const s_readableStreamInternalsReadableStreamErrorCode; extern const int s_readableStreamInternalsReadableStreamErrorCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamErrorCodeConstructAbility; @@ -215,15 +255,20 @@ extern const char* const s_readableStreamInternalsReadableStreamDefaultControlle extern const int s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeLength; extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeConstructAbility; extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeConstructorKind; +extern const char* const s_readableStreamInternalsLazyLoadStreamCode; +extern const int s_readableStreamInternalsLazyLoadStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsLazyLoadStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsLazyLoadStreamCodeConstructorKind; #define WEBCORE_FOREACH_READABLESTREAMINTERNALS_BUILTIN_DATA(macro) \ macro(readableStreamReaderGenericInitialize, readableStreamInternalsReadableStreamReaderGenericInitialize, 2) \ macro(privateInitializeReadableStreamDefaultController, readableStreamInternalsPrivateInitializeReadableStreamDefaultController, 4) \ - macro(setupReadableStreamDefaultController, readableStreamInternalsSetupReadableStreamDefaultController, 7) \ - macro(readableStreamDefaultControllerStart, readableStreamInternalsReadableStreamDefaultControllerStart, 1) \ macro(readableStreamDefaultControllerError, readableStreamInternalsReadableStreamDefaultControllerError, 2) \ macro(readableStreamPipeTo, readableStreamInternalsReadableStreamPipeTo, 2) \ macro(acquireReadableStreamDefaultReader, readableStreamInternalsAcquireReadableStreamDefaultReader, 1) \ + macro(setupReadableStreamDefaultController, readableStreamInternalsSetupReadableStreamDefaultController, 7) \ + macro(createReadableStreamController, readableStreamInternalsCreateReadableStreamController, 3) \ + macro(readableStreamDefaultControllerStart, readableStreamInternalsReadableStreamDefaultControllerStart, 1) \ macro(readableStreamPipeToWritableStream, readableStreamInternalsReadableStreamPipeToWritableStream, 6) \ macro(pipeToLoop, readableStreamInternalsPipeToLoop, 1) \ macro(pipeToDoReadWrite, readableStreamInternalsPipeToDoReadWrite, 1) \ @@ -241,6 +286,15 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault macro(isReadableStream, readableStreamInternalsIsReadableStream, 1) \ macro(isReadableStreamDefaultReader, readableStreamInternalsIsReadableStreamDefaultReader, 1) \ macro(isReadableStreamDefaultController, readableStreamInternalsIsReadableStreamDefaultController, 1) \ + macro(assignDirectStream, readableStreamInternalsAssignDirectStream, 0) \ + macro(handleDirectStreamError, readableStreamInternalsHandleDirectStreamError, 1) \ + macro(handleDirectStreamErrorReject, readableStreamInternalsHandleDirectStreamErrorReject, 1) \ + macro(onPullDirectStream, readableStreamInternalsOnPullDirectStream, 1) \ + macro(noopDoneFunction, readableStreamInternalsNoopDoneFunction, 0) \ + macro(onReadableStreamDirectControllerClosed, readableStreamInternalsOnReadableStreamDirectControllerClosed, 1) \ + macro(onCloseDirectStream, readableStreamInternalsOnCloseDirectStream, 1) \ + macro(onDrainDirectStream, readableStreamInternalsOnDrainDirectStream, 0) \ + macro(initializeArrayBufferStream, readableStreamInternalsInitializeArrayBufferStream, 2) \ macro(readableStreamError, readableStreamInternalsReadableStreamError, 2) \ macro(readableStreamDefaultControllerShouldCallPull, readableStreamInternalsReadableStreamDefaultControllerShouldCallPull, 1) \ macro(readableStreamDefaultControllerCallPullIfNeeded, readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeeded, 1) \ @@ -259,14 +313,16 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault macro(isReadableStreamDisturbed, readableStreamInternalsIsReadableStreamDisturbed, 1) \ macro(readableStreamReaderGenericRelease, readableStreamInternalsReadableStreamReaderGenericRelease, 1) \ macro(readableStreamDefaultControllerCanCloseOrEnqueue, readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueue, 1) \ + macro(lazyLoadStream, readableStreamInternalsLazyLoadStream, 2) \ #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMREADERGENERICINITIALIZE 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_PRIVATEINITIALIZEREADABLESTREAMDEFAULTCONTROLLER 1 -#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_SETUPREADABLESTREAMDEFAULTCONTROLLER 1 -#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERSTART 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERERROR 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMPIPETO 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ACQUIREREADABLESTREAMDEFAULTREADER 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_SETUPREADABLESTREAMDEFAULTCONTROLLER 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_CREATEREADABLESTREAMCONTROLLER 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERSTART 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMPIPETOWRITABLESTREAM 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_PIPETOLOOP 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_PIPETODOREADWRITE 1 @@ -284,6 +340,15 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ISREADABLESTREAM 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ISREADABLESTREAMDEFAULTREADER 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ISREADABLESTREAMDEFAULTCONTROLLER 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ASSIGNDIRECTSTREAM 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_HANDLEDIRECTSTREAMERROR 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_HANDLEDIRECTSTREAMERRORREJECT 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ONPULLDIRECTSTREAM 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_NOOPDONEFUNCTION 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ONREADABLESTREAMDIRECTCONTROLLERCLOSED 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ONCLOSEDIRECTSTREAM 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ONDRAINDIRECTSTREAM 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_INITIALIZEARRAYBUFFERSTREAM 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMERROR 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERSHOULDCALLPULL 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERCALLPULLIFNEEDED 1 @@ -302,15 +367,17 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_ISREADABLESTREAMDISTURBED 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMREADERGENERICRELEASE 1 #define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_READABLESTREAMDEFAULTCONTROLLERCANCLOSEORENQUEUE 1 +#define WEBCORE_BUILTIN_READABLESTREAMINTERNALS_LAZYLOADSTREAM 1 #define WEBCORE_FOREACH_READABLESTREAMINTERNALS_BUILTIN_CODE(macro) \ macro(readableStreamInternalsReadableStreamReaderGenericInitializeCode, readableStreamReaderGenericInitialize, ASCIILiteral(), s_readableStreamInternalsReadableStreamReaderGenericInitializeCodeLength) \ macro(readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCode, privateInitializeReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength) \ - macro(readableStreamInternalsSetupReadableStreamDefaultControllerCode, setupReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength) \ - macro(readableStreamInternalsReadableStreamDefaultControllerStartCode, readableStreamDefaultControllerStart, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength) \ macro(readableStreamInternalsReadableStreamDefaultControllerErrorCode, readableStreamDefaultControllerError, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength) \ macro(readableStreamInternalsReadableStreamPipeToCode, readableStreamPipeTo, ASCIILiteral(), s_readableStreamInternalsReadableStreamPipeToCodeLength) \ macro(readableStreamInternalsAcquireReadableStreamDefaultReaderCode, acquireReadableStreamDefaultReader, ASCIILiteral(), s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength) \ + macro(readableStreamInternalsSetupReadableStreamDefaultControllerCode, setupReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength) \ + macro(readableStreamInternalsCreateReadableStreamControllerCode, createReadableStreamController, ASCIILiteral(), s_readableStreamInternalsCreateReadableStreamControllerCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerStartCode, readableStreamDefaultControllerStart, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength) \ macro(readableStreamInternalsReadableStreamPipeToWritableStreamCode, readableStreamPipeToWritableStream, ASCIILiteral(), s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength) \ macro(readableStreamInternalsPipeToLoopCode, pipeToLoop, ASCIILiteral(), s_readableStreamInternalsPipeToLoopCodeLength) \ macro(readableStreamInternalsPipeToDoReadWriteCode, pipeToDoReadWrite, ASCIILiteral(), s_readableStreamInternalsPipeToDoReadWriteCodeLength) \ @@ -328,6 +395,15 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault macro(readableStreamInternalsIsReadableStreamCode, isReadableStream, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamCodeLength) \ macro(readableStreamInternalsIsReadableStreamDefaultReaderCode, isReadableStreamDefaultReader, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDefaultReaderCodeLength) \ macro(readableStreamInternalsIsReadableStreamDefaultControllerCode, isReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDefaultControllerCodeLength) \ + macro(readableStreamInternalsAssignDirectStreamCode, assignDirectStream, ASCIILiteral(), s_readableStreamInternalsAssignDirectStreamCodeLength) \ + macro(readableStreamInternalsHandleDirectStreamErrorCode, handleDirectStreamError, ASCIILiteral(), s_readableStreamInternalsHandleDirectStreamErrorCodeLength) \ + macro(readableStreamInternalsHandleDirectStreamErrorRejectCode, handleDirectStreamErrorReject, ASCIILiteral(), s_readableStreamInternalsHandleDirectStreamErrorRejectCodeLength) \ + macro(readableStreamInternalsOnPullDirectStreamCode, onPullDirectStream, ASCIILiteral(), s_readableStreamInternalsOnPullDirectStreamCodeLength) \ + macro(readableStreamInternalsNoopDoneFunctionCode, noopDoneFunction, ASCIILiteral(), s_readableStreamInternalsNoopDoneFunctionCodeLength) \ + macro(readableStreamInternalsOnReadableStreamDirectControllerClosedCode, onReadableStreamDirectControllerClosed, ASCIILiteral(), s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeLength) \ + macro(readableStreamInternalsOnCloseDirectStreamCode, onCloseDirectStream, ASCIILiteral(), s_readableStreamInternalsOnCloseDirectStreamCodeLength) \ + macro(readableStreamInternalsOnDrainDirectStreamCode, onDrainDirectStream, ASCIILiteral(), s_readableStreamInternalsOnDrainDirectStreamCodeLength) \ + macro(readableStreamInternalsInitializeArrayBufferStreamCode, initializeArrayBufferStream, ASCIILiteral(), s_readableStreamInternalsInitializeArrayBufferStreamCodeLength) \ macro(readableStreamInternalsReadableStreamErrorCode, readableStreamError, ASCIILiteral(), s_readableStreamInternalsReadableStreamErrorCodeLength) \ macro(readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCode, readableStreamDefaultControllerShouldCallPull, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength) \ macro(readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCode, readableStreamDefaultControllerCallPullIfNeeded, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength) \ @@ -346,14 +422,26 @@ extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefault macro(readableStreamInternalsIsReadableStreamDisturbedCode, isReadableStreamDisturbed, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDisturbedCodeLength) \ macro(readableStreamInternalsReadableStreamReaderGenericReleaseCode, readableStreamReaderGenericRelease, ASCIILiteral(), s_readableStreamInternalsReadableStreamReaderGenericReleaseCodeLength) \ macro(readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCode, readableStreamDefaultControllerCanCloseOrEnqueue, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeLength) \ + macro(readableStreamInternalsLazyLoadStreamCode, lazyLoadStream, ASCIILiteral(), s_readableStreamInternalsLazyLoadStreamCodeLength) \ #define WEBCORE_FOREACH_READABLESTREAMINTERNALS_BUILTIN_FUNCTION_NAME(macro) \ macro(acquireReadableStreamDefaultReader) \ + macro(assignDirectStream) \ + macro(createReadableStreamController) \ + macro(handleDirectStreamError) \ + macro(handleDirectStreamErrorReject) \ + macro(initializeArrayBufferStream) \ macro(isReadableStream) \ macro(isReadableStreamDefaultController) \ macro(isReadableStreamDefaultReader) \ macro(isReadableStreamDisturbed) \ macro(isReadableStreamLocked) \ + macro(lazyLoadStream) \ + macro(noopDoneFunction) \ + macro(onCloseDirectStream) \ + macro(onDrainDirectStream) \ + macro(onPullDirectStream) \ + macro(onReadableStreamDirectControllerClosed) \ macro(pipeToClosingMustBePropagatedBackward) \ macro(pipeToClosingMustBePropagatedForward) \ macro(pipeToDoReadWrite) \ diff --git a/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp index 161e6664b..34a680bdc 100644 --- a/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp +++ b/src/javascript/jsc/bindings/WritableStreamInternalsBuiltins.cpp @@ -75,12 +75,11 @@ const char* const s_writableStreamInternalsIsWritableStreamDefaultWriterCode = const JSC::ConstructAbility s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeConstructorKind = JSC::ConstructorKind::None; -const int s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeLength = 165; +const int s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeLength = 77; static const JSC::Intrinsic s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeIntrinsic = JSC::NoIntrinsic; const char* const s_writableStreamInternalsAcquireWritableStreamDefaultWriterCode = "(function (stream)\n" \ "{\n" \ - " @writableStreamDefaultControllerStart(@getByIdDirectPrivate(stream, \"controller\"));\n" \ " return new @WritableStreamDefaultWriter(stream);\n" \ "})\n" \ ; @@ -842,7 +841,7 @@ const char* const s_writableStreamInternalsWritableStreamDefaultWriterWriteCode const JSC::ConstructAbility s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeConstructorKind = JSC::ConstructorKind::None; -const int s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeLength = 1086; +const int s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeLength = 1142; static const JSC::Intrinsic s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeIntrinsic = JSC::NoIntrinsic; const char* const s_writableStreamInternalsSetUpWritableStreamDefaultControllerCode = "(function (stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm)\n" \ @@ -867,6 +866,8 @@ const char* const s_writableStreamInternalsSetUpWritableStreamDefaultControllerC "\n" \ " const backpressure = @writableStreamDefaultControllerGetBackpressure(controller);\n" \ " @writableStreamUpdateBackpressure(stream, backpressure);\n" \ + "\n" \ + " @writableStreamDefaultControllerStart(controller);\n" \ "})\n" \ ; diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 5b45be50a..43e2de52e 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -1661,6 +1661,12 @@ void GlobalObject::finishCreation(VM& vm) init.setStructure(Zig::NapiClass::createStructure(init.vm, init.global, init.global->functionPrototype())); }); + m_JSArrayBufferControllerPrototype.initLater( + [](const JSC::LazyProperty::Initializer& init) { + auto* prototype = createJSSinkControllerPrototype(init.vm, init.owner, WebCore::SinkID::ArrayBufferSink); + init.set(prototype); + }); + m_JSArrayBufferSinkClassStructure.initLater( [](LazyClassStructure::Initializer& init) { auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::ArrayBufferSink); @@ -1748,6 +1754,12 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) "reportError"_s, functionReportError), JSC::PropertyAttribute::DontDelete | 0 }); + extraStaticGlobals.uncheckedAppend( + GlobalPropertyInfo { builtinNames.startDirectStreamPrivateName(), + JSC::JSFunction::create(vm, JSC::jsCast(globalObject()), 0, + String(), functionStartDirectStream), + JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 }); + static NeverDestroyed BunLazyString(MAKE_STATIC_STRING_IMPL("Bun.lazy")); JSC::Identifier BunLazyIdentifier = JSC::Identifier::fromUid(vm.symbolRegistry().symbolForKey(BunLazyString)); extraStaticGlobals.uncheckedAppend( @@ -1782,6 +1794,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) putDirectBuiltinFunction(vm, this, builtinNames.createEmptyReadableStreamPrivateName(), readableStreamCreateEmptyReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectBuiltinFunction(vm, this, builtinNames.consumeReadableStreamPrivateName(), readableStreamConsumeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectBuiltinFunction(vm, this, builtinNames.readableStreamToArrayPrivateName(), readableStreamReadableStreamToArrayCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); + putDirectBuiltinFunction(vm, this, builtinNames.assignDirectStreamPrivateName(), readableStreamInternalsAssignDirectStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function); @@ -2008,6 +2021,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_builtinInternalFunctions.visit(visitor); thisObject->m_JSFFIFunctionStructure.visit(visitor); thisObject->m_JSArrayBufferSinkClassStructure.visit(visitor); + thisObject->m_JSArrayBufferControllerPrototype.visit(visitor); visitor.append(thisObject->m_readableStreamToArrayBufferResolve); visitor.append(thisObject->m_readableStreamToText); diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.h b/src/javascript/jsc/bindings/ZigGlobalObject.h index 34c9ef412..95fba762d 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.h +++ b/src/javascript/jsc/bindings/ZigGlobalObject.h @@ -151,6 +151,7 @@ public: JSC::Structure* ArrayBufferSinkStructure() { return m_JSArrayBufferSinkClassStructure.getInitializedOnMainThread(this); } JSC::JSObject* ArrayBufferSink() { return m_JSArrayBufferSinkClassStructure.constructorInitializedOnMainThread(this); } JSC::JSValue ArrayBufferSinkPrototype() { return m_JSArrayBufferSinkClassStructure.prototypeInitializedOnMainThread(this); } + JSC::JSValue JSReadableArrayBufferSinkControllerPrototype() { return m_JSArrayBufferControllerPrototype.getInitializedOnMainThread(this); } void* bunVM() { return m_bunVM; } bool isThreadLocalDefaultGlobalObject = false; @@ -175,6 +176,7 @@ private: LazyClassStructure m_JSFFIFunctionStructure; LazyClassStructure m_NapiClassStructure; LazyClassStructure m_JSArrayBufferSinkClassStructure; + LazyProperty m_JSArrayBufferControllerPrototype; DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock); void* m_bunVM; diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index cb606ba39..f061e50b5 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -15,6 +15,7 @@ const is_bindgen: bool = std.meta.globalOption("bindgen", bool) orelse false; const ArrayBuffer = @import("../base.zig").ArrayBuffer; const JSC = @import("../../../jsc.zig"); const Shimmer = JSC.Shimmer; +const FFI = @import("./FFI.zig"); pub const JSObject = extern struct { pub const shim = Shimmer("JSC", "JSObject", @This()); bytes: shim.Bytes, @@ -2424,7 +2425,7 @@ pub const JSValue = enum(i64) { } pub fn jsNumberFromDouble(i: f64) JSValue { - return cppFn("jsNumberFromDouble", .{i}); + return FFI.DOUBLE_TO_JSVALUE(i).asJSValue; } pub fn jsNumberFromChar(i: u8) JSValue { return cppFn("jsNumberFromChar", .{i}); @@ -2433,13 +2434,30 @@ pub const JSValue = enum(i64) { return cppFn("jsNumberFromU16", .{i}); } pub fn jsNumberFromInt32(i: i32) JSValue { - return cppFn("jsNumberFromInt32", .{i}); + return FFI.INT32_TO_JSVALUE(i).asJSValue; } pub fn jsNumberFromInt64(i: i64) JSValue { + if (i <= std.math.maxInt(i32)) { + return jsNumberFromInt32(@intCast(i32, i)); + } + + if (i <= std.math.maxInt(i52)) { + return jsNumberFromDouble(@intToFloat(f64, @intCast(i52, i))); + } + return cppFn("jsNumberFromInt64", .{i}); } + pub fn jsNumberFromUint64(i: u64) JSValue { + if (i <= std.math.maxInt(i32)) { + return jsNumberFromInt32(@intCast(i32, i)); + } + + if (i <= std.math.maxInt(i52)) { + return jsNumberFromDouble(@intToFloat(f64, @intCast(i52, i))); + } + return cppFn("jsNumberFromUint64", .{i}); } @@ -2487,7 +2505,7 @@ pub const JSValue = enum(i64) { } pub fn isInt32(this: JSValue) bool { - return (@bitCast(c_ulonglong, @enumToInt(this)) & @as(c_ulonglong, 18446181123756130304)) == @as(c_ulonglong, 18446181123756130304); + return FFI.JSVALUE_IS_INT32(.{ .asJSValue = this }); } pub fn isInt32AsAnyInt(this: JSValue) bool { @@ -2495,7 +2513,7 @@ pub const JSValue = enum(i64) { } pub fn isNumber(this: JSValue) bool { - return (@bitCast(c_ulonglong, @enumToInt(this)) & @as(c_ulonglong, 18446181123756130304)) != 0; + return FFI.JSVALUE_IS_NUMBER(.{ .asJSValue = this }); } pub fn isError(this: JSValue) bool { @@ -2776,7 +2794,7 @@ pub const JSValue = enum(i64) { pub fn asNumber(this: JSValue) f64 { if (this.isInt32()) { - return @intToFloat(f64, this.toInt32()); + return @intToFloat(f64, this.asInt32()); } if (isNumber(this)) { @@ -2795,7 +2813,7 @@ pub const JSValue = enum(i64) { } pub fn asDouble(this: JSValue) f64 { - return @bitCast(f64, @enumToInt(this) - comptime (@as(c_longlong, 1) << @intCast(@import("std").math.Log2Int(c_longlong), 49))); + return FFI.JSVALUE_TO_DOUBLE(.{ .asJSValue = this }); } pub fn asPtr(this: JSValue, comptime Pointer: type) *Pointer { @@ -2915,7 +2933,7 @@ pub const JSValue = enum(i64) { return @intToPtr(*anyopaque, @bitCast(usize, @enumToInt(this))); } - pub const Extern = [_][]const u8{ "createUninitializedUint8Array", "fromInt64NoTruncate", "fromUInt64NoTruncate", "toUInt64NoTruncate", "asPromise", "toInt64", "_then", "put", "makeWithNameAndPrototype", "parseJSON", "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" }; + pub const Extern = [_][]const u8{ "createUninitializedUint8Array", "fromInt64NoTruncate", "fromUInt64NoTruncate", "toUInt64NoTruncate", "asPromise", "toInt64", "_then", "put", "makeWithNameAndPrototype", "parseJSON", "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt64", "jsNumberFromUint64", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" }; }; extern "c" fn Microtask__run(*Microtask, *JSGlobalObject) void; @@ -3289,17 +3307,12 @@ pub const CallFrame = opaque { // }; -pub const EncodedJSValue = enum(i64) { - _, - - pub const shim = Shimmer("JSC", "EncodedJSValue", @This()); - - pub const Type = u64; - const cppFn = shim.cppFn; - - pub const include = "JavaScriptCore/EncodedJSValue.h"; - pub const name = "JSC::EncodedJSValue"; - pub const namespace = "JSC"; +pub const EncodedJSValue = extern union { + asInt64: i64, + ptr: ?*JSCell, + asBits: [8]u8, + asPtr: ?*anyopaque, + asDouble: f64, }; pub const Identifier = extern struct { diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js index 372c980a1..f59a7bdbc 100644 --- a/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js +++ b/src/javascript/jsc/bindings/builtins/js/ReadableByteStreamInternals.js @@ -61,12 +61,20 @@ function privateInitializeReadableByteStreamController(stream, underlyingByteSou @putByIdDirectPrivate(this, "cancel", @readableByteStreamControllerCancel); @putByIdDirectPrivate(this, "pull", @readableByteStreamControllerPull); + if (@getByIdDirectPrivate(underlyingByteSource, "lazy") === true) { + @putByIdDirectPrivate(this, "start", () => @readableStreamByteStreamControllerStart(this)); + } else { + @putByIdDirectPrivate(this, "start", @undefined); + @readableStreamByteStreamControllerStart(this); + } + return this; } function readableStreamByteStreamControllerStart(controller) { "use strict"; - + @putByIdDirectPrivate(controller, "start", @undefined); + if (@getByIdDirectPrivate(controller, "started") !== -1) return; @@ -84,6 +92,7 @@ function readableStreamByteStreamControllerStart(controller) { }); } + function privateInitializeReadableStreamBYOBRequest(controller, view) { "use strict"; diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js index cf9eba8b6..cfe68d13c 100644 --- a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js +++ b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js @@ -52,38 +52,27 @@ function initializeReadableStream(underlyingSource, strategy) const isDirect = underlyingSource.type === "direct"; // direct streams are always lazy - const isLazy = isDirect || !!underlyingSource.@lazy; + const isUnderlyingSourceLazy = !!underlyingSource.@lazy; + const isLazy = isDirect || isUnderlyingSourceLazy; - - @putByIdDirectPrivate(this, "direct", isDirect); - - // FIXME: We should introduce https://streams.spec.whatwg.org/#create-readable-stream. - // For now, we emulate this with underlyingSource with private properties. - if (@getByIdDirectPrivate(underlyingSource, "pull") !== @undefined) { - @putByIdDirectPrivate(this, "underlyingSource", @undefined); + // // FIXME: We should introduce https://streams.spec.whatwg.org/#create-readable-stream. + // // For now, we emulate this with underlyingSource with private properties. + if (@getByIdDirectPrivate(underlyingSource, "pull") !== @undefined && !isLazy) { const size = @getByIdDirectPrivate(strategy, "size"); const highWaterMark = @getByIdDirectPrivate(strategy, "highWaterMark"); @setupReadableStreamDefaultController(this, underlyingSource, size, highWaterMark !== @undefined ? highWaterMark : 1, @getByIdDirectPrivate(underlyingSource, "start"), @getByIdDirectPrivate(underlyingSource, "pull"), @getByIdDirectPrivate(underlyingSource, "cancel")); return this; } - - if (isLazy) { - - if (isDirect) { - if ("start" in underlyingSource && typeof underlyingSource.start === "function") - @throwTypeError("\"start\" for direct streams are not implemented yet"); - - - @putByIdDirectPrivate(this, "underlyingSource", underlyingSource); - @putByIdDirectPrivate(this, "start", () => @createReadableStreamController(this, underlyingSource, strategy, true)); - } else { - @putByIdDirectPrivate(this, "underlyingSource", @undefined); - const autoAllocateChunkSize = underlyingSource.autoAllocateChunkSize; - @putByIdDirectPrivate(this, "start", () => @lazyLoadStream(this, autoAllocateChunkSize)); - } + if (isDirect) { + if ("start" in underlyingSource && typeof underlyingSource.start === "function") + @throwTypeError("\"start\" for direct streams are not implemented yet"); + + @putByIdDirectPrivate(this, "start", () => @createReadableStreamController.@call(this, underlyingSource, strategy, true)); + } else if (isLazy) { + const autoAllocateChunkSize = underlyingSource.autoAllocateChunkSize; + @putByIdDirectPrivate(this, "start", () => @lazyLoadStream(this, autoAllocateChunkSize)); } else { - @putByIdDirectPrivate(this, "underlyingSource", @undefined); @putByIdDirectPrivate(this, "start", @undefined); @createReadableStreamController.@call(this, underlyingSource, strategy, false); } @@ -92,300 +81,6 @@ function initializeReadableStream(underlyingSource, strategy) return this; } -function handleDirectStreamError(e) { - "use strict"; - - var controller = this; - var sink = controller.@sink; - if (sink) { - @putByIdDirectPrivate(controller "sink", @undefined); - try { - sink.close(e); - } catch (f) {} - } - - this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed; - - if (typeof this.@underlyingSource.close === 'function') { - try { - this.@underlyingSource.close.@call(this.@underlyingSource, e); - } catch (e) { - } - } - - try { - var pend = controller._pendingRead; - if (pend) { - controller._pendingRead = @undefined; - @rejectPromise(pend, e); - } - } catch (f) {} - var stream = controller.@controlledReadableStream; - if (stream) @readableStreamError(stream, e); -} - -function handleDirectStreamErrorReject(e) { - @handleDirectStreamError.@call(this, e); - return @Promise.@reject(e); -} - -function onPullDirectStream(controller) -{ - - "use strict"; - - var stream = controller.@controlledReadableStream; - if (!stream || @getByIdDirectPrivate(stream, "state") !== @streamReadable) - return; - - // pull is in progress - // this is a recursive call - // ignore it - if (controller._deferClose === -1) { - return; - } - - - controller._deferClose = -1; - controller._deferDrain = -1; - var deferClose; - var deferDrain; - - // Direct streams allow @pull to be called multiple times, unlike the spec. - // Backpressure is handled by the destination, not by the underlying source. - // In this case, we rely on the heuristic that repeatedly draining in the same tick - // is bad for performance - // this code is only run when consuming a direct stream from JS - // without the HTTP server or anything else - try { - var result = controller.@underlyingSource.@pull( - controller, - ); - - if (result && @isPromise(result)) { - if (controller._handleError === @undefined) { - controller._handleError = @handleDirectStreamErrorReject.@bind(controller); - } - - @Promise.prototype.@catch.@call(result, controller._handleError); - } - } catch(e) { - return @handleDirectStreamErrorReject.@call(controller, e); - } finally { - deferDrain = controller._deferClose; - deferClose = controller._deferDrain; - controller._deferDrain = 0; - controller._deferClose = 0; - - } - - - var promiseToReturn; - - - if (controller._pendingRead === @undefined) { - controller._pendingRead = promiseToReturn = @newPromise(); - } else { - promiseToReturn = @readableStreamAddReadRequest(stream); - } - - // they called close during @pull() - // we delay that - if (deferClose === 1) { - var reason = controller._deferCloseReason; - controller._deferCloseReason = @undefined; - @onCloseDirectStream.@call(controller, reason); - return promiseToReturn; - } - - // not done, but they called drain() - if (deferDrain === 1) { - @onDrainDirectStream.@call(controller); - } - - - return promiseToReturn; -} - -function noopDoneFunction() { - return @Promise.@resolve({value: @undefined, done: true}); -} - -function onReadableStreamDirectControllerClosed(reason) -{ - "use strict"; - @throwTypeError("ReadableStreamDirectController is now closed"); -} - -function onCloseDirectStream(reason) -{ - "use strict"; - var stream = this.@controlledReadableStream; - if (!stream || @getByIdDirectPrivate(stream, "state") !== @streamReadable) - return; - - if (this._deferClose !== 0) { - this._deferClose = 1; - this._deferCloseReason = reason; - return; - } - - @putByIdDirectPrivate(stream, "state", @streamClosing); - if (typeof this.@underlyingSource.close === 'function') { - try { - this.@underlyingSource.close.@call(this.@underlyingSource, reason); - } catch (e) { - - } - } - - var drained; - try { - drained = this.@sink.end(); - @putByIdDirectPrivate(this, "sink", @undefined); - } catch (e) { - if (this._pendingRead) { - var read = this._pendingRead; - this._pendingRead = @undefined; - @rejectPromise(read, e); - } - @readableStreamError(stream, e); - return; - } - - this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed; - - var reader = @getByIdDirectPrivate(stream, "reader"); - - if (reader && @isReadableStreamDefaultReader(reader)) { - var _pendingRead = this._pendingRead; - if (_pendingRead && @isPromise(_pendingRead) && drained?.byteLength) { - this._pendingRead = @undefined; - @fulfillPromise(_pendingRead, {value: drained, done: false}); - @readableStreamClose(stream); - return; - } - } - - if (drained?.byteLength) { - var requests = @getByIdDirectPrivate(reader, "readRequests"); - if (requests?.isNotEmpty()) { - @readableStreamFulfillReadRequest(stream, drained, false); - @readableStreamClose(stream); - return; - } - - @putByIdDirectPrivate(stream, "state", @streamReadable); - this.@pull = () => { - var thisResult = @createFulfilledPromise({value: drained, done: false}); - drained = @undefined; - @readableStreamClose(stream); - stream = @undefined; - return thisResult; - }; - } else if (this._pendingRead) { - var read = this._pendingRead; - this._pendingRead = @undefined; - @putByIdDirectPrivate(this, "pull", @noopDoneFunction); - @fulfillPromise(read, {value: @undefined, done: true}); - } - - @readableStreamClose(stream); -} - -function onDrainDirectStream() -{ - "use strict"; - - var straem = this.@controlledReadableStream; - var reader = @getByIdDirectPrivate(stream, "reader"); - if (!reader || !@isReadableStreamDefaultReader(reader)) { - return; - } - - var _pendingRead = this._pendingRead; - this._pendingRead = @undefined; - if (_pendingRead && @isPromise(_pendingRead)) { - var drained = this.@sink.drain(); - if (drained?.byteLength) { - this._pendingRead = @getByIdDirectPrivate(stream, "readRequests")?.shift(); - @fulfillPromise(_pendingRead, {value: drained, done: false}); - } else { - this._pendingRead = _pendingRead; - } - } else if (@getByIdDirectPrivate(stream, "readRequests")?.isNotEmpty()) { - var drained = this.@sink.drain(); - if (drained?.byteLength) { - @readableStreamFulfillReadRequest(stream, drained, false); - } - } else if (this._deferDrain === -1) { - this._deferDrain = 1; - } - -} - -function initializeArrayBufferStream(underlyingSource, highWaterMark) -{ - "use strict"; - - // This is the fallback implementation for direct streams - // When we don't know what the destination type is - // We assume it is a Uint8Array. - var sink = new globalThis.Bun.ArrayBufferSink(highWaterMark ? {highWaterMark, stream: true, asUint8Array: true} : {stream: true, asUint8Array: true}); - var controller = { - @underlyingSource: underlyingSource, - @pull: @onPullDirectStream, - @controlledReadableStream: this, - @sink: sink, - close: @onCloseDirectStream, - write: sink.write.@bind(sink), - end: @onCloseDirectStream, - drain: @onDrainDirectStream, - _pendingRead: @undefined, - _deferClose: 0, - _deferDrain: 0, - _deferCloseReason: @undefined, - _handleError: @undefined, - }; - - - @putByIdDirectPrivate(this, "readableStreamController", controller); - -} - -function createReadableStreamController(underlyingSource, strategy, fromLazy) { - if (fromLazy) { - @putByIdDirectPrivate(this, "start", @undefined); - } - - const type = underlyingSource.type; - const typeString = @toString(type); - - if (typeString === "bytes") { - // if (!@readableByteStreamAPIEnabled()) - // @throwTypeError("ReadableByteStreamController is not implemented"); - - if (strategy.highWaterMark === @undefined) - strategy.highWaterMark = 0; - if (strategy.size !== @undefined) - @throwRangeError("Strategy for a ReadableByteStreamController cannot have a size"); - - @putByIdDirectPrivate(this, "readableStreamController", new @ReadableByteStreamController(this, underlyingSource, strategy.highWaterMark, @isReadableStream)); - } else if (typeString === "direct") { - if (strategy.size !== @undefined) - @throwRangeError("Strategy for a ReadableDirectStreamController cannot have a size"); - - var highWaterMark = strategy.highWaterMark; - @initializeArrayBufferStream.@call(this, underlyingSource, highWaterMark); - } else if (type === @undefined) { - if (strategy.highWaterMark === @undefined) - strategy.highWaterMark = 1; - - @setupReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, underlyingSource.start, underlyingSource.pull, underlyingSource.cancel); - } else - @throwRangeError("Invalid type for underlying source"); - -} @globalPrivate function readableStreamToArray(stream) { @@ -516,14 +211,14 @@ function readableStreamToArrayPublic(stream) { @globalPrivate function consumeReadableStream(nativePtr, nativeType, inputStream) { "use strict"; - const symbol = Symbol.for("Bun.consumeReadableStreamPrototype"); + const symbol = globalThis.Symbol.for("Bun.consumeReadableStreamPrototype"); var cached = globalThis[symbol]; if (!cached) { cached = globalThis[symbol] = []; } var Prototype = cached[nativeType]; if (Prototype === @undefined) { - var [doRead, doError, doReadMany, doClose, onClose, deinit] = globalThis[Symbol.for("Bun.lazy")](nativeType); + var [doRead, doError, doReadMany, doClose, onClose, deinit] = globalThis[globalThis.Symbol.for("Bun.lazy")](nativeType); Prototype = class NativeReadableStreamSink { constructor(reader, ptr) { @@ -639,100 +334,6 @@ function createEmptyReadableStream() { return stream; } -function lazyLoadStream(stream, autoAllocateChunkSize) { - "use strict"; - - @putByIdDirectPrivate(stream, "start", @undefined); - var bunNativeType = @getByIdDirectPrivate(stream, "bunNativeType"); - var bunNativePtr = @getByIdDirectPrivate(stream, "bunNativePtr"); - - 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 {c, v} = this; - this.c = @undefined; - this.v = @undefined; - handleResult(val, c, v); - } - - handleResult = function handleResult(result, controller, view) { - "use strict"; - - if (result && @isPromise(result)) { - return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, v: view}), (err) => controller.error(err)); - } else if (result !== false) { - if (view && view.byteLength === result) { - controller.byobRequest.respondWithNewView(view); - } else { - controller.byobRequest.respond(result); - } - } - - if (closer[0] || result === false) { - @enqueueJob(() => controller.close()); - closer[0] = false; - } - }; - - Prototype = class NativeReadableStreamSource { - constructor(tag, autoAllocateChunkSize) { - this.pull = this.pull_.bind(tag); - this.cancel = this.cancel_.bind(tag); - this.autoAllocateChunkSize = autoAllocateChunkSize; - } - - pull; - cancel; - - type = "bytes"; - autoAllocateChunkSize = 0; - - static startSync = start; - - pull_(controller) { - closer[0] = false; - var result; - - const view = controller.byobRequest.view; - try { - result = pull(this, view, closer); - } catch(err) { - return controller.error(err); - } - - return handleResult(result, controller, view); - } - - cancel_(reason) { - cancel(this, reason); - } - - static registry = new FinalizationRegistry(deinit); - } - cached.@set(nativeType, Prototype); - } - - // 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) { - @readableStreamClose(stream); - return; - } - - var instance = new Prototype(nativePtr, chunkSize); - Prototype.registry.register(instance, nativePtr); - @createReadableStreamController.@call(stream, instance, @undefined, true); -} - @globalPrivate function createNativeReadableStream(nativePtr, nativeType, autoAllocateChunkSize) { "use strict"; @@ -766,18 +367,15 @@ function getReader(options) throw @makeThisTypeError("ReadableStream", "getReader"); const mode = @toDictionary(options, { }, "ReadableStream.getReader takes an object as first argument").mode; - if (mode === @undefined) + if (mode === @undefined) { + var start_ = @getByIdDirectPrivate(this, "start"); + if (start_) { + start_.@call(this); + } return new @ReadableStreamDefaultReader(this); - + } // String conversion is required by spec, hence double equals. if (mode == 'byob') { - var controller = @getByIdDirectPrivate(this, "controller"); - if (@isReadableStreamDefaultController(controller)) { - @readableStreamDefaultControllerStart(controller); - } else { - @readableStreamByteStreamControllerStart(controller); - } - return new @ReadableStreamBYOBReader(this); } diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js index 5d0779745..d2dfd5137 100644 --- a/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js +++ b/src/javascript/jsc/bindings/builtins/js/ReadableStreamInternals.js @@ -67,48 +67,6 @@ function privateInitializeReadableStreamDefaultController(stream, underlyingSour return this; } - -// https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller, starting from step 6. -// The other part is implemented in privateInitializeReadableStreamDefaultController. -function setupReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, startMethod, pullMethod, cancelMethod) -{ - "use strict"; - - const controller = new @ReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, @isReadableStream); - - const pullAlgorithm = () => @promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]); - const cancelAlgorithm = (reason) => @promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]); - - @putByIdDirectPrivate(controller, "pullAlgorithm", pullAlgorithm); - @putByIdDirectPrivate(controller, "cancelAlgorithm", cancelAlgorithm); - @putByIdDirectPrivate(controller, "pull", @readableStreamDefaultControllerPull); - @putByIdDirectPrivate(controller, "cancel", @readableStreamDefaultControllerCancel); - @putByIdDirectPrivate(stream, "readableStreamController", controller); - - if (@getByIdDirectPrivate(controller, "sink") === @undefined) { - @readableStreamDefaultControllerStart(controller); - } - -} - -function readableStreamDefaultControllerStart(controller) { - if (@getByIdDirectPrivate(controller, "started") !== -1) - return; - - const underlyingSource = @getByIdDirectPrivate(controller, "underlyingSource"); - const startMethod = underlyingSource.start; - @putByIdDirectPrivate(controller, "started", 0); - - return @promiseInvokeOrNoopMethodNoCatch(underlyingSource, startMethod, [controller]).@then(() => { - @putByIdDirectPrivate(controller, "started", 1); - @assert(!@getByIdDirectPrivate(controller, "pulling")); - @assert(!@getByIdDirectPrivate(controller, "pullAgain")); - @readableStreamDefaultControllerCallPullIfNeeded(controller); - }, (error) => { - @readableStreamDefaultControllerError(controller, error); - }); -} - function readableStreamDefaultControllerError(controller, error) { "use strict"; @@ -157,12 +115,88 @@ function acquireReadableStreamDefaultReader(stream) "use strict"; var start = @getByIdDirectPrivate(stream, "start"); if (start) { - start(); + start.@call(stream); } return new @ReadableStreamDefaultReader(stream); } +// https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller, starting from step 6. +// The other part is implemented in privateInitializeReadableStreamDefaultController. +function setupReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, startMethod, pullMethod, cancelMethod) +{ + "use strict"; + + const controller = new @ReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, @isReadableStream); + + const pullAlgorithm = () => @promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]); + const cancelAlgorithm = (reason) => @promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]); + + @putByIdDirectPrivate(controller, "pullAlgorithm", pullAlgorithm); + @putByIdDirectPrivate(controller, "cancelAlgorithm", cancelAlgorithm); + @putByIdDirectPrivate(controller, "pull", @readableStreamDefaultControllerPull); + @putByIdDirectPrivate(controller, "cancel", @readableStreamDefaultControllerCancel); + @putByIdDirectPrivate(stream, "readableStreamController", controller); + + @readableStreamDefaultControllerStart(controller); + +} + + +function createReadableStreamController(underlyingSource, strategy, fromLazy) { + if (fromLazy) { + @putByIdDirectPrivate(this, "start", @undefined); + } + + const type = underlyingSource.type; + const typeString = @toString(type); + + if (typeString === "bytes") { + // if (!@readableByteStreamAPIEnabled()) + // @throwTypeError("ReadableByteStreamController is not implemented"); + + if (strategy.highWaterMark === @undefined) + strategy.highWaterMark = 0; + if (strategy.size !== @undefined) + @throwRangeError("Strategy for a ReadableByteStreamController cannot have a size"); + + @putByIdDirectPrivate(this, "readableStreamController", new @ReadableByteStreamController(this, underlyingSource, strategy.highWaterMark, @isReadableStream)); + } else if (typeString === "direct") { + var highWaterMark = strategy?.highWaterMark; + @initializeArrayBufferStream.@call(this, underlyingSource, highWaterMark); + } else if (type === @undefined) { + if (strategy.highWaterMark === @undefined) + strategy.highWaterMark = 1; + + @setupReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, underlyingSource.start, underlyingSource.pull, underlyingSource.cancel); + } else + @throwRangeError("Invalid type for underlying source"); + +} + +function readableStreamDefaultControllerStart(controller) { + "use strict"; + + + + if (@getByIdDirectPrivate(controller, "started") !== -1) + return; + + const underlyingSource = @getByIdDirectPrivate(controller, "underlyingSource"); + const startMethod = underlyingSource.start; + @putByIdDirectPrivate(controller, "started", 0); + + @promiseInvokeOrNoopMethodNoCatch(underlyingSource, startMethod, [controller]).@then(() => { + @putByIdDirectPrivate(controller, "started", 1); + @assert(!@getByIdDirectPrivate(controller, "pulling")); + @assert(!@getByIdDirectPrivate(controller, "pullAgain")); + @readableStreamDefaultControllerCallPullIfNeeded(controller); + }, (error) => { + @readableStreamDefaultControllerError(controller, error); + }); +} + + // FIXME: Replace readableStreamPipeTo by below function. // This method implements the latest https://streams.spec.whatwg.org/#readable-stream-pipe-to. function readableStreamPipeToWritableStream(source, destination, preventClose, preventAbort, preventCancel, signal) @@ -563,6 +597,281 @@ function isReadableStreamDefaultController(controller) return @isObject(controller) && !!@getByIdDirectPrivate(controller, "underlyingSource"); } + +@globalPrivate +function assignDirectStream() { + "use strict"; + + var stream = this; +} + + +function handleDirectStreamError(e) { + "use strict"; + + var controller = this; + var sink = controller.@sink; + if (sink) { + @putByIdDirectPrivate(controller, "sink", @undefined); + try { + sink.close(e); + } catch (f) {} + } + + this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed; + + if (typeof this.@underlyingSource.close === 'function') { + try { + this.@underlyingSource.close.@call(this.@underlyingSource, e); + } catch (e) { + } + } + + try { + var pend = controller._pendingRead; + if (pend) { + controller._pendingRead = @undefined; + @rejectPromise(pend, e); + } + } catch (f) {} + var stream = controller.@controlledReadableStream; + if (stream) @readableStreamError(stream, e); +} + +function handleDirectStreamErrorReject(e) { + @handleDirectStreamError.@call(this, e); + return @Promise.@reject(e); +} + +function onPullDirectStream(controller) +{ + + "use strict"; + + var stream = controller.@controlledReadableStream; + if (!stream || @getByIdDirectPrivate(stream, "state") !== @streamReadable) + return; + + // pull is in progress + // this is a recursive call + // ignore it + if (controller._deferClose === -1) { + return; + } + + + controller._deferClose = -1; + controller._deferDrain = -1; + var deferClose; + var deferDrain; + + // Direct streams allow @pull to be called multiple times, unlike the spec. + // Backpressure is handled by the destination, not by the underlying source. + // In this case, we rely on the heuristic that repeatedly draining in the same tick + // is bad for performance + // this code is only run when consuming a direct stream from JS + // without the HTTP server or anything else + try { + var result = controller.@underlyingSource.pull( + controller, + ); + + if (result && @isPromise(result)) { + if (controller._handleError === @undefined) { + controller._handleError = @handleDirectStreamErrorReject.bind(controller); + } + + @Promise.prototype.catch.@call(result, controller._handleError); + } + } catch(e) { + return @handleDirectStreamErrorReject.@call(controller, e); + } finally { + deferClose = controller._deferClose; + deferDrain = controller._deferDrain; + controller._deferDrain = controller._deferClose = 0; + } + + + var promiseToReturn; + + + if (controller._pendingRead === @undefined) { + controller._pendingRead = promiseToReturn = @newPromise(); + } else { + promiseToReturn = @readableStreamAddReadRequest(stream); + } + + + // they called close during @pull() + // we delay that + if (deferClose === 1) { + var reason = controller._deferCloseReason; + controller._deferCloseReason = @undefined; + @onCloseDirectStream.@call(controller, reason); + return promiseToReturn; + } + + // not done, but they called drain() + if (deferDrain === 1) { + @onDrainDirectStream.@call(controller); + } + + + return promiseToReturn; +} + +function noopDoneFunction() { + return @Promise.@resolve({value: @undefined, done: true}); +} + +function onReadableStreamDirectControllerClosed(reason) +{ + "use strict"; + @throwTypeError("ReadableStreamDirectController is now closed"); +} + +function onCloseDirectStream(reason) +{ + "use strict"; + var stream = this.@controlledReadableStream; + if (!stream || @getByIdDirectPrivate(stream, "state") !== @streamReadable) + return; + + if (this._deferClose !== 0) { + this._deferClose = 1; + this._deferCloseReason = reason; + return; + } + + @putByIdDirectPrivate(stream, "state", @streamClosing); + if (typeof this.@underlyingSource.close === 'function') { + try { + this.@underlyingSource.close.@call(this.@underlyingSource, reason); + } catch (e) { + + } + } + + var drained; + try { + drained = this.@sink.end(); + @putByIdDirectPrivate(this, "sink", @undefined); + } catch (e) { + if (this._pendingRead) { + var read = this._pendingRead; + this._pendingRead = @undefined; + @rejectPromise(read, e); + } + @readableStreamError(stream, e); + return; + } + + this.error = this.drain = this.write = this.close = this.end = @onReadableStreamDirectControllerClosed; + + var reader = @getByIdDirectPrivate(stream, "reader"); + + if (reader && @isReadableStreamDefaultReader(reader)) { + var _pendingRead = this._pendingRead; + if (_pendingRead && @isPromise(_pendingRead) && drained?.byteLength) { + this._pendingRead = @undefined; + @fulfillPromise(_pendingRead, {value: drained, done: false}); + @readableStreamClose(stream); + return; + } + } + + if (drained?.byteLength) { + var requests = @getByIdDirectPrivate(reader, "readRequests"); + if (requests?.isNotEmpty()) { + @readableStreamFulfillReadRequest(stream, drained, false); + @readableStreamClose(stream); + return; + } + + @putByIdDirectPrivate(stream, "state", @streamReadable); + this.@pull = () => { + var thisResult = @createFulfilledPromise({value: drained, done: false}); + drained = @undefined; + @readableStreamClose(stream); + stream = @undefined; + return thisResult; + }; + } else if (this._pendingRead) { + var read = this._pendingRead; + this._pendingRead = @undefined; + @putByIdDirectPrivate(this, "pull", @noopDoneFunction); + @fulfillPromise(read, {value: @undefined, done: true}); + } + + @readableStreamClose(stream); +} + +function onDrainDirectStream() +{ + "use strict"; + + var stream = this.@controlledReadableStream; + var reader = @getByIdDirectPrivate(stream, "reader"); + if (!reader || !@isReadableStreamDefaultReader(reader)) { + return; + } + + var _pendingRead = this._pendingRead; + this._pendingRead = @undefined; + if (_pendingRead && @isPromise(_pendingRead)) { + var drained = this.@sink.drain(); + if (drained?.byteLength) { + this._pendingRead = @getByIdDirectPrivate(stream, "readRequests")?.shift(); + @fulfillPromise(_pendingRead, {value: drained, done: false}); + } else { + this._pendingRead = _pendingRead; + } + } else if (@getByIdDirectPrivate(stream, "readRequests")?.isNotEmpty()) { + var drained = this.@sink.drain(); + if (drained?.byteLength) { + @readableStreamFulfillReadRequest(stream, drained, false); + } + } else if (this._deferDrain === -1) { + this._deferDrain = 1; + } + +} + +function initializeArrayBufferStream(underlyingSource, highWaterMark) +{ + "use strict"; + + // This is the fallback implementation for direct streams + // When we don't know what the destination type is + // We assume it is a Uint8Array. + + var opts = highWaterMark ? {highWaterMark, stream: true, asUint8Array: true} : {stream: true, asUint8Array: true}; + var sink = new globalThis.Bun.ArrayBufferSink(); + sink.start(opts); + + var controller = { + @underlyingSource: underlyingSource, + @pull: @onPullDirectStream, + @controlledReadableStream: this, + @sink: sink, + close: @onCloseDirectStream, + write: sink.write.bind(sink), + error: @handleDirectStreamError, + end: @onCloseDirectStream, + @close: @onCloseDirectStream, + drain: @onDrainDirectStream, + _pendingRead: @undefined, + _deferClose: 0, + _deferDrain: 0, + _deferCloseReason: @undefined, + _handleError: @undefined, + }; + + + @putByIdDirectPrivate(this, "readableStreamController", controller); + +} + function readableStreamError(stream, error) { "use strict"; @@ -597,11 +906,13 @@ function readableStreamError(stream, error) function readableStreamDefaultControllerShouldCallPull(controller) { - const stream = @getByIdDirectPrivate(controller, "controlledReadableStream"); + "use strict"; + const stream = @getByIdDirectPrivate(controller, "controlledReadableStream"); + if (!@readableStreamDefaultControllerCanCloseOrEnqueue(controller)) return false; - if (!(@getByIdDirectPrivate(controller, "started") > 0)) + if (!(@getByIdDirectPrivate(controller, "started") === 1)) return false; if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0) return false; @@ -619,7 +930,7 @@ function readableStreamDefaultControllerCallPullIfNeeded(controller) if (!@readableStreamDefaultControllerCanCloseOrEnqueue(controller)) return; - if (!(@getByIdDirectPrivate(controller, "started") > 0)) + if (!(@getByIdDirectPrivate(controller, "started") === 1)) return; if ((!@isReadableStreamLocked(stream) || !@getByIdDirectPrivate(@getByIdDirectPrivate(stream, "reader"), "readRequests")?.isNotEmpty()) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0) return; @@ -629,6 +940,7 @@ function readableStreamDefaultControllerCallPullIfNeeded(controller) return; } + @assert(!@getByIdDirectPrivate(controller, "pullAgain")); @putByIdDirectPrivate(controller, "pulling", true); @@ -636,6 +948,7 @@ function readableStreamDefaultControllerCallPullIfNeeded(controller) @putByIdDirectPrivate(controller, "pulling", false); if (@getByIdDirectPrivate(controller, "pullAgain")) { @putByIdDirectPrivate(controller, "pullAgain", false); + @readableStreamDefaultControllerCallPullIfNeeded(controller); } }, function(error) { @@ -849,3 +1162,98 @@ function readableStreamDefaultControllerCanCloseOrEnqueue(controller) return !@getByIdDirectPrivate(controller, "closeRequested") && @getByIdDirectPrivate(@getByIdDirectPrivate(controller, "controlledReadableStream"), "state") === @streamReadable; } + + +function lazyLoadStream(stream, autoAllocateChunkSize) { + "use strict"; + + @putByIdDirectPrivate(stream, "start", @undefined); + var bunNativeType = @getByIdDirectPrivate(stream, "bunNativeType"); + var bunNativePtr = @getByIdDirectPrivate(stream, "bunNativePtr"); + + var cached = globalThis[globalThis.Symbol.for("Bun.nativeReadableStreamPrototype")] ||= new @Map; + var Prototype = cached.@get(nativeType); + if (Prototype === @undefined) { + var [pull, start, cancel, setClose, deinit] = globalThis[globalThis.Symbol.for("Bun.lazy")](nativeType); + var closer = [false]; + var handleResult; + function handleNativeReadableStreamPromiseResult(val) { + "use strict"; + var {c, v} = this; + this.c = @undefined; + this.v = @undefined; + handleResult(val, c, v); + } + + handleResult = function handleResult(result, controller, view) { + "use strict"; + + if (result && @isPromise(result)) { + return result.then(handleNativeReadableStreamPromiseResult.bind({c: controller, v: view}), (err) => controller.error(err)); + } else if (result !== false) { + if (view && view.byteLength === result) { + controller.byobRequest.respondWithNewView(view); + } else { + controller.byobRequest.respond(result); + } + } + + if (closer[0] || result === false) { + @enqueueJob(() => controller.close()); + closer[0] = false; + } + }; + + Prototype = class NativeReadableStreamSource { + constructor(tag, autoAllocateChunkSize) { + this.pull = this.pull_.bind(tag); + this.cancel = this.cancel_.bind(tag); + this.autoAllocateChunkSize = autoAllocateChunkSize; + } + + pull; + cancel; + + type = "bytes"; + autoAllocateChunkSize = 0; + + static startSync = start; + + pull_(controller) { + closer[0] = false; + var result; + + const view = controller.byobRequest.view; + try { + result = pull(this, view, closer); + } catch(err) { + return controller.error(err); + } + + return handleResult(result, controller, view); + } + + cancel_(reason) { + cancel(this, reason); + } + + static registry = new FinalizationRegistry(deinit); + } + cached.@set(nativeType, Prototype); + } + + // 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) { + @readableStreamClose(stream); + return; + } + + var instance = new Prototype(nativePtr, chunkSize); + Prototype.registry.register(instance, nativePtr); + @createReadableStreamController.@call(stream, instance, @undefined, true); +} \ No newline at end of file diff --git a/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js b/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js index 5870cd05d..5a97155f2 100644 --- a/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js +++ b/src/javascript/jsc/bindings/builtins/js/WritableStreamInternals.js @@ -42,7 +42,6 @@ function isWritableStreamDefaultWriter(writer) function acquireWritableStreamDefaultWriter(stream) { - @writableStreamDefaultControllerStart(@getByIdDirectPrivate(stream, "controller")); return new @WritableStreamDefaultWriter(stream); } diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig index 47cd3488d..04142d040 100644 --- a/src/javascript/jsc/bindings/exports.zig +++ b/src/javascript/jsc/bindings/exports.zig @@ -184,7 +184,7 @@ pub const JSReadableStreamBlob = JSC.WebCore.ByteBlobLoader.Source.JSReadableStr pub const JSReadableStreamFile = JSC.WebCore.FileBlobLoader.Source.JSReadableStreamSource; // Sinks -pub const JSArrayBufferSink = JSC.WebCore.ArrayBufferSink.JSArrayBufferSink; +pub const JSArrayBufferSink = JSC.WebCore.ArrayBufferSink.JSSink; pub fn Errorable(comptime Type: type) type { return extern struct { diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index c2c68bc60..7a5ec325a 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1655075078 +//-- AUTOGENERATED FILE -- 1655288763 // clang-format off #pragma once diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index e3d642676..4bb9c65cb 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format: off -//-- AUTOGENERATED FILE -- 1655075078 +//-- AUTOGENERATED FILE -- 1655288763 #pragma once #include @@ -513,7 +513,6 @@ CPP_DECL JSC__JSValue JSC__JSValue__jsDoubleNumber(double arg0); CPP_DECL JSC__JSValue JSC__JSValue__jsNull(); CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromChar(unsigned char arg0); CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromDouble(double arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromInt32(int32_t arg0); CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromInt64(int64_t arg0); CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromU16(uint16_t arg0); CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromUint64(uint64_t arg0); @@ -735,8 +734,7 @@ CPP_DECL void* ArrayBufferSink__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue J #ifdef __cplusplus -ZIG_DECL JSC__JSValue ArrayBufferSink__close(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1); -ZIG_DECL JSC__JSValue ArrayBufferSink__closeWithError(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1); +ZIG_DECL JSC__JSValue ArrayBufferSink__close(JSC__JSGlobalObject* arg0, void* arg1); ZIG_DECL JSC__JSValue ArrayBufferSink__construct(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1); ZIG_DECL JSC__JSValue ArrayBufferSink__drain(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1); ZIG_DECL JSC__JSValue ArrayBufferSink__end(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1); diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig index e6417ab0f..d8915b9d3 100644 --- a/src/javascript/jsc/bindings/headers.zig +++ b/src/javascript/jsc/bindings/headers.zig @@ -364,7 +364,6 @@ pub extern fn JSC__JSValue__jsDoubleNumber(arg0: f64) JSC__JSValue; pub extern fn JSC__JSValue__jsNull(...) JSC__JSValue; pub extern fn JSC__JSValue__jsNumberFromChar(arg0: u8) JSC__JSValue; pub extern fn JSC__JSValue__jsNumberFromDouble(arg0: f64) JSC__JSValue; -pub extern fn JSC__JSValue__jsNumberFromInt32(arg0: i32) JSC__JSValue; pub extern fn JSC__JSValue__jsNumberFromInt64(arg0: i64) JSC__JSValue; pub extern fn JSC__JSValue__jsNumberFromU16(arg0: u16) JSC__JSValue; pub extern fn JSC__JSValue__jsNumberFromUint64(arg0: u64) JSC__JSValue; diff --git a/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h b/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h index 876b6843f..8cb65504f 100644 --- a/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h +++ b/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h @@ -23,6 +23,7 @@ public: std::unique_ptr m_clientSubspaceForJSSQLStatement; std::unique_ptr m_clientSubspaceForJSSQLStatementConstructor; std::unique_ptr m_clientSubspaceForJSSinkConstructor; + std::unique_ptr m_clientSubspaceForJSSinkController; std::unique_ptr m_clientSubspaceForJSSink; /* --- bun --- */ diff --git a/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h b/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h index 6b55f05e7..5e74e4d43 100644 --- a/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h +++ b/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h @@ -23,6 +23,7 @@ public: std::unique_ptr m_subspaceForJSSQLStatement; std::unique_ptr m_subspaceForJSSQLStatementConstructor; std::unique_ptr m_subspaceForJSSinkConstructor; + std::unique_ptr m_subspaceForJSSinkController; std::unique_ptr m_subspaceForJSSink; /*-- BUN --*/ diff --git a/src/javascript/jsc/generate-jssink.js b/src/javascript/jsc/generate-jssink.js index de5c5ec02..924b8f059 100644 --- a/src/javascript/jsc/generate-jssink.js +++ b/src/javascript/jsc/generate-jssink.js @@ -1,25 +1,24 @@ -const classes = [ "ArrayBufferSink" ]; +const classes = ["ArrayBufferSink"]; +const SINK_COUNT = 5; function names(name) { return { - constructor : `JS${name}Constructor`, - className : `JS${name}`, - controller : `JSReadable${name}Controller`, - controllerName : `Readable${name}Controller`, - prototypeName : `JS${name}Prototype`, - controllerPrototypeName : `JSReadable${name}ControllerPrototype`, + constructor: `JS${name}Constructor`, + className: `JS${name}`, + controller: `JSReadable${name}Controller`, + controllerName: `Readable${name}Controller`, + prototypeName: `JS${name}Prototype`, + controllerPrototypeName: `JSReadable${name}ControllerPrototype`, }; } function header() { function classTemplate(name) { - const {constructor, className, controller} = names(name); + const { constructor, className, controller } = names(name); - return `class ${ - constructor} final : public JSC::InternalFunction { + return `class ${constructor} final : public JSC::InternalFunction { public: using Base = JSC::InternalFunction; - static ${ - constructor}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype); + static ${constructor}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype); static constexpr SinkID Sink = SinkID::${name}; static constexpr unsigned StructureFlags = Base::StructureFlags; @@ -30,8 +29,7 @@ function header() { { if constexpr (mode == JSC::SubspaceAccess::Concurrently) return nullptr; - return WebCore::subspaceForImpl<${ - constructor}, WebCore::UseCustomHeapCellType::No>( + return WebCore::subspaceForImpl<${constructor}, WebCore::UseCustomHeapCellType::No>( vm, [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkConstructor.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkConstructor = WTFMove(space); }, @@ -50,8 +48,7 @@ function header() { static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); private: - ${ - constructor}(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) + ${constructor}(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) : Base(vm, structure, nativeFunction, nativeFunction) { @@ -60,22 +57,18 @@ function header() { void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype); }; - class ${ - className} final : public JSC::JSDestructibleObject { + class ${className} final : public JSC::JSDestructibleObject { public: using Base = JSC::JSDestructibleObject; - static ${ - className}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); - static constexpr SinkID Sink = SinkID::${ - name}; + static ${className}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); + static constexpr SinkID Sink = SinkID::${name}; DECLARE_EXPORT_INFO; template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) { if constexpr (mode == JSC::SubspaceAccess::Concurrently) return nullptr; - return WebCore::subspaceForImpl<${ - className}, WebCore::UseCustomHeapCellType::No>( + return WebCore::subspaceForImpl<${className}, WebCore::UseCustomHeapCellType::No>( vm, [](auto& spaces) { return spaces.m_clientSubspaceForJSSink.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSink = WTFMove(space); }, @@ -89,8 +82,7 @@ function header() { return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); } - ~${ - className}(); + ~${className}(); void* wrapped() const { return m_sinkPtr; } @@ -102,8 +94,7 @@ function header() { void* m_sinkPtr; - ${ - className}(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + ${className}(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) : Base(vm, structure) { m_sinkPtr = sinkPtr; @@ -112,22 +103,18 @@ function header() { void finishCreation(JSC::VM&); }; - class ${ - controller} final : public JSC::JSDestructibleObject { + class ${controller} final : public JSC::JSDestructibleObject { public: using Base = JSC::JSDestructibleObject; - static ${ - controller}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); - static constexpr SinkID Sink = SinkID::${ - name}; + static ${controller}* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr); + static constexpr SinkID Sink = SinkID::${name}; DECLARE_EXPORT_INFO; template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) { if constexpr (mode == JSC::SubspaceAccess::Concurrently) return nullptr; - return WebCore::subspaceForImpl<${ - controller}, WebCore::UseCustomHeapCellType::No>( + return WebCore::subspaceForImpl<${controller}, WebCore::UseCustomHeapCellType::No>( vm, [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkController.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkController = WTFMove(space); }, @@ -141,8 +128,7 @@ function header() { return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); } - ~${ - controller}(); + ~${controller}(); void* wrapped() const { return m_sinkPtr; } @@ -158,10 +144,9 @@ function header() { void* m_sinkPtr; mutable WriteBarrier m_onPull; mutable WriteBarrier m_onClose; - JSC::Weak m_weakReadableStream; + mutable JSC::Weak m_weakReadableStream; - ${ - controller}(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + ${controller}(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) : Base(vm, structure) { m_sinkPtr = sinkPtr; @@ -198,8 +183,9 @@ using namespace JSC; JSC_DECLARE_HOST_FUNCTION(functionStartDirectStream); `; - const bottom = - `JSObject* createJSSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WebCore::SinkID sinkID); + const bottom = ` +JSObject* createJSSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WebCore::SinkID sinkID); +JSObject* createJSSinkControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WebCore::SinkID sinkID); } // namespace WebCore `; @@ -263,6 +249,11 @@ async function implementation() { // #include "JavaScriptCore/JSTypedArrayViewPrototype.h" #include "JavaScriptCore/JSArrayBufferViewInlines.h" +#include "JSReadableStream.h" +#include "BunClientData.h" +#include "JavaScriptCore/Weak.h" +#include "JavaScriptCore/WeakInlines.h" + namespace WebCore { using namespace JSC; @@ -280,7 +271,7 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic JSC::JSValue onPull = callFrame->argument(1); JSC::JSValue onClose = callFrame->argument(2); if (!readableStream.isObject()) { - scope.throwException(callFrame, JSC::createTypeError(callFrame, "Expected ReadableStream"_s)) + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected ReadableStream"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } @@ -292,6 +283,9 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic onClose = JSC::jsUndefined(); } + JSC::JSFunction *onPullFunction = JSC::jsDynamicCast(onPull); + JSC::JSFunction *onCloseFunction = JSC::jsDynamicCast(onClose); + `; var templ = head; @@ -307,24 +301,23 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic templ += ` - ${isFirst ? "" : "else"} if (${controller}* ${ - name}Controller = JSC::jsDynamicCast<${ - controller}*>(callFrame->thisValue())) { + ${ + isFirst ? "" : "else" + } if (WebCore::${controller}* ${name}Controller = JSC::jsDynamicCast(callFrame->thisValue())) { if (${name}Controller->wrapped() == nullptr) { - scope.throwException(callFrame, JSC::createTypeError(callFrame, "Controller is already closed"_s)); + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } - ${name}Controller->start(globalObject, readableStream, onPull, onClose); + ${name}Controller->start(globalObject, readableStream, onPullFunction, onCloseFunction); } -} `; isFirst = false; } templ += ` else { - scope.throwException(callFrame, JSC::createTypeError(callFrame, "Unknown direct controller. This is a bug in Bun."_s)); + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Unknown direct controller. This is a bug in Bun."_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } @@ -343,8 +336,7 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic } = names(name); templ += ` -JSC_DEFINE_CUSTOM_GETTER(function${ - name}__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) +JSC_DEFINE_CUSTOM_GETTER(function${name}__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) { auto& vm = lexicalGlobalObject->vm(); Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); @@ -354,29 +346,50 @@ JSC_DEFINE_CUSTOM_GETTER(function${ JSC_DECLARE_HOST_FUNCTION(${controller}__close); -JSC_DEFINE_HOST_FUNCTION(${ - controller}__close, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame)) +JSC_DEFINE_HOST_FUNCTION(${controller}__close, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame)) { auto& vm = lexicalGlobalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); - ${controller}* controller = JSC::jsDynamicCast<${ - controller}*>(callFrame->thisValue()); - if (!${controller}) { - scope.throwException(callFrame, JSC::createTypeError(callFrame, "Expected ${ - controller}"_s)); + WebCore::${controller}* controller = JSC::jsDynamicCast(callFrame->thisValue()); + if (!controller) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected ${controller}"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } void *ptr = controller->wrapped(); if (ptr == nullptr) { - scope.throwException(callFrame, JSC::createTypeError(callFrame, "Controller is already closed"_s)); + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); return JSC::JSValue::encode(JSC::jsUndefined()); } controller->detach(); - ${name}__close(ptr, callFrame->argument(0)); + ${name}__close(lexicalGlobalObject, ptr); + return JSC::JSValue::encode(JSC::jsUndefined()); +} + +JSC_DECLARE_HOST_FUNCTION(${name}__doClose); +JSC_DEFINE_HOST_FUNCTION(${name}__doClose, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame)) +{ + + auto& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); + WebCore::${className}* sink = JSC::jsDynamicCast(callFrame->thisValue()); + if (!sink) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected ${name}"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + void *ptr = sink->wrapped(); + if (ptr == nullptr) { + scope.throwException(globalObject, JSC::createTypeError(globalObject, "Controller is already closed"_s)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + sink->detach(); + ${name}__close(lexicalGlobalObject, ptr); return JSC::JSValue::encode(JSC::jsUndefined()); } @@ -385,30 +398,20 @@ JSC_DEFINE_HOST_FUNCTION(${ static const HashTableValue JS${name}PrototypeTableValues[] = { - { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__close), (intptr_t)(0) } }, - { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__drain), (intptr_t)(1) } }, - { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__end), (intptr_t)(0) } }, - { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__start), (intptr_t)(1) } }, - { "write"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__write), (intptr_t)(1) } }, + { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__doClose), (intptr_t)(0) } }, + { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__drain), (intptr_t)(1) } }, + { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__end), (intptr_t)(0) } }, + { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__start), (intptr_t)(1) } }, + { "write"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__write), (intptr_t)(1) } }, }; static const HashTableValue ${controllerPrototypeName}TableValues[] = { - { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - controller}__close), (intptr_t)(0) } }, - { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__drain), (intptr_t)(1) } }, - { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__end), (intptr_t)(0) } }, - { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(function${ - controller}__start), (intptr_t)(1) } }, - { "write"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${ - name}__write), (intptr_t)(1) } }, + { "close"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${controller}__close), (intptr_t)(0) } }, + { "drain"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__drain), (intptr_t)(1) } }, + { "end"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__end), (intptr_t)(0) } }, + { "start"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__start), (intptr_t)(1) } }, + { "write"_s, static_cast(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast(${name}__write), (intptr_t)(1) } }, }; `; @@ -439,11 +442,9 @@ class ${prototypeName} final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; - static ${ - prototypeName}* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) + static ${prototypeName}* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) { - ${prototypeName}* ptr = new (NotNull, JSC::allocateCell<${ - prototypeName}>(vm)) ${prototypeName}(vm, globalObject, structure); + ${prototypeName}* ptr = new (NotNull, JSC::allocateCell<${prototypeName}>(vm)) ${prototypeName}(vm, globalObject, structure); ptr->finishCreation(vm, globalObject); return ptr; } @@ -469,23 +470,45 @@ private: }; STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${prototypeName}, ${prototypeName}::Base); -const ClassInfo ${prototypeName}::s_info = { "${ - name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${ - prototypeName}) }; -const ClassInfo ${className}::s_info = { "${ - name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${ - className}) }; -const ClassInfo ${constructor}::s_info = { "${ - name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${ - constructor}) }; +class ${controllerPrototypeName} final : public JSC::JSNonFinalObject { + public: + using Base = JSC::JSNonFinalObject; + + static ${controllerPrototypeName}* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) + { + ${controllerPrototypeName}* ptr = new (NotNull, JSC::allocateCell<${controllerPrototypeName}>(vm)) ${controllerPrototypeName}(vm, globalObject, structure); + ptr->finishCreation(vm, globalObject); + return ptr; + } + + DECLARE_INFO; + template + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + private: + ${controllerPrototypeName}(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) + : Base(vm, structure) + { + } + + void finishCreation(JSC::VM&, JSC::JSGlobalObject*); + }; + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${controllerPrototypeName}, ${controllerPrototypeName}::Base); + +const ClassInfo ${prototypeName}::s_info = { "${name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${prototypeName}) }; +const ClassInfo ${className}::s_info = { "${name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${className}) }; +const ClassInfo ${constructor}::s_info = { "${name}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${constructor}) }; -const ClassInfo ${controllerPrototypeName}::s_info = { "${ - controllerName}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${ - controllerPrototypeName}) }; -const ClassInfo ${controller}::s_info = { "${ - controllerName}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${ - controller}) }; +const ClassInfo ${controllerPrototypeName}::s_info = { "${controllerName}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${controllerPrototypeName}) }; +const ClassInfo ${controller}::s_info = { "${controllerName}"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${controller}) }; ${className}::~${className}() { @@ -507,29 +530,23 @@ ${controller}::~${controller}() templ += ` -${constructor}* ${ - constructor}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSObject* prototype) +${constructor}* ${constructor}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSObject* prototype) { - ${constructor}* ptr = new (NotNull, JSC::allocateCell<${ - constructor}>(vm)) ${constructor}(vm, structure, ${name}__construct); + ${constructor}* ptr = new (NotNull, JSC::allocateCell<${constructor}>(vm)) ${constructor}(vm, structure, ${name}__construct); ptr->finishCreation(vm, globalObject, prototype); return ptr; } -${className}* ${ - className}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr) +${className}* ${className}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr) { - ${className}* ptr = new (NotNull, JSC::allocateCell<${className}>(vm)) ${ - className}(vm, structure, sinkPtr); + ${className}* ptr = new (NotNull, JSC::allocateCell<${className}>(vm)) ${className}(vm, structure, sinkPtr); ptr->finishCreation(vm); return ptr; } -${controller}* ${ - controller}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr) +${controller}* ${controller}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr) { - ${controller}* ptr = new (NotNull, JSC::allocateCell<${controller}>(vm)) ${ - controller}(vm, structure, sinkPtr); + ${controller}* ptr = new (NotNull, JSC::allocateCell<${controller}>(vm)) ${controller}(vm, structure, sinkPtr); ptr->finishCreation(vm); return ptr; } @@ -541,8 +558,7 @@ void ${constructor}::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, J initializeProperties(vm, globalObject, prototype); } -JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES ${ - constructor}::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { +JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES ${constructor}::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { return ${name}__construct(globalObject, callFrame); } @@ -558,16 +574,14 @@ void ${constructor}::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObj void ${prototypeName}::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) { Base::finishCreation(vm); - reifyStaticProperties(vm, ${className}::info(), ${ - className}PrototypeTableValues, *this); + reifyStaticProperties(vm, ${className}::info(), ${className}PrototypeTableValues, *this); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); } void ${controllerPrototypeName}::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) { Base::finishCreation(vm); - reifyStaticProperties(vm, ${controller}::info(), ${ - controller}PrototypeTableValues, *this); + reifyStaticProperties(vm, ${controller}::info(), ${controller}PrototypeTableValues, *this); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); } @@ -610,7 +624,7 @@ void ${controller}::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) template void ${controller}::visitChildrenImpl(JSCell* cell, Visitor& visitor) { - auto* thisObject = jsCast<${controller}*>(cell); + ${controller}* thisObject = jsCast<${controller}*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); Base::visitChildren(thisObject, visitor); visitor.append(thisObject->m_onPull); @@ -621,6 +635,12 @@ void ${controller}::visitChildrenImpl(JSCell* cell, Visitor& visitor) DEFINE_VISIT_CHILDREN(${controller}); +void ${controller}::start(JSC::JSGlobalObject *globalObject, JSC::JSValue readableStream, JSC::JSFunction *onPull, JSC::JSFunction *onClose) { + this->m_weakReadableStream = JSC::Weak(readableStream.getObject()); + this->m_onPull.set(globalObject->vm(), this, onPull); + this->m_onClose.set(globalObject->vm(), this, onClose); +} + void ${className}::destroy(JSCell* cell) { static_cast<${className}*>(cell)->${className}::~${className}(); @@ -644,8 +664,7 @@ void ${controller}::destroy(JSCell* cell) for (let name of classes) { templ += ` case ${name}: - return JS${name}Prototype::create(vm, globalObject, JS${ - name}Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); + return JS${name}Prototype::create(vm, globalObject, JS${name}Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); `; } templ += ` @@ -654,6 +673,24 @@ default: } }`; + templ += ` +JSObject* createJSSinkControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, SinkID sinkID) +{ + switch (sinkID) { + `; + for (let name of classes) { + const { controllerPrototypeName } = names(name); + templ += ` + case ${name}: + return ${controllerPrototypeName}::create(vm, globalObject, ${controllerPrototypeName}::createStructure(vm, globalObject, globalObject->objectPrototype())); +`; + } + templ += ` +default: + RELEASE_ASSERT_NOT_REACHED(); + } +}`; + templ += footer; for (let name of classes) { @@ -666,54 +703,56 @@ default: } = names(name); templ += ` -extern "C" JSC__JSValue ${ - name}__createObject(JSC__JSGlobalObject* arg0, void* sinkPtr) +extern "C" JSC__JSValue ${name}__createObject(JSC__JSGlobalObject* arg0, void* sinkPtr) { auto& vm = arg0->vm(); Zig::GlobalObject* globalObject = reinterpret_cast(arg0); JSC::JSValue prototype = globalObject->${name}Prototype(); - JSC::Structure* structure = WebCore::JS${ - name}::createStructure(vm, globalObject, prototype); - return JSC::JSValue::encode(WebCore::JS${ - name}::create(vm, globalObject, structure, sinkPtr)); + JSC::Structure* structure = WebCore::JS${name}::createStructure(vm, globalObject, prototype); + return JSC::JSValue::encode(WebCore::JS${name}::create(vm, globalObject, structure, sinkPtr)); } -extern "C" void* ${ - name}__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1) +extern "C" void* ${name}__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1) { JSC::VM& vm = WebCore::getVM(arg0); - if (auto* sink = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) + if (auto* sink = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) return sink->wrapped(); + if (auto* controller = JSC::jsDynamicCast(JSC::JSValue::decode(JSValue1))) + return controller->wrapped(); + return nullptr; } -extern "C" JSC__JSValue ${ - name}__assignToStream(JSC__JSGlobalObject* arg0, JSC__JSValue stream, void* sinkPtr, int32_t *bunNativeTag, void** bunNativePtr) +extern "C" JSC__JSValue ${name}__assignToStream(JSC__JSGlobalObject* arg0, JSC__JSValue stream, void* sinkPtr, int32_t *bunNativeTag, void** bunNativePtr) { auto& vm = arg0->vm(); Zig::GlobalObject* globalObject = reinterpret_cast(arg0); - JSC::JSValue prototype = globalObject->${controllerPrototypeName}(); - JSC::Structure* structure = WebCore::${ - controller}::createStructure(vm, globalObject, prototype); - ${controller} *controller = WebCore::${ - controller}::create(vm, globalObject, structure, sinkPtr); - auto &clientData = WebCore:;getClientData(vm); + auto clientData = WebCore::clientData(vm); JSC::JSObject *readableStream = JSC::JSValue::decode(stream).getObject(); - if (readableStream->get(vm, clientData.builtinNames().bunNativeTag()).isUndefined()) { - + if (JSC::JSValue tag = readableStream->get(globalObject, clientData->builtinNames().bunNativeTypePrivateName())) { + if (tag.isInt32()) { + int32_t tagNumber = tag.toInt32(arg0); + if (tagNumber > 0 && tagNumber < 5) { + *bunNativeTag = tagNumber; + *bunNativePtr = reinterpret_cast(bitwise_cast(readableStream->get(globalObject, clientData->builtinNames().bunNativePtrPrivateName()).asNumber())); + return JSC::JSValue::encode(JSC::jsNull()); + } + } } + JSC::JSValue prototype = globalObject->${controllerPrototypeName}(); + JSC::Structure* structure = WebCore::${controller}::createStructure(vm, globalObject, prototype); + WebCore::${controller} *controller = WebCore::${controller}::create(vm, globalObject, structure, sinkPtr); - JSC::JSObject *function = globalObject->getDirect(vm, clientData.builtinNames()->assignDirectStreamPrivateName()).getObject(); + JSC::JSObject *function = globalObject->getDirect(vm, clientData->builtinNames().assignDirectStreamPrivateName()).getObject(); auto callData = JSC::getCallData(function); - MarkedArgumentBuffer arguments; - args.append(JSC::JSValue::encode(stream)); - args.append(JSC::JSValue::encode(controller)); + JSC::MarkedArgumentBuffer arguments; + arguments.append(JSC::JSValue::decode(stream)); + arguments.append(controller); - auto result = JSC::call(arg0, function, callData, jsUndefined(), arguments); + auto result = JSC::call(arg0, function, callData, JSC::jsUndefined(), arguments); return JSC::JSValue::encode(result); } @@ -725,5 +764,7 @@ extern "C" JSC__JSValue ${ } await Bun.write(import.meta.dir + "/bindings/JSSink.h", header()); -await Bun.write(import.meta.dir + "/bindings/JSSink.cpp", - await implementation()); +await Bun.write( + import.meta.dir + "/bindings/JSSink.cpp", + await implementation() +); diff --git a/src/javascript/jsc/webcore/streams.zig b/src/javascript/jsc/webcore/streams.zig index f36563ce7..e61e599ca 100644 --- a/src/javascript/jsc/webcore/streams.zig +++ b/src/javascript/jsc/webcore/streams.zig @@ -266,7 +266,7 @@ pub const StreamStart = union(Tag) { .ArrayBufferSink => { var as_uint8array = false; var stream = false; - var chunk_size: JSC.Blob.SizeType = 0; + var chunk_size: JSC.WebCore.Blob.SizeType = 0; var empty = true; if (value.get(globalThis, "asUint8Array")) |as_array| { @@ -279,9 +279,9 @@ pub const StreamStart = union(Tag) { empty = false; } - if (value.get(globalThis, "chunkSize")) |chunkSize| { + if (value.get(globalThis, "highwaterMark")) |chunkSize| { empty = false; - chunk_size = @intCast(JSC.Blob.SizeType, @maximum(0, @truncate(i51, chunkSize.toInt64()))); + chunk_size = @intCast(JSC.WebCore.Blob.SizeType, @maximum(0, @truncate(i51, chunkSize.toInt64()))); } if (!empty) { @@ -831,7 +831,7 @@ pub const ArrayBufferSink = struct { false => JSC.ArrayBuffer.create(globalThis, this.bytes.slice(), .ArrayBuffer), }; this.bytes.len = 0; - return value; + return .{ .result = value }; } return .{ .result = JSValue.jsUndefined() }; @@ -938,7 +938,13 @@ pub const ArrayBufferSink = struct { this.bytes = bun.ByteList.init(""); this.done = true; this.signal.close(null); - return .{ .result = ArrayBuffer.fromBytes(list.toOwnedSlice(), .ArrayBuffer) }; + return .{ .result = ArrayBuffer.fromBytes( + list.toOwnedSlice(), + if (this.as_uint8array) + .Uint8Array + else + .ArrayBuffer, + ) }; } pub fn sink(this: *ArrayBufferSink) Sink { @@ -1079,30 +1085,13 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { return this.sink.writeLatin1(.{ .temporary = str.slice() }).toJS(globalThis); } - pub fn close(globalThis: *JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue { - JSC.markBinding(); - var this = @ptrCast(*ThisSink, @alignCast(std.meta.alignment(ThisSink), fromJS(globalThis, callframe.this()) orelse { - const err = JSC.toTypeError(JSC.Node.ErrorCode.ERR_INVALID_THIS, "Expected Sink", .{}, globalThis); - globalThis.vm().throwError(globalThis, err); - return JSC.JSValue.jsUndefined(); - })); - - if (comptime @hasDecl(SinkType, "getPendingError")) { - if (this.sink.getPendingError()) |err| { - globalThis.vm().throwError(globalThis, err); - return JSC.JSValue.jsUndefined(); - } - } - - return this.sink.end(null).toJS(globalThis); - } - pub fn closeWithError(globalThis: *JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue { + pub fn close(globalThis: *JSGlobalObject, sink_ptr: ?*anyopaque) callconv(.C) JSValue { JSC.markBinding(); - var this = @ptrCast(*ThisSink, @alignCast(std.meta.alignment(ThisSink), fromJS(globalThis, callframe.this()) orelse { + var this = @ptrCast(*ThisSink, @alignCast(std.meta.alignment(ThisSink), sink_ptr) orelse { const err = JSC.toTypeError(JSC.Node.ErrorCode.ERR_INVALID_THIS, "Expected Sink", .{}, globalThis); globalThis.vm().throwError(globalThis, err); return JSC.JSValue.jsUndefined(); - })); + }); if (comptime @hasDecl(SinkType, "getPendingError")) { if (this.sink.getPendingError()) |err| { @@ -1111,12 +1100,6 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { } } - if (callframe.argumentsCount() == 0) { - const err = JSC.toTypeError(JSC.Node.ErrorCode.ERR_MISSING_ARGS, "closeWithError() expects an error", .{}, globalThis); - globalThis.vm().throwError(globalThis, err); - return JSC.JSValue.jsUndefined(); - } - return this.sink.end(null).toJS(globalThis); } @@ -1137,7 +1120,7 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { } if (comptime @hasDecl(SinkType, "drainFromJS")) { - return this.sink.drainFromJS(globalThis); + return this.sink.drainFromJS(globalThis).result; } return this.sink.drain().toJS(globalThis); @@ -1203,7 +1186,6 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { .@"finalize" = finalize, .@"write" = write, .@"close" = close, - .@"closeWithError" = closeWithError, .@"drain" = drain, .@"start" = start, .@"end" = end, @@ -1215,11 +1197,10 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { @export(finalize, .{ .name = Export[0].symbol_name }); @export(write, .{ .name = Export[1].symbol_name }); @export(close, .{ .name = Export[2].symbol_name }); - @export(closeWithError, .{ .name = Export[3].symbol_name }); - @export(drain, .{ .name = Export[4].symbol_name }); - @export(start, .{ .name = Export[5].symbol_name }); - @export(end, .{ .name = Export[6].symbol_name }); - @export(construct, .{ .name = Export[7].symbol_name }); + @export(drain, .{ .name = Export[3].symbol_name }); + @export(start, .{ .name = Export[4].symbol_name }); + @export(end, .{ .name = Export[5].symbol_name }); + @export(construct, .{ .name = Export[6].symbol_name }); } } -- cgit v1.2.3