diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 37 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 7 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 1 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.zig | 1 | ||||
-rw-r--r-- | src/bun.js/event_loop.zig | 2 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 6 |
8 files changed, 58 insertions, 6 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 5b8e057f9..daf6d3f14 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -361,11 +361,24 @@ void GlobalObject::reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObje Zig__GlobalObject__reportUncaughtException(globalObject, exception); } -void GlobalObject::promiseRejectionTracker(JSGlobalObject* obj, JSC::JSPromise* prom, - JSC::JSPromiseRejectionOperation reject) +void GlobalObject::promiseRejectionTracker(JSGlobalObject* obj, JSC::JSPromise* promise, + JSC::JSPromiseRejectionOperation operation) { - Zig__GlobalObject__promiseRejectionTracker( - obj, prom, reject == JSC::JSPromiseRejectionOperation::Reject ? 0 : 1); + // Zig__GlobalObject__promiseRejectionTracker( + // obj, prom, reject == JSC::JSPromiseRejectionOperation::Reject ? 0 : 1); + + // Do this in C++ for now + auto* globalObj = reinterpret_cast<GlobalObject*>(obj); + switch (operation) { + case JSPromiseRejectionOperation::Reject: + globalObj->m_aboutToBeNotifiedRejectedPromises.append(JSC::Strong<JSPromise>(obj->vm(), promise)); + break; + case JSPromiseRejectionOperation::Handle: + globalObj->m_aboutToBeNotifiedRejectedPromises.removeFirstMatching([&] (Strong<JSPromise>& unhandledPromise) { + return unhandledPromise.get() == promise; + }); + break; + } } static Zig::ConsoleClient* m_console; @@ -2235,6 +2248,22 @@ void GlobalObject::queueTask(WebCore::EventLoopTask* task) Bun__queueMicrotask(this, task); } +extern "C" void Bun__handleRejectedPromise(Zig::GlobalObject* JSGlobalObject, JSC::JSPromise* promise); + +void GlobalObject::handleRejectedPromises() +{ + JSC::VM& virtual_machine = vm(); + do { + auto unhandledRejections = WTFMove(m_aboutToBeNotifiedRejectedPromises); + for (auto& promise : unhandledRejections) { + if (promise->isHandled(virtual_machine)) + continue; + + Bun__handleRejectedPromise(this, promise.get()); + } + } while (!m_aboutToBeNotifiedRejectedPromises.isEmpty()); +} + DEFINE_VISIT_CHILDREN(GlobalObject); // void GlobalObject::destroy(JSCell* cell) diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 3832eb9c2..7189e8f11 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -201,6 +201,8 @@ public: return m_processEnvObject.getInitializedOnMainThread(this); } + void handleRejectedPromises(); + void* bunVM() { return m_bunVM; } bool isThreadLocalDefaultGlobalObject = false; @@ -242,6 +244,7 @@ private: DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock); void* m_bunVM; + WTF::Vector<JSC::Strong<JSC::JSPromise>> m_aboutToBeNotifiedRejectedPromises; }; class JSMicrotaskCallbackDefaultGlobal final : public RefCounted<JSMicrotaskCallbackDefaultGlobal> { @@ -313,4 +316,4 @@ using JSDOMGlobalObject = Zig::GlobalObject; } #endif -#endif
\ No newline at end of file +#endif diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 3e6c67b51..33cdff39d 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -1702,6 +1702,11 @@ JSC__VM* JSC__JSGlobalObject__vm(JSC__JSGlobalObject* arg0) { return &arg0->vm() // JSC__JSGlobalObject__throwError(JSC__JSGlobalObject* arg0, JSC__JSObject* // arg1) {}; +void JSC__JSGlobalObject__handleRejectedPromises(JSC__JSGlobalObject* arg0) +{ + return static_cast<Zig::GlobalObject*>(arg0)->handleRejectedPromises(); +} + #pragma mark - JSC::JSValue JSC__JSCell* JSC__JSValue__asCell(JSC__JSValue JSValue0) @@ -3013,4 +3018,4 @@ JSC__JSValue JSC__JSValue__createUninitializedUint8Array(JSC__JSGlobalObject* ar { JSC::JSValue value = JSC::JSUint8Array::createUninitialized(arg0, arg0->m_typedArrayUint8.get(arg0), arg1); return JSC::JSValue::encode(value); -}
\ No newline at end of file +} diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 9f7771081..f44f446a6 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -1693,6 +1693,10 @@ pub const JSGlobalObject = extern struct { return @ptrCast(*JSC.VirtualMachine, @alignCast(std.meta.alignment(JSC.VirtualMachine), this.bunVM_())); } + pub fn handleRejectedPromises(this: *JSGlobalObject) void { + return cppFn("handleRejectedPromises", .{this}); + } + pub fn startRemoteInspector(this: *JSGlobalObject, host: [:0]const u8, port: u16) bool { return cppFn("startRemoteInspector", .{ this, host, port }); } @@ -1755,6 +1759,7 @@ pub const JSGlobalObject = extern struct { "vm", "generateHeapSnapshot", "startRemoteInspector", + "handleRejectedPromises", // "createError", // "throwError", }; diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index c1e70807f..02b2bbb2d 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -407,6 +407,7 @@ CPP_DECL bool JSC__JSGlobalObject__startRemoteInspector(JSC__JSGlobalObject* arg CPP_DECL JSC__StringPrototype* JSC__JSGlobalObject__stringPrototype(JSC__JSGlobalObject* arg0); CPP_DECL JSC__JSObject* JSC__JSGlobalObject__symbolPrototype(JSC__JSGlobalObject* arg0); CPP_DECL JSC__VM* JSC__JSGlobalObject__vm(JSC__JSGlobalObject* arg0); +CPP_DECL void JSC__JSGlobalObject__handleRejectedPromises(JSC__JSGlobalObject* arg0); #pragma mark - WTF::URL diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig index c0db6777a..80600f457 100644 --- a/src/bun.js/bindings/headers.zig +++ b/src/bun.js/bindings/headers.zig @@ -212,6 +212,7 @@ pub extern fn JSC__JSGlobalObject__startRemoteInspector(arg0: ?*JSC__JSGlobalObj pub extern fn JSC__JSGlobalObject__stringPrototype(arg0: ?*JSC__JSGlobalObject) ?*bindings.StringPrototype; pub extern fn JSC__JSGlobalObject__symbolPrototype(arg0: ?*JSC__JSGlobalObject) [*c]JSC__JSObject; pub extern fn JSC__JSGlobalObject__vm(arg0: ?*JSC__JSGlobalObject) [*c]JSC__VM; +pub extern fn JSC__JSGlobalObject__handleRejectedPromises(arg0: ?*JSC__JSGlobalObject) void; pub extern fn WTF__URL__encodedPassword(arg0: [*c]WTF__URL) bWTF__StringView; pub extern fn WTF__URL__encodedUser(arg0: [*c]WTF__URL) bWTF__StringView; pub extern fn WTF__URL__fileSystemPath(arg0: [*c]WTF__URL) bWTF__String; diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index f5ed49eb7..baf96937c 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -436,6 +436,8 @@ pub const EventLoop = struct { ctx.enterUWSLoop(); ctx.is_us_loop_entered = false; } + + this.global.handleRejectedPromises(); } // TODO: fix this technical debt diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 615a2003c..ee0e70bd7 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -272,6 +272,7 @@ comptime { _ = Bun__getVM; _ = Bun__drainMicrotasks; _ = Bun__queueMicrotask; + _ = Bun__handleRejectedPromise; _ = Bun__readOriginTimer; } } @@ -280,6 +281,11 @@ pub export fn Bun__queueMicrotask(global: *JSGlobalObject, task: *JSC.CppTask) v global.bunVM().eventLoop().enqueueTask(Task.init(task)); } +pub export fn Bun__handleRejectedPromise(global: *JSGlobalObject, promise: *JSC.JSPromise) void { + const result = promise.result(global.vm()); + global.bunVM().runErrorHandler(result, null); +} + // If you read JavascriptCore/API/JSVirtualMachine.mm - https://github.com/WebKit/WebKit/blob/acff93fb303baa670c055cb24c2bad08691a01a0/Source/JavaScriptCore/API/JSVirtualMachine.mm#L101 // We can see that it's sort of like std.mem.Allocator but for JSGlobalContextRef, to support Automatic Reference Counting // Its unavailable on Linux |