aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bun.js/bindings/bindings.cpp13
-rw-r--r--src/bun.js/bindings/webcore/EventEmitter.cpp66
-rw-r--r--src/bun.js/bindings/webcore/IdentifierEventListenerMap.h4
-rw-r--r--src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp15
4 files changed, 57 insertions, 41 deletions
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp
index 8e401b4cd..114b59163 100644
--- a/src/bun.js/bindings/bindings.cpp
+++ b/src/bun.js/bindings/bindings.cpp
@@ -3819,21 +3819,23 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC__JSGlobalObject* arg0
JSC::JSValue::decode(JSValue4));
}
-extern "C" JSC__JSValue JSC__AbortSignal__create(JSC__JSGlobalObject* globalObject) {
+extern "C" JSC__JSValue JSC__AbortSignal__create(JSC__JSGlobalObject* globalObject)
+{
Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(globalObject);
auto* context = thisObject->scriptExecutionContext();
auto abortSignal = WebCore::AbortSignal::create(context);
return JSValue::encode(toJSNewlyCreated<IDLInterface<JSC__AbortSignal>>(*globalObject, *jsCast<JSDOMGlobalObject*>(globalObject), WTFMove(abortSignal)));
}
-extern "C" JSC__JSValue JSC__AbortSignal__toJS(JSC__AbortSignal* arg0, JSC__JSGlobalObject* globalObject) {
+extern "C" JSC__JSValue JSC__AbortSignal__toJS(JSC__AbortSignal* arg0, JSC__JSGlobalObject* globalObject)
+{
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
return JSValue::encode(toJS<IDLInterface<JSC__AbortSignal>>(*globalObject, *jsCast<JSDOMGlobalObject*>(globalObject), *abortSignal));
}
-
-extern "C" JSC__AbortSignal* JSC__AbortSignal__signal(JSC__AbortSignal* arg0, JSC__JSValue JSValue1) {
+extern "C" JSC__AbortSignal* JSC__AbortSignal__signal(JSC__AbortSignal* arg0, JSC__JSValue JSValue1)
+{
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
abortSignal->signalAbort(JSC::JSValue::decode(JSValue1));
@@ -3865,7 +3867,8 @@ extern "C" JSC__AbortSignal* JSC__AbortSignal__unref(JSC__AbortSignal* arg0)
abortSignal->deref();
return arg0;
}
-extern "C" void JSC__AbortSignal__cleanNativeBindings(JSC__AbortSignal* arg0, void* arg1) {
+extern "C" void JSC__AbortSignal__cleanNativeBindings(JSC__AbortSignal* arg0, void* arg1)
+{
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
abortSignal->cleanNativeBindings(arg1);
}
diff --git a/src/bun.js/bindings/webcore/EventEmitter.cpp b/src/bun.js/bindings/webcore/EventEmitter.cpp
index 02770be68..4ea10587e 100644
--- a/src/bun.js/bindings/webcore/EventEmitter.cpp
+++ b/src/bun.js/bindings/webcore/EventEmitter.cpp
@@ -177,12 +177,14 @@ void EventEmitter::fireEventListeners(const Identifier& eventType, const MarkedA
if (!data)
return;
- SetForScope firingEventListenersScope(data->isFiringEventListeners, true);
-
- if (auto* listenersVector = data->eventListenerMap.find(eventType)) {
- innerInvokeEventListeners(eventType, *listenersVector, arguments);
+ auto* listenersVector = data->eventListenerMap.find(eventType);
+ if (UNLIKELY(!listenersVector))
return;
- }
+
+ bool prevFiringEventListeners = data->isFiringEventListeners;
+ data->isFiringEventListeners = true;
+ innerInvokeEventListeners(eventType, *listenersVector, arguments);
+ data->isFiringEventListeners = prevFiringEventListeners;
}
// Intentionally creates a copy of the listeners vector to avoid event listeners added after this point from being run.
@@ -204,39 +206,45 @@ void EventEmitter::innerInvokeEventListeners(const Identifier& eventType, Simple
if (UNLIKELY(registeredListener->wasRemoved()))
continue;
+ auto& callback = registeredListener->callback();
+
// Make sure the JS wrapper and function stay alive until the end of this scope. Otherwise,
// event listeners with 'once' flag may get collected as soon as they get unregistered below,
// before we call the js function.
- JSC::EnsureStillAliveScope wrapperProtector(registeredListener->callback().wrapper());
- JSC::EnsureStillAliveScope jsFunctionProtector(registeredListener->callback().jsFunction());
+ JSObject* jsFunction = callback.jsFunction();
+ JSC::EnsureStillAliveScope wrapperProtector(callback.wrapper());
+ JSC::EnsureStillAliveScope jsFunctionProtector(jsFunction);
// Do this before invocation to avoid reentrancy issues.
if (registeredListener->isOnce())
- removeListener(eventType, registeredListener->callback());
+ removeListener(eventType, callback);
- if (JSC::JSObject* jsFunction = registeredListener->callback().jsFunction()) {
- JSC::JSGlobalObject* lexicalGlobalObject = jsFunction->globalObject();
- auto callData = JSC::getCallData(jsFunction);
- if (callData.type == JSC::CallData::Type::None)
- continue;
+ if (UNLIKELY(!jsFunction))
+ continue;
+
+ JSC::JSGlobalObject* lexicalGlobalObject = jsFunction->globalObject();
+ auto callData = JSC::getCallData(jsFunction);
+ if (UNLIKELY(callData.type == JSC::CallData::Type::None))
+ continue;
- WTF::NakedPtr<JSC::Exception> exceptionPtr;
- JSC::call(jsFunction->globalObject(), jsFunction, callData, thisValue, arguments, exceptionPtr);
- if (auto* exception = exceptionPtr.get()) {
- auto errorIdentifier = JSC::Identifier::fromString(vm, eventNames().errorEvent);
- auto hasErrorListener = this->hasActiveEventListeners(errorIdentifier);
- if (!hasErrorListener || eventType == errorIdentifier) {
- // If the event type is error, report the exception to the console.
- Bun__reportUnhandledError(lexicalGlobalObject, JSValue::encode(JSValue(exception)));
- } else if (hasErrorListener) {
- MarkedArgumentBuffer expcep;
- JSValue errorValue = exception->value();
- if (!errorValue) {
- errorValue = JSC::jsUndefined();
- }
- expcep.append(errorValue);
- fireEventListeners(errorIdentifier, WTFMove(expcep));
+ WTF::NakedPtr<JSC::Exception> exceptionPtr;
+ JSC::call(lexicalGlobalObject, jsFunction, callData, thisValue, arguments, exceptionPtr);
+ auto* exception = exceptionPtr.get();
+
+ if (UNLIKELY(exception)) {
+ auto errorIdentifier = JSC::Identifier::fromString(vm, eventNames().errorEvent);
+ auto hasErrorListener = this->hasActiveEventListeners(errorIdentifier);
+ if (!hasErrorListener || eventType == errorIdentifier) {
+ // If the event type is error, report the exception to the console.
+ Bun__reportUnhandledError(lexicalGlobalObject, JSValue::encode(JSValue(exception)));
+ } else if (hasErrorListener) {
+ MarkedArgumentBuffer expcep;
+ JSValue errorValue = exception->value();
+ if (!errorValue) {
+ errorValue = JSC::jsUndefined();
}
+ expcep.append(errorValue);
+ fireEventListeners(errorIdentifier, WTFMove(expcep));
}
}
}
diff --git a/src/bun.js/bindings/webcore/IdentifierEventListenerMap.h b/src/bun.js/bindings/webcore/IdentifierEventListenerMap.h
index 1d3f00cbd..d78f7ec11 100644
--- a/src/bun.js/bindings/webcore/IdentifierEventListenerMap.h
+++ b/src/bun.js/bindings/webcore/IdentifierEventListenerMap.h
@@ -36,8 +36,8 @@ private:
Ref<EventListener> m_callback;
};
-using SimpleEventListenerVector = Vector<RefPtr<SimpleRegisteredEventListener>, 0, CrashOnOverflow, 2>;
-using EntriesVector = Vector<std::pair<JSC::Identifier, SimpleEventListenerVector>, 0, CrashOnOverflow, 4>;
+using SimpleEventListenerVector = Vector<RefPtr<SimpleRegisteredEventListener>, 2, CrashOnOverflow, 6>;
+using EntriesVector = Vector<std::pair<JSC::Identifier, SimpleEventListenerVector>, 4, CrashOnOverflow, 8>;
class IdentifierEventListenerMap {
public:
diff --git a/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp b/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp
index e6e15b874..fd2a61822 100644
--- a/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp
+++ b/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp
@@ -42,19 +42,24 @@ std::unique_ptr<JSEventEmitterWrapper> jsEventEmitterCast(VM& vm, JSC::JSGlobalO
JSEventEmitter* jsEventEmitterCastFast(VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSValue thisValue)
{
- if (thisValue.inherits<JSEventEmitter>())
- return jsCast<JSEventEmitter*>(asObject(thisValue));
+ if (UNLIKELY(!thisValue.isCell())) {
+ return nullptr;
+ }
- if (UNLIKELY(thisValue.isUndefinedOrNull() || !thisValue.isObject())) {
+ JSCell* thisCell = thisValue.asCell();
+ if (UNLIKELY(!thisCell->isObject())) {
return nullptr;
}
- auto* thisObject = asObject(thisValue);
+ auto* thisObject = asObject(thisCell);
+
+ if (thisObject->inherits<JSEventEmitter>())
+ return jsCast<JSEventEmitter*>(thisObject);
auto clientData = WebCore::clientData(vm);
auto name = clientData->builtinNames()._eventsPublicName();
if (JSValue _events = thisObject->getIfPropertyExists(lexicalGlobalObject, name)) {
- if (!_events.isUndefinedOrNull() && _events.inherits<JSEventEmitter>()) {
+ if (_events.isCell() && _events.inherits<JSEventEmitter>()) {
return jsCast<JSEventEmitter*>(asObject(_events));
}
}