More files

This commit is contained in:
Jarred Sumner
2024-12-19 20:04:40 -08:00
parent 799770680d
commit 5fc5baaddd
6 changed files with 341 additions and 209 deletions

View File

@@ -1,91 +1,19 @@
#include "ErrorCode+List.h"
#include "root.h"
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/JSObjectInlines.h>
#include "JavaScriptCore/JSCast.h"
#include <JavaScriptCore/JSPromise.h>
#include <JavaScriptCore/JSArray.h>
#include "BunReadableStreamDefaultReader.h"
#include "BunReadableStream.h"
#include <JavaScriptCore/WriteBarrier.h>
#include "BunReadableStreamDefaultController.h"
#include "BunStreamInlines.h"
#include "BunTeeState.h"
#include "JSAbortSignal.h"
#include "BunReadableStreamDefaultController.h"
#include <JavaScriptCore/Completion.h>
#include "BunReadableStreamDefaultReader.h"
#include "ErrorCode.h"
#include <JavaScriptCore/JSPromise.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSObjectInlines.h>
namespace Bun {
using namespace JSC;
class JSReadableStreamDefaultReaderPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSReadableStreamDefaultReaderPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
{
JSReadableStreamDefaultReaderPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReaderPrototype>(vm)) JSReadableStreamDefaultReaderPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultReaderPrototype, Base);
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:
JSReadableStreamDefaultReaderPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
: Base(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
// JSReadableStreamDefaultReader.cpp
static JSC_DECLARE_CUSTOM_GETTER(readableStreamDefaultReaderClosedGetter);
static JSC_DECLARE_CUSTOM_GETTER(readableStreamDefaultReaderReadyGetter);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderRead);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderReleaseLock);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderCancel);
const ClassInfo JSReadableStreamDefaultReader::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReader) };
static const HashTableValue JSReadableStreamDefaultReaderPrototypeTableValues[] = {
{ "closed"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor),
NoIntrinsic,
{ HashTableValue::GetterSetterType, readableStreamDefaultReaderClosedGetter, nullptr } },
{ "ready"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor),
NoIntrinsic,
{ HashTableValue::GetterSetterType, readableStreamDefaultReaderReadyGetter, nullptr } },
{ "read"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderRead, 0 } },
{ "releaseLock"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderReleaseLock, 0 } },
{ "cancel"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderCancel, 1 } },
};
const ClassInfo JSReadableStreamDefaultReaderPrototype::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderPrototype) };
JSReadableStreamDefaultReader* JSReadableStreamDefaultReader::create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure, JSReadableStream* stream)
{
JSReadableStreamDefaultReader* reader = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReader>(vm)) JSReadableStreamDefaultReader(vm, structure);
@@ -135,13 +63,6 @@ void JSReadableStreamDefaultReader::releaseLock()
detach();
}
void JSReadableStreamDefaultReaderPrototype::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSReadableStreamDefaultReader::info(), JSReadableStreamDefaultReaderPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
JSPromise* JSReadableStreamDefaultReader::read(JSC::VM& vm, JSGlobalObject* globalObject)
{
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -162,134 +83,27 @@ JSPromise* JSReadableStreamDefaultReader::read(JSC::VM& vm, JSGlobalObject* glob
return promise;
}
// JS Bindings Implementation
JSC_DEFINE_HOST_FUNCTION(readableStreamDefaultReaderRead, (JSGlobalObject * globalObject, CallFrame* callFrame))
Structure* JSReadableStreamDefaultReader::structure(JSC::VM& vm, JSGlobalObject* globalObject)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(callFrame->thisValue());
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.read called on incompatible object"_s));
return {};
}
JSC::JSPromise* promise = reader->read(vm, globalObject);
RETURN_IF_EXCEPTION(scope, {});
return JSC::JSValue::encode(promise);
return globalObject->readableStreamDefaultReaderStructure();
}
class JSReadableStreamDefaultReaderConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static JSReadableStreamDefaultReaderConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSReadableStreamDefaultReaderPrototype* prototype)
{
JSReadableStreamDefaultReaderConstructor* constructor = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReaderConstructor>(vm)) JSReadableStreamDefaultReaderConstructor(vm, structure);
constructor->finishCreation(vm, globalObject, prototype);
return constructor;
}
DECLARE_INFO;
template<typename, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
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::InternalFunctionType, StructureFlags), info());
}
static constexpr unsigned StructureFlags = Base::StructureFlags;
static constexpr bool needsDestruction = false;
private:
JSReadableStreamDefaultReaderConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, call, construct)
{
}
void finishCreation(JSC::VM&, JSC::JSGlobalObject*, JSReadableStreamDefaultReaderPrototype*);
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES call(JSC::JSGlobalObject*, JSC::CallFrame*);
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*);
};
// Implementation
const ClassInfo JSReadableStreamDefaultReaderConstructor::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderConstructor) };
void JSReadableStreamDefaultReaderConstructor::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSReadableStreamDefaultReaderPrototype* prototype)
JSObject* JSReadableStreamDefaultReader::prototype(JSC::VM& vm, JSGlobalObject* globalObject)
{
Base::finishCreation(vm, 1, "ReadableStreamDefaultReader"_s, PropertyAdditionMode::WithStructureTransition);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
ASSERT(inherits(info()));
return globalObject->readableStreamDefaultReaderPrototype();
}
JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSReadableStreamDefaultReaderConstructor::call(JSC::JSGlobalObject* globalObject, JSC::CallFrame*)
JSObject* JSReadableStreamDefaultReader::constructor(JSC::VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Bun::throwError(globalObject, scope, Bun::ErrorCode::ERR_ILLEGAL_CONSTRUCTOR, "ReadableStreamDefaultReader constructor cannot be called as a function"_s);
return {};
return globalObject->readableStreamDefaultReaderConstructor();
}
JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSReadableStreamDefaultReaderConstructor::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
template<typename CellType, SubspaceAccess mode>
GCClient::IsoSubspace* JSReadableStreamDefaultReader::subspaceFor(VM& vm)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (callFrame->argumentCount() < 1) {
return throwVMTypeError(globalObject, scope, "ReadableStreamDefaultReader constructor requires a ReadableStream argument"_s);
}
JSValue streamValue = callFrame->uncheckedArgument(0);
JSReadableStream* stream = jsDynamicCast<JSReadableStream*>(streamValue);
if (!stream) {
return throwVMTypeError(globalObject, scope, "ReadableStreamDefaultReader constructor argument must be a ReadableStream"_s);
}
// Check if stream is already locked
if (stream->isLocked()) {
return throwVMTypeError(globalObject, scope, "Cannot construct a ReadableStreamDefaultReader for a locked ReadableStream"_s);
}
JSC::JSObject* newTarget = callFrame->newTarget().getObject();
JSC::JSObject* constructor = callFrame->jsCallee();
auto* structure = defaultGlobalObject(globalObject)->readableStreamDefaultReaderStructure();
// TODO: double-check this.
if (!(!newTarget || newTarget == constructor)) {
if (newTarget) {
structure = JSC::InternalFunction::createSubclassStructure(getFunctionRealm(globalObject, newTarget), newTarget, structure);
} else {
structure = JSC::InternalFunction::createSubclassStructure(globalObject, constructor, structure);
}
}
RETURN_IF_EXCEPTION(scope, {});
JSReadableStreamDefaultReader* reader = JSReadableStreamDefaultReader::create(vm, globalObject, structure, stream);
RETURN_IF_EXCEPTION(scope, {});
// Lock the stream to this reader
stream->setReader(reader);
// Set up initial ready state
if (stream->isDisturbed() || stream->state() == JSReadableStream::State::Errored) {
JSValue error = stream->storedError();
if (!error)
error = jsUndefined();
reader->readyPromise()->reject(globalObject, error);
} else {
reader->readyPromise()->fulfillWithNonPromise(globalObject, jsUndefined());
}
RELEASE_AND_RETURN(scope, JSValue::encode(reader));
if constexpr (mode == SubspaceAccess::Concurrently)
return nullptr;
return &vm.plainObjectSpace();
}
}
} // namespace Bun

