From cfcef4be538f6e37d34cec724e6ce85d601bd472 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 26 Dec 2024 17:20:41 -0800 Subject: [PATCH] wip --- src/bun.js/bindings/BunReadableStream.cpp | 74 ++++++++++++++++--- src/bun.js/bindings/BunReadableStream.h | 2 +- .../BunReadableStreamDefaultController.cpp | 2 +- .../BunReadableStreamPipeToOperation.h | 52 ++++++++++--- 4 files changed, 110 insertions(+), 20 deletions(-) diff --git a/src/bun.js/bindings/BunReadableStream.cpp b/src/bun.js/bindings/BunReadableStream.cpp index 18c0c42eb3..dfc83fc53b 100644 --- a/src/bun.js/bindings/BunReadableStream.cpp +++ b/src/bun.js/bindings/BunReadableStream.cpp @@ -150,10 +150,10 @@ JSPromise* JSReadableStream::pipeTo(VM& vm, JSGlobalObject* globalObject, JSObje return nullptr; } - bool preventClose = false; - bool preventAbort = false; - bool preventCancel = false; - JSObject* signal = nullptr; + bool preventClose [[maybe_unused]] = false; + bool preventAbort [[maybe_unused]] = false; + bool preventCancel [[maybe_unused]] = false; + JSObject* signal [[maybe_unused]] = nullptr; if (!options.isUndefined()) { JSObject* optionsObject = options.toObject(globalObject); @@ -192,11 +192,12 @@ JSPromise* JSReadableStream::pipeTo(VM& vm, JSGlobalObject* globalObject, JSObje auto* reader = JSReadableStreamDefaultReader::create(vm, globalObject, streams.structure(domGlobalObject), this); m_reader.set(vm, this, reader); - auto* writer = JSWritableStreamDefaultWriter::create(vm, streams.structure(domGlobalObject), writableStream); + auto* writer [[maybe_unused]] = JSWritableStreamDefaultWriter::create(vm, streams.structure(domGlobalObject), writableStream); JSPromise* promise = JSPromise::create(vm, globalObject->promiseStructure()); - auto* pipeToOperation = PipeToOperation::create(vm, globalObject, reader, writer, preventClose, preventAbort, preventCancel, signal, promise); - pipeToOperation->perform(vm, globalObject); + // auto* pipeToOperation = PipeToOperation::create(vm, globalObject, reader, writer, preventClose, preventAbort, preventCancel, signal, promise); + // pipeToOperation->perform(vm, globalObject); + // promise->reject(globalObject, ) return promise; } @@ -254,8 +255,8 @@ void JSReadableStream::tee(VM& vm, JSGlobalObject* globalObject, JSValue& firstS Structure* streamStructure = streams.structure(domGlobalObject); auto* stream1 = JSReadableStream::create(vm, globalObject, streamStructure); auto* stream2 = JSReadableStream::create(vm, globalObject, streamStructure); - stream1->error(error); - stream2->error(error); + stream1->error(globalObject, error); + stream2->error(globalObject, error); firstStream = stream1; secondStream = stream2; return; @@ -293,4 +294,59 @@ void JSReadableStream::visitChildrenImpl(JSCell* cell, Visitor& visitor) DEFINE_VISIT_CHILDREN(JSReadableStream); +bool JSReadableStream::isLocked() const +{ + return locked(); +} + +JSReadableStream* JSReadableStream::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) +{ + JSReadableStream* stream = new (NotNull, allocateCell(vm)) JSReadableStream(vm, structure); + stream->finishCreation(vm); + return stream; +} + +JSReadableStream::JSReadableStream(VM& vm, Structure* structure) + : Base(vm, structure) +{ +} + +void JSReadableStream::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + m_state = State::Readable; + m_disturbed = false; +} + +Structure* JSReadableStream::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) +{ + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); +} + +void JSReadableStream::close(JSGlobalObject* globalObject) +{ + m_state = State::Closed; + if (auto* reader = this->reader()) + reader->closedPromise()->resolve(globalObject, jsUndefined()); +} + +void JSReadableStream::error(JSGlobalObject* globalObject, JSValue error) +{ + VM& vm = globalObject->vm(); + m_state = State::Errored; + m_storedError.set(vm, this, error.toObject(globalObject)); + if (auto* reader = this->reader()) + reader->closedPromise()->reject(globalObject, error); +} + +void JSReadableStream::setReader(JSReadableStreamDefaultReader* reader) +{ + if (reader) { + VM& vm = reader->vm(); + m_reader.set(vm, this, reader); + } else { + m_reader.clear(); + } +} + } diff --git a/src/bun.js/bindings/BunReadableStream.h b/src/bun.js/bindings/BunReadableStream.h index 82e8b555d2..d342157683 100644 --- a/src/bun.js/bindings/BunReadableStream.h +++ b/src/bun.js/bindings/BunReadableStream.h @@ -54,7 +54,7 @@ public: JSC::JSValue pipeThrough(VM&, JSGlobalObject*, JSObject* transform, JSValue options = jsUndefined()); void tee(VM&, JSGlobalObject*, JSValue& firstStream, JSValue& secondStream); - void error(JSValue); + void error(JSGlobalObject*, JSValue); void close(JSGlobalObject*); void setReader(JSReadableStreamDefaultReader*); diff --git a/src/bun.js/bindings/BunReadableStreamDefaultController.cpp b/src/bun.js/bindings/BunReadableStreamDefaultController.cpp index 1d09fcb868..171206e044 100644 --- a/src/bun.js/bindings/BunReadableStreamDefaultController.cpp +++ b/src/bun.js/bindings/BunReadableStreamDefaultController.cpp @@ -129,7 +129,7 @@ void JSReadableStreamDefaultController::error(VM& vm, JSGlobalObject* globalObje m_cancelAlgorithm.clear(); m_strategySizeAlgorithm.clear(); - stream->error(error); + stream->error(globalObject, error); } void JSReadableStreamDefaultController::close(VM& vm, JSGlobalObject* globalObject) diff --git a/src/bun.js/bindings/BunReadableStreamPipeToOperation.h b/src/bun.js/bindings/BunReadableStreamPipeToOperation.h index a4428dd3db..9319009f0b 100644 --- a/src/bun.js/bindings/BunReadableStreamPipeToOperation.h +++ b/src/bun.js/bindings/BunReadableStreamPipeToOperation.h @@ -1,3 +1,4 @@ +#pragma once #include "root.h" @@ -8,15 +9,48 @@ namespace Bun { class JSReadableStreamDefaultReader; class JSWritableStreamDefaultWriter; -class PipeToOperation : public JSC::JSInternalFieldObjectImpl<5> { -public: - static constexpr unsigned numberOfInternalFields = 5; - using Base = JSC::JSInternalFieldObjectImpl; - static PipeToOperation* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, - JSReadableStreamDefaultReader* reader, JSWritableStreamDefaultWriter* writer, - bool preventClose, bool preventAbort, bool preventCancel, JSC::JSObject* signal, JSC::JSPromise* promise); +// class PipeToOperation : public JSC::JSInternalFieldObjectImpl<7> { +// public: +// static constexpr unsigned numberOfInternalFields = 7; +// using Base = JSC::JSInternalFieldObjectImpl; +// static PipeToOperation* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, +// JSC::JSObject* reader, JSC::JSObject* writer, +// bool preventClose, bool preventAbort, bool preventCancel, JSC::JSObject* signal, JSC::JSPromise* promise) +// { +// PipeToOperation* operation = new (NotNull, JSC::allocateCell(vm)) PipeToOperation(vm, globalObject); +// operation->finishCreation(vm, reader, writer, preventClose, preventAbort, preventCancel, signal, promise); +// return operation; +// } - void perform(JSC::VM& vm, JSC::JSGlobalObject* globalObject) {} -}; +// void perform(JSC::VM& vm, JSC::JSGlobalObject* globalObject) {} + +// bool preventClose { false }; +// bool preventAbort { false }; +// bool preventCancel { false }; + +// mutable JSC::WriteBarrier reader; +// mutable JSC::WriteBarrier writer; +// mutable JSC::WriteBarrier signal; +// mutable JSC::WriteBarrier promise; + +// private: +// PipeToOperation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +// : Base(vm, globalObject) +// { +// } + +// void finishCreation(JSC::VM& vm, JSC::JSObject* reader, JSC::JSObject* writer, +// bool preventClose, bool preventAbort, bool preventCancel, JSC::JSObject* signal, JSC::JSPromise* promise) +// { +// Base::finishCreation(vm); +// internalField(0).set(vm, this, reader); +// internalField(1).set(vm, this, writer); +// internalField(2).set(vm, this, JSC::jsBoolean(preventClose)); +// internalField(3).set(vm, this, JSC::jsBoolean(preventAbort)); +// internalField(4).set(vm, this, JSC::jsBoolean(preventCancel)); +// internalField(5).set(vm, this, signal ? signal : JSC::jsUndefined()); +// internalField(6).set(vm, this, promise); +// } +// }; }