aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/BunStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings/BunStream.cpp')
-rw-r--r--src/bun.js/bindings/BunStream.cpp527
1 files changed, 527 insertions, 0 deletions
diff --git a/src/bun.js/bindings/BunStream.cpp b/src/bun.js/bindings/BunStream.cpp
new file mode 100644
index 000000000..2dbb53562
--- /dev/null
+++ b/src/bun.js/bindings/BunStream.cpp
@@ -0,0 +1,527 @@
+#include "BunStream.h"
+#include "JavaScriptCore/JSMicrotask.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+
+namespace WebCore {
+using JSGlobalObject = JSC::JSGlobalObject;
+using Exception = JSC::Exception;
+using JSValue = JSC::JSValue;
+using JSString = JSC::JSString;
+using JSModuleLoader = JSC::JSModuleLoader;
+using JSModuleRecord = JSC::JSModuleRecord;
+using Identifier = JSC::Identifier;
+using SourceOrigin = JSC::SourceOrigin;
+using JSObject = JSC::JSObject;
+using JSNonFinalObject = JSC::JSNonFinalObject;
+namespace JSCastingHelpers = JSC::JSCastingHelpers;
+
+static ReadableEvent getReadableEvent(const WTF::String& eventName);
+static ReadableEvent getReadableEvent(const WTF::String& eventName)
+{
+ if (eventName == "close")
+ return ReadableEvent__Close;
+ else if (eventName == "data")
+ return ReadableEvent__Data;
+ else if (eventName == "end")
+ return ReadableEvent__End;
+ else if (eventName == "error")
+ return ReadableEvent__Error;
+ else if (eventName == "pause")
+ return ReadableEvent__Pause;
+ else if (eventName == "readable")
+ return ReadableEvent__Readable;
+ else if (eventName == "resume")
+ return ReadableEvent__Resume;
+ else if (eventName == "open")
+ return ReadableEvent__Open;
+ else
+ return ReadableEventUser;
+}
+
+static WritableEvent getWritableEvent(const WTF::String& eventName);
+static WritableEvent getWritableEvent(const WTF::String& eventName)
+{
+ if (eventName == "close")
+ return WritableEvent__Close;
+ else if (eventName == "drain")
+ return WritableEvent__Drain;
+ else if (eventName == "error")
+ return WritableEvent__Error;
+ else if (eventName == "finish")
+ return WritableEvent__Finish;
+ else if (eventName == "pipe")
+ return WritableEvent__Pipe;
+ else if (eventName == "unpipe")
+ return WritableEvent__Unpipe;
+ else if (eventName == "open")
+ return WritableEvent__Open;
+ else
+ return WritableEventUser;
+}
+
+// clang-format off
+#define DEFINE_CALLBACK_FUNCTION_BODY(TypeName, ZigFunction) JSC::VM& vm = globalObject->vm(); \
+ auto* thisObject = JSC::jsDynamicCast<TypeName*>( callFrame->thisValue()); \
+ auto scope = DECLARE_THROW_SCOPE(vm); \
+ if (!thisObject) \
+ return throwVMTypeError(globalObject, scope); \
+ auto argCount = static_cast<uint16_t>(callFrame->argumentCount()); \
+ WTF::Vector<JSC::EncodedJSValue, 16> arguments; \
+ arguments.reserveInitialCapacity(argCount); \
+ if (argCount) { \
+ for (uint16_t i = 0; i < argCount; ++i) { \
+ arguments.uncheckedAppend(JSC::JSValue::encode(callFrame->uncheckedArgument(i))); \
+ } \
+ } \
+ JSC::JSValue result = JSC::JSValue::decode( \
+ ZigFunction(thisObject->state, globalObject, reinterpret_cast<JSC__JSValue*>(arguments.data()), argCount) \
+ ); \
+ JSC::JSObject *obj = result.getObject(); \
+ if (UNLIKELY(obj != nullptr && obj->isErrorInstance())) { \
+ scope.throwException(globalObject, obj); \
+ return JSC::JSValue::encode(JSC::jsUndefined()); \
+ } \
+ if (UNLIKELY(scope.exception())) \
+ return JSC::JSValue::encode(JSC::jsUndefined()); \
+ return JSC::JSValue::encode(result);
+
+// clang-format on
+// static JSC_DECLARE_HOST_FUNCTION(Writable__addEventListener);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__addEventListener);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__prependListener);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__prependListener);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__prependOnceListener);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__prependOnceListener);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__setMaxListeners);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__setMaxListeners);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__getMaxListeners);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__getMaxListeners);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__setDefaultEncoding);
+static JSC_DECLARE_HOST_FUNCTION(Readable__on);
+// static JSC_DECLARE_HOST_FUNCTION(Readable__off);
+static JSC_DECLARE_HOST_FUNCTION(Readable__once);
+static JSC_DECLARE_HOST_FUNCTION(Readable__pause);
+static JSC_DECLARE_HOST_FUNCTION(Readable__pipe);
+static JSC_DECLARE_HOST_FUNCTION(Readable__read);
+static JSC_DECLARE_HOST_FUNCTION(Readable__resume);
+static JSC_DECLARE_HOST_FUNCTION(Readable__unpipe);
+static JSC_DECLARE_HOST_FUNCTION(Readable__unshift);
+
+static JSC_DECLARE_HOST_FUNCTION(Writable__close);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__off);
+static JSC_DECLARE_HOST_FUNCTION(Writable__cork);
+static JSC_DECLARE_HOST_FUNCTION(Writable__destroy);
+static JSC_DECLARE_HOST_FUNCTION(Writable__end);
+static JSC_DECLARE_HOST_FUNCTION(Writable__on);
+static JSC_DECLARE_HOST_FUNCTION(Writable__once);
+static JSC_DECLARE_HOST_FUNCTION(Writable__uncork);
+static JSC_DECLARE_HOST_FUNCTION(Writable__write);
+
+static JSC_DEFINE_HOST_FUNCTION(Readable__on,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+
+ if (callFrame->argumentCount() < 2) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto thisObject = JSC::jsDynamicCast<WebCore::Readable*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ scope.release();
+ JSC::throwVMTypeError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto eventName = callFrame->argument(0).toStringOrNull(globalObject);
+ if (UNLIKELY(!eventName)) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ ReadableEvent event = getReadableEvent(eventName->value(globalObject));
+ if (event == ReadableEventUser) {
+ // TODO:
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto listener = callFrame->argument(1);
+ JSC::JSObject* object = listener.getObject();
+ if (UNLIKELY(!object) || !listener.isCallable()) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ Bun__Readable__addEventListener(thisObject->state, globalObject, event,
+ JSC::JSValue::encode(listener), true);
+
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+extern "C" Bun__Readable* JSC__JSValue__getReadableStreamState(JSC__JSValue value, JSC__VM* vm)
+{
+ auto* thisObject = JSC::jsDynamicCast<WebCore::Readable*>(JSC::JSValue::decode(value));
+ if (UNLIKELY(!thisObject)) {
+ return nullptr;
+ }
+ return thisObject->state;
+}
+extern "C" Bun__Writable* JSC__JSValue__getWritableStreamState(JSC__JSValue value, JSC__VM* vm)
+{
+ auto* thisObject = JSC::jsDynamicCast<WebCore::Writable*>(JSC::JSValue::decode(value));
+ if (UNLIKELY(!thisObject)) {
+ return nullptr;
+ }
+ return thisObject->state;
+}
+
+const JSC::ClassInfo Readable::s_info = { "Readable"_s, &Base::s_info, nullptr, nullptr,
+ CREATE_METHOD_TABLE(Readable) };
+
+const JSC::ClassInfo Writable::s_info = { "Writable"_s, &Base::s_info, nullptr, nullptr,
+ CREATE_METHOD_TABLE(Writable) };
+
+static JSC_DEFINE_HOST_FUNCTION(Readable__once,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+
+ if (callFrame->argumentCount() < 2) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto thisObject = JSC::jsDynamicCast<WebCore::Readable*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ scope.release();
+ JSC::throwVMTypeError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto eventName = callFrame->argument(0).toStringOrNull(globalObject);
+ if (UNLIKELY(!eventName)) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ ReadableEvent event = getReadableEvent(eventName->value(globalObject));
+ if (event == ReadableEventUser) {
+ // TODO:
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto listener = callFrame->argument(1);
+ JSC::JSObject* object = listener.getObject();
+ if (UNLIKELY(!object) || !listener.isCallable()) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ Bun__Readable__addEventListener(thisObject->state, globalObject, event,
+ JSC::JSValue::encode(listener), true);
+
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+static JSC_DEFINE_HOST_FUNCTION(Writable__on,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+
+ if (callFrame->argumentCount() < 2) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto thisObject = JSC::jsDynamicCast<WebCore::Writable*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ scope.release();
+ JSC::throwVMTypeError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto eventName = callFrame->argument(0).toStringOrNull(globalObject);
+ if (UNLIKELY(!eventName)) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ WritableEvent event = getWritableEvent(eventName->value(globalObject));
+ if (event == WritableEventUser) {
+ // TODO:
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto listener = callFrame->argument(1);
+ JSC::JSObject* object = listener.getObject();
+ if (UNLIKELY(!object) || !listener.isCallable()) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ Bun__Writable__addEventListener(thisObject->state, globalObject, event,
+ JSC::JSValue::encode(listener), false);
+
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+static JSC_DEFINE_HOST_FUNCTION(Writable__once,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+
+ if (callFrame->argumentCount() < 2) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto thisObject = JSC::jsDynamicCast<WebCore::Writable*>(callFrame->thisValue());
+ if (UNLIKELY(!thisObject)) {
+ scope.release();
+ JSC::throwVMTypeError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto eventName = callFrame->argument(0).toStringOrNull(globalObject);
+ if (UNLIKELY(!eventName)) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ WritableEvent event = getWritableEvent(eventName->value(globalObject));
+ if (event == WritableEventUser) {
+ // TODO:
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto listener = callFrame->argument(1);
+ JSC::JSObject* object = listener.getObject();
+ if (UNLIKELY(!object) || !listener.isCallable()) {
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ Bun__Writable__addEventListener(thisObject->state, globalObject, event,
+ JSC::JSValue::encode(listener), true);
+
+ scope.release();
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+static JSC_DEFINE_HOST_FUNCTION(Readable__read,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__read);
+}
+
+static JSC_DEFINE_HOST_FUNCTION(Readable__pipe,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__pipe);
+}
+
+static JSC_DEFINE_HOST_FUNCTION(Readable__resume,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__resume);
+}
+static JSC_DEFINE_HOST_FUNCTION(Readable__unpipe,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__unpipe);
+}
+static JSC_DEFINE_HOST_FUNCTION(Readable__pause,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__pause);
+}
+static JSC_DEFINE_HOST_FUNCTION(Readable__unshift,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__unshift);
+}
+
+// static JSC_DECLARE_HOST_FUNCTION(Readable__isPaused);
+// static JSC_DECLARE_HOST_FUNCTION(Writable__setDefaultEncoding);
+
+// static DEFINE_CALLBACK_FUNCTION(Writable__setDefaultEncoding, WebCore::Writable,
+// Bun__Writable__setDefaultEncoding);
+
+static JSC_DEFINE_HOST_FUNCTION(Writable__write,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__write);
+}
+static JSC_DEFINE_HOST_FUNCTION(Writable__end,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__end);
+}
+static JSC_DEFINE_HOST_FUNCTION(Writable__close,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__close);
+}
+static JSC_DEFINE_HOST_FUNCTION(Writable__destroy,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__destroy);
+}
+static JSC_DEFINE_HOST_FUNCTION(Writable__cork,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__cork);
+}
+static JSC_DEFINE_HOST_FUNCTION(Writable__uncork,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__uncork);
+}
+
+extern "C" JSC__JSValue Bun__Readable__create(Bun__Readable* state,
+ JSC__JSGlobalObject* globalObject)
+{
+ JSC::JSValue result = JSC::JSValue(Readable::create(
+ globalObject->vm(), state,
+ Readable::createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype())));
+
+ return JSC::JSValue::encode(result);
+}
+extern "C" JSC__JSValue Bun__Writable__create(Bun__Writable* state,
+ JSC__JSGlobalObject* globalObject)
+{
+ JSC::JSValue result = JSC::JSValue(Writable::create(
+ globalObject->vm(), state,
+ Writable::createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype())));
+
+ return JSC::JSValue::encode(result);
+}
+
+Readable::~Readable()
+{
+ if (this->state) {
+ Bun__Readable__deinit(this->state);
+ }
+}
+
+Writable::~Writable()
+{
+ if (this->state) {
+ Bun__Writable__deinit(this->state);
+ }
+}
+
+void Readable::finishCreation(JSC::VM& vm)
+{
+ Base::finishCreation(vm);
+ auto clientData = WebCore::clientData(vm);
+ auto* globalObject = this->globalObject();
+
+ putDirect(vm, clientData->builtinNames().onPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().onPublicName().string(), Readable__on),
+ 0);
+ putDirect(vm, clientData->builtinNames().oncePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().oncePublicName().string(),
+ Readable__once),
+ 0);
+ putDirect(vm, clientData->builtinNames().pausePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().pausePublicName().string(),
+ Readable__pause),
+ 0);
+ putDirect(vm, clientData->builtinNames().pipePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().pipePublicName().string(),
+ Readable__pipe),
+ 0);
+ putDirect(vm, clientData->builtinNames().readPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().readPublicName().string(),
+ Readable__read),
+ 0);
+ putDirect(vm, clientData->builtinNames().resumePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().resumePublicName().string(),
+ Readable__resume),
+ 0);
+ putDirect(vm, clientData->builtinNames().unpipePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().unpipePublicName().string(),
+ Readable__unpipe),
+ 0);
+ putDirect(vm, clientData->builtinNames().unshiftPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().unshiftPublicName().string(),
+ Readable__unshift),
+ 0);
+}
+
+void Writable::finishCreation(JSC::VM& vm)
+{
+ Base::finishCreation(vm);
+ auto clientData = WebCore::clientData(vm);
+
+ auto* globalObject = this->globalObject();
+
+ putDirect(vm, clientData->builtinNames().onPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().onPublicName().string(), Writable__on),
+ 0);
+
+ putDirect(vm, clientData->builtinNames().oncePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().oncePublicName().string(),
+ Writable__once),
+ 0);
+
+ putDirect(vm, clientData->builtinNames().closePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().closePublicName().string(),
+ Writable__close),
+ 0);
+ putDirect(vm, clientData->builtinNames().corkPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().corkPublicName().string(),
+ Writable__cork),
+ 0);
+ putDirect(vm, clientData->builtinNames().destroyPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().destroyPublicName().string(),
+ Writable__destroy),
+ 0);
+ putDirect(vm, clientData->builtinNames().endPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().endPublicName().string(), Writable__end),
+ 0);
+ putDirect(vm, clientData->builtinNames().onPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().onPublicName().string(), Writable__on),
+ 0);
+ putDirect(vm, clientData->builtinNames().oncePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().oncePublicName().string(),
+ Writable__once),
+ 0);
+ putDirect(vm, clientData->builtinNames().uncorkPublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().uncorkPublicName().string(),
+ Writable__uncork),
+ 0);
+ putDirect(vm, clientData->builtinNames().writePublicName(),
+ JSFunction::create(vm, globalObject, 2,
+ clientData->builtinNames().writePublicName().string(),
+ Writable__write),
+ 0);
+}
+
+} // namespace WebCore \ No newline at end of file