View File

@@ -1,12 +1,11 @@
#include "root.h"
#pragma once
#include "root.h"
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/JSObjectInlines.h>
#include "JavaScriptCore/JSCast.h"
#include <JavaScriptCore/JSPromise.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/WriteBarrier.h>
#include <JavaScriptCore/Completion.h>
namespace Bun {
@@ -33,7 +32,12 @@ public:
DECLARE_VISIT_CHILDREN;
template<typename CellType, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm);
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return &vm.plainObjectSpace();
}
// Public API for C++ usage
JSC::JSPromise* readyPromise() { return m_readyPromise.get(); }
@@ -65,4 +69,4 @@ private:
JSC::WriteBarrier<JSC::JSArray> m_readRequests;
};
}
} // namespace Bun

View File

@@ -0,0 +1,90 @@
#include "BunReadableStreamDefaultReaderConstructor.h"
#include "BunReadableStreamDefaultReader.h"
#include "BunReadableStream.h"
#include "ErrorCode.h"
#include <JavaScriptCore/JSObjectInlines.h>
namespace Bun {
using namespace JSC;
const ClassInfo JSReadableStreamDefaultReaderConstructor::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderConstructor) };
JSReadableStreamDefaultReaderConstructor* JSReadableStreamDefaultReaderConstructor::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSReadableStreamDefaultReaderPrototype* prototype)
{
JSReadableStreamDefaultReaderConstructor* constructor = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReaderConstructor>(vm)) JSReadableStreamDefaultReaderConstructor(vm, structure);
constructor->finishCreation(vm, globalObject, prototype);
return constructor;
}
void JSReadableStreamDefaultReaderConstructor::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSReadableStreamDefaultReaderPrototype* prototype)
{
Base::finishCreation(vm, 1, "ReadableStreamDefaultReader"_s, PropertyAdditionMode::WithStructureTransition);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
ASSERT(inherits(info()));
}
JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSReadableStreamDefaultReaderConstructor::call(JSC::JSGlobalObject* globalObject, JSC::CallFrame*)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Bun::throwError(globalObject, scope, Bun::ErrorCode::ERR_ILLEGAL_CONSTRUCTOR, "ReadableStreamDefaultReader constructor cannot be called as a function"_s);
return {};
}
JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSReadableStreamDefaultReaderConstructor::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (callFrame->argumentCount() < 1) {
return throwVMTypeError(globalObject, scope, "ReadableStreamDefaultReader constructor requires a ReadableStream argument"_s);
}
JSValue streamValue = callFrame->uncheckedArgument(0);
JSReadableStream* stream = jsDynamicCast<JSReadableStream*>(streamValue);
if (!stream) {
return throwVMTypeError(globalObject, scope, "ReadableStreamDefaultReader constructor argument must be a ReadableStream"_s);
}
// Check if stream is already locked
if (stream->isLocked()) {
return throwVMTypeError(globalObject, scope, "Cannot construct a ReadableStreamDefaultReader for a locked ReadableStream"_s);
}
JSC::JSObject* newTarget = callFrame->newTarget().getObject();
JSC::JSObject* constructor = callFrame->jsCallee();
auto* structure = defaultGlobalObject(globalObject)->readableStreamDefaultReaderStructure();
// TODO: double-check this.
if (!(!newTarget || newTarget == constructor)) {
if (newTarget) {
structure = JSC::InternalFunction::createSubclassStructure(getFunctionRealm(globalObject, newTarget), newTarget, structure);
} else {
structure = JSC::InternalFunction::createSubclassStructure(globalObject, constructor, structure);
}
}
RETURN_IF_EXCEPTION(scope, {});
JSReadableStreamDefaultReader* reader = JSReadableStreamDefaultReader::create(vm, globalObject, structure, stream);
RETURN_IF_EXCEPTION(scope, {});
// Lock the stream to this reader
stream->setReader(reader);
// Set up initial ready state
if (stream->isDisturbed() || stream->state() == JSReadableStream::State::Errored) {
JSValue error = stream->storedError();
if (!error)
error = jsUndefined();
reader->readyPromise()->reject(globalObject, error);
} else {
reader->readyPromise()->fulfillWithNonPromise(globalObject, jsUndefined());
}
RELEASE_AND_RETURN(scope, JSValue::encode(reader));
}
} // namespace Bun

