mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 12:29:07 +00:00
Delete BunStream
This commit is contained in:
@@ -1,527 +0,0 @@
|
||||
#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
|
||||
@@ -1,89 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "BunBuiltinNames.h"
|
||||
#include "BunClientData.h"
|
||||
#include "root.h"
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
class Readable : public JSC::JSNonFinalObject {
|
||||
using Base = JSC::JSNonFinalObject;
|
||||
|
||||
public:
|
||||
Bun__Readable* state;
|
||||
Readable(JSC::VM& vm, Bun__Readable* readable, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
state = readable;
|
||||
}
|
||||
|
||||
~Readable();
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
template<typename CellType, SubspaceAccess> static GCClient::IsoSubspace* subspaceFor(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());
|
||||
}
|
||||
|
||||
static Readable* create(JSC::VM& vm, Bun__Readable* state, JSC::Structure* structure)
|
||||
{
|
||||
Readable* accessor = new (NotNull, JSC::allocateCell<WebCore::Readable>(vm)) Readable(vm, state, structure);
|
||||
accessor->finishCreation(vm);
|
||||
return accessor;
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm);
|
||||
};
|
||||
|
||||
class Writable : public JSC::JSNonFinalObject {
|
||||
using Base = JSC::JSNonFinalObject;
|
||||
|
||||
public:
|
||||
Bun__Writable* state;
|
||||
Writable(JSC::VM& vm, Bun__Writable* writable, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
state = writable;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
template<typename CellType, SubspaceAccess> static GCClient::IsoSubspace* subspaceFor(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());
|
||||
}
|
||||
|
||||
static Writable* create(JSC::VM& vm, Bun__Writable* state, JSC::Structure* structure)
|
||||
{
|
||||
|
||||
Writable* accessor = new (NotNull, JSC::allocateCell<Writable>(vm)) Writable(vm, state, structure);
|
||||
accessor->finishCreation(vm);
|
||||
return accessor;
|
||||
}
|
||||
~Writable();
|
||||
|
||||
void finishCreation(JSC::VM& vm);
|
||||
};
|
||||
|
||||
} // namespace WebCore
|
||||
@@ -173,10 +173,6 @@ pub const ZigErrorType = extern struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// do not use this reference directly, use JSC.Node.Readable
|
||||
pub const NodeReadableStream = JSC.Node.Readable.State;
|
||||
/// do not use this reference directly, use JSC.Node.Writable
|
||||
pub const NodeWritableStream = JSC.Node.Writable.State;
|
||||
pub const NodePath = JSC.Node.Path;
|
||||
|
||||
// Web Streams
|
||||
@@ -2521,24 +2517,22 @@ pub const HTTPDebugServerRequestContext = JSC.API.DebugServer.RequestContext;
|
||||
pub const HTTPDebugSSLServerRequestContext = JSC.API.DebugSSLServer.RequestContext;
|
||||
|
||||
comptime {
|
||||
WebSocketHTTPClient.shim.ref();
|
||||
WebSocketHTTSPClient.shim.ref();
|
||||
WebSocketClient.shim.ref();
|
||||
WebSocketClientTLS.shim.ref();
|
||||
|
||||
HTTPServerRequestContext.shim.ref();
|
||||
HTTPSSLServerRequestContext.shim.ref();
|
||||
HTTPDebugServerRequestContext.shim.ref();
|
||||
HTTPDebugSSLServerRequestContext.shim.ref();
|
||||
|
||||
if (!is_bindgen) {
|
||||
WebSocketHTTPClient.shim.ref();
|
||||
WebSocketHTTSPClient.shim.ref();
|
||||
WebSocketClient.shim.ref();
|
||||
WebSocketClientTLS.shim.ref();
|
||||
|
||||
HTTPServerRequestContext.shim.ref();
|
||||
HTTPSSLServerRequestContext.shim.ref();
|
||||
HTTPDebugServerRequestContext.shim.ref();
|
||||
HTTPDebugSSLServerRequestContext.shim.ref();
|
||||
|
||||
_ = Process.getTitle;
|
||||
_ = Process.setTitle;
|
||||
_ = Zig__getAPIGlobals;
|
||||
_ = Zig__getAPIConstructors;
|
||||
NodeReadableStream.shim.ref();
|
||||
Bun.Timer.shim.ref();
|
||||
NodeWritableStream.shim.ref();
|
||||
NodePath.shim.ref();
|
||||
JSReadableStreamBlob.shim.ref();
|
||||
JSArrayBufferSink.shim.ref();
|
||||
|
||||
@@ -2306,8 +2306,6 @@ const Return = struct {
|
||||
pub const WatchFile = void;
|
||||
pub const Utimes = void;
|
||||
|
||||
pub const CreateReadStream = *JSC.Node.Stream;
|
||||
pub const CreateWriteStream = *JSC.Node.Stream;
|
||||
pub const Chown = void;
|
||||
pub const Lutimes = void;
|
||||
};
|
||||
@@ -3611,47 +3609,10 @@ pub const NodeFS = struct {
|
||||
_ = flavor;
|
||||
return Maybe(Return.Watch).todo;
|
||||
}
|
||||
pub fn createReadStream(this: *NodeFS, args: Arguments.CreateReadStream, comptime flavor: Flavor) Maybe(Return.CreateReadStream) {
|
||||
_ = args;
|
||||
_ = this;
|
||||
_ = flavor;
|
||||
var stream = bun.default_allocator.create(JSC.Node.Stream) catch unreachable;
|
||||
stream.* = JSC.Node.Stream{
|
||||
.sink = .{
|
||||
.readable = JSC.Node.Readable{
|
||||
.stream = stream,
|
||||
.globalObject = args.global_object,
|
||||
},
|
||||
},
|
||||
.sink_type = .readable,
|
||||
.content = undefined,
|
||||
.content_type = undefined,
|
||||
.allocator = bun.default_allocator,
|
||||
};
|
||||
|
||||
args.file.copyToStream(args.flags, args.autoClose, args.mode, bun.default_allocator, stream) catch unreachable;
|
||||
args.copyToState(&stream.sink.readable.state);
|
||||
return Maybe(Return.CreateReadStream){ .result = stream };
|
||||
pub fn createReadStream(_: *NodeFS, _: Arguments.CreateReadStream, comptime _: Flavor) Maybe(Return.CreateReadStream) {
|
||||
return Maybe(Return.CreateReadStream).todo;
|
||||
}
|
||||
pub fn createWriteStream(this: *NodeFS, args: Arguments.CreateWriteStream, comptime flavor: Flavor) Maybe(Return.CreateWriteStream) {
|
||||
_ = args;
|
||||
_ = this;
|
||||
_ = flavor;
|
||||
var stream = bun.default_allocator.create(JSC.Node.Stream) catch unreachable;
|
||||
stream.* = JSC.Node.Stream{
|
||||
.sink = .{
|
||||
.writable = JSC.Node.Writable{
|
||||
.stream = stream,
|
||||
.globalObject = args.global_object,
|
||||
},
|
||||
},
|
||||
.sink_type = .writable,
|
||||
.content = undefined,
|
||||
.content_type = undefined,
|
||||
.allocator = bun.default_allocator,
|
||||
};
|
||||
args.file.copyToStream(args.flags, args.autoClose, args.mode, bun.default_allocator, stream) catch unreachable;
|
||||
args.copyToState(&stream.sink.writable.state);
|
||||
return Maybe(Return.CreateWriteStream){ .result = stream };
|
||||
pub fn createWriteStream(_: *NodeFS, _: Arguments.CreateWriteStream, comptime _: Flavor) Maybe(Return.CreateWriteStream) {
|
||||
return Maybe(Return.CreateWriteStream).todo;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -659,36 +659,6 @@ pub const PathOrFileDescriptor = union(Tag) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn copyToStream(this: PathOrFileDescriptor, flags: FileSystemFlags, auto_close: bool, mode: Mode, allocator: std.mem.Allocator, stream: *Stream) !void {
|
||||
switch (this) {
|
||||
.fd => |fd| {
|
||||
stream.content = Stream.Content{
|
||||
.file = .{
|
||||
.fd = fd,
|
||||
.flags = flags,
|
||||
.mode = mode,
|
||||
},
|
||||
};
|
||||
stream.content_type = .file;
|
||||
},
|
||||
.path => |path| {
|
||||
stream.content = Stream.Content{
|
||||
.file_path = .{
|
||||
.path = PathString.init(std.mem.span(try allocator.dupeZ(u8, path.slice()))),
|
||||
.auto_close = auto_close,
|
||||
.file = .{
|
||||
.fd = std.math.maxInt(FileDescriptor),
|
||||
.flags = flags,
|
||||
.mode = mode,
|
||||
},
|
||||
.opened = false,
|
||||
},
|
||||
};
|
||||
stream.content_type = .file_path;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?PathOrFileDescriptor {
|
||||
const first = arguments.next() orelse return null;
|
||||
|
||||
@@ -1246,917 +1216,6 @@ pub const Emitter = struct {
|
||||
}
|
||||
};
|
||||
|
||||
// pub fn Untag(comptime Union: type) type {
|
||||
// const info: std.builtin.TypeInfo.Union = @typeInfo(Union);
|
||||
// const tag = info.tag_type orelse @compileError("Must be tagged");
|
||||
// return struct {
|
||||
// pub const Tag = tag;
|
||||
// pub const Union =
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Stream = struct {
|
||||
sink_type: Sink.Type,
|
||||
sink: Sink,
|
||||
content: Content,
|
||||
content_type: Content.Type,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn open(this: *Stream) ?JSC.Node.Syscall.Error {
|
||||
switch (Syscall.open(this.content.file_path.path.sliceAssumeZ(), @enumToInt(this.content.file_path.file.flags))) {
|
||||
.err => |err| {
|
||||
return err.withPath(this.content.file_path.path.slice());
|
||||
},
|
||||
.result => |fd| {
|
||||
this.content.file_path.file.fd = fd;
|
||||
this.content.file_path.opened = true;
|
||||
this.emit(.open);
|
||||
return null;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getFd(this: *Stream) FileDescriptor {
|
||||
return switch (this.content_type) {
|
||||
.file => this.content.file.fd,
|
||||
.file_path => if (comptime Environment.allow_assert) brk: {
|
||||
std.debug.assert(this.content.file_path.opened);
|
||||
break :brk this.content.file_path.file.fd;
|
||||
} else this.content.file_path.file.fd,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn close(this: *Stream) ?JSC.Node.Syscall.Error {
|
||||
const fd = this.getFd();
|
||||
|
||||
// Don't ever close stdin, stdout, or stderr
|
||||
// we are assuming that these are always 0 1 2, which is not strictly true in some cases
|
||||
if (fd <= 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Syscall.close(fd)) |err| {
|
||||
return err;
|
||||
}
|
||||
|
||||
switch (this.content_type) {
|
||||
.file_path => {
|
||||
this.content.file_path.opened = false;
|
||||
this.content.file_path.file.fd = std.math.maxInt(FileDescriptor);
|
||||
},
|
||||
.file => {
|
||||
this.content.file.fd = std.math.maxInt(FileDescriptor);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
this.emit(.Close);
|
||||
}
|
||||
|
||||
const CommonEvent = enum { Error, Open, Close };
|
||||
pub fn emit(this: *Stream, comptime event: CommonEvent) void {
|
||||
switch (this.sink_type) {
|
||||
.readable => {
|
||||
switch (comptime event) {
|
||||
.Open => this.sink.readable.emit(.Open),
|
||||
.Close => this.sink.readable.emit(.Close),
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.writable => {
|
||||
switch (comptime event) {
|
||||
.Open => this.sink.writable.emit(.Open),
|
||||
.Close => this.sink.writable.emit(.Close),
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// This allocates a new stream object
|
||||
pub fn toJS(this: *Stream, ctx: JSC.C.JSContextRef, _: JSC.C.ExceptionRef) JSC.C.JSValueRef {
|
||||
switch (this.sink_type) {
|
||||
.readable => {
|
||||
var readable = &this.sink.readable.state;
|
||||
return readable.create(
|
||||
ctx.ptr(),
|
||||
).asObjectRef();
|
||||
},
|
||||
.writable => {
|
||||
var writable = &this.sink.writable.state;
|
||||
return writable.create(
|
||||
ctx.ptr(),
|
||||
).asObjectRef();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(this: *Stream) void {
|
||||
this.allocator.destroy(this);
|
||||
}
|
||||
|
||||
pub const Sink = union {
|
||||
readable: Readable,
|
||||
writable: Writable,
|
||||
|
||||
pub const Type = enum(u8) {
|
||||
readable,
|
||||
writable,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Consumed = u52;
|
||||
|
||||
const Response = struct {
|
||||
bytes: [8]u8 = std.mem.zeroes([8]u8),
|
||||
};
|
||||
|
||||
const Error = union(Type) {
|
||||
Syscall: Syscall.Error,
|
||||
JavaScript: JSC.JSValue,
|
||||
Internal: anyerror,
|
||||
|
||||
pub const Type = enum {
|
||||
Syscall,
|
||||
JavaScript,
|
||||
Internal,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Content = union {
|
||||
file: File,
|
||||
file_path: FilePath,
|
||||
socket: Socket,
|
||||
buffer: *Buffer,
|
||||
stream: *Stream,
|
||||
javascript: JSC.JSValue,
|
||||
|
||||
pub fn getFile(this: *Content, content_type: Content.Type) *File {
|
||||
return switch (content_type) {
|
||||
.file => &this.file,
|
||||
.file_path => &this.file_path.file,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub const File = struct {
|
||||
fd: FileDescriptor,
|
||||
flags: FileSystemFlags,
|
||||
mode: Mode,
|
||||
size: Consumed = std.math.maxInt(Consumed),
|
||||
|
||||
// pub fn read(this: *File, comptime chunk_type: Content.Type, chunk: Source.Type.of(chunk_type)) Response {}
|
||||
|
||||
pub inline fn setPermissions(this: File) meta.ReturnOf(Syscall.fchmod) {
|
||||
return Syscall.fchmod(this.fd, this.mode);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FilePath = struct {
|
||||
path: PathString,
|
||||
auto_close: bool = false,
|
||||
file: File = File{ .fd = std.math.maxInt(FileDescriptor), .mode = 0o666, .flags = FileSystemFlags.@"r" },
|
||||
opened: bool = false,
|
||||
|
||||
// pub fn read(this: *File, comptime chunk_type: Content.Type, chunk: Source.Type.of(chunk_type)) Response {}
|
||||
};
|
||||
|
||||
pub const Socket = struct {
|
||||
fd: FileDescriptor,
|
||||
flags: FileSystemFlags,
|
||||
|
||||
// pub fn write(this: *File, comptime chunk_type: Source.Type, chunk: Source.Type.of(chunk_type)) Response {}
|
||||
// pub fn read(this: *File, comptime chunk_type: Source.Type, chunk: Source.Type.of(chunk_type)) Response {}
|
||||
};
|
||||
|
||||
pub const Type = enum(u8) {
|
||||
file,
|
||||
file_path,
|
||||
socket,
|
||||
buffer,
|
||||
stream,
|
||||
javascript,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pub const Writable = struct {
|
||||
state: State = State{},
|
||||
emitter: EventEmitter = EventEmitter{},
|
||||
|
||||
connection: ?*Stream = null,
|
||||
globalObject: ?*JSC.JSGlobalObject = null,
|
||||
|
||||
// workaround https://github.com/ziglang/zig/issues/6611
|
||||
stream: *Stream = undefined,
|
||||
pipeline: Pipeline = Pipeline{},
|
||||
started: bool = false,
|
||||
|
||||
pub const Chunk = struct {
|
||||
data: StringOrBuffer,
|
||||
encoding: Encoding = Encoding.utf8,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, size: u32) !Chunk {
|
||||
var bytes = try allocator.alloc(u8, size);
|
||||
return Chunk{
|
||||
.data = JSC.ArrayBuffer.fromBytes(bytes, JSC.JSValue.JSType.Uint8Array),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Pipe = struct {
|
||||
source: *Stream,
|
||||
destination: *Stream,
|
||||
chunk: ?*Chunk = null,
|
||||
// Might be the end of the stream
|
||||
// or it might just be another stream
|
||||
next: ?*Pipe = null,
|
||||
|
||||
pub fn start(this: *Pipe, pipeline: *Pipeline, chunk: ?*Chunk) void {
|
||||
this.run(pipeline, chunk, null);
|
||||
}
|
||||
|
||||
var disable_clonefile = false;
|
||||
|
||||
fn runCloneFileWithFallback(pipeline: *Pipeline, source: *Stream.Content, destination: *Stream.Content) void {
|
||||
switch (Syscall.clonefile(source.path.sliceAssumeZ(), destination.path.sliceAssumeZ())) {
|
||||
.result => return,
|
||||
.err => |err| {
|
||||
switch (err.getErrno()) {
|
||||
// these are retryable
|
||||
.ENOTSUP, .EXDEV, .EXIST, .EIO, .ENOTDIR => |call| {
|
||||
if (call == .ENOTSUP) {
|
||||
disable_clonefile = true;
|
||||
}
|
||||
|
||||
return runCopyfile(
|
||||
false,
|
||||
pipeline,
|
||||
source,
|
||||
.file_path,
|
||||
destination,
|
||||
.file_path,
|
||||
);
|
||||
},
|
||||
else => {
|
||||
pipeline.err = err;
|
||||
return;
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn runCopyfile(
|
||||
must_open_files: bool,
|
||||
pipeline: *Pipeline,
|
||||
source: *Stream.Content,
|
||||
source_type: Stream.Content.Type,
|
||||
destination: *Stream.Content,
|
||||
destination_type: Stream.Content.Type,
|
||||
is_end: bool,
|
||||
) void {
|
||||
do_the_work: {
|
||||
// fallback-only
|
||||
if (destination_type == .file_path and source_type == .file_path and !destination.file_path.opened and !must_open_files) {
|
||||
switch (Syscall.copyfile(source.path.sliceAssumeZ(), destination.path.sliceAssumeZ(), 0)) {
|
||||
.err => |err| {
|
||||
pipeline.err = err;
|
||||
|
||||
return;
|
||||
},
|
||||
.result => break :do_the_work,
|
||||
}
|
||||
}
|
||||
|
||||
defer {
|
||||
if (source_type == .file_path and source.file_path.auto_close and source.file_path.opened) {
|
||||
if (source.stream.close()) |err| {
|
||||
if (pipeline.err == null) {
|
||||
pipeline.err = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_end and destination_type == .file_path and destination.file_path.auto_close and destination.file_path.opened) {
|
||||
if (destination.stream.close()) |err| {
|
||||
if (pipeline.err == null) {
|
||||
pipeline.err = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source_type == .file_path and !source.file_path.opened) {
|
||||
if (source.stream.open()) |err| {
|
||||
pipeline.err = err;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const source_fd = if (source_type == .file_path)
|
||||
source.file_path.file.fd
|
||||
else
|
||||
source.file.fd;
|
||||
|
||||
if (destination == .file_path and !destination.file_path.opened) {
|
||||
if (destination.stream.open()) |err| {
|
||||
pipeline.err = err;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const dest_fd = if (destination_type == .file_path)
|
||||
destination.file_path.file.fd
|
||||
else
|
||||
destination.file.fd;
|
||||
|
||||
switch (Syscall.fcopyfile(source_fd, dest_fd, 0)) {
|
||||
.err => |err| {
|
||||
pipeline.err = err;
|
||||
return;
|
||||
},
|
||||
.result => break :do_the_work,
|
||||
}
|
||||
}
|
||||
|
||||
switch (destination.getFile(destination_type).setPermissions()) {
|
||||
.err => |err| {
|
||||
destination.stream.emitError(err);
|
||||
pipeline.err = err;
|
||||
return;
|
||||
},
|
||||
.result => return,
|
||||
}
|
||||
}
|
||||
|
||||
// fn runGeneric(this: *Pipe, pipeline: *Pipeline) !void {
|
||||
// var source = this.source;
|
||||
// var destination = this.destination;
|
||||
// const source_content_type = source.content_type;
|
||||
// const destination_content_type = destination.content_type;
|
||||
|
||||
// if (this.chunk == null) {
|
||||
// this.chunk = try this.source.allocator.create(Chunk);
|
||||
// this.chunk.?.* = try Chunk.init(this.source.allocator, this.source.sink.readable.state.highwater_mark);
|
||||
// }
|
||||
|
||||
// source.readInto
|
||||
// }
|
||||
|
||||
pub fn run(this: *Pipe, pipeline: *Pipeline) void {
|
||||
var source = this.source;
|
||||
var destination = this.destination;
|
||||
const source_content_type = source.content_type;
|
||||
const destination_content_type = destination.content_type;
|
||||
|
||||
if (pipeline.err != null) return;
|
||||
|
||||
switch (FastPath.get(
|
||||
source_content_type,
|
||||
destination_content_type,
|
||||
pipeline.head == this,
|
||||
pipeline.tail == this,
|
||||
)) {
|
||||
.clonefile => {
|
||||
if (comptime !Environment.isMac) unreachable;
|
||||
if (destination.content.file_path.opened) {
|
||||
runCopyfile(
|
||||
// Can we skip sending a .open event?
|
||||
(!source.content.file_path.auto_close and !source.content.file_path.opened) or (!destination.content.file_path.auto_close and !destination.content.file_path.opened),
|
||||
pipeline,
|
||||
&source.content,
|
||||
.file_path,
|
||||
&destination.content,
|
||||
.file_path,
|
||||
this.next == null,
|
||||
);
|
||||
} else {
|
||||
runCloneFileWithFallback(pipeline, source.content.file_path, destination.content.file_path);
|
||||
}
|
||||
},
|
||||
.copyfile => {
|
||||
if (comptime !Environment.isMac) unreachable;
|
||||
runCopyfile(
|
||||
// Can we skip sending a .open event?
|
||||
(!source.content.file_path.auto_close and !source.content.file_path.opened) or (!destination.content.file_path.auto_close and !destination.content.file_path.opened),
|
||||
pipeline,
|
||||
&source.content,
|
||||
source_content_type,
|
||||
&destination.content,
|
||||
destination_content_type,
|
||||
this.next == null,
|
||||
);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub const FastPath = enum {
|
||||
none,
|
||||
clonefile,
|
||||
sendfile,
|
||||
copyfile,
|
||||
copy_file_range,
|
||||
|
||||
pub fn get(source: Stream.Content.Type, destination: Stream.Content.Type, is_head: bool, is_tail: bool) FastPath {
|
||||
_ = is_tail;
|
||||
if (comptime Environment.isMac) {
|
||||
if (is_head) {
|
||||
if (source == .file_path and destination == .file_path and !disable_clonefile)
|
||||
return .clonefile;
|
||||
|
||||
if ((source == .file or source == .file_path) and (destination == .file or destination == .file_path)) {
|
||||
return .copyfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FastPath.none;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub const Pipeline = struct {
|
||||
head: ?*Pipe = null,
|
||||
tail: ?*Pipe = null,
|
||||
|
||||
// Preallocate a single pipe so that
|
||||
preallocated_tail_pipe: Pipe = undefined,
|
||||
|
||||
/// Does the data exit at any point to JavaScript?
|
||||
closed_loop: bool = true,
|
||||
|
||||
// If there is a pending error, this is the error
|
||||
err: ?Syscall.Error = null,
|
||||
|
||||
pub const StartTask = struct {
|
||||
writable: *Writable,
|
||||
pub fn run(this: *StartTask) void {
|
||||
var writable = this.writable;
|
||||
var head = writable.pipeline.head orelse return;
|
||||
if (writable.started) {
|
||||
return;
|
||||
}
|
||||
writable.started = true;
|
||||
|
||||
head.start(&writable.pipeline, null);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub fn appendReadable(this: *Writable, readable: *Stream) void {
|
||||
if (comptime Environment.allow_assert) {
|
||||
std.debug.assert(readable.sink_type == .readable);
|
||||
}
|
||||
|
||||
if (this.pipeline.tail == null) {
|
||||
this.pipeline.head = &this.pipeline.preallocated_tail_pipe;
|
||||
this.pipeline.head.?.* = Pipe{
|
||||
.destination = this.stream,
|
||||
.source = readable,
|
||||
};
|
||||
this.pipeline.tail = this.pipeline.head;
|
||||
return;
|
||||
}
|
||||
|
||||
var pipe = readable.allocator.create(Pipe) catch unreachable;
|
||||
pipe.* = Pipe{
|
||||
.source = readable,
|
||||
.destination = this.stream,
|
||||
};
|
||||
this.pipeline.tail.?.next = pipe;
|
||||
this.pipeline.tail = pipe;
|
||||
}
|
||||
|
||||
pub const EventEmitter = Emitter.New(Events);
|
||||
|
||||
pub fn emit(this: *Writable, event: Events, value: JSC.JSValue) void {
|
||||
if (this.shouldSkipEvent(event)) return;
|
||||
|
||||
this.emitter.emit(event, this.globalObject.?, value);
|
||||
}
|
||||
|
||||
pub inline fn shouldEmitEvent(this: *const Writable, event: Events) bool {
|
||||
return switch (event) {
|
||||
.Close => this.state.emit_close and this.emitter.listeners.get(.Close).list.len > 0,
|
||||
.Drain => this.emitter.listeners.get(.Drain).list.len > 0,
|
||||
.Error => this.emitter.listeners.get(.Error).list.len > 0,
|
||||
.Finish => this.emitter.listeners.get(.Finish).list.len > 0,
|
||||
.Pipe => this.emitter.listeners.get(.Pipe).list.len > 0,
|
||||
.Unpipe => this.emitter.listeners.get(.Unpipe).list.len > 0,
|
||||
.Open => this.emitter.listeners.get(.Open).list.len > 0,
|
||||
};
|
||||
}
|
||||
|
||||
pub const State = extern struct {
|
||||
highwater_mark: u32 = 256_000,
|
||||
encoding: Encoding = Encoding.utf8,
|
||||
start: i32 = 0,
|
||||
destroyed: bool = false,
|
||||
ended: bool = false,
|
||||
corked: bool = false,
|
||||
finished: bool = false,
|
||||
emit_close: bool = true,
|
||||
|
||||
pub fn deinit(state: *State) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
|
||||
var stream = state.getStream();
|
||||
stream.deinit();
|
||||
}
|
||||
|
||||
pub fn create(state: *State, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
|
||||
return shim.cppFn("create", .{ state, globalObject });
|
||||
}
|
||||
|
||||
// i know.
|
||||
pub inline fn getStream(state: *State) *Stream {
|
||||
return getWritable(state).stream;
|
||||
}
|
||||
|
||||
pub inline fn getWritable(state: *State) *Writable {
|
||||
return @fieldParentPtr(Writable, "state", state);
|
||||
}
|
||||
|
||||
pub fn addEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
var writable = state.getWritable();
|
||||
writable.emitter.addListener(global.ref(), event, .{
|
||||
.once = is_once,
|
||||
.callback = callback,
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn removeEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue) callconv(.C) bool {
|
||||
if (comptime is_bindgen) return true;
|
||||
var writable = state.getWritable();
|
||||
return writable.emitter.removeListener(global.ref(), event, callback);
|
||||
}
|
||||
|
||||
pub fn prependEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
var writable = state.getWritable();
|
||||
writable.emitter.prependListener(global.ref(), event, .{
|
||||
.once = is_once,
|
||||
.callback = callback,
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn write(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
pub fn end(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
pub fn close(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
pub fn destroy(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
pub fn cork(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
pub fn uncork(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub const Flowing = enum(u8) {
|
||||
pending,
|
||||
yes,
|
||||
paused,
|
||||
};
|
||||
|
||||
pub const shim = Shimmer("Bun", "Writable", @This());
|
||||
pub const name = "Bun__Writable";
|
||||
pub const include = "BunStream.h";
|
||||
pub const namespace = shim.namespace;
|
||||
|
||||
pub const Export = shim.exportFunctions(.{
|
||||
.@"deinit" = deinit,
|
||||
.@"addEventListener" = addEventListener,
|
||||
.@"removeEventListener" = removeEventListener,
|
||||
.@"prependEventListener" = prependEventListener,
|
||||
.@"write" = write,
|
||||
.@"end" = end,
|
||||
.@"close" = close,
|
||||
.@"destroy" = destroy,
|
||||
.@"cork" = cork,
|
||||
.@"uncork" = uncork,
|
||||
});
|
||||
|
||||
pub const Extern = [_][]const u8{"create"};
|
||||
|
||||
comptime {
|
||||
if (!is_bindgen) {
|
||||
@export(deinit, .{ .name = Export[0].symbol_name });
|
||||
@export(addEventListener, .{ .name = Export[1].symbol_name });
|
||||
@export(removeEventListener, .{ .name = Export[2].symbol_name });
|
||||
@export(prependEventListener, .{ .name = Export[3].symbol_name });
|
||||
@export(write, .{ .name = Export[4].symbol_name });
|
||||
@export(end, .{ .name = Export[5].symbol_name });
|
||||
@export(close, .{ .name = Export[6].symbol_name });
|
||||
@export(destroy, .{ .name = Export[7].symbol_name });
|
||||
@export(cork, .{ .name = Export[8].symbol_name });
|
||||
@export(uncork, .{ .name = Export[9].symbol_name });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Events = enum(u8) {
|
||||
Close,
|
||||
Drain,
|
||||
Error,
|
||||
Finish,
|
||||
Pipe,
|
||||
Unpipe,
|
||||
Open,
|
||||
|
||||
pub const name = "WritableEvent";
|
||||
};
|
||||
};
|
||||
|
||||
pub const Readable = struct {
|
||||
state: State = State{},
|
||||
emitter: EventEmitter = EventEmitter{},
|
||||
stream: *Stream = undefined,
|
||||
destination: ?*Writable = null,
|
||||
globalObject: ?*JSC.JSGlobalObject = null,
|
||||
|
||||
pub const EventEmitter = Emitter.New(Events);
|
||||
|
||||
pub fn emit(this: *Readable, event: Events, comptime ValueType: type, value: JSC.JSValue) void {
|
||||
_ = ValueType;
|
||||
if (this.shouldEmitEvent(event)) return;
|
||||
|
||||
this.emitter.emit(event, this.globalObject.?, value);
|
||||
}
|
||||
|
||||
pub fn shouldEmitEvent(this: *Readable, event: Events) bool {
|
||||
return switch (event) {
|
||||
.Close => this.state.emit_close and this.emitter.listeners.get(.Close).list.len > 0,
|
||||
.Data => this.emitter.listeners.get(.Data).list.len > 0,
|
||||
.End => this.state.emit_end and this.emitter.listeners.get(.End).list.len > 0,
|
||||
.Error => this.emitter.listeners.get(.Error).list.len > 0,
|
||||
.Pause => this.emitter.listeners.get(.Pause).list.len > 0,
|
||||
.Readable => this.emitter.listeners.get(.Readable).list.len > 0,
|
||||
.Resume => this.emitter.listeners.get(.Resume).list.len > 0,
|
||||
.Open => this.emitter.listeners.get(.Open).list.len > 0,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Events = enum(u8) {
|
||||
Close,
|
||||
Data,
|
||||
End,
|
||||
Error,
|
||||
Pause,
|
||||
Readable,
|
||||
Resume,
|
||||
Open,
|
||||
|
||||
pub const name = "ReadableEvent";
|
||||
};
|
||||
|
||||
// This struct is exposed to JavaScript
|
||||
pub const State = extern struct {
|
||||
highwater_mark: u32 = 256_000,
|
||||
encoding: Encoding = Encoding.utf8,
|
||||
|
||||
start: i32 = 0,
|
||||
end: i32 = std.math.maxInt(i32),
|
||||
|
||||
readable: bool = false,
|
||||
aborted: bool = false,
|
||||
did_read: bool = false,
|
||||
ended: bool = false,
|
||||
flowing: Flowing = Flowing.pending,
|
||||
|
||||
emit_close: bool = true,
|
||||
emit_end: bool = true,
|
||||
|
||||
// i know.
|
||||
pub inline fn getStream(state: *State) *Stream {
|
||||
return getReadable(state).stream;
|
||||
}
|
||||
|
||||
pub inline fn getReadable(state: *State) *Readable {
|
||||
return @fieldParentPtr(Readable, "state", state);
|
||||
}
|
||||
|
||||
pub const Flowing = enum(u8) {
|
||||
pending,
|
||||
yes,
|
||||
paused,
|
||||
};
|
||||
|
||||
pub const shim = Shimmer("Bun", "Readable", @This());
|
||||
pub const name = "Bun__Readable";
|
||||
pub const include = "BunStream.h";
|
||||
pub const namespace = shim.namespace;
|
||||
|
||||
pub fn create(
|
||||
state: *State,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
) callconv(.C) JSC.JSValue {
|
||||
return shim.cppFn("create", .{ state, globalObject });
|
||||
}
|
||||
|
||||
pub fn deinit(state: *State) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
var stream = state.getStream();
|
||||
stream.deinit();
|
||||
}
|
||||
|
||||
pub fn addEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
var readable = state.getReadable();
|
||||
|
||||
readable.emitter.addListener(global.ref(), event, .{
|
||||
.once = is_once,
|
||||
.callback = callback,
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn removeEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue) callconv(.C) bool {
|
||||
if (comptime is_bindgen) return true;
|
||||
var readable = state.getReadable();
|
||||
return readable.emitter.removeListener(global.ref(), event, callback);
|
||||
}
|
||||
|
||||
pub fn prependEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void {
|
||||
if (comptime is_bindgen) return;
|
||||
var readable = state.getReadable();
|
||||
readable.emitter.prependListener(global.ref(), event, .{
|
||||
.once = is_once,
|
||||
.callback = callback,
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn pipe(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
if (len < 1) {
|
||||
return JSC.toInvalidArguments("Writable is required", .{}, global.ref());
|
||||
}
|
||||
const args: []const JSC.JSValue = args_ptr[0..len];
|
||||
var writable_state: *Writable.State = args[0].getWritableStreamState(global.vm()) orelse {
|
||||
return JSC.toInvalidArguments("Expected Writable but didn't receive it", .{}, global.ref());
|
||||
};
|
||||
writable_state.getWritable().appendReadable(state.getStream());
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn unpipe(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn unshift(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn read(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn pause(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn @"resume"(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue {
|
||||
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
|
||||
_ = state;
|
||||
_ = global;
|
||||
_ = args_ptr;
|
||||
_ = len;
|
||||
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub const Export = shim.exportFunctions(.{
|
||||
.@"deinit" = deinit,
|
||||
.@"addEventListener" = addEventListener,
|
||||
.@"removeEventListener" = removeEventListener,
|
||||
.@"prependEventListener" = prependEventListener,
|
||||
.@"pipe" = pipe,
|
||||
.@"unpipe" = unpipe,
|
||||
.@"unshift" = unshift,
|
||||
.@"read" = read,
|
||||
.@"pause" = pause,
|
||||
.@"resume" = State.@"resume",
|
||||
});
|
||||
|
||||
pub const Extern = [_][]const u8{"create"};
|
||||
|
||||
comptime {
|
||||
if (!is_bindgen) {
|
||||
@export(deinit, .{
|
||||
.name = Export[0].symbol_name,
|
||||
});
|
||||
@export(addEventListener, .{
|
||||
.name = Export[1].symbol_name,
|
||||
});
|
||||
@export(removeEventListener, .{
|
||||
.name = Export[2].symbol_name,
|
||||
});
|
||||
@export(prependEventListener, .{
|
||||
.name = Export[3].symbol_name,
|
||||
});
|
||||
@export(
|
||||
pipe,
|
||||
.{ .name = Export[4].symbol_name },
|
||||
);
|
||||
@export(
|
||||
unpipe,
|
||||
.{ .name = Export[5].symbol_name },
|
||||
);
|
||||
@export(
|
||||
unshift,
|
||||
.{ .name = Export[6].symbol_name },
|
||||
);
|
||||
@export(
|
||||
read,
|
||||
.{ .name = Export[7].symbol_name },
|
||||
);
|
||||
@export(
|
||||
pause,
|
||||
.{ .name = Export[8].symbol_name },
|
||||
);
|
||||
@export(
|
||||
State.@"resume",
|
||||
.{ .name = Export[9].symbol_name },
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub const Path = struct {
|
||||
pub const shim = Shimmer("Bun", "Path", @This());
|
||||
pub const name = "Bun__Path";
|
||||
@@ -2694,10 +1753,5 @@ pub const Process = struct {
|
||||
|
||||
comptime {
|
||||
std.testing.refAllDecls(Process);
|
||||
std.testing.refAllDecls(Stream);
|
||||
std.testing.refAllDecls(Readable);
|
||||
std.testing.refAllDecls(Path);
|
||||
std.testing.refAllDecls(Writable);
|
||||
std.testing.refAllDecls(Writable.State);
|
||||
std.testing.refAllDecls(Readable.State);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user