aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings')
-rw-r--r--src/bun.js/bindings/AsyncContextFrame.cpp22
-rw-r--r--src/bun.js/bindings/AsyncContextFrame.h4
-rw-r--r--src/bun.js/bindings/BunDebugger.cpp530
-rw-r--r--src/bun.js/bindings/BunInspector.cpp19
-rw-r--r--src/bun.js/bindings/Debugger.zig33
-rw-r--r--src/bun.js/bindings/InternalModuleRegistry.cpp2
-rw-r--r--src/bun.js/bindings/JSBundlerPlugin.cpp2
-rw-r--r--src/bun.js/bindings/JSReadableHelper.cpp2
-rw-r--r--src/bun.js/bindings/ModuleLoader.cpp2
-rw-r--r--src/bun.js/bindings/ScriptExecutionContext.cpp7
-rw-r--r--src/bun.js/bindings/ScriptExecutionContext.h2
-rw-r--r--src/bun.js/bindings/Strong.cpp21
-rw-r--r--src/bun.js/bindings/Strong.h27
-rw-r--r--src/bun.js/bindings/ZigConsoleClient.cpp11
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp2
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h1
-rw-r--r--src/bun.js/bindings/bindings.cpp7
-rw-r--r--src/bun.js/bindings/debug-helpers.h18
-rw-r--r--src/bun.js/bindings/napi.cpp2
-rw-r--r--src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h2
-rw-r--r--src/bun.js/bindings/webcore/DOMIsoSubspaces.h1
-rw-r--r--src/bun.js/bindings/webcore/EventEmitter.cpp2
22 files changed, 673 insertions, 46 deletions
diff --git a/src/bun.js/bindings/AsyncContextFrame.cpp b/src/bun.js/bindings/AsyncContextFrame.cpp
index 326350664..2a103a8d1 100644
--- a/src/bun.js/bindings/AsyncContextFrame.cpp
+++ b/src/bun.js/bindings/AsyncContextFrame.cpp
@@ -81,27 +81,27 @@ extern "C" EncodedJSValue AsyncContextFrame__withAsyncContextIfNeeded(JSGlobalOb
restoreAsyncContext = asyncContextData->getInternalField(0); \
asyncContextData->putInternalField(vm, 0, wrapper->context.get()); \
} \
- auto result = JSC::call(__VA_ARGS__); \
+ auto result = JSC::profiledCall(__VA_ARGS__); \
if (asyncContextData) { \
asyncContextData->putInternalField(vm, 0, restoreAsyncContext); \
} \
return result;
-JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, const ArgList& args, ASCIILiteral errorMessage)
-{
- ASYNCCONTEXTFRAME_CALL_IMPL(global, functionObject, args, errorMessage);
-}
-JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, JSValue thisValue, const ArgList& args, ASCIILiteral errorMessage)
-{
- ASYNCCONTEXTFRAME_CALL_IMPL(global, functionObject, thisValue, args, errorMessage);
-}
+// JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, const ArgList& args, ASCIILiteral errorMessage)
+// {
+// ASYNCCONTEXTFRAME_CALL_IMPL(global, ProfilingReason::API, functionObject, args, errorMessage);
+// }
+// JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, JSValue thisValue, const ArgList& args, ASCIILiteral errorMessage)
+// {
+// ASYNCCONTEXTFRAME_CALL_IMPL(global, ProfilingReason::API, functionObject, thisValue, args, errorMessage);
+// }
JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, JSValue thisValue, const ArgList& args)
{
- ASYNCCONTEXTFRAME_CALL_IMPL(global, functionObject, JSC::getCallData(functionObject), thisValue, args);
+ ASYNCCONTEXTFRAME_CALL_IMPL(global, ProfilingReason::API, functionObject, JSC::getCallData(functionObject), thisValue, args);
}
JSValue AsyncContextFrame::call(JSGlobalObject* global, JSValue functionObject, JSValue thisValue, const ArgList& args, NakedPtr<Exception>& returnedException)
{
- ASYNCCONTEXTFRAME_CALL_IMPL(global, functionObject, JSC::getCallData(functionObject), thisValue, args, returnedException);
+ ASYNCCONTEXTFRAME_CALL_IMPL(global, ProfilingReason::API, functionObject, JSC::getCallData(functionObject), thisValue, args, returnedException);
}
#undef ASYNCCONTEXTFRAME_CALL_IMPL
diff --git a/src/bun.js/bindings/AsyncContextFrame.h b/src/bun.js/bindings/AsyncContextFrame.h
index 52ca0d160..f5ddf4ce0 100644
--- a/src/bun.js/bindings/AsyncContextFrame.h
+++ b/src/bun.js/bindings/AsyncContextFrame.h
@@ -20,8 +20,8 @@ public:
// The following is JSC::call but
// - it unwraps AsyncContextFrame
// - does not take a CallData, because JSC::getCallData(AsyncContextFrame) -> not callable
- static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, const JSC::ArgList&, ASCIILiteral errorMessage);
- static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, JSC::JSValue thisValue, const JSC::ArgList&, ASCIILiteral errorMessage);
+ // static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, const JSC::ArgList&, ASCIILiteral errorMessage);
+ // static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, JSC::JSValue thisValue, const JSC::ArgList&, ASCIILiteral errorMessage);
static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, JSC::JSValue thisValue, const JSC::ArgList&);
static JSC::JSValue call(JSC::JSGlobalObject*, JSC::JSValue functionObject, JSC::JSValue thisValue, const JSC::ArgList&, NakedPtr<JSC::Exception>& returnedException);
diff --git a/src/bun.js/bindings/BunDebugger.cpp b/src/bun.js/bindings/BunDebugger.cpp
new file mode 100644
index 000000000..9d14a75b7
--- /dev/null
+++ b/src/bun.js/bindings/BunDebugger.cpp
@@ -0,0 +1,530 @@
+#include "root.h"
+#include <uws/src/App.h>
+
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/JSGlobalObjectDebuggable.h>
+#include <JavaScriptCore/JSGlobalObjectDebugger.h>
+#include <JavaScriptCore/Debugger.h>
+#include "ScriptExecutionContext.h"
+#include "Strong.h"
+#include "debug-helpers.h"
+
+extern "C" void Bun__tickWhilePaused(bool*);
+
+namespace Bun {
+using namespace JSC;
+using namespace WebCore;
+
+class BunInspectorConnection;
+
+static WebCore::ScriptExecutionContext* debuggerScriptExecutionContext = nullptr;
+static WTF::Lock inspectorConnectionsLock = WTF::Lock();
+static WTF::HashMap<ScriptExecutionContextIdentifier, Vector<BunInspectorConnection*, 8>>* inspectorConnections = nullptr;
+
+enum class ConnectionStatus : int32_t {
+ Pending = 0,
+ Connected = 1,
+ Disconnecting = 2,
+ Disconnected = 3,
+};
+
+class BunInspectorConnection : public Inspector::FrontendChannel {
+
+public:
+ BunInspectorConnection(ScriptExecutionContext& scriptExecutionContext, JSC::JSGlobalObject* globalObject)
+ : Inspector::FrontendChannel()
+ , globalObject(globalObject)
+ , scriptExecutionContextIdentifier(scriptExecutionContext.identifier())
+ {
+ }
+
+ ~BunInspectorConnection()
+ {
+ }
+
+ static BunInspectorConnection* create(ScriptExecutionContext& scriptExecutionContext, JSC::JSGlobalObject* globalObject)
+ {
+ return new BunInspectorConnection(scriptExecutionContext, globalObject);
+ }
+
+ ConnectionType connectionType() const override
+ {
+ return ConnectionType::Remote;
+ }
+
+ void connect()
+ {
+ switch (this->status) {
+ case ConnectionStatus::Disconnected:
+ case ConnectionStatus::Disconnecting: {
+ return;
+ }
+ default: {
+ break;
+ }
+ }
+
+ if (this->jsWaitForMessageFromInspectorLock.isLocked())
+ this->jsWaitForMessageFromInspectorLock.unlockFairly();
+
+ ScriptExecutionContext::ensureOnContextThread(scriptExecutionContextIdentifier, [connection = this](ScriptExecutionContext& context) {
+ switch (connection->status) {
+ case ConnectionStatus::Pending: {
+ connection->status = ConnectionStatus::Connected;
+ auto* globalObject = context.jsGlobalObject();
+ globalObject->setInspectable(true);
+
+ auto& inspector = globalObject->inspectorDebuggable();
+ inspector.setInspectable(true);
+
+ inspector.connect(*connection);
+
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(globalObject->debugger());
+ if (debugger) {
+ debugger->runWhilePausedCallback = [](JSC::JSGlobalObject& globalObject, bool& isDoneProcessingEvents) -> void {
+ BunInspectorConnection::runWhilePaused(globalObject, isDoneProcessingEvents);
+ };
+ }
+
+ connection->receiveMessagesOnInspectorThread(context, reinterpret_cast<Zig::GlobalObject*>(globalObject));
+
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ });
+ }
+
+ void disconnect()
+ {
+ if (jsWaitForMessageFromInspectorLock.isLocked())
+ jsWaitForMessageFromInspectorLock.unlockFairly();
+
+ switch (this->status) {
+ case ConnectionStatus::Disconnected: {
+ return;
+ }
+ default: {
+ break;
+ }
+ }
+
+ ScriptExecutionContext::ensureOnContextThread(scriptExecutionContextIdentifier, [connection = this](ScriptExecutionContext& context) {
+ if (connection->status == ConnectionStatus::Disconnected)
+ return;
+
+ connection->status = ConnectionStatus::Disconnected;
+ connection->inspector().disconnect(*connection);
+ });
+ }
+
+ JSC::JSGlobalObjectDebuggable& inspector()
+ {
+ return globalObject->inspectorDebuggable();
+ }
+
+ void sendMessageToFrontend(const String& message) override
+ {
+ if (message.length() == 0)
+ return;
+
+ this->sendMessageToDebuggerThread(message.isolatedCopy());
+ }
+
+ static void runWhilePaused(JSGlobalObject& globalObject, bool& isDoneProcessingEvents)
+ {
+ Zig::GlobalObject* global = reinterpret_cast<Zig::GlobalObject*>(&globalObject);
+ Vector<BunInspectorConnection*, 8> connections;
+ {
+ WTF::LockHolder locker(inspectorConnectionsLock);
+ connections.appendVector(inspectorConnections->get(global->scriptExecutionContext()->identifier()));
+ }
+
+ for (auto* connection : connections) {
+ if (connection->status == ConnectionStatus::Pending) {
+ connection->connect();
+ }
+
+ if (connection->status != ConnectionStatus::Disconnected) {
+ connection->receiveMessagesOnInspectorThread(*global->scriptExecutionContext(), global);
+ }
+ }
+
+ // for (auto* connection : connections) {
+ // if (connection->status == ConnectionStatus::Connected) {
+ // connection->jsWaitForMessageFromInspectorLock.lock();
+ // }
+ // }
+
+ if (connections.size() == 1) {
+ while (!isDoneProcessingEvents) {
+ auto* connection = connections[0];
+ if (connection->status == ConnectionStatus::Disconnected || connection->status == ConnectionStatus::Disconnecting) {
+ if (global->debugger() && global->debugger()->isPaused()) {
+ global->debugger()->continueProgram();
+ }
+ break;
+ }
+ connection->receiveMessagesOnInspectorThread(*global->scriptExecutionContext(), global);
+ }
+ } else {
+ while (!isDoneProcessingEvents) {
+ size_t closedCount = 0;
+ for (auto* connection : connections) {
+ closedCount += connection->status == ConnectionStatus::Disconnected || connection->status == ConnectionStatus::Disconnecting;
+ connection->receiveMessagesOnInspectorThread(*global->scriptExecutionContext(), global);
+ if (isDoneProcessingEvents)
+ break;
+ }
+
+ if (closedCount == connections.size() && global->debugger() && !isDoneProcessingEvents) {
+ global->debugger()->continueProgram();
+ continue;
+ }
+ }
+ }
+ }
+
+ void receiveMessagesOnInspectorThread(ScriptExecutionContext& context, Zig::GlobalObject* globalObject)
+ {
+ this->jsThreadMessageScheduledCount.store(0);
+ WTF::Vector<WTF::String, 12> messages;
+
+ {
+ WTF::LockHolder locker(jsThreadMessagesLock);
+ this->jsThreadMessages.swap(messages);
+ }
+
+ auto& dispatcher = globalObject->inspectorDebuggable();
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(globalObject->debugger());
+
+ if (!debugger) {
+ for (auto message : messages) {
+ dispatcher.dispatchMessageFromRemote(WTFMove(message));
+
+ debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(globalObject->debugger());
+ if (debugger) {
+ debugger->runWhilePausedCallback = [](JSC::JSGlobalObject& globalObject, bool& isDoneProcessingEvents) -> void {
+ runWhilePaused(globalObject, isDoneProcessingEvents);
+ };
+ }
+ }
+ } else {
+ for (auto message : messages) {
+ dispatcher.dispatchMessageFromRemote(WTFMove(message));
+ }
+ }
+
+ messages.clear();
+ }
+
+ void receiveMessagesOnDebuggerThread(ScriptExecutionContext& context, Zig::GlobalObject* debuggerGlobalObject)
+ {
+ debuggerThreadMessageScheduledCount.store(0);
+ WTF::Vector<WTF::String, 12> messages;
+
+ {
+ WTF::LockHolder locker(debuggerThreadMessagesLock);
+ this->debuggerThreadMessages.swap(messages);
+ }
+
+ JSFunction* onMessageFn = jsCast<JSFunction*>(jsBunDebuggerOnMessageFunction->m_cell.get());
+ MarkedArgumentBuffer arguments;
+ arguments.ensureCapacity(messages.size());
+ auto& vm = debuggerGlobalObject->vm();
+
+ for (auto& message : messages) {
+ arguments.append(jsString(vm, message));
+ }
+
+ messages.clear();
+
+ JSC::call(debuggerGlobalObject, onMessageFn, arguments, "BunInspectorConnection::receiveMessagesOnDebuggerThread - onMessageFn"_s);
+ }
+
+ void sendMessageToDebuggerThread(WTF::String&& inputMessage)
+ {
+ {
+ WTF::LockHolder locker(debuggerThreadMessagesLock);
+ debuggerThreadMessages.append(inputMessage);
+ }
+
+ if (this->debuggerThreadMessageScheduledCount++ == 0) {
+ debuggerScriptExecutionContext->postTaskConcurrently([connection = this](ScriptExecutionContext& context) {
+ connection->receiveMessagesOnDebuggerThread(context, reinterpret_cast<Zig::GlobalObject*>(context.jsGlobalObject()));
+ });
+ }
+ }
+
+ void sendMessageToInspectorFromDebuggerThread(const WTF::String& inputMessage)
+ {
+ {
+ WTF::LockHolder locker(jsThreadMessagesLock);
+ jsThreadMessages.append(inputMessage);
+ }
+
+ if (this->jsWaitForMessageFromInspectorLock.isLocked()) {
+ this->jsWaitForMessageFromInspectorLock.unlock();
+ } else if (this->jsThreadMessageScheduledCount++ == 0) {
+ ScriptExecutionContext::postTaskTo(scriptExecutionContextIdentifier, [connection = this](ScriptExecutionContext& context) {
+ connection->receiveMessagesOnInspectorThread(context, reinterpret_cast<Zig::GlobalObject*>(context.jsGlobalObject()));
+ });
+ }
+ }
+
+ WTF::Vector<WTF::String, 12> debuggerThreadMessages;
+ WTF::Lock debuggerThreadMessagesLock = WTF::Lock();
+ std::atomic<uint32_t> debuggerThreadMessageScheduledCount { 0 };
+
+ WTF::Vector<WTF::String, 12> jsThreadMessages;
+ WTF::Lock jsThreadMessagesLock = WTF::Lock();
+ std::atomic<uint32_t> jsThreadMessageScheduledCount { 0 };
+
+ JSC::JSGlobalObject* globalObject;
+ ScriptExecutionContextIdentifier scriptExecutionContextIdentifier;
+ Bun::StrongRef* jsBunDebuggerOnMessageFunction = nullptr;
+
+ WTF::Lock jsWaitForMessageFromInspectorLock;
+ std::atomic<ConnectionStatus> status = ConnectionStatus::Pending;
+};
+
+JSC_DECLARE_HOST_FUNCTION(jsFunctionSend);
+JSC_DECLARE_HOST_FUNCTION(jsFunctionDisconnect);
+
+class JSBunInspectorConnection final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static constexpr unsigned StructureFlags = Base::StructureFlags;
+ static constexpr bool needsDestruction = false;
+
+ static JSBunInspectorConnection* create(JSC::VM& vm, JSC::Structure* structure, BunInspectorConnection* connection)
+ {
+ JSBunInspectorConnection* ptr = new (NotNull, JSC::allocateCell<JSBunInspectorConnection>(vm)) JSBunInspectorConnection(vm, structure, connection);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ DECLARE_EXPORT_INFO;
+ template<typename, SubspaceAccess mode>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSBunInspectorConnection, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForBunInspectorConnection.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBunInspectorConnection = std::forward<decltype(space)>(space); },
+ [](auto& spaces) { return spaces.m_subspaceForBunInspectorConnection.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForBunInspectorConnection = std::forward<decltype(space)>(space); });
+ }
+ 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(), JSC::NonArray, 2);
+ }
+
+ BunInspectorConnection* connection()
+ {
+ return m_connection;
+ }
+
+private:
+ JSBunInspectorConnection(JSC::VM& vm, JSC::Structure* structure, BunInspectorConnection* connection)
+ : Base(vm, structure)
+ , m_connection(connection)
+ {
+ }
+
+ void finishCreation(JSC::VM& vm)
+ {
+ Base::finishCreation(vm);
+ }
+
+ BunInspectorConnection* m_connection;
+};
+
+JSC_DEFINE_HOST_FUNCTION(jsFunctionSend, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ auto* jsConnection = jsDynamicCast<JSBunInspectorConnection*>(callFrame->thisValue());
+ auto message = callFrame->uncheckedArgument(0).toWTFString(globalObject).isolatedCopy();
+
+ if (!jsConnection)
+ return JSValue::encode(jsUndefined());
+
+ jsConnection->connection()->sendMessageToInspectorFromDebuggerThread(message);
+
+ return JSValue::encode(jsUndefined());
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsFunctionDisconnect, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ auto* jsConnection = jsDynamicCast<JSBunInspectorConnection*>(callFrame->thisValue());
+ if (!jsConnection)
+ return JSValue::encode(jsUndefined());
+
+ auto& connection = *jsConnection->connection();
+
+ if (connection.status == ConnectionStatus::Connected || connection.status == ConnectionStatus::Pending) {
+ connection.status = ConnectionStatus::Disconnecting;
+ connection.disconnect();
+ if (connection.jsWaitForMessageFromInspectorLock.isLocked())
+ connection.jsWaitForMessageFromInspectorLock.unlockFairly();
+ }
+
+ return JSValue::encode(jsUndefined());
+}
+
+const JSC::ClassInfo JSBunInspectorConnection::s_info = { "BunInspectorConnection"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBunInspectorConnection) };
+
+extern "C" unsigned int Bun__createJSDebugger(Zig::GlobalObject* globalObject)
+{
+ {
+ WTF::LockHolder locker(inspectorConnectionsLock);
+ if (inspectorConnections == nullptr) {
+ inspectorConnections = new WTF::HashMap<ScriptExecutionContextIdentifier, Vector<BunInspectorConnection*, 8>>();
+ }
+
+ inspectorConnections->add(globalObject->scriptExecutionContext()->identifier(), Vector<BunInspectorConnection*, 8>());
+ }
+
+ return static_cast<unsigned int>(globalObject->scriptExecutionContext()->identifier());
+}
+extern "C" void Bun__tickWhilePaused(bool*);
+
+extern "C" void Bun__ensureDebugger(ScriptExecutionContextIdentifier scriptId, bool pauseOnStart)
+{
+
+ auto* globalObject = ScriptExecutionContext::getScriptExecutionContext(scriptId)->jsGlobalObject();
+ globalObject->setInspectable(true);
+
+ auto& inspector = globalObject->inspectorDebuggable();
+ inspector.setInspectable(true);
+
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(globalObject->debugger());
+ if (debugger) {
+ debugger->runWhilePausedCallback = [](JSC::JSGlobalObject& globalObject, bool& isDoneProcessingEvents) -> void {
+ BunInspectorConnection::runWhilePaused(globalObject, isDoneProcessingEvents);
+ };
+ }
+
+ if (pauseOnStart)
+ inspector.pauseWaitingForAutomaticInspection();
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateConnection, (JSGlobalObject * globalObject, CallFrame* callFrame))
+{
+ auto* debuggerGlobalObject = jsDynamicCast<Zig::GlobalObject*>(globalObject);
+ if (!debuggerGlobalObject)
+ return JSValue::encode(jsUndefined());
+
+ ScriptExecutionContext* targetContext = ScriptExecutionContext::getScriptExecutionContext(static_cast<ScriptExecutionContextIdentifier>(callFrame->argument(0).toUInt32(globalObject)));
+ JSFunction* onMessageFn = jsCast<JSFunction*>(callFrame->argument(1).toObject(globalObject));
+
+ if (!targetContext || !onMessageFn)
+ return JSValue::encode(jsUndefined());
+
+ auto& vm = globalObject->vm();
+ auto connection = BunInspectorConnection::create(
+ *targetContext,
+ targetContext->jsGlobalObject());
+
+ {
+ WTF::LockHolder locker(inspectorConnectionsLock);
+ auto connections = inspectorConnections->get(targetContext->identifier());
+ connections.append(connection);
+ inspectorConnections->set(targetContext->identifier(), connections);
+ }
+ connection->jsBunDebuggerOnMessageFunction = new Bun::StrongRef(vm, onMessageFn);
+ connection->connect();
+
+ return JSValue::encode(JSBunInspectorConnection::create(vm, JSBunInspectorConnection::createStructure(vm, globalObject, globalObject->objectPrototype()), connection));
+}
+
+extern "C" BunString Bun__startJSDebuggerThread(Zig::GlobalObject* debuggerGlobalObject, ScriptExecutionContextIdentifier scriptId, BunString* portOrPathString)
+{
+ if (!debuggerScriptExecutionContext)
+ debuggerScriptExecutionContext = debuggerGlobalObject->scriptExecutionContext();
+ JSC::VM& vm = debuggerGlobalObject->vm();
+ JSValue defaultValue = debuggerGlobalObject->internalModuleRegistry()->requireId(debuggerGlobalObject, vm, InternalModuleRegistry::Field::InternalDebugger);
+ JSFunction* debuggerDefaultFn = jsCast<JSFunction*>(defaultValue.asCell());
+
+ MarkedArgumentBuffer arguments;
+
+ arguments.append(jsNumber(static_cast<unsigned int>(scriptId)));
+ arguments.append(Bun::toJS(debuggerGlobalObject, *portOrPathString));
+ arguments.append(JSFunction::create(vm, debuggerGlobalObject, 1, String(), jsFunctionCreateConnection, ImplementationVisibility::Public));
+ arguments.append(JSFunction::create(vm, debuggerGlobalObject, 1, String("send"_s), jsFunctionSend, ImplementationVisibility::Public));
+ arguments.append(JSFunction::create(vm, debuggerGlobalObject, 0, String("disconnect"_s), jsFunctionDisconnect, ImplementationVisibility::Public));
+
+ JSValue serverURLValue = JSC::call(debuggerGlobalObject, debuggerDefaultFn, arguments, "Bun__initJSDebuggerThread - debuggerDefaultFn"_s);
+
+ if (serverURLValue.isUndefinedOrNull())
+ return BunStringEmpty;
+
+ return Bun::toStringRef(debuggerGlobalObject, serverURLValue);
+}
+
+enum class AsyncCallTypeUint8 : uint8_t {
+ DOMTimer = 1,
+ EventListener = 2,
+ PostMessage = 3,
+ RequestAnimationFrame = 4,
+ Microtask = 5,
+};
+
+static Inspector::InspectorDebuggerAgent::AsyncCallType getCallType(AsyncCallTypeUint8 callType)
+{
+ Inspector::InspectorDebuggerAgent::AsyncCallType type;
+ switch (callType) {
+ case AsyncCallTypeUint8::DOMTimer:
+ return Inspector::InspectorDebuggerAgent::AsyncCallType::DOMTimer;
+ case AsyncCallTypeUint8::EventListener:
+ return Inspector::InspectorDebuggerAgent::AsyncCallType::EventListener;
+ case AsyncCallTypeUint8::PostMessage:
+ return Inspector::InspectorDebuggerAgent::AsyncCallType::PostMessage;
+ case AsyncCallTypeUint8::RequestAnimationFrame:
+ return Inspector::InspectorDebuggerAgent::AsyncCallType::RequestAnimationFrame;
+ case AsyncCallTypeUint8::Microtask:
+ return Inspector::InspectorDebuggerAgent::AsyncCallType::Microtask;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
+extern "C" void Debugger__didScheduleAsyncCall(JSGlobalObject* globalObject, AsyncCallTypeUint8 callType, uint64_t callbackId, bool singleShot)
+{
+ auto* agent = debuggerAgent(globalObject);
+ if (!agent)
+ return;
+
+ agent->didScheduleAsyncCall(globalObject, getCallType(callType), callbackId, singleShot);
+}
+
+extern "C" void Debugger__didCancelAsyncCall(JSGlobalObject* globalObject, AsyncCallTypeUint8 callType, uint64_t callbackId)
+{
+ auto* agent = debuggerAgent(globalObject);
+ if (!agent)
+ return;
+
+ agent->didCancelAsyncCall(getCallType(callType), callbackId);
+}
+
+extern "C" void Debugger__didDispatchAsyncCall(JSGlobalObject* globalObject, AsyncCallTypeUint8 callType, uint64_t callbackId)
+{
+ auto* agent = debuggerAgent(globalObject);
+ if (!agent)
+ return;
+
+ agent->didDispatchAsyncCall(getCallType(callType), callbackId);
+}
+
+extern "C" void Debugger__willDispatchAsyncCall(JSGlobalObject* globalObject, AsyncCallTypeUint8 callType, uint64_t callbackId)
+{
+ auto* agent = debuggerAgent(globalObject);
+ if (!agent)
+ return;
+
+ agent->willDispatchAsyncCall(getCallType(callType), callbackId);
+}
+}
diff --git a/src/bun.js/bindings/BunInspector.cpp b/src/bun.js/bindings/BunInspector.cpp
index ccb0a702d..76920e398 100644
--- a/src/bun.js/bindings/BunInspector.cpp
+++ b/src/bun.js/bindings/BunInspector.cpp
@@ -3,6 +3,10 @@
#include <JavaScriptCore/InspectorFrontendChannel.h>
#include <JavaScriptCore/JSGlobalObjectDebuggable.h>
+#include <JavaScriptCore/JSGlobalObjectDebugger.h>
+#include <JavaScriptCore/Debugger.h>
+
+extern "C" void Bun__tickWhilePaused(bool*);
namespace Bun {
using namespace JSC;
@@ -31,6 +35,13 @@ public:
{
this->globalObject = globalObject;
this->globalObject->inspectorDebuggable().connect(*this);
+
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(this->globalObject->debugger());
+ if (debugger) {
+ debugger->runWhilePausedCallback = [](JSC::JSGlobalObject& globalObject, bool& isPaused) -> void {
+ Bun__tickWhilePaused(&isPaused);
+ };
+ }
}
void onClose()
@@ -57,6 +68,13 @@ public:
void onMessage(std::string_view message)
{
WTF::String messageString = WTF::String::fromUTF8(message.data(), message.length());
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(this->globalObject->debugger());
+ if (debugger) {
+ debugger->runWhilePausedCallback = [](JSC::JSGlobalObject& globalObject, bool& done) -> void {
+ Inspector::JSGlobalObjectDebugger* debugger = reinterpret_cast<Inspector::JSGlobalObjectDebugger*>(globalObject.debugger());
+ Bun__tickWhilePaused(&done);
+ };
+ }
this->globalObject->inspectorDebuggable().dispatchMessageFromRemote(WTFMove(messageString));
}
@@ -84,6 +102,7 @@ public:
using BunInspectorConnectionNoSSL = BunInspectorConnection<false>;
using SSLBunInspectorConnection = BunInspectorConnection<true>;
+
template<bool isSSL>
static void addInspector(void* app, JSC::JSGlobalObject* globalObject)
{
diff --git a/src/bun.js/bindings/Debugger.zig b/src/bun.js/bindings/Debugger.zig
new file mode 100644
index 000000000..3d9fc450c
--- /dev/null
+++ b/src/bun.js/bindings/Debugger.zig
@@ -0,0 +1,33 @@
+const bun = @import("root").bun;
+const JSC = bun.JSC;
+
+pub const Debugger = struct {
+ pub const AsyncCallType = enum(u8) {
+ DOMTimer = 1,
+ EventListener = 2,
+ PostMessage = 3,
+ RequestAnimationFrame = 4,
+ Microtask = 5,
+ };
+ extern fn Debugger__didScheduleAsyncCall(*JSC.JSGlobalObject, AsyncCallType, u64, bool) void;
+ extern fn Debugger__didCancelAsyncCall(*JSC.JSGlobalObject, AsyncCallType, u64) void;
+ extern fn Debugger__didDispatchAsyncCall(*JSC.JSGlobalObject, AsyncCallType, u64) void;
+ extern fn Debugger__willDispatchAsyncCall(*JSC.JSGlobalObject, AsyncCallType, u64) void;
+
+ pub fn didScheduleAsyncCall(globalObject: *JSC.JSGlobalObject, call: AsyncCallType, id: u64, single_shot: bool) void {
+ JSC.markBinding(@src());
+ Debugger__didScheduleAsyncCall(globalObject, call, id, single_shot);
+ }
+ pub fn didCancelAsyncCall(globalObject: *JSC.JSGlobalObject, call: AsyncCallType, id: u64) void {
+ JSC.markBinding(@src());
+ Debugger__didCancelAsyncCall(globalObject, call, id);
+ }
+ pub fn didDispatchAsyncCall(globalObject: *JSC.JSGlobalObject, call: AsyncCallType, id: u64) void {
+ JSC.markBinding(@src());
+ Debugger__didDispatchAsyncCall(globalObject, call, id);
+ }
+ pub fn willDispatchAsyncCall(globalObject: *JSC.JSGlobalObject, call: AsyncCallType, id: u64) void {
+ JSC.markBinding(@src());
+ Debugger__willDispatchAsyncCall(globalObject, call, id);
+ }
+};
diff --git a/src/bun.js/bindings/InternalModuleRegistry.cpp b/src/bun.js/bindings/InternalModuleRegistry.cpp
index 8323560d6..8dbf42a02 100644
--- a/src/bun.js/bindings/InternalModuleRegistry.cpp
+++ b/src/bun.js/bindings/InternalModuleRegistry.cpp
@@ -160,4 +160,4 @@ JSC_DEFINE_HOST_FUNCTION(InternalModuleRegistry::jsCreateInternalModuleById, (JS
} // namespace Bun
#undef INTERNAL_MODULE_REGISTRY_GENERATE_
-#undef INTERNAL_MODULE_REGISTRY_GENERATE
+#undef INTERNAL_MODULE_REGISTRY_GENERATE \ No newline at end of file
diff --git a/src/bun.js/bindings/JSBundlerPlugin.cpp b/src/bun.js/bindings/JSBundlerPlugin.cpp
index ec3933574..6ae266df7 100644
--- a/src/bun.js/bindings/JSBundlerPlugin.cpp
+++ b/src/bun.js/bindings/JSBundlerPlugin.cpp
@@ -404,7 +404,7 @@ extern "C" EncodedJSValue JSBundlerPlugin__runSetupFunction(
arguments.append(JSValue::decode(encodedConfig));
auto* lexicalGlobalObject = jsCast<JSFunction*>(JSValue::decode(encodedSetupFunction))->globalObject();
- auto result = JSC::call(lexicalGlobalObject, setupFunction, callData, plugin, arguments);
+ auto result = call(lexicalGlobalObject, setupFunction, callData, plugin, arguments);
if (UNLIKELY(scope.exception())) {
auto exception = scope.exception();
scope.clearException();
diff --git a/src/bun.js/bindings/JSReadableHelper.cpp b/src/bun.js/bindings/JSReadableHelper.cpp
index 3a4de4637..0c459f329 100644
--- a/src/bun.js/bindings/JSReadableHelper.cpp
+++ b/src/bun.js/bindings/JSReadableHelper.cpp
@@ -38,7 +38,7 @@ static bool callRead(JSValue stream, JSFunction* read, JSC::MarkedArgumentBuffer
{
WTF::NakedPtr<JSC::Exception> exceptionPtr;
JSC::CallData callData = JSC::getCallData(read);
- JSValue ret = JSC::call(lexicalGlobalObject, read, callData, JSValue(stream), WTFMove(args), exceptionPtr);
+ JSValue ret = call(lexicalGlobalObject, read, callData, JSValue(stream), WTFMove(args), exceptionPtr);
if (auto* exception = exceptionPtr.get()) {
JSC::Identifier errorEventName = JSC::Identifier::fromString(vm, "error"_s);
if (emitter.hasEventListeners(errorEventName)) {
diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp
index 2c8b95612..4e2de9294 100644
--- a/src/bun.js/bindings/ModuleLoader.cpp
+++ b/src/bun.js/bindings/ModuleLoader.cpp
@@ -359,7 +359,7 @@ static JSValue handleVirtualModuleResult(
arguments.append(jsUndefined());
arguments.append(pendingModule);
ASSERT(!arguments.hasOverflowed());
- JSC::call(globalObject, performPromiseThenFunction, callData, jsUndefined(), arguments);
+ JSC::profiledCall(globalObject, ProfilingReason::Microtask, performPromiseThenFunction, callData, jsUndefined(), arguments);
return internalPromise;
}
default: {
diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp
index eab41d584..2113c9f64 100644
--- a/src/bun.js/bindings/ScriptExecutionContext.cpp
+++ b/src/bun.js/bindings/ScriptExecutionContext.cpp
@@ -114,12 +114,17 @@ void ScriptExecutionContext::willDestroyDestructionObserver(ContextDestructionOb
m_destructionObservers.remove(&observer);
}
+bool ScriptExecutionContext::isJSExecutionForbidden()
+{
+ return !m_vm || m_vm->executionForbidden();
+}
+
extern "C" void* Bun__getVM();
bool ScriptExecutionContext::isContextThread()
{
auto clientData = WebCore::clientData(vm());
- return clientData->bunVM == Bun__getVM();
+ return clientData && clientData->bunVM == Bun__getVM();
}
bool ScriptExecutionContext::ensureOnContextThread(ScriptExecutionContextIdentifier identifier, Function<void(ScriptExecutionContext&)>&& task)
diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h
index b32435240..6f10dced7 100644
--- a/src/bun.js/bindings/ScriptExecutionContext.h
+++ b/src/bun.js/bindings/ScriptExecutionContext.h
@@ -129,7 +129,7 @@ public:
bool isContextThread();
bool isDocument() { return false; }
bool isWorkerGlobalScope() { return true; }
- bool isJSExecutionForbidden() { return false; }
+ bool isJSExecutionForbidden();
void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception* exception, RefPtr<void*>&&, CachedScript* = nullptr, bool = false)
{
}
diff --git a/src/bun.js/bindings/Strong.cpp b/src/bun.js/bindings/Strong.cpp
index 8ec63e318..045b4484a 100644
--- a/src/bun.js/bindings/Strong.cpp
+++ b/src/bun.js/bindings/Strong.cpp
@@ -1,28 +1,9 @@
#include "root.h"
#include <JavaScriptCore/StrongInlines.h>
#include "BunClientData.h"
-
+#include "Strong.h"
namespace Bun {
-// We tried to pool these
-// But it was very complicated
-class StrongRef {
- WTF_MAKE_ISO_ALLOCATED(StrongRef);
-
-public:
- StrongRef(JSC::VM& vm, JSC::JSValue value)
- : m_cell(vm, value)
- {
- }
-
- StrongRef()
- : m_cell()
- {
- }
-
- JSC::Strong<JSC::Unknown> m_cell;
-};
-
WTF_MAKE_ISO_ALLOCATED_IMPL(StrongRef);
}
diff --git a/src/bun.js/bindings/Strong.h b/src/bun.js/bindings/Strong.h
new file mode 100644
index 000000000..f39d1c611
--- /dev/null
+++ b/src/bun.js/bindings/Strong.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "root.h"
+#include "JavaScriptCore/Strong.h"
+
+namespace Bun {
+
+// We tried to pool these
+// But it was very complicated
+class StrongRef {
+ WTF_MAKE_ISO_ALLOCATED(StrongRef);
+
+public:
+ StrongRef(JSC::VM& vm, JSC::JSValue value)
+ : m_cell(vm, value)
+ {
+ }
+
+ StrongRef()
+ : m_cell()
+ {
+ }
+
+ JSC::Strong<JSC::Unknown> m_cell;
+};
+
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigConsoleClient.cpp b/src/bun.js/bindings/ZigConsoleClient.cpp
index a98c246de..6fb364d93 100644
--- a/src/bun.js/bindings/ZigConsoleClient.cpp
+++ b/src/bun.js/bindings/ZigConsoleClient.cpp
@@ -8,6 +8,12 @@
#include "ZigConsoleClient.h"
#include "wtf/text/WTFString.h"
+#undef ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS
+
+#include "JavaScriptCore/JSGlobalObjectInspectorController.h"
+#include "JavaScriptCore/JSGlobalObjectDebuggable.h"
+#include "JavaScriptCore/ConsoleClient.h"
+
#include "GCDefferalContext.h"
using ScriptArguments = Inspector::ScriptArguments;
@@ -24,6 +30,11 @@ void Zig::ConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel
JSC::JSGlobalObject* globalObject,
Ref<ScriptArguments>&& arguments)
{
+ if (globalObject->inspectable()) {
+ if (auto* client = globalObject->inspectorController().consoleClient().get()) {
+ client->messageWithTypeAndLevel(type, level, globalObject, arguments.copyRef());
+ }
+ }
JSC::VM& vm = globalObject->vm();
auto args = arguments.ptr();
JSC__JSValue jsArgs[255];
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 3de7d3daa..baa1ddda7 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -3863,7 +3863,7 @@ EncodedJSValue GlobalObject::assignToStream(JSValue stream, JSValue controller)
arguments.append(stream);
arguments.append(controller);
- auto result = JSC::call(this, function, callData, JSC::jsUndefined(), arguments);
+ auto result = call(this, function, callData, JSC::jsUndefined(), arguments);
if (scope.exception())
return JSC::JSValue::encode(scope.exception());
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 1d82cd0f3..0535b1e8f 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -398,6 +398,7 @@ public:
mutable WriteBarrier<Unknown> m_JSWebSocketSetterValue;
mutable WriteBarrier<Unknown> m_JSWorkerSetterValue;
+ mutable WriteBarrier<Unknown> m_JSBunDebuggerValue;
mutable WriteBarrier<JSFunction> m_thenables[promiseFunctionsSize + 1];
Structure* memoryFootprintStructure()
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp
index f7998c83c..e1d6ba526 100644
--- a/src/bun.js/bindings/bindings.cpp
+++ b/src/bun.js/bindings/bindings.cpp
@@ -252,7 +252,8 @@ static void handlePromise(PromiseType* promise, JSC__JSGlobalObject* globalObjec
arguments.append(jsUndefined());
arguments.append(JSValue::decode(ctx));
ASSERT(!arguments.hasOverflowed());
- JSC::call(globalThis, performPromiseThenFunction, callData, jsUndefined(), arguments);
+ // async context tracking is handled by performPromiseThenFunction internally.
+ JSC::profiledCall(globalThis, JSC::ProfilingReason::Microtask, performPromiseThenFunction, callData, jsUndefined(), arguments);
} else {
promise->then(globalThis, resolverFunction, rejecterFunction);
}
@@ -1770,7 +1771,7 @@ extern "C" JSC__JSValue JSObjectCallAsFunctionReturnValue(JSContextRef ctx, JSC_
return JSC::JSValue::encode(JSC::JSValue());
NakedPtr<JSC::Exception> returnedException = nullptr;
- auto result = JSC::call(globalObject, jsObject, callData, jsThisObject, argList, returnedException);
+ auto result = JSC::profiledCall(globalObject, ProfilingReason::API, jsObject, callData, jsThisObject, argList, returnedException);
if (asyncContextData) {
asyncContextData->putInternalField(vm, 0, restoreAsyncContext);
@@ -1811,7 +1812,7 @@ JSC__JSValue JSObjectCallAsFunctionReturnValueHoldingAPILock(JSContextRef ctx, J
return JSC::JSValue::encode(JSC::JSValue());
NakedPtr<JSC::Exception> returnedException = nullptr;
- auto result = JSC::call(globalObject, jsObject, callData, jsThisObject, argList, returnedException);
+ auto result = call(globalObject, jsObject, callData, jsThisObject, argList, returnedException);
if (returnedException.get()) {
return JSC::JSValue::encode(JSC::JSValue(returnedException.get()));
diff --git a/src/bun.js/bindings/debug-helpers.h b/src/bun.js/bindings/debug-helpers.h
new file mode 100644
index 000000000..a0fc99868
--- /dev/null
+++ b/src/bun.js/bindings/debug-helpers.h
@@ -0,0 +1,18 @@
+#include "root.h"
+
+#include "JavaScriptCore/InspectorDebuggerAgent.h"
+
+namespace JSC {
+Inspector::InspectorDebuggerAgent* debuggerAgent(JSC::JSGlobalObject* globalObject)
+{
+ if (LIKELY(!globalObject->hasDebugger())) {
+ return nullptr;
+ }
+
+ if (auto* debugger = globalObject->debugger()) {
+ return dynamicDowncast<Inspector::InspectorDebuggerAgent>(debugger->client());
+ }
+
+ return nullptr;
+}
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp
index c27bcf533..d532e5444 100644
--- a/src/bun.js/bindings/napi.cpp
+++ b/src/bun.js/bindings/napi.cpp
@@ -1918,7 +1918,7 @@ extern "C" napi_status napi_call_function(napi_env env, napi_value recv_napi,
if (thisValue.isEmpty()) {
thisValue = JSC::jsUndefined();
}
- JSC::JSValue result = JSC::call(globalObject, funcValue, callData, thisValue, args);
+ JSC::JSValue result = call(globalObject, funcValue, callData, thisValue, args);
if (result_ptr) {
*result_ptr = toNapi(result);
diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
index a81b84577..4c09df6a5 100644
--- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
@@ -41,7 +41,7 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockWithImplementationCleanupData;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProcessObject;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalModuleRegistry;
-
+ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBunInspectorConnection;
#include "ZigGeneratedClasses+DOMClientIsoSubspaces.h"
/* --- bun --- */
diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
index c67112388..2b834cf3c 100644
--- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
@@ -41,6 +41,7 @@ public:
std::unique_ptr<IsoSubspace> m_subspaceForMockWithImplementationCleanupData;
std::unique_ptr<IsoSubspace> m_subspaceForProcessObject;
std::unique_ptr<IsoSubspace> m_subspaceForInternalModuleRegistry;
+ std::unique_ptr<IsoSubspace> m_subspaceForBunInspectorConnection;
#include "ZigGeneratedClasses+DOMIsoSubspaces.h"
/*-- BUN --*/
diff --git a/src/bun.js/bindings/webcore/EventEmitter.cpp b/src/bun.js/bindings/webcore/EventEmitter.cpp
index 0e273042b..de0be2c89 100644
--- a/src/bun.js/bindings/webcore/EventEmitter.cpp
+++ b/src/bun.js/bindings/webcore/EventEmitter.cpp
@@ -234,7 +234,7 @@ void EventEmitter::innerInvokeEventListeners(const Identifier& eventType, Simple
continue;
WTF::NakedPtr<JSC::Exception> exceptionPtr;
- JSC::call(lexicalGlobalObject, jsFunction, callData, thisValue, arguments, exceptionPtr);
+ call(lexicalGlobalObject, jsFunction, callData, thisValue, arguments, exceptionPtr);
auto* exception = exceptionPtr.get();
if (UNLIKELY(exception)) {