View File

@@ -0,0 +1,48 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/InternalFunction.h>
namespace Bun {
using namespace JSC;
class JSReadableStreamDefaultReaderPrototype;
class JSReadableStreamDefaultReaderConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static JSReadableStreamDefaultReaderConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSReadableStreamDefaultReaderPrototype* prototype);
DECLARE_INFO;
template<typename, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
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::InternalFunctionType, StructureFlags), info());
}
static constexpr unsigned StructureFlags = Base::StructureFlags;
static constexpr bool needsDestruction = false;
private:
JSReadableStreamDefaultReaderConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, call, construct)
{
}
void finishCreation(JSC::VM&, JSC::JSGlobalObject*, JSReadableStreamDefaultReaderPrototype*);
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES call(JSC::JSGlobalObject*, JSC::CallFrame*);
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*);
};
} // namespace Bun

View File

@@ -0,0 +1,136 @@
#include "BunReadableStreamDefaultReaderPrototype.h"
#include "BunReadableStreamDefaultReader.h"
#include "BunReadableStream.h"
#include <JavaScriptCore/JSPromise.h>
#include <JavaScriptCore/JSObjectInlines.h>
namespace Bun {
using namespace JSC;
static JSC_DECLARE_CUSTOM_GETTER(readableStreamDefaultReaderClosedGetter);
static JSC_DECLARE_CUSTOM_GETTER(readableStreamDefaultReaderReadyGetter);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderRead);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderReleaseLock);
static JSC_DECLARE_HOST_FUNCTION(readableStreamDefaultReaderCancel);
const ClassInfo JSReadableStreamDefaultReaderPrototype::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderPrototype) };
static const HashTableValue JSReadableStreamDefaultReaderPrototypeTableValues[] = {
{ "closed"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor),
NoIntrinsic,
{ HashTableValue::GetterSetterType, readableStreamDefaultReaderClosedGetter, nullptr } },
{ "ready"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor),
NoIntrinsic,
{ HashTableValue::GetterSetterType, readableStreamDefaultReaderReadyGetter, nullptr } },
{ "read"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderRead, 0 } },
{ "releaseLock"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderReleaseLock, 0 } },
{ "cancel"_s,
static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function),
NoIntrinsic,
{ HashTableValue::NativeFunctionType, readableStreamDefaultReaderCancel, 1 } },
};
JSReadableStreamDefaultReaderPrototype* JSReadableStreamDefaultReaderPrototype::create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
{
JSReadableStreamDefaultReaderPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReaderPrototype>(vm)) JSReadableStreamDefaultReaderPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
void JSReadableStreamDefaultReaderPrototype::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSReadableStreamDefaultReader::info(), JSReadableStreamDefaultReaderPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
// JS Bindings Implementation
JSC_DEFINE_HOST_FUNCTION(readableStreamDefaultReaderRead, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(callFrame->thisValue());
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.read called on incompatible object"_s));
return {};
}
JSC::JSPromise* promise = reader->read(vm, globalObject);
RETURN_IF_EXCEPTION(scope, {});
return JSC::JSValue::encode(promise);
}
JSC_DEFINE_HOST_FUNCTION(readableStreamDefaultReaderReleaseLock, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(callFrame->thisValue());
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.releaseLock called on incompatible object"_s));
return {};
}
reader->releaseLock();
return JSValue::encode(jsUndefined());
}
JSC_DEFINE_CUSTOM_GETTER(readableStreamDefaultReaderClosedGetter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(JSValue::decode(thisValue));
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.closed called on incompatible object"_s));
return {};
}
return JSValue::encode(reader->closedPromise());
}
JSC_DEFINE_CUSTOM_GETTER(readableStreamDefaultReaderReadyGetter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(JSValue::decode(thisValue));
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.ready called on incompatible object"_s));
return {};
}
return JSValue::encode(reader->readyPromise());
}
JSC_DEFINE_HOST_FUNCTION(readableStreamDefaultReaderCancel, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSReadableStreamDefaultReader* reader = jsDynamicCast<JSReadableStreamDefaultReader*>(callFrame->thisValue());
if (!reader) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.cancel called on incompatible object"_s));
return {};
}
JSValue reason = callFrame->argument(0);
if (!reader->isActive()) {
scope.throwException(globalObject, createTypeError(globalObject, "ReadableStreamDefaultReader.prototype.cancel called on released reader"_s));
return {};
}
return JSValue::encode(reader->stream()->cancel(globalObject, reason));
}
} // namespace Bun

View File

@@ -0,0 +1,40 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/JSObjectInlines.h>
namespace Bun {
using namespace JSC;
class JSReadableStreamDefaultReaderPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSReadableStreamDefaultReaderPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure);
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultReaderPrototype, Base);
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:
JSReadableStreamDefaultReaderPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
: Base(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
} // namespace Bun