diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bun.js/bindings/ScriptExecutionContext.h | 2 | ||||
| -rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 178 | ||||
| -rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 10 | ||||
| -rw-r--r-- | src/bun.js/bindings/webcore/JSEventTargetCustom.cpp | 3 | ||||
| -rw-r--r-- | src/bun.js/bindings/webcore/Worker.cpp | 29 | ||||
| -rw-r--r-- | src/bun.js/bindings/webcore/Worker.h | 1 | 
6 files changed, 162 insertions, 61 deletions
| diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h index c3fbd7c9b..520954c29 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.h +++ b/src/bun.js/bindings/ScriptExecutionContext.h @@ -86,6 +86,7 @@ public:          , m_globalObject(globalObject)          , m_identifier(identifier)      { +        addToContextsMap();      }      static ScriptExecutionContextIdentifier generateIdentifier(); @@ -183,6 +184,7 @@ public:      void setGlobalObject(JSC::JSGlobalObject* globalObject)      {          m_globalObject = globalObject; +        m_vm = &globalObject->vm();      }  private: diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index a8d14e533..0262050ff 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -179,6 +179,17 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;  #include "webcrypto/JSSubtleCrypto.h"  #include "JSDOMFormData.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMConvertEventListener.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "AddEventListenerOptions.h"  #include "ErrorStackTrace.h"  #include "CallSite.h" @@ -423,11 +434,10 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje      Zig::GlobalObject* globalObject;      if (UNLIKELY(executionContextId > -1)) { -        ScriptExecutionContext* context = new WebCore::ScriptExecutionContext(&vm, nullptr, static_cast<ScriptExecutionContextIdentifier>(executionContextId));          globalObject = Zig::GlobalObject::create(              vm,              Zig::GlobalObject::createStructure(vm, JSC::JSGlobalObject::create(vm, JSC::JSGlobalObject::createStructure(vm, JSC::jsNull())), JSC::jsNull()), -            context); +            static_cast<ScriptExecutionContextIdentifier>(executionContextId));      } else {          globalObject = Zig::GlobalObject::create(              vm, @@ -435,7 +445,7 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje                  JSC::jsNull()));      } -    globalObject->setConsole(globalObject); +    globalObject->setConsole(console_client);      globalObject->isThreadLocalDefaultGlobalObject = true;      globalObject->setStackTraceLimit(DEFAULT_ERROR_STACK_TRACE_LIMIT); // Node.js defaults to 10      vm.setOnComputeErrorInfo(computeErrorInfo); @@ -699,27 +709,25 @@ GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure)      , m_world(WebCore::DOMWrapperWorld::create(vm, WebCore::DOMWrapperWorld::Type::Normal))      , m_worldIsNormal(true)      , m_builtinInternalFunctions(vm) -    , globalEventScope(Bun::GlobalScope::create(nullptr)) - +    , m_scriptExecutionContext(new WebCore::ScriptExecutionContext(&vm, this)) +    , globalEventScope(*new Bun::GlobalScope(m_scriptExecutionContext))  { -    m_scriptExecutionContext = new WebCore::ScriptExecutionContext(&vm, this); -    globalEventScope->m_context = m_scriptExecutionContext;      mockModule = Bun::JSMockModule::create(this); +    globalEventScope.m_context = m_scriptExecutionContext;  } -GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure, WebCore::ScriptExecutionContext* context) +GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure, WebCore::ScriptExecutionContextIdentifier contextId)      : JSC::JSGlobalObject(vm, structure, &s_globalObjectMethodTable)      , m_bunVM(Bun__getVM())      , m_constructors(makeUnique<WebCore::DOMConstructors>())      , m_world(WebCore::DOMWrapperWorld::create(vm, WebCore::DOMWrapperWorld::Type::Normal))      , m_worldIsNormal(true)      , m_builtinInternalFunctions(vm) -    , globalEventScope(Bun::GlobalScope::create(context)) +    , m_scriptExecutionContext(new WebCore::ScriptExecutionContext(&vm, this, contextId)) +    , globalEventScope(*new Bun::GlobalScope(m_scriptExecutionContext))  {      mockModule = Bun::JSMockModule::create(this); -    m_scriptExecutionContext = context; -    context->setGlobalObject(this); -    context->addToContextsMap(); +    globalEventScope.m_context = m_scriptExecutionContext;  }  GlobalObject::~GlobalObject() @@ -774,12 +782,9 @@ void GlobalObject::promiseRejectionTracker(JSGlobalObject* obj, JSC::JSPromise*      }  } -static Zig::ConsoleClient* m_console; -  void GlobalObject::setConsole(void* console)  { -    m_console = new Zig::ConsoleClient(console); -    this->setConsoleClient(m_console); +    this->setConsoleClient(new Zig::ConsoleClient(console));  }  #pragma mark - Globals @@ -826,7 +831,7 @@ JSC_DEFINE_CUSTOM_SETTER(globalSetterOnError,      return true;  } -Ref<WebCore::EventTarget> GlobalObject::eventTarget() +WebCore::EventTarget& GlobalObject::eventTarget()  {      return globalEventScope;  } @@ -1689,6 +1694,84 @@ JSC:      }  } +static inline JSC::EncodedJSValue jsFunctionAddEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Zig::GlobalObject* castedThis) +{ +    auto& vm = JSC::getVM(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    UNUSED_PARAM(throwScope); +    UNUSED_PARAM(callFrame); +    auto& impl = castedThis->globalEventScope; +    if (UNLIKELY(callFrame->argumentCount() < 2)) +        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); +    EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); +    auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); +    auto listener = convert<IDLNullable<IDLEventListener<JSEventListener>>>(*lexicalGlobalObject, argument1.value(), *castedThis, [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeObjectError(lexicalGlobalObject, scope, 1, "listener", "EventTarget", "addEventListener"); }); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    EnsureStillAliveScope argument2 = callFrame->argument(2); +    auto options = argument2.value().isUndefined() ? false : convert<IDLUnion<IDLDictionary<AddEventListenerOptions>, IDLBoolean>>(*lexicalGlobalObject, argument2.value()); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    auto result = JSValue::encode(WebCore::toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.addEventListenerForBindings(WTFMove(type), WTFMove(listener), WTFMove(options)); })); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    vm.writeBarrier(&static_cast<JSObject&>(*castedThis), argument1.value()); +    return result; +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionAddEventListener, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ +    return jsFunctionAddEventListenerBody(lexicalGlobalObject, callFrame, jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject)); +} + +static inline JSC::EncodedJSValue jsFunctionRemoveEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Zig::GlobalObject* castedThis) +{ +    auto& vm = JSC::getVM(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    UNUSED_PARAM(throwScope); +    UNUSED_PARAM(callFrame); +    auto& impl = castedThis->globalEventScope; +    if (UNLIKELY(callFrame->argumentCount() < 2)) +        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); +    EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); +    auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); +    auto listener = convert<IDLNullable<IDLEventListener<JSEventListener>>>(*lexicalGlobalObject, argument1.value(), *castedThis, [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeObjectError(lexicalGlobalObject, scope, 1, "listener", "EventTarget", "removeEventListener"); }); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    EnsureStillAliveScope argument2 = callFrame->argument(2); +    auto options = argument2.value().isUndefined() ? false : convert<IDLUnion<IDLDictionary<EventListenerOptions>, IDLBoolean>>(*lexicalGlobalObject, argument2.value()); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    auto result = JSValue::encode(WebCore::toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.removeEventListenerForBindings(WTFMove(type), WTFMove(listener), WTFMove(options)); })); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    vm.writeBarrier(&static_cast<JSObject&>(*castedThis), argument1.value()); +    return result; +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionRemoveEventListener, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ +    return jsFunctionRemoveEventListenerBody(lexicalGlobalObject, callFrame, jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject)); +} + +static inline JSC::EncodedJSValue jsFunctionDispatchEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Zig::GlobalObject* castedThis) +{ +    auto& vm = JSC::getVM(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    UNUSED_PARAM(throwScope); +    UNUSED_PARAM(callFrame); +    auto& impl = castedThis->globalEventScope; +    if (UNLIKELY(callFrame->argumentCount() < 1)) +        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); +    EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); +    auto event = convert<IDLInterface<Event>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "event", "EventTarget", "dispatchEvent", "Event"); }); +    RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +    RELEASE_AND_RETURN(throwScope, JSValue::encode(WebCore::toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, impl.dispatchEventForBindings(*event)))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionDispatchEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ +    return jsFunctionDispatchEventBody(lexicalGlobalObject, callFrame, jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject)); +} +  static inline JSValue jsServiceWorkerGlobalScope_ByteLengthQueuingStrategyConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)  {      UNUSED_PARAM(lexicalGlobalObject); @@ -3463,11 +3546,11 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage,          return JSValue::encode(jsUndefined());      } -    ScriptExecutionContext::postTaskTo(context->identifier(), [message = serialized.releaseReturnValue(), protectedThis = Ref { *worker }](ScriptExecutionContext& context) { +    RefPtr<SerializedScriptValue> message = serialized.releaseReturnValue(); +    ScriptExecutionContext::postTaskTo(context->identifier(), [message = WTFMove(message), protectedThis = Ref { *worker }](ScriptExecutionContext& context) {          Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(context.jsGlobalObject());          bool didFail = false;          JSValue value = message->deserialize(*globalObject, globalObject, SerializationErrorMode::NonThrowing, &didFail); -        message->deref();          if (didFail) {              protectedThis->dispatchEvent(MessageEvent::create(eventNames().messageerrorEvent, MessageEvent::Init {}, MessageEvent::IsTrusted::Yes)); @@ -3774,7 +3857,6 @@ JSC_DEFINE_HOST_FUNCTION(functionGetDirectStreamDetails, (JSC::JSGlobalObject *      return JSC::JSValue::encode(resultObject);  } -  JSC::GCClient::IsoSubspace* GlobalObject::subspaceForImpl(JSC::VM& vm)  {      return WebCore::subspaceForImpl<GlobalObject, WebCore::UseCustomHeapCellType::Yes>( @@ -3881,31 +3963,6 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)                  JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });      } -    { -        JSC::Identifier addEventListener = JSC::Identifier::fromString(vm, "addEventListener"_s); -        extraStaticGlobals.uncheckedAppend( -            GlobalPropertyInfo { addEventListener, -                JSC::JSFunction::create(vm, this, 2, -                    "addEventListener"_s, WebCore::jsEventTargetPrototypeFunction_addEventListener, ImplementationVisibility::Public), -                JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 }); -    } - -    { -        extraStaticGlobals.uncheckedAppend( -            GlobalPropertyInfo { JSC::Identifier::fromString(vm, "dispatchEvent"_s), -                JSC::JSFunction::create(vm, this, 1, -                    "dispatchEvent"_s, WebCore::jsEventTargetPrototypeFunction_dispatchEvent, ImplementationVisibility::Public), -                JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 }); -    } - -    { -        extraStaticGlobals.uncheckedAppend( -            GlobalPropertyInfo { JSC::Identifier::fromString(vm, "removeEventListener"_s), -                JSC::JSFunction::create(vm, this, 1, -                    "removeEventListener"_s, WebCore::jsEventTargetPrototypeFunction_removeEventListener, ImplementationVisibility::Public), -                JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 }); -    } -      extraStaticGlobals.uncheckedAppend(          GlobalPropertyInfo { builtinNames.startDirectStreamPrivateName(),              JSC::JSFunction::create(vm, this, 1, @@ -4101,6 +4158,30 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)      putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CountQueuingStrategy"_s), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_CountQueuingStrategyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);      putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "SubtleCrypto"_s), JSC::CustomGetterSetter::create(vm, getterSubtleCryptoConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);      putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CryptoKey"_s), JSC::CustomGetterSetter::create(vm, getterCryptoKeyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + +    putDirectNativeFunction(vm, this, +        Identifier::fromString(vm, "addEventListener"_s), +        2, +        jsFunctionAddEventListener, +        ImplementationVisibility::Public, +        NoIntrinsic, +        JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0); + +    putDirectNativeFunction(vm, this, +        Identifier::fromString(vm, "dispatchEvent"_s), +        1, +        jsFunctionDispatchEvent, +        ImplementationVisibility::Public, +        NoIntrinsic, +        JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0); + +    putDirectNativeFunction(vm, this, +        Identifier::fromString(vm, "removeEventListener"_s), +        2, +        jsFunctionRemoveEventListener, +        ImplementationVisibility::Public, +        NoIntrinsic, +        JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);  }  // We set it in here since it's a global @@ -4474,8 +4555,6 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)      thisObject->visitGeneratedLazyClasses<Visitor>(thisObject, visitor);      visitor.append(thisObject->m_BunCommonJSModuleValue);      thisObject->visitAdditionalChildren<Visitor>(visitor); -    ScriptExecutionContext* context = thisObject->scriptExecutionContext(); -    visitor.addOpaqueRoot(context);  }  extern "C" bool JSGlobalObject__setTimeZone(JSC::JSGlobalObject* globalObject, const ZigString* timeZone) @@ -4547,7 +4626,10 @@ void GlobalObject::visitAdditionalChildren(Visitor& visitor)      GlobalObject* thisObject = this;      ASSERT_GC_OBJECT_INHERITS(thisObject, info()); -    thisObject->globalEventScope->visitJSEventListeners(visitor); +    thisObject->globalEventScope.visitJSEventListeners(visitor); + +    ScriptExecutionContext* context = thisObject->scriptExecutionContext(); +    visitor.addOpaqueRoot(context);  }  DEFINE_VISIT_ADDITIONAL_CHILDREN(GlobalObject); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 5df1560b0..7501be89e 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -133,9 +133,9 @@ public:          return ptr;      } -    static GlobalObject* create(JSC::VM& vm, JSC::Structure* structure, WebCore::ScriptExecutionContext* scriptExecutionContext) +    static GlobalObject* create(JSC::VM& vm, JSC::Structure* structure, uint32_t scriptExecutionContextId)      { -        GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, scriptExecutionContext); +        GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, scriptExecutionContextId);          ptr->finishCreation(vm);          return ptr;      } @@ -312,8 +312,8 @@ public:      EncodedJSValue assignToStream(JSValue stream, JSValue controller); -    Ref<WebCore::EventTarget> eventTarget(); -    Ref<Bun::GlobalScope> globalEventScope; +    WebCore::EventTarget& eventTarget(); +    Bun::GlobalScope& globalEventScope;      enum class PromiseFunctions : uint8_t {          Bun__HTTPRequestContext__onReject, @@ -448,7 +448,7 @@ private:      friend void WebCore::JSBuiltinInternalFunctions::initialize(Zig::GlobalObject&);      WebCore::JSBuiltinInternalFunctions m_builtinInternalFunctions;      GlobalObject(JSC::VM& vm, JSC::Structure* structure); -    GlobalObject(JSC::VM& vm, JSC::Structure* structure, WebCore::ScriptExecutionContext*); +    GlobalObject(JSC::VM& vm, JSC::Structure* structure, uint32_t);      std::unique_ptr<WebCore::DOMConstructors> m_constructors;      uint8_t m_worldIsNormal;      JSDOMStructureMap m_structures WTF_GUARDED_BY_LOCK(m_gcLock); diff --git a/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp b/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp index 75ee90c9f..1b00dc987 100644 --- a/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp +++ b/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp @@ -36,6 +36,7 @@  // #include "JSWindowProxy.h"  // #include "JSWorkerGlobalScope.h"  // #include "WorkerGlobalScope.h" +#include "BunWorkerGlobalScope.h"  #if ENABLE(OFFSCREEN_CANVAS)  #include "OffscreenCanvas.h" @@ -56,7 +57,7 @@ EventTarget* JSEventTarget::toWrapped(VM& vm, JSValue value)      // if (value.inherits<JSDOMWindow>())      //     return &jsCast<JSDOMWindow*>(asObject(value))->wrapped();      if (value.inherits<JSDOMGlobalObject>()) -        return jsCast<JSDOMGlobalObject*>(asObject(value))->eventTarget().ptr(); +        return &jsCast<JSDOMGlobalObject*>(asObject(value))->globalEventScope;      if (value.inherits<JSEventTarget>())          return &jsCast<JSEventTarget*>(asObject(value))->wrapped();      return nullptr; diff --git a/src/bun.js/bindings/webcore/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index 4ffbc0684..d92b6e2e5 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -60,6 +60,7 @@  #include "JavaScriptCore/DeferredWorkTimer.h"  #include "MessageEvent.h"  #include <JavaScriptCore/HashMapImplInlines.h> +#include "BunWorkerGlobalScope.h"  namespace WebCore { @@ -176,20 +177,21 @@ ExceptionOr<void> Worker::postMessage(JSC::JSGlobalObject& state, JSC::JSValue m      if (message.hasException())          return message.releaseException(); -    this->postTaskToWorkerGlobalScope([message = message.releaseReturnValue()](auto& context) { +    RefPtr<SerializedScriptValue> result = message.releaseReturnValue(); + +    this->postTaskToWorkerGlobalScope([message = WTFMove(result)](auto& context) {          Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(context.jsGlobalObject());          bool didFail = false;          JSValue value = message->deserialize(*globalObject, globalObject, SerializationErrorMode::NonThrowing, &didFail); -        message->deref();          if (didFail) { -            globalObject->eventTarget()->dispatchEvent(MessageEvent::create(eventNames().messageerrorEvent, MessageEvent::Init {}, MessageEvent::IsTrusted::Yes)); +            globalObject->globalEventScope.dispatchEvent(MessageEvent::create(eventNames().messageerrorEvent, MessageEvent::Init {}, MessageEvent::IsTrusted::Yes));              return;          }          WebCore::MessageEvent::Init init;          init.data = value; -        globalObject->eventTarget()->dispatchEvent(MessageEvent::create(eventNames().messageEvent, WTFMove(init), MessageEvent::IsTrusted::Yes)); +        globalObject->globalEventScope.dispatchEvent(MessageEvent::create(eventNames().messageEvent, WTFMove(init), MessageEvent::IsTrusted::Yes));      });      return {};  } @@ -229,6 +231,10 @@ void Worker::terminate()  bool Worker::hasPendingActivity() const  { +    if (this->refCount() > 0) { +        return true; +    } +      if (this->m_isOnline) {          return !this->m_isClosing;      } @@ -241,7 +247,7 @@ void Worker::dispatchEvent(Event& event)      if (m_wasTerminated)          return; -    EventTarget::dispatchEvent(event); +    EventTargetWithInlineData::dispatchEvent(event);  }  #if ENABLE(WEB_RTC) @@ -259,6 +265,7 @@ void Worker::createRTCRtpScriptTransformer(RTCRtpScriptTransform& transform, Mes  void Worker::drainEvents()  { +    Locker lock(this->m_pendingTasksMutex);      for (auto& task : m_pendingTasks)          postTaskToWorkerGlobalScope(WTFMove(task));      m_pendingTasks.clear(); @@ -277,19 +284,26 @@ void Worker::dispatchOnline(Zig::GlobalObject* workerGlobalObject)          });      } +    Locker lock(this->m_pendingTasksMutex); +      this->m_isOnline = true;      auto* thisContext = workerGlobalObject->scriptExecutionContext();      if (!thisContext) {          return;      } +    RELEASE_ASSERT(&thisContext->vm() == &workerGlobalObject->vm()); +    RELEASE_ASSERT(thisContext == workerGlobalObject->globalEventScope.scriptExecutionContext()); -    if (workerGlobalObject->eventTarget()->hasActiveEventListeners(eventNames().messageEvent)) { +    if (workerGlobalObject->globalEventScope.hasActiveEventListeners(eventNames().messageEvent)) {          auto tasks = std::exchange(this->m_pendingTasks, {}); +        lock.unlockEarly();          for (auto& task : tasks) {              task(*thisContext);          }      } else {          auto tasks = std::exchange(this->m_pendingTasks, {}); +        lock.unlockEarly(); +          thisContext->postTask([tasks = WTFMove(tasks)](auto& ctx) mutable {              for (auto& task : tasks) {                  task(ctx); @@ -334,6 +348,7 @@ void Worker::dispatchExit()  void Worker::postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&& task)  {      if (!this->m_isOnline) { +        Locker lock(this->m_pendingTasksMutex);          this->m_pendingTasks.append(WTFMove(task));          return;      } @@ -388,7 +403,7 @@ extern "C" void WebWorker__dispatchError(Zig::GlobalObject* globalObject, Worker      init.cancelable = false;      init.bubbles = false; -    globalObject->eventTarget()->dispatchEvent(ErrorEvent::create(eventNames().errorEvent, init, EventIsTrusted::Yes)); +    globalObject->globalEventScope.dispatchEvent(ErrorEvent::create(eventNames().errorEvent, init, EventIsTrusted::Yes));      worker->dispatchError(Bun::toWTFString(message));  } diff --git a/src/bun.js/bindings/webcore/Worker.h b/src/bun.js/bindings/webcore/Worker.h index edd9f082d..99a54e37f 100644 --- a/src/bun.js/bindings/webcore/Worker.h +++ b/src/bun.js/bindings/webcore/Worker.h @@ -126,6 +126,7 @@ private:      // bool m_isSuspendedForBackForwardCache { false };      // JSC::RuntimeFlags m_runtimeFlags;      Deque<RefPtr<Event>> m_pendingEvents; +    Lock m_pendingTasksMutex;      Deque<Function<void(ScriptExecutionContext&)>> m_pendingTasks;      bool m_wasTerminated { false };      bool m_didStartWorkerGlobalScope { false }; | 
