aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-22 23:44:53 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-22 23:45:02 -0700
commit2c1926993bc4d94f9e7bc4d171217a707efd385c (patch)
tree827148c57920e40ad48c4c6d73ceec68a9b21c96 /src/bun.js
parente14a3af491ece8d1b0309e76ae3022b4fad91f16 (diff)
downloadbun-2c1926993bc4d94f9e7bc4d171217a707efd385c.tar.gz
bun-2c1926993bc4d94f9e7bc4d171217a707efd385c.tar.zst
bun-2c1926993bc4d94f9e7bc4d171217a707efd385c.zip
Faster `Blob` + begin to implement `FileSink`
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/api/bun.zig10
-rw-r--r--src/bun.js/api/server.zig2
-rw-r--r--src/bun.js/bindings/JSSink.cpp463
-rw-r--r--src/bun.js/bindings/JSSink.h177
-rw-r--r--src/bun.js/bindings/JSSinkLookupTable.h78
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h3
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h3
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h8
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h7
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.cpp413
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.h124
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp27
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h9
-rw-r--r--src/bun.js/bindings/bindings.zig26
-rw-r--r--src/bun.js/bindings/exports.zig10
-rw-r--r--src/bun.js/bindings/generated_classes.zig90
-rw-r--r--src/bun.js/bindings/generated_classes_list.zig1
-rw-r--r--src/bun.js/bindings/headers-cpp.h8
-rw-r--r--src/bun.js/bindings/headers.h21
-rw-r--r--src/bun.js/bindings/headers.zig6
-rw-r--r--src/bun.js/event_loop.zig7
-rw-r--r--src/bun.js/javascript.zig1
-rw-r--r--src/bun.js/scripts/class-definitions.ts1
-rw-r--r--src/bun.js/scripts/generate-classes.ts105
-rw-r--r--src/bun.js/scripts/generate-jssink.js18
-rw-r--r--src/bun.js/webcore/response.classes.ts28
-rw-r--r--src/bun.js/webcore/response.zig346
-rw-r--r--src/bun.js/webcore/streams.zig443
28 files changed, 2161 insertions, 274 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index e01868af6..8a75c3653 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -282,8 +282,8 @@ pub fn getStdin(
blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
return ctx.ptr().putCachedObject(
- &ZigString.init("BunSTDIN"),
- JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ ZigString.static("BunSTDIN"),
+ blob.toJS(ctx),
).asObjectRef();
}
@@ -305,8 +305,8 @@ pub fn getStderr(
blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
return ctx.ptr().putCachedObject(
- &ZigString.init("BunSTDERR"),
- JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ ZigString.static("BunSTDERR"),
+ blob.toJS(ctx),
).asObjectRef();
}
@@ -329,7 +329,7 @@ pub fn getStdout(
return ctx.ptr().putCachedObject(
&ZigString.init("BunSTDOUT"),
- JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ blob.toJS(ctx),
).asObjectRef();
}
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index 2410b5e7c..d7cfbe4c1 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -1933,7 +1933,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
}
if (opts.fastGet(ctx.ptr(), .body)) |body__| {
- if (Blob.fromJS(ctx.ptr(), body__, true, false)) |new_blob| {
+ if (Blob.get(ctx.ptr(), body__, true, false)) |new_blob| {
body = .{ .Blob = new_blob };
} else |_| {
return JSPromise.rejectedPromiseValue(globalThis, ZigString.init("fetch() received invalid body").toErrorInstance(globalThis)).asRef();
diff --git a/src/bun.js/bindings/JSSink.cpp b/src/bun.js/bindings/JSSink.cpp
index fbb8b56fb..47bb2cac3 100644
--- a/src/bun.js/bindings/JSSink.cpp
+++ b/src/bun.js/bindings/JSSink.cpp
@@ -1,6 +1,6 @@
// AUTO-GENERATED FILE. DO NOT EDIT.
-// Generated by 'make generate-sink' at 2022-08-27T22:18:48.797Z
+// Generated by 'make generate-sink' at 2022-09-23T02:14:49.416Z
// To regenerate this file, run:
//
// make generate-sink
@@ -101,6 +101,16 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic
}
+ else if (WebCore::JSReadableFileSinkController* FileSinkController = JSC::jsDynamicCast<WebCore::JSReadableFileSinkController*>(callFrame->thisValue())) {
+ if (FileSinkController->wrapped() == nullptr) {
+ scope.throwException(globalObject, JSC::createTypeError(globalObject, "Cannot start stream with closed controller"_s));
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ FileSinkController->start(globalObject, readableStream, onPullFunction, onCloseFunction);
+ }
+
+
else if (WebCore::JSReadableHTTPResponseSinkController* HTTPResponseSinkController = JSC::jsDynamicCast<WebCore::JSReadableHTTPResponseSinkController*>(callFrame->thisValue())) {
if (HTTPResponseSinkController->wrapped() == nullptr) {
scope.throwException(globalObject, JSC::createTypeError(globalObject, "Cannot start stream with closed controller"_s));
@@ -210,6 +220,88 @@ JSC_DEFINE_HOST_FUNCTION(ArrayBufferSink__doClose, (JSC::JSGlobalObject * lexica
+JSC_DEFINE_CUSTOM_GETTER(functionFileSink__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+
+ return JSC::JSValue::encode(globalObject->FileSink());
+}
+
+
+JSC_DECLARE_HOST_FUNCTION(JSReadableFileSinkController__close);
+JSC_DEFINE_HOST_FUNCTION(JSReadableFileSinkController__close, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame))
+{
+
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ WebCore::JSReadableFileSinkController* controller = JSC::jsDynamicCast<WebCore::JSReadableFileSinkController*>(callFrame->thisValue());
+ if (!controller) {
+ scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected JSReadableFileSinkController"_s));
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ void *ptr = controller->wrapped();
+ if (ptr == nullptr) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ controller->detach();
+ FileSink__close(lexicalGlobalObject, ptr);
+ // Release the controller right before close.
+ controller->m_hasPendingActivity = false;
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+JSC_DECLARE_HOST_FUNCTION(JSReadableFileSinkController__end);
+JSC_DEFINE_HOST_FUNCTION(JSReadableFileSinkController__end, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame))
+{
+
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ WebCore::JSReadableFileSinkController* controller = JSC::jsDynamicCast<WebCore::JSReadableFileSinkController*>(callFrame->thisValue());
+ if (!controller) {
+ scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected JSReadableFileSinkController"_s));
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ void *ptr = controller->wrapped();
+ if (ptr == nullptr) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ controller->detach();
+ return FileSink__endWithSink(ptr, lexicalGlobalObject);
+}
+
+
+JSC_DECLARE_HOST_FUNCTION(FileSink__doClose);
+JSC_DEFINE_HOST_FUNCTION(FileSink__doClose, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame))
+{
+
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ WebCore::JSFileSink* sink = JSC::jsDynamicCast<WebCore::JSFileSink*>(callFrame->thisValue());
+ if (!sink) {
+ scope.throwException(globalObject, JSC::createTypeError(globalObject, "Expected FileSink"_s));
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ void *ptr = sink->wrapped();
+ if (ptr == nullptr) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ sink->detach();
+ FileSink__close(lexicalGlobalObject, ptr);
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+
+
JSC_DEFINE_CUSTOM_GETTER(functionHTTPResponseSink__getter, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -398,6 +490,28 @@ JSC_DEFINE_HOST_FUNCTION(HTTPSResponseSink__doClose, (JSC::JSGlobalObject * lexi
*/
+/* Source for JSFileSinkPrototypeTableValues.lut.h
+@begin JSFileSinkPrototypeTable
+ close FileSink__doClose ReadOnly|DontDelete|Function 0
+ flush FileSink__flush ReadOnly|DontDelete|Function 1
+ end FileSink__end ReadOnly|DontDelete|Function 0
+ start FileSink__start ReadOnly|DontDelete|Function 1
+ write FileSink__write ReadOnly|DontDelete|Function 1
+@end
+*/
+
+
+/* Source for JSReadableFileSinkControllerPrototypeTableValues.lut.h
+@begin JSReadableFileSinkControllerPrototypeTable
+ close JSReadableFileSinkController__close ReadOnly|DontDelete|Function 0
+ flush FileSink__flush ReadOnly|DontDelete|Function 1
+ end JSReadableFileSinkController__end ReadOnly|DontDelete|Function 0
+ start FileSink__start ReadOnly|DontDelete|Function 1
+ write FileSink__write ReadOnly|DontDelete|Function 1
+@end
+*/
+
+
/* Source for JSHTTPResponseSinkPrototypeTableValues.lut.h
@begin JSHTTPResponseSinkPrototypeTable
close HTTPResponseSink__doClose ReadOnly|DontDelete|Function 0
@@ -688,6 +802,252 @@ void JSReadableArrayBufferSinkController::destroy(JSCell* cell)
+#pragma mark - FileSink
+
+class JSFileSinkPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+
+ static JSFileSinkPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSFileSinkPrototype* ptr = new (NotNull, JSC::allocateCell<JSFileSinkPrototype>(vm)) JSFileSinkPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm, globalObject);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSFileSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFileSinkPrototype, JSFileSinkPrototype::Base);
+
+class JSReadableFileSinkControllerPrototype final : public JSC::JSNonFinalObject {
+ public:
+ using Base = JSC::JSNonFinalObject;
+
+ static JSReadableFileSinkControllerPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSReadableFileSinkControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableFileSinkControllerPrototype>(vm)) JSReadableFileSinkControllerPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm, globalObject);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ private:
+ JSReadableFileSinkControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+ };
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableFileSinkControllerPrototype, JSReadableFileSinkControllerPrototype::Base);
+
+const ClassInfo JSFileSinkPrototype::s_info = { "FileSink"_s, &Base::s_info, &JSFileSinkPrototypeTable, nullptr, CREATE_METHOD_TABLE(JSFileSinkPrototype) };
+const ClassInfo JSFileSink::s_info = { "FileSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFileSink) };
+const ClassInfo JSFileSinkConstructor::s_info = { "FileSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFileSinkConstructor) };
+
+
+const ClassInfo JSReadableFileSinkControllerPrototype::s_info = { "ReadableFileSinkController"_s, &Base::s_info, &JSReadableFileSinkControllerPrototypeTable, nullptr, CREATE_METHOD_TABLE(JSReadableFileSinkControllerPrototype) };
+const ClassInfo JSReadableFileSinkController::s_info = { "ReadableFileSinkController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableFileSinkController) };
+
+JSFileSink::~JSFileSink()
+{
+ if (m_sinkPtr) {
+ FileSink__finalize(m_sinkPtr);
+ }
+}
+
+
+JSReadableFileSinkController::~JSReadableFileSinkController()
+{
+ if (m_sinkPtr) {
+ FileSink__finalize(m_sinkPtr);
+ }
+}
+
+JSObject* JSFileSink::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSFileSinkPrototype::create(vm, &globalObject, JSFileSinkPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSReadableFileSinkController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSReadableFileSinkControllerPrototype::create(vm, &globalObject, JSReadableFileSinkControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+void JSReadableFileSinkController::detach() {
+ m_sinkPtr = nullptr;
+ m_onPull.clear();
+
+ auto readableStream = m_weakReadableStream.get();
+ auto onClose = m_onClose.get();
+ m_onClose.clear();
+
+ if (readableStream && onClose) {
+ JSC::JSGlobalObject *globalObject = this->globalObject();
+ auto callData = JSC::getCallData(onClose);
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ JSC::call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
+
+ m_weakReadableStream.clear();
+}
+
+
+JSFileSinkConstructor* JSFileSinkConstructor::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSObject* prototype)
+{
+ JSFileSinkConstructor* ptr = new (NotNull, JSC::allocateCell<JSFileSinkConstructor>(vm)) JSFileSinkConstructor(vm, structure, FileSink__construct);
+ ptr->finishCreation(vm, globalObject, prototype);
+ return ptr;
+}
+
+JSFileSink* JSFileSink::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr)
+{
+ JSFileSink* ptr = new (NotNull, JSC::allocateCell<JSFileSink>(vm)) JSFileSink(vm, structure, sinkPtr);
+ ptr->finishCreation(vm);
+ return ptr;
+}
+
+JSReadableFileSinkController* JSReadableFileSinkController::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr)
+{
+ JSReadableFileSinkController* ptr = new (NotNull, JSC::allocateCell<JSReadableFileSinkController>(vm)) JSReadableFileSinkController(vm, structure, sinkPtr);
+ ptr->finishCreation(vm);
+ return ptr;
+}
+
+void JSFileSinkConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSObject* prototype)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+ initializeProperties(vm, globalObject, prototype);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSFileSinkConstructor::construct(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) {
+ return FileSink__construct(globalObject, callFrame);
+}
+
+
+void JSFileSinkConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSObject* prototype)
+{
+ putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ JSString* nameString = jsNontrivialString(vm, "FileSink"_s);
+ m_originalName.set(vm, this, nameString);
+ putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+}
+
+void JSFileSinkPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSFileSink::info(), JSFileSinkPrototypeTableValues, *this);
+ putDirect(vm, JSC::Identifier::fromString(vm, "sinkId"_s), JSC::jsNumber(JSFileSink::Sink), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+void JSReadableFileSinkControllerPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSReadableFileSinkController::info(), JSReadableFileSinkControllerPrototypeTableValues, *this);
+ putDirect(vm, JSC::Identifier::fromString(vm, "sinkId"_s), JSC::jsNumber(JSFileSink::Sink), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+void JSFileSink::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+void JSReadableFileSinkController::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+
+void JSFileSink::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSFileSink*>(cell);
+ if (void* wrapped = thisObject->wrapped()) {
+ analyzer.setWrappedObjectForCell(cell, wrapped);
+ // if (thisObject->scriptExecutionContext())
+ // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ }
+ Base::analyzeHeap(cell, analyzer);
+}
+
+void JSReadableFileSinkController::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSReadableFileSinkController*>(cell);
+ if (void* wrapped = thisObject->wrapped()) {
+ analyzer.setWrappedObjectForCell(cell, wrapped);
+ // if (thisObject->scriptExecutionContext())
+ // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ }
+ Base::analyzeHeap(cell, analyzer);
+}
+
+
+template<typename Visitor>
+void JSReadableFileSinkController::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ JSReadableFileSinkController* thisObject = jsCast<JSReadableFileSinkController*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ visitor.append(thisObject->m_onPull);
+ visitor.append(thisObject->m_onClose);
+ visitor.append(thisObject->m_weakReadableStream);
+}
+
+DEFINE_VISIT_CHILDREN(JSReadableFileSinkController);
+
+
+void JSReadableFileSinkController::start(JSC::JSGlobalObject *globalObject, JSC::JSValue readableStream, JSC::JSFunction *onPull, JSC::JSFunction *onClose) {
+ this->m_weakReadableStream = JSC::Weak<JSC::JSObject>(readableStream.getObject());
+ this->m_onPull.set(globalObject->vm(), this, onPull);
+ this->m_onClose.set(globalObject->vm(), this, onClose);
+}
+
+void JSFileSink::destroy(JSCell* cell)
+{
+ static_cast<JSFileSink*>(cell)->JSFileSink::~JSFileSink();
+}
+
+
+void JSReadableFileSinkController::destroy(JSCell* cell)
+{
+ static_cast<JSReadableFileSinkController*>(cell)->JSReadableFileSinkController::~JSReadableFileSinkController();
+}
+
+
+
#pragma mark - HTTPResponseSink
class JSHTTPResponseSinkPrototype final : public JSC::JSNonFinalObject {
@@ -1187,6 +1547,9 @@ void JSReadableHTTPSResponseSinkController::destroy(JSCell* cell)
case ArrayBufferSink:
return JSArrayBufferSinkPrototype::create(vm, globalObject, JSArrayBufferSinkPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+ case FileSink:
+ return JSFileSinkPrototype::create(vm, globalObject, JSFileSinkPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+
case HTTPResponseSink:
return JSHTTPResponseSinkPrototype::create(vm, globalObject, JSHTTPResponseSinkPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
@@ -1204,6 +1567,9 @@ JSObject* createJSSinkControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject* glob
case ArrayBufferSink:
return JSReadableArrayBufferSinkControllerPrototype::create(vm, globalObject, JSReadableArrayBufferSinkControllerPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+ case FileSink:
+ return JSReadableFileSinkControllerPrototype::create(vm, globalObject, JSReadableFileSinkControllerPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+
case HTTPResponseSink:
return JSReadableHTTPResponseSinkControllerPrototype::create(vm, globalObject, JSReadableHTTPResponseSinkControllerPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
@@ -1223,6 +1589,11 @@ Structure* createJSSinkControllerStructure(JSC::VM& vm, JSC::JSGlobalObject* glo
return JSReadableArrayBufferSinkController::createStructure(vm, globalObject, prototype);
}
+ case FileSink: {
+ auto* prototype = createJSSinkControllerPrototype(vm, globalObject, sinkID);
+ return JSReadableFileSinkController::createStructure(vm, globalObject, prototype);
+ }
+
case HTTPResponseSink: {
auto* prototype = createJSSinkControllerPrototype(vm, globalObject, sinkID);
return JSReadableHTTPResponseSinkController::createStructure(vm, globalObject, prototype);
@@ -1330,6 +1701,96 @@ extern "C" void ArrayBufferSink__onClose(JSC__JSValue controllerValue, JSC__JSVa
}
+extern "C" JSC__JSValue FileSink__createObject(JSC__JSGlobalObject* arg0, void* sinkPtr)
+{
+ auto& vm = arg0->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(arg0);
+ JSC::JSValue prototype = globalObject->FileSinkPrototype();
+ JSC::Structure* structure = WebCore::JSFileSink::createStructure(vm, globalObject, prototype);
+ return JSC::JSValue::encode(WebCore::JSFileSink::create(vm, globalObject, structure, sinkPtr));
+}
+
+extern "C" void* FileSink__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1)
+{
+ JSC::VM& vm = WebCore::getVM(arg0);
+ if (auto* sink = JSC::jsDynamicCast<WebCore::JSFileSink*>(JSC::JSValue::decode(JSValue1)))
+ return sink->wrapped();
+
+ if (auto* controller = JSC::jsDynamicCast<WebCore::JSReadableFileSinkController*>(JSC::JSValue::decode(JSValue1)))
+ return controller->wrapped();
+
+ return nullptr;
+}
+
+extern "C" void FileSink__detachPtr(JSC__JSValue JSValue0)
+{
+ if (auto* sink = JSC::jsDynamicCast<WebCore::JSFileSink*>(JSC::JSValue::decode(JSValue0))) {
+ sink->detach();
+ return;
+ }
+
+
+ if (auto* controller = JSC::jsDynamicCast<WebCore::JSReadableFileSinkController*>(JSC::JSValue::decode(JSValue0))) {
+ controller->detach();
+ return;
+ }
+}
+
+extern "C" JSC__JSValue FileSink__assignToStream(JSC__JSGlobalObject* arg0, JSC__JSValue stream, void* sinkPtr, void **controllerValue)
+{
+ auto& vm = arg0->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(arg0);
+
+ JSC::Structure* structure = WebCore::getDOMStructure<WebCore::JSReadableFileSinkController>(vm, *globalObject);
+ WebCore::JSReadableFileSinkController *controller = WebCore::JSReadableFileSinkController::create(vm, globalObject, structure, sinkPtr);
+ *controllerValue = reinterpret_cast<void*>(JSC::JSValue::encode(controller));
+ return globalObject->assignToStream(JSC::JSValue::decode(stream), controller);
+}
+
+extern "C" void FileSink__onReady(JSC__JSValue controllerValue, JSC__JSValue amt, JSC__JSValue offset)
+{
+ WebCore::JSReadableFileSinkController* controller = JSC::jsCast<WebCore::JSReadableFileSinkController*>(JSC::JSValue::decode(controllerValue).getObject());
+
+ JSC::JSFunction *function = controller->m_onPull.get();
+ if (function == nullptr)
+ return;
+ JSC::JSGlobalObject *globalObject = controller->globalObject();
+
+ auto callData = JSC::getCallData(function);
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(controller);
+ arguments.append(JSC::JSValue::decode(amt));
+ arguments.append(JSC::JSValue::decode(offset));
+
+ JSC::call(globalObject, function, callData, JSC::jsUndefined(), arguments);
+}
+
+extern "C" void FileSink__onStart(JSC__JSValue controllerValue)
+{
+
+}
+
+extern "C" void FileSink__onClose(JSC__JSValue controllerValue, JSC__JSValue reason)
+{
+ WebCore::JSReadableFileSinkController* controller = JSC::jsCast<WebCore::JSReadableFileSinkController*>(JSC::JSValue::decode(controllerValue).getObject());
+
+ JSC::JSFunction *function = controller->m_onClose.get();
+ if (function == nullptr)
+ return;
+ // only call close once
+ controller->m_onClose.clear();
+ JSC::JSGlobalObject *globalObject = controller->globalObject();
+
+ auto callData = JSC::getCallData(function);
+ JSC::MarkedArgumentBuffer arguments;
+ auto readableStream = controller->m_weakReadableStream.get();
+ arguments.append(readableStream ? readableStream : JSC::jsUndefined());
+
+ arguments.append(JSC::JSValue::decode(reason));
+ JSC::call(globalObject, function, callData, JSC::jsUndefined(), arguments);
+}
+
+
extern "C" JSC__JSValue HTTPResponseSink__createObject(JSC__JSGlobalObject* arg0, void* sinkPtr)
{
auto& vm = arg0->vm();
diff --git a/src/bun.js/bindings/JSSink.h b/src/bun.js/bindings/JSSink.h
index 0cf046ffa..e55545302 100644
--- a/src/bun.js/bindings/JSSink.h
+++ b/src/bun.js/bindings/JSSink.h
@@ -1,6 +1,6 @@
// AUTO-GENERATED FILE. DO NOT EDIT.
-// Generated by 'make generate-sink' at 2022-08-27T22:18:48.793Z
+// Generated by 'make generate-sink' at 2022-09-23T02:14:49.415Z
//
#pragma once
@@ -108,6 +108,8 @@ class JSArrayBufferSinkConstructor final : public JSC::InternalFunction {
void finishCreation(JSC::VM&);
};
+
+
class JSReadableArrayBufferSinkController final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
@@ -184,6 +186,175 @@ class JSArrayBufferSinkConstructor final : public JSC::InternalFunction {
JSC_DECLARE_CUSTOM_GETTER(functionArrayBufferSink__getter);
+class JSFileSinkConstructor final : public JSC::InternalFunction {
+ public:
+ using Base = JSC::InternalFunction;
+ static JSFileSinkConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype);
+ static constexpr SinkID Sink = SinkID::FileSink;
+
+ static constexpr unsigned StructureFlags = Base::StructureFlags;
+ static constexpr bool needsDestruction = false;
+
+ DECLARE_EXPORT_INFO;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSFileSinkConstructor, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkConstructor.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkConstructor = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForJSSinkConstructor.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkConstructor = WTFMove(space); });
+ }
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
+ }
+ void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype);
+
+
+ // Must be defined for each specialization class.
+ static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*);
+
+ private:
+ JSFileSinkConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction)
+ : Base(vm, structure, nativeFunction, nativeFunction)
+
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSC::JSObject* prototype);
+ };
+
+ class JSFileSink final : public JSC::JSDestructibleObject {
+ public:
+ using Base = JSC::JSDestructibleObject;
+ static JSFileSink* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr);
+ static constexpr SinkID Sink = SinkID::FileSink;
+
+ DECLARE_EXPORT_INFO;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSFileSink, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForJSSink.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSink = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForJSSink.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSink = WTFMove(space); });
+ }
+
+ static void destroy(JSC::JSCell*);
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ static JSObject* createPrototype(VM& vm, JSDOMGlobalObject& globalObject);
+
+ ~JSFileSink();
+
+ void* wrapped() const { return m_sinkPtr; }
+
+ void detach() {
+ m_sinkPtr = nullptr;
+
+ }
+
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+
+ void* m_sinkPtr;
+
+ JSFileSink(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
+ : Base(vm, structure)
+ {
+ m_sinkPtr = sinkPtr;
+ }
+
+ void finishCreation(JSC::VM&);
+ };
+
+
+
+ class JSReadableFileSinkController final : public JSC::JSDestructibleObject {
+ public:
+ using Base = JSC::JSDestructibleObject;
+ static JSReadableFileSinkController* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* sinkPtr);
+ static constexpr SinkID Sink = SinkID::FileSink;
+
+ DECLARE_EXPORT_INFO;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSReadableFileSinkController, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForJSSinkController.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSinkController = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForJSSinkController.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSinkController = WTFMove(space); });
+ }
+
+ static void destroy(JSC::JSCell*);
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+ static JSObject* createPrototype(VM& vm, JSDOMGlobalObject& globalObject);
+
+ ~JSReadableFileSinkController();
+
+
+ void* wrapped() const { return m_sinkPtr; }
+ void detach();
+
+ void start(JSC::JSGlobalObject *globalObject, JSC::JSValue readableStream, JSC::JSFunction *onPull, JSC::JSFunction *onClose);
+ DECLARE_VISIT_CHILDREN;
+
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+
+ bool hasPendingActivity() { return m_hasPendingActivity; }
+
+ void* m_sinkPtr;
+ bool m_hasPendingActivity;
+ mutable WriteBarrier<JSC::JSFunction> m_onPull;
+ mutable WriteBarrier<JSC::JSFunction> m_onClose;
+ mutable JSC::Weak<JSObject> m_weakReadableStream;
+ JSC::Weak<JSReadableFileSinkController> m_weakThis;
+
+ JSReadableFileSinkController(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
+ : Base(vm, structure)
+ {
+ m_sinkPtr = sinkPtr;
+ m_hasPendingActivity = true;
+ m_weakThis = JSC::Weak<JSReadableFileSinkController>(this, getOwner());
+ }
+
+ void finishCreation(JSC::VM&);
+
+ class Owner final : public JSC::WeakHandleOwner {
+ public:
+ bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, JSC::AbstractSlotVisitor&, const char**) final
+ {
+ auto* controller = JSC::jsCast<JSReadableFileSinkController*>(handle.slot()->asCell());
+ return controller->hasPendingActivity();
+ }
+ void finalize(JSC::Handle<JSC::Unknown>, void* context) final {}
+ };
+
+ static JSC::WeakHandleOwner* getOwner()
+ {
+ static NeverDestroyed<Owner> m_owner;
+ return &m_owner.get();
+ }
+ };
+
+JSC_DECLARE_CUSTOM_GETTER(functionFileSink__getter);
+
+
class JSHTTPResponseSinkConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
@@ -275,6 +446,8 @@ class JSHTTPResponseSinkConstructor final : public JSC::InternalFunction {
void finishCreation(JSC::VM&);
};
+
+
class JSReadableHTTPResponseSinkController final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
@@ -442,6 +615,8 @@ class JSHTTPSResponseSinkConstructor final : public JSC::InternalFunction {
void finishCreation(JSC::VM&);
};
+
+
class JSReadableHTTPSResponseSinkController final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
diff --git a/src/bun.js/bindings/JSSinkLookupTable.h b/src/bun.js/bindings/JSSinkLookupTable.h
index 8d0f8cde5..14d547708 100644
--- a/src/bun.js/bindings/JSSinkLookupTable.h
+++ b/src/bun.js/bindings/JSSinkLookupTable.h
@@ -82,6 +82,84 @@ static const struct HashTable JSReadableArrayBufferSinkControllerPrototypeTable
+static const struct CompactHashIndex JSFileSinkPrototypeTableIndex[19] = {
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 0, 16 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { 1, 17 },
+ { 2, 18 },
+ { 3, -1 },
+};
+
+static const struct HashTableValue JSFileSinkPrototypeTableValues[5] = {
+ { "close"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__doClose, 0 } },
+ { "flush"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__flush, 1 } },
+ { "end"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__end, 0 } },
+ { "start"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__start, 1 } },
+ { "write"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__write, 1 } },
+};
+
+static const struct HashTable JSFileSinkPrototypeTable =
+ { 5, 15, false, nullptr, JSFileSinkPrototypeTableValues, JSFileSinkPrototypeTableIndex };
+
+
+
+
+
+
+
+static const struct CompactHashIndex JSReadableFileSinkControllerPrototypeTableIndex[19] = {
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 0, 16 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { 1, 17 },
+ { 2, 18 },
+ { 3, -1 },
+};
+
+static const struct HashTableValue JSReadableFileSinkControllerPrototypeTableValues[5] = {
+ { "close"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, JSReadableFileSinkController__close, 0 } },
+ { "flush"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__flush, 1 } },
+ { "end"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, JSReadableFileSinkController__end, 0 } },
+ { "start"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__start, 1 } },
+ { "write"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly|PropertyAttribute::DontDelete|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSink__write, 1 } },
+};
+
+static const struct HashTable JSReadableFileSinkControllerPrototypeTable =
+ { 5, 15, false, nullptr, JSReadableFileSinkControllerPrototypeTableValues, JSReadableFileSinkControllerPrototypeTableIndex };
+
+
+
+
+
+
+
static const struct CompactHashIndex JSHTTPResponseSinkPrototypeTableIndex[19] = {
{ -1, -1 },
{ -1, -1 },
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
index 03282a16a..b4d389d46 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
@@ -9,4 +9,5 @@ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA256Constructor;std:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA512_256Constructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoder;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoderConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequest;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequestConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResponse;
-std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResponseConstructor; \ No newline at end of file
+std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResponseConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBlob;
+std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBlobConstructor; \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
index 0cbf0776c..b23b98853 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
@@ -9,4 +9,5 @@ std::unique_ptr<IsoSubspace> m_subspaceForSHA256Constructor;std::unique_ptr<IsoS
std::unique_ptr<IsoSubspace> m_subspaceForSHA512_256Constructor;std::unique_ptr<IsoSubspace> m_subspaceForTextDecoder;
std::unique_ptr<IsoSubspace> m_subspaceForTextDecoderConstructor;std::unique_ptr<IsoSubspace> m_subspaceForRequest;
std::unique_ptr<IsoSubspace> m_subspaceForRequestConstructor;std::unique_ptr<IsoSubspace> m_subspaceForResponse;
-std::unique_ptr<IsoSubspace> m_subspaceForResponseConstructor; \ No newline at end of file
+std::unique_ptr<IsoSubspace> m_subspaceForResponseConstructor;std::unique_ptr<IsoSubspace> m_subspaceForBlob;
+std::unique_ptr<IsoSubspace> m_subspaceForBlobConstructor; \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
index c7b1fa75a..31100e3a4 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
@@ -63,4 +63,10 @@ JSC::Structure* JSResponseStructure() { return m_JSResponse.getInitializedOnMain
JSC::JSValue JSResponsePrototype() { return m_JSResponse.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSResponse;
bool hasJSResponseSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSResponseSetterValue; \ No newline at end of file
+ mutable JSC::WriteBarrier<JSC::Unknown> m_JSResponseSetterValue;
+JSC::Structure* JSBlobStructure() { return m_JSBlob.getInitializedOnMainThread(this); }
+ JSC::JSObject* JSBlobConstructor() { return m_JSBlob.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSBlobPrototype() { return m_JSBlob.prototypeInitializedOnMainThread(this); }
+ JSC::LazyClassStructure m_JSBlob;
+ bool hasJSBlobSetterValue { false };
+ mutable JSC::WriteBarrier<JSC::Unknown> m_JSBlobSetterValue; \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
index 695424897..d5d28ec81 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
@@ -65,6 +65,12 @@ void GlobalObject::initGeneratedLazyClasses() {
init.setStructure(WebCore::JSResponse::createStructure(init.vm, init.global, init.prototype));
init.setConstructor(WebCore::JSResponseConstructor::create(init.vm, init.global, WebCore::JSResponseConstructor::createStructure(init.vm, init.global, init.global->functionPrototype()), jsCast<WebCore::JSResponsePrototype*>(init.prototype)));
});
+ m_JSBlob.initLater(
+ [](LazyClassStructure::Initializer& init) {
+ init.setPrototype(WebCore::JSBlob::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global)));
+ init.setStructure(WebCore::JSBlob::createStructure(init.vm, init.global, init.prototype));
+ init.setConstructor(WebCore::JSBlobConstructor::create(init.vm, init.global, WebCore::JSBlobConstructor::createStructure(init.vm, init.global, init.global->functionPrototype()), jsCast<WebCore::JSBlobPrototype*>(init.prototype)));
+ });
}
template<typename Visitor>
void GlobalObject::visitGeneratedLazyClasses(GlobalObject *thisObject, Visitor& visitor)
@@ -80,4 +86,5 @@ void GlobalObject::visitGeneratedLazyClasses(GlobalObject *thisObject, Visitor&
thisObject->m_JSTextDecoder.visit(visitor); visitor.append(thisObject->m_JSTextDecoderSetterValue);
thisObject->m_JSRequest.visit(visitor); visitor.append(thisObject->m_JSRequestSetterValue);
thisObject->m_JSResponse.visit(visitor); visitor.append(thisObject->m_JSResponseSetterValue);
+ thisObject->m_JSBlob.visit(visitor); visitor.append(thisObject->m_JSBlobSetterValue);
} \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp
index 12db35785..90c628c01 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses.cpp
+++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp
@@ -192,9 +192,9 @@ void JSSHA1Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* global
const ClassInfo JSSHA1Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA1Constructor) };
-extern "C" EncodedJSValue SHA1__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA1Constructor());
-}
+ extern "C" EncodedJSValue SHA1__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA1Constructor());
+ }
JSSHA1::~JSSHA1()
{
@@ -424,9 +424,9 @@ void JSMD5Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalO
const ClassInfo JSMD5Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMD5Constructor) };
-extern "C" EncodedJSValue MD5__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSMD5Constructor());
-}
+ extern "C" EncodedJSValue MD5__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSMD5Constructor());
+ }
JSMD5::~JSMD5()
{
@@ -656,9 +656,9 @@ void JSMD4Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalO
const ClassInfo JSMD4Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMD4Constructor) };
-extern "C" EncodedJSValue MD4__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSMD4Constructor());
-}
+ extern "C" EncodedJSValue MD4__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSMD4Constructor());
+ }
JSMD4::~JSMD4()
{
@@ -888,9 +888,9 @@ void JSSHA224Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* glob
const ClassInfo JSSHA224Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA224Constructor) };
-extern "C" EncodedJSValue SHA224__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA224Constructor());
-}
+ extern "C" EncodedJSValue SHA224__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA224Constructor());
+ }
JSSHA224::~JSSHA224()
{
@@ -1120,9 +1120,9 @@ void JSSHA512Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* glob
const ClassInfo JSSHA512Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA512Constructor) };
-extern "C" EncodedJSValue SHA512__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA512Constructor());
-}
+ extern "C" EncodedJSValue SHA512__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA512Constructor());
+ }
JSSHA512::~JSSHA512()
{
@@ -1352,9 +1352,9 @@ void JSSHA384Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* glob
const ClassInfo JSSHA384Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA384Constructor) };
-extern "C" EncodedJSValue SHA384__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA384Constructor());
-}
+ extern "C" EncodedJSValue SHA384__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA384Constructor());
+ }
JSSHA384::~JSSHA384()
{
@@ -1584,9 +1584,9 @@ void JSSHA256Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* glob
const ClassInfo JSSHA256Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA256Constructor) };
-extern "C" EncodedJSValue SHA256__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA256Constructor());
-}
+ extern "C" EncodedJSValue SHA256__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA256Constructor());
+ }
JSSHA256::~JSSHA256()
{
@@ -1816,9 +1816,9 @@ void JSSHA512_256Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject*
const ClassInfo JSSHA512_256Constructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSHA512_256Constructor) };
-extern "C" EncodedJSValue SHA512_256__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSSHA512_256Constructor());
-}
+ extern "C" EncodedJSValue SHA512_256__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSSHA512_256Constructor());
+ }
JSSHA512_256::~JSSHA512_256()
{
@@ -2042,9 +2042,9 @@ void JSTextDecoderConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject*
const ClassInfo JSTextDecoderConstructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTextDecoderConstructor) };
-extern "C" EncodedJSValue TextDecoder__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSTextDecoderConstructor());
-}
+ extern "C" EncodedJSValue TextDecoder__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSTextDecoderConstructor());
+ }
JSTextDecoder::~JSTextDecoder()
{
@@ -2554,9 +2554,9 @@ void JSRequestConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* glo
const ClassInfo JSRequestConstructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSRequestConstructor) };
-extern "C" EncodedJSValue Request__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSRequestConstructor());
-}
+ extern "C" EncodedJSValue Request__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSRequestConstructor());
+ }
JSRequest::~JSRequest()
{
@@ -2995,9 +2995,9 @@ void JSResponseConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* gl
const ClassInfo JSResponseConstructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSResponseConstructor) };
-extern "C" EncodedJSValue Response__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->JSResponseConstructor());
-}
+ extern "C" EncodedJSValue Response__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSResponseConstructor());
+ }
JSResponse::~JSResponse()
{
@@ -3071,7 +3071,352 @@ void JSResponse::visitChildrenImpl(JSCell* cell, Visitor& visitor)
visitor.append(thisObject->m_url);
}
-DEFINE_VISIT_CHILDREN(JSResponse);
+DEFINE_VISIT_CHILDREN(JSResponse);extern "C" void* BlobClass__construct(JSC::JSGlobalObject*, JSC::CallFrame*);
+JSC_DECLARE_CUSTOM_GETTER(jsBlobConstructor);
+extern "C" void BlobClass__finalize(void*);
+
+extern "C" EncodedJSValue BlobPrototype__getArrayBuffer(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__arrayBufferCallback);
+
+
+extern "C" EncodedJSValue BlobPrototype__getJSON(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__jsonCallback);
+
+
+extern "C" JSC::EncodedJSValue BlobPrototype__getSize(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(BlobPrototype__sizeGetterWrap);
+
+
+extern "C" EncodedJSValue BlobPrototype__getSlice(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__sliceCallback);
+
+
+extern "C" EncodedJSValue BlobPrototype__getStream(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__streamCallback);
+
+
+extern "C" EncodedJSValue BlobPrototype__getText(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__textCallback);
+
+
+extern "C" JSC::EncodedJSValue BlobPrototype__getType(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(BlobPrototype__typeGetterWrap);
+
+
+extern "C" bool BlobPrototype__setType(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value);
+JSC_DECLARE_CUSTOM_SETTER(BlobPrototype__typeSetterWrap);
+
+
+extern "C" EncodedJSValue BlobPrototype__getWriter(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(BlobPrototype__writerCallback);
+
+
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBlobPrototype, JSBlobPrototype::Base);
+
+
+ static const HashTableValue JSBlobPrototypeTableValues[] = {
+{ "arrayBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__arrayBufferCallback, 0 } } ,
+{ "json"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__jsonCallback, 0 } } ,
+{ "size"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, BlobPrototype__sizeGetterWrap, 0 } } ,
+{ "slice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__sliceCallback, 2 } } ,
+{ "stream"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__streamCallback, 1 } } ,
+{ "text"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__textCallback, 0 } } ,
+{ "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, BlobPrototype__typeGetterWrap, BlobPrototype__typeSetterWrap } } ,
+{ "writer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__writerCallback, 1 } }
+ };
+
+
+const ClassInfo JSBlobPrototype::s_info = { "Blob"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBlobPrototype) };
+
+
+
+JSC_DEFINE_CUSTOM_GETTER(jsBlobConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
+{
+ VM& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto* prototype = jsDynamicCast<JSBlobPrototype*>(JSValue::decode(thisValue));
+
+ if (UNLIKELY(!prototype))
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ return JSValue::encode(globalObject->JSBlobConstructor());
+}
+
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__arrayBufferCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getArrayBuffer(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__jsonCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getJSON(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+JSC_DEFINE_CUSTOM_GETTER(BlobPrototype__sizeGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSBlob* thisObject = jsCast<JSBlob*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+ JSC::EncodedJSValue result = BlobPrototype__getSize(thisObject->wrapped(), globalObject);
+ RETURN_IF_EXCEPTION(throwScope, {});
+ RELEASE_AND_RETURN(throwScope, result);
+}
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__sliceCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getSlice(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__streamCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getStream(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__textCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getText(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+JSC_DEFINE_CUSTOM_GETTER(BlobPrototype__typeGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSBlob* thisObject = jsCast<JSBlob*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+ JSC::EncodedJSValue result = BlobPrototype__getType(thisObject->wrapped(), globalObject);
+ RETURN_IF_EXCEPTION(throwScope, {});
+ RELEASE_AND_RETURN(throwScope, result);
+}
+
+
+JSC_DEFINE_CUSTOM_SETTER(BlobPrototype__typeSetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSBlob* thisObject = jsCast<JSBlob*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+ auto result = BlobPrototype__setType(thisObject->wrapped(), lexicalGlobalObject, encodedValue);
+
+ RELEASE_AND_RETURN(throwScope, result);
+}
+
+
+JSC_DEFINE_HOST_FUNCTION(BlobPrototype__writerCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSBlob* thisObject = jsDynamicCast<JSBlob*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ return BlobPrototype__getWriter(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
+
+void JSBlobPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSBlob::info(), JSBlobPrototypeTableValues, *this);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+void JSBlobConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSBlobPrototype* prototype)
+{
+ Base::finishCreation(vm, 0, "Blob"_s, PropertyAdditionMode::WithoutStructureTransition);
+
+ putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ ASSERT(inherits(info()));
+}
+
+JSBlobConstructor* JSBlobConstructor::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSBlobPrototype* prototype) {
+ JSBlobConstructor* ptr = new (NotNull, JSC::allocateCell<JSBlobConstructor>(vm)) JSBlobConstructor(vm, structure, construct);
+ ptr->finishCreation(vm, globalObject, prototype);
+ return ptr;
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSBlobConstructor::construct(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ JSC::VM &vm = globalObject->vm();
+ JSObject* newTarget = asObject(callFrame->newTarget());
+ auto* constructor = globalObject->JSBlobConstructor();
+ Structure* structure = globalObject->JSBlobStructure();
+ if (constructor != newTarget) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* functionGlobalObject = reinterpret_cast<Zig::GlobalObject*>(
+ // ShadowRealm functions belong to a different global object.
+ getFunctionRealm(globalObject, newTarget)
+ );
+ RETURN_IF_EXCEPTION(scope, {});
+ structure = InternalFunction::createSubclassStructure(
+ globalObject,
+ newTarget,
+ functionGlobalObject->JSBlobStructure()
+ );
+ }
+
+ void* ptr = BlobClass__construct(globalObject, callFrame);
+
+ if (UNLIKELY(!ptr)) {
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr);
+
+ return JSValue::encode(instance);
+}
+
+extern "C" EncodedJSValue Blob__create(Zig::GlobalObject* globalObject, void* ptr) {
+ auto &vm = globalObject->vm();
+ JSC::Structure* structure = globalObject->JSBlobStructure();
+ JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr);
+ return JSValue::encode(instance);
+}
+
+void JSBlobConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSBlobPrototype* prototype)
+{
+
+}
+
+const ClassInfo JSBlobConstructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBlobConstructor) };
+
+
+ extern "C" EncodedJSValue Blob__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->JSBlobConstructor());
+ }
+
+JSBlob::~JSBlob()
+{
+ if (m_ctx) {
+ BlobClass__finalize(m_ctx);
+ }
+}
+void JSBlob::destroy(JSCell* cell)
+{
+ static_cast<JSBlob*>(cell)->JSBlob::~JSBlob();
+}
+
+const ClassInfo JSBlob::s_info = { "Blob"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBlob) };
+
+void JSBlob::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+JSBlob* JSBlob::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx) {
+ JSBlob* ptr = new (NotNull, JSC::allocateCell<JSBlob>(vm)) JSBlob(vm, structure, ctx);
+ ptr->finishCreation(vm);
+ return ptr;
+}
+
+
+extern "C" void* Blob__fromJS(JSC::EncodedJSValue value) {
+ JSBlob* object = JSC::jsDynamicCast<JSBlob*>(JSValue::decode(value));
+ if (!object)
+ return nullptr;
+
+ return object->wrapped();
+}
+
+extern "C" bool Blob__dangerouslySetPtr(JSC::EncodedJSValue value, void* ptr) {
+ JSBlob* object = JSC::jsDynamicCast<JSBlob*>(JSValue::decode(value));
+ if (!object)
+ return false;
+
+ object->m_ctx = ptr;
+ return true;
+}
+
+
+extern "C" const size_t Blob__ptrOffset = JSBlob::offsetOfWrapped();
+
+void JSBlob::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSBlob*>(cell);
+ if (void* wrapped = thisObject->wrapped()) {
+ // if (thisObject->scriptExecutionContext())
+ // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ }
+ Base::analyzeHeap(cell, analyzer);
+}
+
+JSObject* JSBlob::createPrototype(VM& vm, JSDOMGlobalObject* globalObject)
+{
+ return JSBlobPrototype::create(vm, globalObject, JSBlobPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+}
} // namespace WebCore
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.h b/src/bun.js/bindings/ZigGeneratedClasses.h
index bc0a2ec6f..e315093c7 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses.h
@@ -1382,6 +1382,130 @@ class JSResponsePrototype final : public JSC::JSNonFinalObject {
void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSResponsePrototype* prototype);
};
+class JSBlob final : public JSC::JSDestructibleObject {
+ public:
+ using Base = JSC::JSDestructibleObject;
+ static JSBlob* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx);
+
+ DECLARE_EXPORT_INFO;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSBlob, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForBlob.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBlob = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForBlob.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForBlob = WTFMove(space); });
+ }
+
+ static void destroy(JSC::JSCell*);
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(static_cast<JSC::JSType>(0b11101110), StructureFlags), info());
+ }
+
+ static JSObject* createPrototype(VM& vm, JSDOMGlobalObject* globalObject);
+
+ ~JSBlob();
+
+ void* wrapped() const { return m_ctx; }
+
+ void detach()
+ {
+ m_ctx = nullptr;
+ }
+
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+ static ptrdiff_t offsetOfWrapped() { return OBJECT_OFFSETOF(JSBlob, m_ctx); }
+
+ void* m_ctx { nullptr };
+
+
+ JSBlob(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
+ : Base(vm, structure)
+ {
+ m_ctx = sinkPtr;
+ }
+
+ void finishCreation(JSC::VM&);
+
+
+
+
+ };
+class JSBlobPrototype final : public JSC::JSNonFinalObject {
+ public:
+ using Base = JSC::JSNonFinalObject;
+
+ static JSBlobPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSBlobPrototype* ptr = new (NotNull, JSC::allocateCell<JSBlobPrototype>(vm)) JSBlobPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm, globalObject);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ private:
+ JSBlobPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+ };
+
+ class JSBlobConstructor final : public JSC::InternalFunction {
+ public:
+ using Base = JSC::InternalFunction;
+ static JSBlobConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSBlobPrototype* prototype);
+
+ static constexpr unsigned StructureFlags = Base::StructureFlags;
+ static constexpr bool needsDestruction = false;
+
+ 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());
+ }
+
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSBlobConstructor, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForBlobConstructor.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBlobConstructor = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForBlobConstructor.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForBlobConstructor = WTFMove(space); });
+ }
+
+
+ void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSBlobPrototype* prototype);
+
+ // Must be defined for each specialization class.
+ static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*);
+ DECLARE_EXPORT_INFO;
+ private:
+ JSBlobConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction)
+ : Base(vm, structure, nativeFunction, nativeFunction)
+
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSBlobPrototype* prototype);
+ };
}
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 706d38135..33828f7ee 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -532,6 +532,9 @@ GENERATED_CONSTRUCTOR_SETTER(JSResponse);
GENERATED_CONSTRUCTOR_GETTER(JSRequest);
GENERATED_CONSTRUCTOR_SETTER(JSRequest);
+GENERATED_CONSTRUCTOR_GETTER(JSBlob);
+GENERATED_CONSTRUCTOR_SETTER(JSBlob);
+
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSMessageEvent);
WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSMessageEvent);
@@ -1917,6 +1920,12 @@ void GlobalObject::finishCreation(VM& vm)
init.set(prototype);
});
+ m_JSFileSinkControllerPrototype.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
+ auto* prototype = createJSSinkControllerPrototype(init.vm, init.owner, WebCore::SinkID::FileSink);
+ init.set(prototype);
+ });
+
m_JSHTTPResponseController.initLater(
[](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::Structure>::Initializer& init) {
auto* structure = createJSSinkControllerStructure(init.vm, init.owner, WebCore::SinkID::HTTPResponseSink);
@@ -1980,6 +1989,16 @@ void GlobalObject::finishCreation(VM& vm)
init.set(object);
});
+ m_JSFileSinkClassStructure.initLater(
+ [](LazyClassStructure::Initializer& init) {
+ auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::FileSink);
+ auto* structure = JSFileSink::createStructure(init.vm, init.global, prototype);
+ auto* constructor = JSFileSinkConstructor::create(init.vm, init.global, JSFileSinkConstructor::createStructure(init.vm, init.global, init.global->functionPrototype()), jsCast<JSObject*>(prototype));
+ init.setPrototype(prototype);
+ init.setStructure(structure);
+ init.setConstructor(constructor);
+ });
+
m_JSArrayBufferSinkClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::ArrayBufferSink);
@@ -2288,6 +2307,9 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "TextDecoder"_s), JSC::CustomGetterSetter::create(vm, JSTextDecoder_getter, JSTextDecoder_setter),
JSC::PropertyAttribute::DontDelete | 0);
+ putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Blob"_s), JSC::CustomGetterSetter::create(vm, JSBlob_getter, JSBlob_setter),
+ JSC::PropertyAttribute::DontDelete | 0);
+
putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "DOMException"_s), JSC::CustomGetterSetter::create(vm, JSDOMException_getter, nullptr),
JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
@@ -2317,7 +2339,6 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
PUT_WEBCORE_GENERATED_CONSTRUCTOR("MessageEvent"_s, JSMessageEvent);
PUT_WEBCORE_GENERATED_CONSTRUCTOR("WebSocket"_s, JSWebSocket);
PUT_WEBCORE_GENERATED_CONSTRUCTOR("Headers"_s, JSFetchHeaders);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("TextEncoder"_s, JSTextEncoder);
PUT_WEBCORE_GENERATED_CONSTRUCTOR("URLSearchParams"_s, JSURLSearchParams);
putDirectCustomAccessor(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().TransformStreamPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_TransformStreamConstructor, nullptr), attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)));
@@ -2582,6 +2603,10 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_performanceObject.visit(visitor);
thisObject->m_navigatorObject.visit(visitor);
+ thisObject->m_JSHTTPResponseSinkClassStructure.visit(visitor);
+ thisObject->m_JSHTTPSResponseSinkClassStructure.visit(visitor);
+ thisObject->m_JSFileSinkClassStructure.visit(visitor);
+
visitor.append(thisObject->m_JSBufferSetterValue);
visitor.append(thisObject->m_JSTextEncoderSetterValue);
visitor.append(thisObject->m_JSMessageEventSetterValue);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 17aee4645..37c9c492c 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -177,6 +177,11 @@ public:
JSC::Structure* FFIFunctionStructure() { return m_JSFFIFunctionStructure.getInitializedOnMainThread(this); }
JSC::Structure* NapiClassStructure() { return m_NapiClassStructure.getInitializedOnMainThread(this); }
+ JSC::Structure* FileSinkStructure() { return m_JSFileSinkClassStructure.getInitializedOnMainThread(this); }
+ JSC::JSObject* FileSink() { return m_JSFileSinkClassStructure.constructorInitializedOnMainThread(this); }
+ JSC::JSValue FileSinkPrototype() { return m_JSFileSinkClassStructure.prototypeInitializedOnMainThread(this); }
+ JSC::JSValue JSReadableFileSinkControllerPrototype() { return m_JSFileSinkControllerPrototype.getInitializedOnMainThread(this); }
+
JSC::Structure* ArrayBufferSinkStructure() { return m_JSArrayBufferSinkClassStructure.getInitializedOnMainThread(this); }
JSC::JSObject* ArrayBufferSink() { return m_JSArrayBufferSinkClassStructure.constructorInitializedOnMainThread(this); }
JSC::JSValue ArrayBufferSinkPrototype() { return m_JSArrayBufferSinkClassStructure.prototypeInitializedOnMainThread(this); }
@@ -380,6 +385,7 @@ private:
LazyClassStructure m_JSArrayBufferSinkClassStructure;
LazyClassStructure m_JSHTTPResponseSinkClassStructure;
LazyClassStructure m_JSHTTPSResponseSinkClassStructure;
+ LazyClassStructure m_JSFileSinkClassStructure;
LazyClassStructure m_JSBufferListClassStructure;
LazyClassStructure m_JSStringDecoderClassStructure;
LazyClassStructure m_JSReadableStateClassStructure;
@@ -388,7 +394,10 @@ private:
LazyProperty<JSGlobalObject, JSObject> m_JSArrayBufferControllerPrototype;
LazyProperty<JSGlobalObject, JSObject> m_JSHTTPSResponseControllerPrototype;
+ LazyProperty<JSGlobalObject, JSObject> m_JSFileSinkControllerPrototype;
+
LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController;
+
LazyProperty<JSGlobalObject, JSObject> m_processObject;
LazyProperty<JSGlobalObject, JSObject> m_processEnvObject;
LazyProperty<JSGlobalObject, JSMap> m_lazyReadableStreamPrototypeMap;
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index cf16a0934..45f95a617 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -140,6 +140,10 @@ pub const ZigString = extern struct {
else
try strings.allocateLatin1IntoUTF8WithList(list, 0, []const u8, this.slice());
+ if (list.capacity > list.items.len) {
+ list.items.ptr[list.items.len] = 0;
+ }
+
return list.items;
}
@@ -221,6 +225,24 @@ pub const ZigString = extern struct {
return std.meta.assumeSentinel(this.ptr[0..this.len], 0);
}
+ pub fn toSliceZ(this: Slice, buf: []u8) [:0]const u8 {
+ if (this.len == 0) {
+ return "";
+ }
+
+ if (this.ptr[this.len] == 0) {
+ return this.sliceZ();
+ }
+
+ if (this.len >= buf.len) {
+ return "";
+ }
+
+ std.mem.copy(u8, buf[0..this.len], this.slice());
+ buf[this.len] = 0;
+ return std.meta.assumeSentinel(buf[0..this.len], 0);
+ }
+
pub fn mut(this: Slice) []u8 {
return @intToPtr([*]u8, @ptrToInt(this.ptr))[0..this.len];
}
@@ -1789,6 +1811,10 @@ pub const JSGlobalObject = extern struct {
pub const name = "JSC::JSGlobalObject";
pub const namespace = "JSC";
+ pub fn allocator(this: *JSGlobalObject) std.mem.Allocator {
+ return this.bunVM().allocator;
+ }
+
pub fn throwInvalidArguments(
this: *JSGlobalObject,
comptime fmt: string,
diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig
index 16a7c0468..113160a7e 100644
--- a/src/bun.js/bindings/exports.zig
+++ b/src/bun.js/bindings/exports.zig
@@ -185,6 +185,7 @@ pub const JSReadableStreamFile = JSC.WebCore.FileBlobLoader.Source.JSReadableStr
pub const JSArrayBufferSink = JSC.WebCore.ArrayBufferSink.JSSink;
pub const JSHTTPSResponseSink = JSC.WebCore.HTTPSResponseSink.JSSink;
pub const JSHTTPResponseSink = JSC.WebCore.HTTPResponseSink.JSSink;
+pub const JSFileSink = JSC.WebCore.FileSink.JSSink;
// WebSocket
pub const WebSocketHTTPClient = @import("../../http/websocket_http_client.zig").WebSocketHTTPClient;
@@ -1795,6 +1796,9 @@ pub const ZigConsoleClient = struct {
} else if (value.as(JSC.WebCore.Request)) |request| {
request.writeFormat(this, writer_, enable_ansi_colors) catch {};
return;
+ } else if (value.as(JSC.WebCore.Blob)) |blob| {
+ blob.writeFormat(this, writer_, enable_ansi_colors) catch {};
+ return;
} else if (jsType != .DOMWrapper) {
if (CAPI.JSObjectGetPrivate(value.asRef())) |private_data_ptr| {
const priv_data = JSPrivateDataPtr.from(private_data_ptr);
@@ -1809,11 +1813,6 @@ pub const ZigConsoleClient = struct {
resolve_error.msg.writeFormat(writer_, enable_ansi_colors) catch {};
return;
},
- .Blob => {
- var request = priv_data.as(JSC.WebCore.Blob);
- request.writeFormat(this, writer_, enable_ansi_colors) catch {};
- return;
- },
else => {},
}
}
@@ -2777,6 +2776,7 @@ comptime {
JSArrayBufferSink.shim.ref();
JSHTTPResponseSink.shim.ref();
JSHTTPSResponseSink.shim.ref();
+ JSFileSink.shim.ref();
JSReadableStreamFile.shim.ref();
_ = ZigString__free;
diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig
index 0bc48964c..494ad1270 100644
--- a/src/bun.js/bindings/generated_classes.zig
+++ b/src/bun.js/bindings/generated_classes.zig
@@ -929,6 +929,95 @@ pub const JSResponse = struct {
}
}
};
+pub const JSBlob = struct {
+ const Blob = Classes.Blob;
+ const GetterType = fn (*Blob, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
+ const SetterType = fn (*Blob, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool;
+ const CallbackType = fn (*Blob, *JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) JSC.JSValue;
+
+ /// Return the pointer to the wrapped object.
+ /// If the object does not match the type, return null.
+ pub fn fromJS(value: JSC.JSValue) ?*Blob {
+ JSC.markBinding();
+ return Blob__fromJS(value);
+ }
+
+ /// Get the Blob constructor value.
+ /// This loads lazily from the global object.
+ pub fn getConstructor(globalObject: *JSC.JSGlobalObject) JSC.JSValue {
+ JSC.markBinding();
+ return Blob__getConstructor(globalObject);
+ }
+
+ /// Create a new instance of Blob
+ pub fn toJS(this: *Blob, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
+ JSC.markBinding();
+ if (comptime Environment.allow_assert) {
+ const value__ = Blob__create(globalObject, this);
+ std.debug.assert(value__.as(Blob).? == this); // If this fails, likely a C ABI issue.
+ return value__;
+ } else {
+ return Blob__create(globalObject, this);
+ }
+ }
+
+ /// Modify the internal ptr to point to a new instance of Blob.
+ pub fn dangerouslySetPtr(value: JSC.JSValue, ptr: ?*Blob) bool {
+ JSC.markBinding();
+ return Blob__dangerouslySetPtr(value, ptr);
+ }
+
+ extern fn Blob__fromJS(JSC.JSValue) ?*Blob;
+ extern fn Blob__getConstructor(*JSC.JSGlobalObject) JSC.JSValue;
+
+ extern fn Blob__create(globalObject: *JSC.JSGlobalObject, ptr: ?*Blob) JSC.JSValue;
+
+ extern fn Blob__dangerouslySetPtr(JSC.JSValue, ?*Blob) bool;
+
+ comptime {
+ if (@TypeOf(Blob.constructor) != (fn (*JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) ?*Blob)) {
+ @compileLog("Blob.constructor is not a constructor");
+ }
+
+ if (@TypeOf(Blob.finalize) != (fn (*Blob) callconv(.C) void)) {
+ @compileLog("Blob.finalize is not a finalizer");
+ }
+
+ if (@TypeOf(Blob.getArrayBuffer) != CallbackType)
+ @compileLog("Expected Blob.getArrayBuffer to be a callback");
+ if (@TypeOf(Blob.getJSON) != CallbackType)
+ @compileLog("Expected Blob.getJSON to be a callback");
+ if (@TypeOf(Blob.getSize) != GetterType)
+ @compileLog("Expected Blob.getSize to be a getter");
+
+ if (@TypeOf(Blob.getSlice) != CallbackType)
+ @compileLog("Expected Blob.getSlice to be a callback");
+ if (@TypeOf(Blob.getStream) != CallbackType)
+ @compileLog("Expected Blob.getStream to be a callback");
+ if (@TypeOf(Blob.getText) != CallbackType)
+ @compileLog("Expected Blob.getText to be a callback");
+ if (@TypeOf(Blob.getType) != GetterType)
+ @compileLog("Expected Blob.getType to be a getter");
+
+ if (@TypeOf(Blob.setType) != SetterType)
+ @compileLog("Expected Blob.setType to be a setter");
+ if (@TypeOf(Blob.getWriter) != CallbackType)
+ @compileLog("Expected Blob.getWriter to be a callback");
+ if (!JSC.is_bindgen) {
+ @export(Blob.constructor, .{ .name = "BlobClass__construct" });
+ @export(Blob.finalize, .{ .name = "BlobClass__finalize" });
+ @export(Blob.getArrayBuffer, .{ .name = "BlobPrototype__getArrayBuffer" });
+ @export(Blob.getJSON, .{ .name = "BlobPrototype__getJSON" });
+ @export(Blob.getSize, .{ .name = "BlobPrototype__getSize" });
+ @export(Blob.getSlice, .{ .name = "BlobPrototype__getSlice" });
+ @export(Blob.getStream, .{ .name = "BlobPrototype__getStream" });
+ @export(Blob.getText, .{ .name = "BlobPrototype__getText" });
+ @export(Blob.getType, .{ .name = "BlobPrototype__getType" });
+ @export(Blob.getWriter, .{ .name = "BlobPrototype__getWriter" });
+ @export(Blob.setType, .{ .name = "BlobPrototype__setType" });
+ }
+ }
+};
comptime {
_ = JSSHA1;
@@ -942,4 +1031,5 @@ comptime {
_ = JSTextDecoder;
_ = JSRequest;
_ = JSResponse;
+ _ = JSBlob;
}
diff --git a/src/bun.js/bindings/generated_classes_list.zig b/src/bun.js/bindings/generated_classes_list.zig
index f491b52a0..f90cc95d4 100644
--- a/src/bun.js/bindings/generated_classes_list.zig
+++ b/src/bun.js/bindings/generated_classes_list.zig
@@ -12,4 +12,5 @@ pub const Classes = struct {
pub const SHA256 = JSC.API.Bun.Crypto.SHA256;
pub const SHA512_256 = JSC.API.Bun.Crypto.SHA512_256;
pub const TextDecoder = JSC.WebCore.TextDecoder;
+ pub const Blob = JSC.WebCore.Blob;
};
diff --git a/src/bun.js/bindings/headers-cpp.h b/src/bun.js/bindings/headers-cpp.h
index 550379eef..93b878c94 100644
--- a/src/bun.js/bindings/headers-cpp.h
+++ b/src/bun.js/bindings/headers-cpp.h
@@ -1,4 +1,4 @@
-//-- AUTOGENERATED FILE -- 1663152297
+//-- AUTOGENERATED FILE -- 1663900299
// clang-format off
#pragma once
@@ -240,8 +240,8 @@ extern "C" const size_t Zig__ConsoleClient_object_align_ = alignof(Zig::ConsoleC
extern "C" const size_t Bun__Timer_object_size_ = sizeof(Bun__Timer);
extern "C" const size_t Bun__Timer_object_align_ = alignof(Bun__Timer);
-const size_t sizes[47] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(FFI__ptr), sizeof(Reader__u8), sizeof(Reader__u16), sizeof(Reader__u32), sizeof(Reader__ptr), sizeof(Reader__i8), sizeof(Reader__i16), sizeof(Reader__i32), sizeof(Reader__f32), sizeof(Reader__f64), sizeof(Reader__i64), sizeof(Reader__u64), sizeof(Reader__intptr), sizeof(Crypto__getRandomValues), sizeof(Crypto__randomUUID), sizeof(Zig::GlobalObject), sizeof(Bun__Path), sizeof(ArrayBufferSink), sizeof(HTTPSResponseSink), sizeof(HTTPResponseSink)};
+const size_t sizes[48] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(FFI__ptr), sizeof(Reader__u8), sizeof(Reader__u16), sizeof(Reader__u32), sizeof(Reader__ptr), sizeof(Reader__i8), sizeof(Reader__i16), sizeof(Reader__i32), sizeof(Reader__f32), sizeof(Reader__f64), sizeof(Reader__i64), sizeof(Reader__u64), sizeof(Reader__intptr), sizeof(Crypto__getRandomValues), sizeof(Crypto__randomUUID), sizeof(Zig::GlobalObject), sizeof(Bun__Path), sizeof(ArrayBufferSink), sizeof(HTTPSResponseSink), sizeof(HTTPResponseSink), sizeof(FileSink)};
-const char* names[47] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "FFI__ptr", "Reader__u8", "Reader__u16", "Reader__u32", "Reader__ptr", "Reader__i8", "Reader__i16", "Reader__i32", "Reader__f32", "Reader__f64", "Reader__i64", "Reader__u64", "Reader__intptr", "Crypto__getRandomValues", "Crypto__randomUUID", "Zig__GlobalObject", "Bun__Path", "ArrayBufferSink", "HTTPSResponseSink", "HTTPResponseSink"};
+const char* names[48] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "FFI__ptr", "Reader__u8", "Reader__u16", "Reader__u32", "Reader__ptr", "Reader__i8", "Reader__i16", "Reader__i32", "Reader__f32", "Reader__f64", "Reader__i64", "Reader__u64", "Reader__intptr", "Crypto__getRandomValues", "Crypto__randomUUID", "Zig__GlobalObject", "Bun__Path", "ArrayBufferSink", "HTTPSResponseSink", "HTTPResponseSink", "FileSink"};
-const size_t aligns[47] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(FFI__ptr), alignof(Reader__u8), alignof(Reader__u16), alignof(Reader__u32), alignof(Reader__ptr), alignof(Reader__i8), alignof(Reader__i16), alignof(Reader__i32), alignof(Reader__f32), alignof(Reader__f64), alignof(Reader__i64), alignof(Reader__u64), alignof(Reader__intptr), alignof(Crypto__getRandomValues), alignof(Crypto__randomUUID), alignof(Zig::GlobalObject), alignof(Bun__Path), alignof(ArrayBufferSink), alignof(HTTPSResponseSink), alignof(HTTPResponseSink)};
+const size_t aligns[48] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(FFI__ptr), alignof(Reader__u8), alignof(Reader__u16), alignof(Reader__u32), alignof(Reader__ptr), alignof(Reader__i8), alignof(Reader__i16), alignof(Reader__i32), alignof(Reader__f32), alignof(Reader__f64), alignof(Reader__i64), alignof(Reader__u64), alignof(Reader__intptr), alignof(Crypto__getRandomValues), alignof(Crypto__randomUUID), alignof(Zig::GlobalObject), alignof(Bun__Path), alignof(ArrayBufferSink), alignof(HTTPSResponseSink), alignof(HTTPResponseSink), alignof(FileSink)};
diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h
index 293abf53f..b251568f9 100644
--- a/src/bun.js/bindings/headers.h
+++ b/src/bun.js/bindings/headers.h
@@ -1,5 +1,5 @@
// clang-format off
-//-- AUTOGENERATED FILE -- 1663152297
+//-- AUTOGENERATED FILE -- 1663900299
#pragma once
#include <stddef.h>
@@ -879,6 +879,25 @@ ZIG_DECL JSC__JSValue HTTPResponseSink__start(JSC__JSGlobalObject* arg0, JSC__Ca
ZIG_DECL JSC__JSValue HTTPResponseSink__write(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
#endif
+CPP_DECL JSC__JSValue FileSink__assignToStream(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1, void* arg2, void** arg3);
+CPP_DECL JSC__JSValue FileSink__createObject(JSC__JSGlobalObject* arg0, void* arg1);
+CPP_DECL void FileSink__detachPtr(JSC__JSValue JSValue0);
+CPP_DECL void* FileSink__fromJS(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1);
+CPP_DECL void FileSink__onClose(JSC__JSValue JSValue0, JSC__JSValue JSValue1);
+CPP_DECL void FileSink__onReady(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSValue JSValue2);
+
+#ifdef __cplusplus
+
+ZIG_DECL JSC__JSValue FileSink__close(JSC__JSGlobalObject* arg0, void* arg1);
+ZIG_DECL JSC__JSValue FileSink__construct(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
+ZIG_DECL JSC__JSValue FileSink__end(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
+ZIG_DECL JSC__JSValue FileSink__endWithSink(void* arg0, JSC__JSGlobalObject* arg1);
+ZIG_DECL void FileSink__finalize(void* arg0);
+ZIG_DECL JSC__JSValue FileSink__flush(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
+ZIG_DECL JSC__JSValue FileSink__start(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
+ZIG_DECL JSC__JSValue FileSink__write(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1);
+
+#endif
#ifdef __cplusplus
diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig
index 819b39ad9..606ae64a4 100644
--- a/src/bun.js/bindings/headers.zig
+++ b/src/bun.js/bindings/headers.zig
@@ -447,4 +447,10 @@ pub extern fn HTTPResponseSink__detachPtr(JSValue0: JSC__JSValue) void;
pub extern fn HTTPResponseSink__fromJS(arg0: ?*JSC__JSGlobalObject, JSValue1: JSC__JSValue) ?*anyopaque;
pub extern fn HTTPResponseSink__onClose(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue) void;
pub extern fn HTTPResponseSink__onReady(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue, JSValue2: JSC__JSValue) void;
+pub extern fn FileSink__assignToStream(arg0: ?*JSC__JSGlobalObject, JSValue1: JSC__JSValue, arg2: ?*anyopaque, arg3: [*c]*anyopaque) JSC__JSValue;
+pub extern fn FileSink__createObject(arg0: ?*JSC__JSGlobalObject, arg1: ?*anyopaque) JSC__JSValue;
+pub extern fn FileSink__detachPtr(JSValue0: JSC__JSValue) void;
+pub extern fn FileSink__fromJS(arg0: ?*JSC__JSGlobalObject, JSValue1: JSC__JSValue) ?*anyopaque;
+pub extern fn FileSink__onClose(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue) void;
+pub extern fn FileSink__onReady(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue, JSValue2: JSC__JSValue) void;
pub extern fn ZigException__fromException(arg0: [*c]JSC__Exception) ZigException;
diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig
index fc072d95e..ff3dfa9e7 100644
--- a/src/bun.js/event_loop.zig
+++ b/src/bun.js/event_loop.zig
@@ -475,12 +475,13 @@ pub const Poller = struct {
const linux = std.os.linux;
const FileBlobLoader = JSC.WebCore.FileBlobLoader;
-
+ const FileSink = JSC.WebCore.FileSink;
/// epoll only allows one pointer
/// We unfortunately need two pointers: one for a function call and one for the context
/// We use a tagged pointer union and then call the function with the context pointer
pub const Pollable = TaggedPointerUnion(.{
FileBlobLoader,
+ FileSink,
AsyncIO.Waker,
});
const Kevent = std.os.Kevent;
@@ -599,8 +600,6 @@ pub const Poller = struct {
pub const Flag = enum { read, write };
comptime {
- if (!JSC.is_bindgen) {
- @export(onTick, .{ .name = "Bun__internal_dispatch_ready_poll" });
- }
+ @export(onTick, .{ .name = "Bun__internal_dispatch_ready_poll" });
}
};
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index eb3a5a455..08aa7b418 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -88,7 +88,6 @@ const Bun = JSC.API.Bun;
const EventLoop = JSC.EventLoop;
const ThreadSafeFunction = JSC.napi.ThreadSafeFunction;
pub const GlobalConstructors = [_]type{
- WebCore.Blob.Constructor,
JSC.Cloudflare.HTMLRewriter.Constructor,
};
diff --git a/src/bun.js/scripts/class-definitions.ts b/src/bun.js/scripts/class-definitions.ts
index 4b202f8a5..67e4cf475 100644
--- a/src/bun.js/scripts/class-definitions.ts
+++ b/src/bun.js/scripts/class-definitions.ts
@@ -19,6 +19,7 @@ export interface ClassDefinition {
klass: Record<string, Field>;
proto: Record<string, Field>;
JSType?: string;
+ noConstructor?: boolean;
}
export function define(
diff --git a/src/bun.js/scripts/generate-classes.ts b/src/bun.js/scripts/generate-classes.ts
index 0b0bc700e..558ba5a31 100644
--- a/src/bun.js/scripts/generate-classes.ts
+++ b/src/bun.js/scripts/generate-classes.ts
@@ -401,9 +401,13 @@ void ${name}::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, ${
const ClassInfo ${name}::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(${name}) };
-
-extern "C" EncodedJSValue ${typeName}__getConstructor(Zig::GlobalObject* globalObject) {
- return JSValue::encode(globalObject->${className(typeName)}Constructor());
+${
+ !obj.noConstructor
+ ? `
+ extern "C" EncodedJSValue ${typeName}__getConstructor(Zig::GlobalObject* globalObject) {
+ return JSValue::encode(globalObject->${className(typeName)}Constructor());
+ }`
+ : ""
}
@@ -451,18 +455,16 @@ function renderDecls(symbolName, typeName, proto) {
"setter" in proto[name] ||
("accessor" in proto[name] && proto[name].setter)
) {
- rows
- .push(
- `extern "C" bool ${symbolName(
- typeName,
- proto[name].setter || proto[name].accessor.setter
- )}(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, EncoedJSValue value);`,
- `
+ rows.push(
+ `extern "C" bool ${symbolName(
+ typeName,
+ proto[name].setter || proto[name].accessor.setter
+ )}(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value);`,
+ `
JSC_DECLARE_CUSTOM_SETTER(${symbolName(typeName, name)}SetterWrap);
- `,
- "\n"
- )
- .trim();
+ `.trim(),
+ "\n"
+ );
}
if ("fn" in proto[name]) {
@@ -620,7 +622,7 @@ JSC_DEFINE_CUSTOM_SETTER(${symbolName(
name
)}SetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName))
{
- auto& vm = lexicalGlobalObject>
+ auto& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
${className(typeName)}* thisObject = jsCast<${className(
typeName
@@ -628,7 +630,7 @@ JSC_DEFINE_CUSTOM_SETTER(${symbolName(
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
auto result = ${symbolName(
typeName,
- roto[name].setter || proto[name].accessor.setter
+ proto[name].setter || proto[name].accessor.setter
)}(thisObject->wrapped(), lexicalGlobalObject, encodedValue);
RELEASE_AND_RETURN(throwScope, result);
@@ -871,7 +873,7 @@ function generateHeader(typeName, obj) {
return (
generateClassHeader(typeName, obj).trim() +
"\n" +
- generateConstructorHeader(typeName).trim() +
+ (!obj.noConstructor ? generateConstructorHeader(typeName).trim() : "") +
"\n"
);
}
@@ -880,7 +882,7 @@ function generateImpl(typeName, obj) {
const proto = obj.proto;
return [
Object.keys(proto).length > 0 && generatePrototype(typeName, obj).trim(),
- generateConstructorImpl(typeName, obj).trim(),
+ !obj.noConstructor ? generateConstructorImpl(typeName, obj).trim() : null,
Object.keys(proto).length > 0 && generateClassImpl(typeName, obj).trim(),
]
.filter(Boolean)
@@ -889,7 +891,13 @@ function generateImpl(typeName, obj) {
function generateZig(
typeName,
- { klass = {}, proto = {}, construct, finalize } = {} as ClassDefinition
+ {
+ klass = {},
+ proto = {},
+ construct,
+ finalize,
+ noConstructor,
+ } = {} as ClassDefinition
) {
const exports: [string, string][] = [];
@@ -1009,13 +1017,18 @@ pub const ${className(typeName)} = struct {
return ${symbolName(typeName, "fromJS")}(value);
}
+ ${
+ !noConstructor
+ ? `
/// Get the ${typeName} constructor value.
/// This loads lazily from the global object.
pub fn getConstructor(globalObject: *JSC.JSGlobalObject) JSC.JSValue {
JSC.markBinding();
return ${symbolName(typeName, "getConstructor")}(globalObject);
}
-
+ `
+ : ""
+ }
/// Create a new instance of ${typeName}
pub fn toJS(this: *${typeName}, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
JSC.markBinding();
@@ -1092,6 +1105,32 @@ function generateLazyClassStructureHeader(
`.trim();
}
+function generateLazyStructureHeader(typeName, { klass = {}, proto = {} }) {
+ return `
+ JSC::Structure* ${className(
+ typeName
+ )}Structure() { return m_${className(typeName)}.get(this); }
+ JSC::LazyProperty<Zig::GlobalObject, Structure> m_${className(typeName)};
+ bool has${className(typeName)}SetterValue { false };
+ mutable JSC::WriteBarrier<JSC::Unknown> m_${className(typeName)}SetterValue;
+ `.trim();
+}
+
+function generateLazyStructureImpl(typeName, { klass = {}, proto = {} }) {
+ return `
+ m_${className(typeName)}.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
+ auto *prototype = WebCore::${className(
+ typeName
+ )}::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.owner));
+ init.set(WebCore::${className(
+ typeName
+ )}::createStructure(init.vm, init.owner, prototype));
+ });
+
+ `.trim();
+}
+
function generateLazyClassStructureImpl(typeName, { klass = {}, proto = {} }) {
return `
m_${className(typeName)}.initLater(
@@ -1273,7 +1312,13 @@ await writeAndUnlink(`${import.meta.dir}/../bindings/ZigGeneratedClasses.cpp`, [
]);
await writeAndUnlink(
`${import.meta.dir}/../bindings/ZigGeneratedClasses+lazyStructureHeader.h`,
- classes.map((a) => generateLazyClassStructureHeader(a.name, a)).join("\n")
+ classes
+ .map((a) =>
+ !a.noConstructor
+ ? generateLazyClassStructureHeader(a.name, a)
+ : generateLazyStructureHeader(a.name, a)
+ )
+ .join("\n")
);
await writeAndUnlink(
@@ -1281,9 +1326,11 @@ await writeAndUnlink(
classes.map((a) =>
[
`std::unique_ptr<GCClient::IsoSubspace> ${clientSubspaceFor(a.name)};`,
- `std::unique_ptr<GCClient::IsoSubspace> ${clientSubspaceFor(
- a.name
- )}Constructor;`,
+ !a.noConstructor
+ ? `std::unique_ptr<GCClient::IsoSubspace> ${clientSubspaceFor(
+ a.name
+ )}Constructor;`
+ : "",
].join("\n")
)
);
@@ -1293,7 +1340,9 @@ await writeAndUnlink(
classes.map((a) =>
[
`std::unique_ptr<IsoSubspace> ${subspaceFor(a.name)};`,
- `std::unique_ptr<IsoSubspace> ${subspaceFor(a.name)}Constructor;`,
+ !a.noConstructor
+ ? `std::unique_ptr<IsoSubspace> ${subspaceFor(a.name)}Constructor;`
+ : ``,
].join("\n")
)
);
@@ -1301,7 +1350,11 @@ await writeAndUnlink(
await writeAndUnlink(
`${import.meta.dir}/../bindings/ZigGeneratedClasses+lazyStructureImpl.h`,
initLazyClasses(
- classes.map((a) => generateLazyClassStructureImpl(a.name, a))
+ classes.map((a) =>
+ !a.noConstructor
+ ? generateLazyClassStructureImpl(a.name, a)
+ : generateLazyStructureImpl(a.name, a)
+ )
) +
"\n" +
visitLazyClasses(classes)
diff --git a/src/bun.js/scripts/generate-jssink.js b/src/bun.js/scripts/generate-jssink.js
index 1caea3c22..65fc864fb 100644
--- a/src/bun.js/scripts/generate-jssink.js
+++ b/src/bun.js/scripts/generate-jssink.js
@@ -1,6 +1,11 @@
import { resolve } from "path";
-const classes = ["ArrayBufferSink", "HTTPResponseSink", "HTTPSResponseSink"];
+const classes = [
+ "ArrayBufferSink",
+ "FileSink",
+ "HTTPResponseSink",
+ "HTTPSResponseSink",
+];
const SINK_COUNT = 5;
function names(name) {
@@ -11,11 +16,14 @@ function names(name) {
controllerName: `Readable${name}Controller`,
prototypeName: `JS${name}Prototype`,
controllerPrototypeName: `JSReadable${name}ControllerPrototype`,
+ writableStreamSourcePrototype: `JSWritableStreamSource${name}Prototype`,
+ writableStreamName: `JSWritableStreamSource${name}`,
};
}
function header() {
function classTemplate(name) {
- const { constructor, className, controller } = names(name);
+ const { constructor, className, controller, writableStreamName } =
+ names(name);
return `class ${constructor} final : public JSC::InternalFunction {
public:
@@ -108,6 +116,8 @@ function header() {
void finishCreation(JSC::VM&);
};
+
+
class ${controller} final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
@@ -360,6 +370,8 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic
controllerName,
controllerPrototypeName,
constructor,
+ writableStreamName,
+ writableStreamSourcePrototype,
} = names(name);
const protopad = `${controller}__close`.length;
const padding = `${name}__doClose`.length;
@@ -460,6 +472,8 @@ JSC_DEFINE_HOST_FUNCTION(${name}__doClose, (JSC::JSGlobalObject * lexicalGlobalO
controllerName,
controllerPrototypeName,
constructor,
+ writableStreamSourcePrototype,
+ writableStreamName,
} = names(name);
const protopad = `${controller}__close`.length;
const padding = `${name}__doClose`.length;
diff --git a/src/bun.js/webcore/response.classes.ts b/src/bun.js/webcore/response.classes.ts
index 45df255e1..3cf695f74 100644
--- a/src/bun.js/webcore/response.classes.ts
+++ b/src/bun.js/webcore/response.classes.ts
@@ -104,4 +104,32 @@ export default [
},
},
}),
+ define({
+ name: "Blob",
+ construct: true,
+ finalize: true,
+ JSType: "0b11101110",
+ klass: {},
+ proto: {
+ text: { fn: "getText" },
+ json: { fn: "getJSON" },
+ arrayBuffer: { fn: "getArrayBuffer" },
+ slice: { fn: "getSlice", length: 2 },
+ stream: { fn: "getStream", length: 1 },
+
+ type: {
+ getter: "getType",
+ setter: "setType",
+ },
+
+ size: {
+ getter: "getSize",
+ },
+
+ writer: {
+ fn: "getWriter",
+ length: 1,
+ },
+ },
+ }),
];
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 1028f4aa9..428ef6ab4 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -770,7 +770,7 @@ pub const Fetch = struct {
}
if (options.fastGet(ctx.ptr(), .body)) |body__| {
- if (Blob.fromJS(ctx.ptr(), body__, true, false)) |new_blob| {
+ if (Blob.get(ctx.ptr(), body__, true, false)) |new_blob| {
body = new_blob;
} else |_| {
return JSPromise.rejectedPromiseValue(globalThis, ZigString.init("fetch() received invalid body").toErrorInstance(globalThis)).asRef();
@@ -905,6 +905,8 @@ const PathOrBlob = union(enum) {
};
pub const Blob = struct {
+ pub usingnamespace JSC.Codegen.JSBlob;
+
size: SizeType = 0,
offset: SizeType = 0,
/// When set, the blob will be freed on finalization callbacks
@@ -1169,13 +1171,16 @@ pub const Blob = struct {
clone.allocator = bun.default_allocator;
var cloned = bun.default_allocator.create(Blob) catch unreachable;
cloned.* = clone;
- return JSPromise.resolvedPromiseValue(ctx.ptr(), JSC.JSValue.fromRef(Blob.Class.make(ctx, cloned))).asObjectRef();
+ return JSPromise.resolvedPromiseValue(ctx.ptr(), cloned.toJS(ctx)).asObjectRef();
} else if (destination_type == .bytes and source_type == .file) {
+ var fake_call_frame: [8]JSC.JSValue = undefined;
+ @memset(@ptrCast([*]u8, &fake_call_frame), 0, @sizeOf(@TypeOf(fake_call_frame)));
+ const blob_value =
+ source_blob.getSlice(ctx, @ptrCast(*JSC.CallFrame, &fake_call_frame));
+
return JSPromise.resolvedPromiseValue(
ctx.ptr(),
- JSC.JSValue.fromRef(
- source_blob.getSlice(ctx, undefined, undefined, &.{}, null),
- ),
+ blob_value,
).asObjectRef();
}
@@ -1320,7 +1325,7 @@ pub const Blob = struct {
}
}
- break :brk Blob.fromJS(
+ break :brk Blob.get(
ctx.ptr(),
data,
false,
@@ -1534,7 +1539,7 @@ pub const Blob = struct {
var ptr = bun.default_allocator.create(Blob) catch unreachable;
ptr.* = blob;
ptr.allocator = bun.default_allocator;
- return Blob.Class.make(ctx, ptr);
+ return ptr.toJS(ctx).asObjectRef();
}
pub fn findOrCreateFileFromPath(path_: JSC.Node.PathOrFileDescriptor, globalThis: *JSGlobalObject) Blob {
@@ -2831,62 +2836,27 @@ pub const Blob = struct {
}
};
- pub const Constructor = JSC.NewConstructor(
- Blob,
- .{
- .constructor = .{ .rfn = constructor },
- },
- .{},
- );
-
- pub const Class = NewClass(
- Blob,
- .{ .name = "Blob" },
- .{ .finalize = finalize, .text = .{
- .rfn = getText_c,
- }, .json = .{
- .rfn = getJSON_c,
- }, .arrayBuffer = .{
- .rfn = getArrayBuffer_c,
- }, .slice = .{
- .rfn = getSlice,
- }, .stream = .{
- .rfn = getStream,
- } },
- .{
- .@"type" = .{
- .get = getType,
- .set = setType,
- },
- .@"size" = .{
- .get = getSize,
- .ro = true,
- },
- },
- );
-
pub fn getStream(
this: *Blob,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) JSC.C.JSValueRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
var recommended_chunk_size: SizeType = 0;
+ var arguments_ = callframe.arguments(2);
+ var arguments = arguments_.ptr[0..arguments_.len];
if (arguments.len > 0) {
- if (!JSValue.c(arguments[0]).isNumber() and !JSValue.c(arguments[0]).isUndefinedOrNull()) {
- JSC.throwInvalidArguments("chunkSize must be a number", .{}, ctx, exception);
- return null;
+ if (!arguments[0].isNumber() and !arguments[0].isUndefinedOrNull()) {
+ globalThis.throwInvalidArguments("chunkSize must be a number", .{});
+ return JSValue.jsUndefined();
}
- recommended_chunk_size = @intCast(SizeType, @maximum(0, @truncate(i52, JSValue.c(arguments[0]).toInt64())));
+ recommended_chunk_size = @intCast(SizeType, @maximum(0, @truncate(i52, arguments[0].toInt64())));
}
return JSC.WebCore.ReadableStream.fromBlob(
- ctx.ptr(),
+ globalThis,
this,
recommended_chunk_size,
- ).asObjectRef();
+ );
}
fn promisified(
@@ -2909,7 +2879,8 @@ pub const Blob = struct {
pub fn getText(
this: *Blob,
globalThis: *JSC.JSGlobalObject,
- ) JSC.JSValue {
+ _: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
return promisified(this.toString(globalThis, .clone), globalThis);
}
@@ -2990,6 +2961,66 @@ pub const Blob = struct {
return promisified(this.toArrayBuffer(ctx.ptr(), .clone), ctx.ptr()).asObjectRef();
}
+ pub fn getWriter(
+ this: *Blob,
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ var arguments_ = callframe.arguments(1);
+ var arguments = arguments_.ptr[0..arguments_.len];
+
+ var store = this.store orelse {
+ globalThis.throwInvalidArguments("Blob is detached", .{});
+ return JSValue.jsUndefined();
+ };
+
+ if (store.data != .file) {
+ globalThis.throwInvalidArguments("Blob is read-only", .{});
+ return JSValue.jsUndefined();
+ }
+
+ var sink = JSC.WebCore.FileSink.init(globalThis.allocator(), null) catch |err| {
+ globalThis.throwInvalidArguments("Failed to create FileSink: {s}", .{@errorName(err)});
+ return JSValue.jsUndefined();
+ };
+
+ var input_path: JSC.WebCore.PathOrFileDescriptor = undefined;
+ if (store.data.file.pathlike == .fd) {
+ input_path = .{ .fd = store.data.file.pathlike.fd };
+ } else {
+ input_path = .{
+ .path = ZigString.Slice{
+ .ptr = store.data.file.pathlike.path.slice().ptr,
+ .len = @truncate(u32, store.data.file.pathlike.path.slice().len),
+ .allocated = false,
+ .allocator = bun.default_allocator,
+ },
+ };
+ }
+
+ var stream_start: JSC.WebCore.StreamStart = .{
+ .FileSink = .{
+ .input_path = input_path,
+ },
+ };
+
+ if (arguments.len > 0) {
+ stream_start = JSC.WebCore.StreamStart.fromJSWithTag(globalThis, arguments[0], .FileSink);
+ stream_start.FileSink.input_path = input_path;
+ }
+
+ switch (sink.start(stream_start)) {
+ .err => |err| {
+ globalThis.vm().throwError(globalThis, err.toJSC(globalThis));
+ sink.finalize();
+ return JSC.JSValue.jsUndefined();
+ },
+ else => {},
+ }
+
+ return sink.toJS(globalThis);
+ }
+
/// https://w3c.github.io/FileAPI/#slice-method-algo
/// The slice() method returns a new Blob object with bytes ranging from the
/// optional start parameter up to but not including the optional end
@@ -2997,22 +3028,30 @@ pub const Blob = struct {
/// contentType parameter. It must act as follows:
pub fn getSlice(
this: *Blob,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- args: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) JSC.C.JSObjectRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ var allocator = globalThis.allocator();
+ var arguments_ = callframe.arguments(2);
+ var args = arguments_.ptr[0..arguments_.len];
+
if (this.size == 0) {
- return constructor(ctx, null, &[_]js.JSValueRef{}, exception);
+ const empty = Blob.initEmpty(globalThis);
+ var ptr = allocator.create(Blob) catch {
+ return JSC.JSValue.jsUndefined();
+ };
+ ptr.* = empty;
+ ptr.allocator = allocator;
+ return ptr.toJS(globalThis);
}
+
// If the optional start parameter is not used as a parameter when making this call, let relativeStart be 0.
var relativeStart: i64 = 0;
// If the optional end parameter is not used as a parameter when making this call, let relativeEnd be size.
var relativeEnd: i64 = @intCast(i64, this.size);
- var args_iter = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), args);
+ var args_iter = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), args);
if (args_iter.nextEat()) |start_| {
const start = start_.toInt64();
if (start < 0) {
@@ -3039,11 +3078,11 @@ pub const Blob = struct {
var content_type: string = "";
if (args_iter.nextEat()) |content_type_| {
if (content_type_.isString()) {
- var zig_str = content_type_.getZigString(ctx.ptr());
+ var zig_str = content_type_.getZigString(globalThis);
var slicer = zig_str.toSlice(bun.default_allocator);
defer slicer.deinit();
var slice = slicer.slice();
- var content_type_buf = getAllocator(ctx).alloc(u8, slice.len) catch unreachable;
+ var content_type_buf = allocator.alloc(u8, slice.len) catch unreachable;
content_type = strings.copyLowercase(slice, content_type_buf);
}
}
@@ -3058,31 +3097,25 @@ pub const Blob = struct {
blob.content_type = content_type;
blob.content_type_allocated = content_type.len > 0;
- var blob_ = getAllocator(ctx).create(Blob) catch unreachable;
+ var blob_ = allocator.create(Blob) catch unreachable;
blob_.* = blob;
- blob_.allocator = getAllocator(ctx);
- return Blob.Class.make(ctx, blob_);
+ blob_.allocator = allocator;
+ return blob_.toJS(globalThis);
}
pub fn getType(
this: *Blob,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- return ZigString.init(this.content_type).toValue(ctx.ptr()).asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ ) callconv(.C) JSValue {
+ return ZigString.init(this.content_type).toValue(globalThis);
}
pub fn setType(
this: *Blob,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- value: js.JSValueRef,
- _: js.ExceptionRef,
- ) bool {
- var zig_str = JSValue.fromRef(value).getZigString(ctx.ptr());
+ globalThis: *JSC.JSGlobalObject,
+ value: JSC.JSValue,
+ ) callconv(.C) bool {
+ var zig_str = value.getZigString(globalThis);
if (zig_str.is16Bit())
return false;
@@ -3093,7 +3126,7 @@ pub const Blob = struct {
const prev_content_type = this.content_type;
{
defer if (this.content_type_allocated) bun.default_allocator.free(prev_content_type);
- var content_type_buf = getAllocator(ctx).alloc(u8, slice.len) catch unreachable;
+ var content_type_buf = globalThis.allocator().alloc(u8, slice.len) catch unreachable;
this.content_type = strings.copyLowercase(slice, content_type_buf);
}
@@ -3101,25 +3134,19 @@ pub const Blob = struct {
return true;
}
- pub fn getSize(
- this: *Blob,
- _: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
+ pub fn getSize(this: *Blob, _: *JSC.JSGlobalObject) callconv(.C) JSValue {
if (this.size == Blob.max_size) {
this.resolveSize();
if (this.size == Blob.max_size and this.store != null) {
- return JSValue.jsNumberFromChar(0).asRef();
+ return JSValue.jsNumberFromChar(0);
}
}
if (this.size < std.math.maxInt(i32)) {
- return JSValue.jsNumber(this.size).asRef();
+ return JSValue.jsNumber(this.size);
}
- return JSC.JSValue.jsNumberFromUint64(this.size).asRef();
+ return JSC.JSValue.jsNumberFromUint64(this.size);
}
pub fn resolveSize(this: *Blob) void {
@@ -3138,40 +3165,42 @@ pub const Blob = struct {
}
pub fn constructor(
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- args: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) ?*Blob {
+ var allocator = globalThis.allocator();
var blob: Blob = undefined;
+ var arguments = callframe.arguments(2);
+ var args = arguments.ptr[0..arguments.len];
+
switch (args.len) {
0 => {
var empty: []u8 = &[_]u8{};
- blob = Blob.init(empty, getAllocator(ctx), ctx.ptr());
+ blob = Blob.init(empty, allocator, globalThis);
},
else => {
- blob = fromJS(ctx.ptr(), JSValue.fromRef(args[0]), false, true) catch |err| {
+ blob = get(globalThis, args[0], false, true) catch |err| {
if (err == error.InvalidArguments) {
- JSC.JSError(getAllocator(ctx), "new Blob() expects an Array", .{}, ctx, exception);
+ globalThis.throwInvalidArguments("new Blob() expects an Array", .{});
return null;
}
- JSC.JSError(getAllocator(ctx), "out of memory :(", .{}, ctx, exception);
+ globalThis.throw("out of memory", .{});
return null;
};
if (args.len > 1) {
- var options = JSValue.fromRef(args[1]);
+ var options = args[0];
if (options.isCell()) {
// type, the ASCII-encoded string in lower case
// representing the media type of the Blob.
// Normative conditions for this member are provided
// in the § 3.1 Constructors.
- if (options.get(ctx.ptr(), "type")) |content_type| {
+ if (options.get(globalThis, "type")) |content_type| {
if (content_type.isString()) {
- var content_type_str = content_type.getZigString(ctx.ptr());
+ var content_type_str = content_type.getZigString(globalThis);
if (!content_type_str.is16Bit()) {
var slice = content_type_str.trimmedSlice();
- var content_type_buf = getAllocator(ctx).alloc(u8, slice.len) catch unreachable;
+ var content_type_buf = allocator.alloc(u8, slice.len) catch unreachable;
blob.content_type = strings.copyLowercase(slice, content_type_buf);
blob.content_type_allocated = true;
}
@@ -3186,13 +3215,13 @@ pub const Blob = struct {
},
}
- var blob_ = getAllocator(ctx).create(Blob) catch unreachable;
+ var blob_ = allocator.create(Blob) catch unreachable;
blob_.* = blob;
- blob_.allocator = getAllocator(ctx);
- return Blob.Class.make(ctx, blob_);
+ blob_.allocator = allocator;
+ return blob_;
}
- pub fn finalize(this: *Blob) void {
+ pub fn finalize(this: *Blob) callconv(.C) void {
this.deinit();
}
@@ -3566,7 +3595,7 @@ pub const Blob = struct {
return toArrayBufferWithBytes(this, global, bun.constStrToU8(view_), lifetime);
}
- pub inline fn fromJS(
+ pub inline fn get(
global: *JSGlobalObject,
arg: JSValue,
comptime move: bool,
@@ -3676,28 +3705,20 @@ pub const Blob = struct {
return Blob.init(buf, bun.default_allocator, global);
},
- else => |tag| {
- if (tag != .DOMWrapper) {
- if (JSC.C.JSObjectGetPrivate(top_value.asObjectRef())) |priv| {
- var data = JSC.JSPrivateDataPtr.from(priv);
- switch (data.tag()) {
- .Blob => {
- var blob: *Blob = data.as(Blob);
- if (comptime move) {
- var _blob = blob.*;
- _blob.allocator = null;
- blob.transfer();
- return _blob;
- } else {
- return blob.dupe();
- }
- },
-
- else => return Blob.initEmpty(global),
- }
+ .DOMWrapper => {
+ if (top_value.as(Blob)) |blob| {
+ if (comptime move) {
+ var _blob = blob.*;
+ _blob.allocator = null;
+ blob.transfer();
+ return _blob;
+ } else {
+ return blob.dupe();
}
}
},
+
+ else => {},
}
}
@@ -3778,20 +3799,15 @@ pub const Blob = struct {
could_have_non_ascii = true;
break;
},
- else => {
- if (JSC.C.JSObjectGetPrivate(item.asObjectRef())) |priv| {
- var data = JSC.JSPrivateDataPtr.from(priv);
- switch (data.tag()) {
- .Blob => {
- var blob: *Blob = data.as(Blob);
- could_have_non_ascii = could_have_non_ascii or !(blob.is_all_ascii orelse false);
- joiner.append(blob.sharedView(), 0, null);
- continue;
- },
- else => {},
- }
+
+ .DOMWrapper => {
+ if (item.as(Blob)) |blob| {
+ could_have_non_ascii = could_have_non_ascii or !(blob.is_all_ascii orelse false);
+ joiner.append(blob.sharedView(), 0, null);
+ continue;
}
},
+ else => {},
}
}
@@ -3799,7 +3815,12 @@ pub const Blob = struct {
}
},
- .DOMWrapper => {},
+ .DOMWrapper => {
+ if (current.as(Blob)) |blob| {
+ could_have_non_ascii = could_have_non_ascii or !(blob.is_all_ascii orelse false);
+ joiner.append(blob.sharedView(), 0, null);
+ }
+ },
JSC.JSValue.JSType.ArrayBuffer,
JSC.JSValue.JSType.Int8Array,
@@ -3821,28 +3842,13 @@ pub const Blob = struct {
},
else => {
- outer: {
- if (JSC.C.JSObjectGetPrivate(current.asObjectRef())) |priv| {
- var data = JSC.JSPrivateDataPtr.from(priv);
- switch (data.tag()) {
- .Blob => {
- var blob: *Blob = data.as(Blob);
- could_have_non_ascii = could_have_non_ascii or !(blob.is_all_ascii orelse false);
- joiner.append(blob.sharedView(), 0, null);
- break :outer;
- },
- else => {},
- }
- }
-
- var sliced = current.toSlice(global, bun.default_allocator);
- could_have_non_ascii = could_have_non_ascii or sliced.allocated;
- joiner.append(
- sliced.slice(),
- 0,
- if (sliced.allocated) sliced.allocator else null,
- );
- }
+ var sliced = current.toSlice(global, bun.default_allocator);
+ could_have_non_ascii = could_have_non_ascii or sliced.allocated;
+ joiner.append(
+ sliced.slice(),
+ 0,
+ if (sliced.allocated) sliced.allocator else null,
+ );
},
}
current = stack.popOrNull() orelse break;
@@ -4101,13 +4107,13 @@ pub const Body = struct {
var ptr = bun.default_allocator.create(Blob) catch unreachable;
ptr.* = blob;
ptr.allocator = bun.default_allocator;
- promise.asPromise().?.resolve(global, JSC.JSValue.fromRef(Blob.Class.make(global.ref(), ptr)));
+ promise.asPromise().?.resolve(global, ptr.toJS(global));
},
else => {
var ptr = bun.default_allocator.create(Blob) catch unreachable;
ptr.* = blob;
ptr.allocator = bun.default_allocator;
- promise.asInternalPromise().?.resolve(global, JSC.JSValue.fromRef(Blob.Class.make(global.ref(), ptr)));
+ promise.asInternalPromise().?.resolve(global, ptr.toJS(global));
},
}
JSC.C.JSValueUnprotect(global.ref(), promise.asObjectRef());
@@ -4300,7 +4306,7 @@ pub const Body = struct {
}
body.value = .{
- .Blob = Blob.fromJS(globalThis, value, true, false) catch |err| {
+ .Blob = Blob.get(globalThis, value, true, false) catch |err| {
if (err == error.InvalidArguments) {
globalThis.throwInvalidArguments("Expected an Array", .{});
return null;
@@ -4511,7 +4517,7 @@ pub const Request = struct {
}
if (urlOrObject.fastGet(globalThis, .body)) |body_| {
- if (Blob.fromJS(globalThis, body_, true, false)) |blob| {
+ if (Blob.get(globalThis, body_, true, false)) |blob| {
if (blob.size > 0) {
request.body = Body.Value{ .Blob = blob };
}
@@ -4536,7 +4542,7 @@ pub const Request = struct {
}
if (arguments[1].fastGet(globalThis, .body)) |body_| {
- if (Blob.fromJS(globalThis, body_, true, false)) |blob| {
+ if (Blob.get(globalThis, body_, true, false)) |blob| {
if (blob.size > 0) {
request.body = Body.Value{ .Blob = blob };
}
@@ -4693,7 +4699,7 @@ fn BlobInterface(comptime Type: type) type {
var ptr = getAllocator(ctx).create(Blob) catch unreachable;
ptr.* = blob;
blob.allocator = getAllocator(ctx);
- return JSC.JSPromise.resolvedPromiseValue(ctx.ptr(), JSValue.fromRef(Blob.Class.make(ctx, ptr))).asObjectRef();
+ return JSC.JSPromise.resolvedPromiseValue(ctx.ptr(), ptr.toJS(ctx)).asObjectRef();
}
// pub fn getBody(
@@ -4775,7 +4781,7 @@ fn NewBlobInterface(comptime Type: type) type {
var ptr = getAllocator(globalObject).create(Blob) catch unreachable;
ptr.* = blob;
blob.allocator = getAllocator(globalObject);
- return JSC.JSPromise.resolvedPromiseValue(globalObject, JSValue.fromRef(Blob.Class.make(globalObject, ptr)));
+ return JSC.JSPromise.resolvedPromiseValue(globalObject, ptr.toJS(globalObject));
}
// pub fn getBody(
diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index b7af9a8df..5c7d08f4f 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -249,6 +249,13 @@ pub const StreamStart = union(Tag) {
as_uint8array: bool,
stream: bool,
},
+ FileSink: struct {
+ chunk_size: Blob.SizeType = 16384,
+ input_path: PathOrFileDescriptor,
+ truncate: bool = true,
+ close: bool = false,
+ mode: JSC.Node.Mode = 0,
+ },
HTTPSResponseSink: void,
HTTPResponseSink: void,
ready: void,
@@ -258,6 +265,7 @@ pub const StreamStart = union(Tag) {
err,
chunk_size,
ArrayBufferSink,
+ FileSink,
HTTPSResponseSink,
HTTPResponseSink,
ready,
@@ -334,6 +342,40 @@ pub const StreamStart = union(Tag) {
};
}
},
+ .FileSink => {
+ var chunk_size: JSC.WebCore.Blob.SizeType = 0;
+
+ if (value.get(globalThis, "highWaterMark")) |chunkSize| {
+ chunk_size = @intCast(JSC.WebCore.Blob.SizeType, @maximum(0, @truncate(i51, chunkSize.toInt64())));
+ }
+
+ if (value.get(globalThis, "path")) |path| {
+ return .{
+ .FileSink = .{
+ .chunk_size = chunk_size,
+ .input_path = .{
+ .path = path.toSlice(globalThis, globalThis.bunVM().allocator),
+ },
+ },
+ };
+ } else if (value.get(globalThis, "fd")) |fd| {
+ return .{
+ .FileSink = .{
+ .chunk_size = chunk_size,
+ .input_path = .{
+ .fd = fd.toInt32(),
+ },
+ },
+ };
+ }
+
+ return .{
+ .FileSink = .{
+ .input_path = .{ .fd = std.math.maxInt(JSC.Node.FileDescriptor) },
+ .chunk_size = chunk_size,
+ },
+ };
+ },
.HTTPSResponseSink, .HTTPResponseSink => {
var empty = true;
var chunk_size: JSC.WebCore.Blob.SizeType = 2048;
@@ -406,7 +448,16 @@ pub const StreamResult = union(Tag) {
frame: anyframe,
result: Writable,
consumed: Blob.SizeType = 0,
- used: bool = false,
+ state: StreamResult.Pending.State = .none,
+
+ pub fn run(this: *Writable.Pending) void {
+ if (this.state != .pending) {
+ return;
+ }
+
+ this.state = .used;
+ resume this.frame;
+ }
};
pub fn toPromised(globalThis: *JSGlobalObject, promise: *JSPromise, pending: *Writable.Pending) void {
@@ -424,7 +475,6 @@ pub const StreamResult = union(Tag) {
fn toPromisedWrap(globalThis: *JSGlobalObject, promise: *JSPromise, pending: *Writable.Pending) void {
suspend {}
- pending.used = true;
const result: Writable = pending.result;
switch (result) {
@@ -472,7 +522,19 @@ pub const StreamResult = union(Tag) {
pub const Pending = struct {
frame: anyframe,
result: StreamResult,
- used: bool = false,
+ state: State = .none,
+
+ pub const State = enum {
+ none,
+ pending,
+ used,
+ };
+
+ pub fn run(this: *Pending) void {
+ if (this.state != .pending) return;
+ this.state = .used;
+ resume this.frame;
+ }
};
pub fn isDone(this: *const StreamResult) bool {
@@ -485,7 +547,6 @@ pub const StreamResult = union(Tag) {
fn toPromisedWrap(globalThis: *JSGlobalObject, promise: *JSPromise, pending: *Pending) void {
suspend {}
- pending.used = true;
const result: StreamResult = pending.result;
switch (result) {
@@ -846,6 +907,360 @@ pub const Sink = struct {
}
};
+pub const PathOrFileDescriptor = union(enum) {
+ path: ZigString.Slice,
+ fd: JSC.Node.FileDescriptor,
+};
+
+pub const FileSink = struct {
+ buffer: bun.ByteList,
+ allocator: std.mem.Allocator,
+ done: bool = false,
+ signal: Signal = .{},
+ next: ?Sink = null,
+ auto_close: bool = false,
+ auto_truncate: bool = false,
+ opened_fd: JSC.Node.FileDescriptor = std.math.maxInt(JSC.Node.FileDescriptor),
+ mode: JSC.Node.Mode = 0,
+ chunk_size: usize = 0,
+ pending: StreamResult.Writable.Pending = StreamResult.Writable.Pending{
+ .frame = undefined,
+ .result = .{ .done = {} },
+ },
+
+ scheduled_count: u32 = 0,
+ written: usize = 0,
+ head: usize = 0,
+ requested_end: bool = false,
+
+ pub fn prepare(this: *FileSink, input_path: PathOrFileDescriptor, mode: JSC.Node.Mode) JSC.Node.Maybe(void) {
+ var file_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ const auto_close = this.auto_close;
+ const fd = if (!auto_close)
+ input_path.fd
+ else switch (JSC.Node.Syscall.open(input_path.path.toSliceZ(&file_buf), std.os.O.WRONLY | std.os.O.NONBLOCK | std.os.O.CLOEXEC | std.os.O.CREAT, mode)) {
+ .result => |_fd| _fd,
+ .err => |err| return .{ .err = err.withPath(input_path.path.slice()) },
+ };
+
+ const stat: std.os.Stat = switch (JSC.Node.Syscall.fstat(fd)) {
+ .result => |result| result,
+ .err => |err| {
+ if (auto_close) {
+ _ = JSC.Node.Syscall.close(fd);
+ }
+ if (input_path == .path)
+ return .{ .err = err.withPath(input_path.path.slice()) };
+ return .{ .err = err };
+ },
+ };
+
+ this.mode = stat.mode;
+ this.opened_fd = fd;
+
+ return .{ .result = {} };
+ }
+
+ pub fn connect(this: *FileSink, signal: Signal) void {
+ std.debug.assert(this.reader == null);
+ this.signal = signal;
+ }
+
+ pub fn start(this: *FileSink, stream_start: StreamStart) JSC.Node.Maybe(void) {
+ if (this.opened_fd != std.math.maxInt(JSC.Node.FileDescriptor)) {
+ _ = JSC.Node.Syscall.close(this.opened_fd);
+ this.opened_fd = std.math.maxInt(JSC.Node.FileDescriptor);
+ }
+
+ this.done = false;
+ this.written = 0;
+ this.auto_close = false;
+ this.auto_truncate = false;
+ this.requested_end = false;
+
+ this.buffer.len = 0;
+
+ switch (stream_start) {
+ .FileSink => |config| {
+ this.chunk_size = config.chunk_size;
+ this.auto_close = config.close or config.input_path == .path;
+ this.auto_truncate = config.truncate;
+
+ defer if (config.input_path == .path) config.input_path.path.deinit();
+
+ switch (this.prepare(config.input_path, config.mode)) {
+ .err => |err| {
+ return .{ .err = err };
+ },
+ .result => {},
+ }
+ },
+ else => {},
+ }
+
+ this.signal.start();
+ return .{ .result = {} };
+ }
+
+ pub fn flush(this: *FileSink) StreamResult.Writable {
+ std.debug.assert(this.opened_fd != std.math.maxInt(JSC.Node.FileDescriptor));
+
+ var total: usize = this.written;
+ const initial = total;
+ defer this.written = total;
+ const fd = this.opened_fd;
+ var remain = this.buffer.slice();
+ remain = remain[@minimum(this.head, remain.len)..];
+ defer {
+ std.debug.assert(total - initial == @ptrToInt(remain.ptr) - @ptrToInt(this.buffer.ptr));
+
+ if (remain.len == 0) {
+ this.head = 0;
+ this.buffer.len = 0;
+ } else {
+ this.head += total - initial;
+ }
+ }
+ while (remain.len > 0) {
+ const res = JSC.Node.Syscall.write(fd, remain);
+ if (res == .err) {
+ const retry = comptime if (Environment.isLinux)
+ std.os.E.WOULDBLOCK
+ else
+ std.os.E.AGAIN;
+
+ switch (res.err.getErrno()) {
+ retry => {
+ this.watch();
+ return .{
+ .pending = &this.pending,
+ };
+ },
+ else => {},
+ }
+ this.pending.result = .{ .err = res.err };
+ this.pending.consumed = @truncate(Blob.SizeType, total - initial);
+
+ return .{ .err = res.err };
+ }
+
+ remain = remain[res.result..];
+ total += res.result;
+ if (res.result == 0) break;
+ }
+
+ this.pending.result = .{
+ .owned = @truncate(Blob.SizeType, total),
+ };
+ this.pending.consumed = @truncate(Blob.SizeType, total - initial);
+ if (this.requested_end) {
+ this.done = true;
+ if (this.auto_truncate)
+ std.os.ftruncate(this.opened_fd, total) catch {};
+
+ if (this.auto_close) {
+ _ = JSC.Node.Syscall.close(this.opened_fd);
+ this.opened_fd = std.math.maxInt(JSC.Node.FileDescriptor);
+ }
+ }
+ this.pending.run();
+ return .{ .owned = @truncate(Blob.SizeType, total - initial) };
+ }
+
+ pub fn flushFromJS(this: *FileSink, globalThis: *JSGlobalObject, _: bool) JSC.Node.Maybe(JSValue) {
+ const result = this.flush();
+
+ if (result == .err) {
+ return .{ .err = result.err };
+ }
+
+ return JSC.Node.Maybe(JSValue){
+ .result = result.toJS(globalThis),
+ };
+ }
+
+ fn cleanup(this: *FileSink) void {
+ if (this.opened_fd != std.math.maxInt(JSC.Node.FileDescriptor)) {
+ _ = JSC.Node.Syscall.close(this.opened_fd);
+ this.opened_fd = std.math.maxInt(JSC.Node.FileDescriptor);
+ }
+
+ if (this.buffer.len > 0) {
+ this.buffer.listManaged(this.allocator).deinit();
+ this.buffer = bun.ByteList.init("");
+ this.done = true;
+ this.head = 0;
+ }
+ }
+
+ pub fn finalize(this: *FileSink) void {
+ this.cleanup();
+
+ this.allocator.destroy(this);
+ }
+
+ pub fn init(allocator: std.mem.Allocator, next: ?Sink) !*FileSink {
+ var this = try allocator.create(FileSink);
+ this.* = FileSink{
+ .buffer = bun.ByteList.init(&.{}),
+ .allocator = allocator,
+ .next = next,
+ };
+ return this;
+ }
+
+ pub fn construct(
+ this: *FileSink,
+ allocator: std.mem.Allocator,
+ ) void {
+ this.* = FileSink{
+ .buffer = bun.ByteList.init(&.{}),
+ .allocator = allocator,
+ .next = null,
+ };
+ }
+
+ pub fn watch(this: *FileSink) void {
+ std.debug.assert(this.opened_fd != std.math.maxInt(JSC.Node.FileDescriptor));
+ _ = JSC.VirtualMachine.vm.poller.watch(this.opened_fd, .write, FileSink, this);
+ this.scheduled_count += 1;
+ }
+
+ pub fn toJS(this: *FileSink, globalThis: *JSGlobalObject) JSValue {
+ return JSSink.createObject(globalThis, this);
+ }
+
+ pub fn onPoll(this: *FileSink, _: i64, _: u16) void {
+ this.scheduled_count -= 1;
+ this.flush();
+ }
+
+ pub fn write(this: *@This(), data: StreamResult) StreamResult.Writable {
+ const input = data.slice();
+
+ if (!this.isPending() and this.buffer.len == 0 and input.len >= this.chunk_size) {
+ var temp = this.buffer;
+ defer this.buffer = temp;
+ this.buffer = bun.ByteList.init(input);
+ const result = this.flush();
+ if (this.isPending()) {
+ _ = temp.write(this.allocator, input) catch {
+ return .{ .err = Syscall.Error.oom };
+ };
+ }
+
+ return result;
+ }
+
+ const len = this.buffer.write(this.allocator, input) catch {
+ return .{ .err = Syscall.Error.oom };
+ };
+
+ if (!this.isPending() and this.buffer.len >= this.chunk_size) {
+ return this.flush();
+ }
+
+ this.signal.ready(null, null);
+ return .{ .owned = len };
+ }
+ pub const writeBytes = write;
+ pub fn writeLatin1(this: *@This(), data: StreamResult) StreamResult.Writable {
+ const input = data.slice();
+
+ if (!this.isPending() and this.buffer.len == 0 and input.len >= this.chunk_size and strings.isAllASCII(input)) {
+ var temp = this.buffer;
+ defer this.buffer = temp;
+ this.buffer = bun.ByteList.init(input);
+ const result = this.flush();
+ if (this.isPending()) {
+ _ = temp.write(this.allocator, input) catch {
+ return .{ .err = Syscall.Error.oom };
+ };
+ }
+
+ return result;
+ }
+
+ const len = this.buffer.writeLatin1(this.allocator, input) catch {
+ return .{ .err = Syscall.Error.oom };
+ };
+
+ if (!this.isPending() and this.buffer.len >= this.chunk_size) {
+ return this.flush();
+ }
+
+ this.signal.ready(null, null);
+ return .{ .owned = len };
+ }
+ pub fn writeUTF16(this: *@This(), data: StreamResult) StreamResult.Writable {
+ if (this.next) |*next| {
+ return next.writeUTF16(data);
+ }
+ const len = this.buffer.writeUTF16(this.allocator, @ptrCast([*]const u16, @alignCast(@alignOf(u16), data.slice().ptr))[0..std.mem.bytesAsSlice(u16, data.slice()).len]) catch {
+ return .{ .err = Syscall.Error.oom };
+ };
+ if (!this.isPending() and this.buffer.len >= this.chunk_size) {
+ return this.flush();
+ }
+ this.signal.ready(null, null);
+
+ return .{ .owned = len };
+ }
+
+ fn isPending(this: *const FileSink) bool {
+ return this.scheduled_count > 0;
+ }
+
+ pub fn end(this: *FileSink, err: ?Syscall.Error) JSC.Node.Maybe(void) {
+ if (this.next) |*next| {
+ return next.end(err);
+ }
+ this.requested_end = true;
+
+ const flushy = this.flush();
+
+ if (flushy == .err) {
+ return .{ .err = flushy.err };
+ }
+
+ if (flushy != .pending) {
+ this.cleanup();
+ }
+
+ this.signal.close(err);
+ return .{ .result = {} };
+ }
+
+ pub fn endFromJS(this: *FileSink, globalThis: *JSGlobalObject) JSC.Node.Maybe(JSValue) {
+ if (this.done) {
+ return .{ .result = JSValue.jsNumber(this.written) };
+ }
+
+ std.debug.assert(this.next == null);
+ this.requested_end = true;
+
+ const flushed = this.flush();
+
+ if (flushed == .err) {
+ return .{ .err = flushed.err };
+ }
+
+ if (flushed != .pending) {
+ this.cleanup();
+ }
+
+ this.signal.close(null);
+
+ return .{ .result = flushed.toJS(globalThis) };
+ }
+
+ pub fn sink(this: *FileSink) Sink {
+ return Sink.init(this);
+ }
+
+ pub const JSSink = NewJSSink(@This(), "FileSink");
+};
+
pub const ArrayBufferSink = struct {
bytes: bun.ByteList,
allocator: std.mem.Allocator,
@@ -2302,7 +2717,7 @@ pub const FileBlobLoader = struct {
callback: anyframe = undefined,
pending: StreamResult.Pending = StreamResult.Pending{
.frame = undefined,
- .used = false,
+ .state = .none,
.result = .{ .done = {} },
},
cancelled: bool = false,
@@ -2348,7 +2763,7 @@ pub const FileBlobLoader = struct {
pub fn taskCallback(task: *NetworkThread.Task) void {
var this = @fieldParentPtr(FileBlobLoader, "concurrent", @fieldParentPtr(Concurrent, "task", task));
- var frame = HTTPClient.getAllocator().create(@Frame(runAsync)) catch unreachable;
+ var frame = bun.default_allocator.create(@Frame(runAsync)) catch unreachable;
_ = @asyncCall(std.mem.asBytes(frame), undefined, runAsync, .{this});
}
@@ -2430,7 +2845,7 @@ pub const FileBlobLoader = struct {
suspend {
var _frame = @frame();
- var this_frame = HTTPClient.getAllocator().create(std.meta.Child(@TypeOf(_frame))) catch unreachable;
+ var this_frame = bun.default_allocator.create(std.meta.Child(@TypeOf(_frame))) catch unreachable;
this_frame.* = _frame.*;
this.concurrent.read_frame = this_frame;
}
@@ -2445,9 +2860,7 @@ pub const FileBlobLoader = struct {
this.protected_view = JSC.JSValue.zero;
if (this.finalized and this.scheduled_count == 0) {
- if (!this.pending.used) {
- resume this.pending.frame;
- }
+ this.pending.run();
this.scheduled_count -= 1;
this.deinit();
@@ -2455,7 +2868,7 @@ pub const FileBlobLoader = struct {
return;
}
- if (!this.pending.used and this.pending.result == .err and this.concurrent.read == 0) {
+ if (this.pending.state == .pending and this.pending.result == .err and this.concurrent.read == 0) {
resume this.pending.frame;
this.scheduled_count -= 1;
this.finalize();
@@ -2489,7 +2902,7 @@ pub const FileBlobLoader = struct {
Concurrent.scheduleRead(this);
suspend {
- HTTPClient.getAllocator().destroy(@frame());
+ bun.default_allocator.destroy(@frame());
}
}
};
@@ -2742,7 +3155,7 @@ pub const FileBlobLoader = struct {
}
}
if (this.finalized and this.scheduled_count == 0) {
- if (!this.pending.used) {
+ if (this.pending.state == .pending) {
// should never be reached
this.pending.result = .{
.err = Syscall.Error.todo,
@@ -2762,7 +3175,7 @@ pub const FileBlobLoader = struct {
}
this.pending.result = this.read(this.buf, this.protected_view);
- resume this.pending.frame;
+ this.pending.run();
}
pub fn finalize(this: *FileBlobLoader) void {
@@ -2783,7 +3196,7 @@ pub const FileBlobLoader = struct {
pub fn deinit(this: *FileBlobLoader) void {
this.finalize();
- if (this.scheduled_count == 0 and !this.pending.used) {
+ if (this.scheduled_count == 0 and this.pending.state == .pending) {
this.destroy();
}
}