From c2dafcaad20dd97d4f45a5800475cda9cabf284f Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Tue, 7 Jan 2025 17:03:16 -0800 Subject: [PATCH 01/15] Bump WebKit and re-enable IPInt --- cmake/tools/SetupWebKit.cmake | 2 +- src/bun.js/bindings/ZigGlobalObject.cpp | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 22e95e77422b9a..7bd8e5a33c6601 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION e1a802a2287edfe7f4046a9dd8307c8b59f5d816) + set(WEBKIT_VERSION 2399a4a00d9e0da0b34b7bd52a369a89a631ae98) endif() if(WEBKIT_LOCAL) diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index c407e2fbe19af7..98a3a38286b754 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -242,9 +242,6 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c JSC::Options::useConcurrentJIT() = true; // JSC::Options::useSigillCrashAnalyzer() = true; JSC::Options::useWasm() = true; - // Disable IPInt, the in-place WASM interpreter, by default until it is more stable - // (it breaks pglite as of 2025-01-06) - JSC::Options::useWasmIPInt() = false; JSC::Options::useSourceProviderCache() = true; // JSC::Options::useUnlinkedCodeBlockJettisoning() = false; JSC::Options::exposeInternalModuleLoader() = true; From 86fa086ea3e1f79c021ec128bc5d0becff4cbbd8 Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Tue, 7 Jan 2025 17:55:57 -0800 Subject: [PATCH 02/15] Bump again --- cmake/tools/SetupWebKit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 7bd8e5a33c6601..d9dc593585780a 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 2399a4a00d9e0da0b34b7bd52a369a89a631ae98) + set(WEBKIT_VERSION 3cb28b31a96dcd075b356739d07947ce0ece8773) endif() if(WEBKIT_LOCAL) From 25481320f1ca34adf10a2f7a5938a1d0843d365d Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 7 Jan 2025 18:38:41 -0800 Subject: [PATCH 03/15] Update InspectorTestReporterAgent.h --- src/bun.js/bindings/InspectorTestReporterAgent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bun.js/bindings/InspectorTestReporterAgent.h b/src/bun.js/bindings/InspectorTestReporterAgent.h index 7c6afcf2e0ec26..625a5d0c271e18 100644 --- a/src/bun.js/bindings/InspectorTestReporterAgent.h +++ b/src/bun.js/bindings/InspectorTestReporterAgent.h @@ -20,6 +20,7 @@ class InspectorTestReporterAgent final : public InspectorAgentBase, public Inspe WTF_MAKE_NONCOPYABLE(InspectorTestReporterAgent); public: + WTF_MAKE_TZONE_ALLOCATED(InspectorTestReporterAgent); InspectorTestReporterAgent(JSC::JSGlobalObject&); virtual ~InspectorTestReporterAgent(); From 2224cd9ab9b2d67080268e13926ce5cb759df212 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 7 Jan 2025 18:42:48 -0800 Subject: [PATCH 04/15] Update InspectorTestReporterAgent.h --- src/bun.js/bindings/InspectorTestReporterAgent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bun.js/bindings/InspectorTestReporterAgent.h b/src/bun.js/bindings/InspectorTestReporterAgent.h index 625a5d0c271e18..374553edd0976b 100644 --- a/src/bun.js/bindings/InspectorTestReporterAgent.h +++ b/src/bun.js/bindings/InspectorTestReporterAgent.h @@ -18,9 +18,9 @@ enum class DisconnectReason; class InspectorTestReporterAgent final : public InspectorAgentBase, public Inspector::TestReporterBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorTestReporterAgent); + WTF_MAKE_TZONE_ALLOCATED(InspectorTestReporterAgent); public: - WTF_MAKE_TZONE_ALLOCATED(InspectorTestReporterAgent); InspectorTestReporterAgent(JSC::JSGlobalObject&); virtual ~InspectorTestReporterAgent(); From 95b47ef23ebe67691851f58ae6263522fb9e4e3b Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 7 Jan 2025 19:28:02 -0800 Subject: [PATCH 05/15] Fix --- src/bun.js/bindings/InspectorLifecycleAgent.cpp | 3 +++ src/bun.js/bindings/InspectorLifecycleAgent.h | 1 + src/bun.js/bindings/InspectorTestReporterAgent.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/bun.js/bindings/InspectorLifecycleAgent.cpp b/src/bun.js/bindings/InspectorLifecycleAgent.cpp index f65b1ffcd4f473..090f9f59d7f0b4 100644 --- a/src/bun.js/bindings/InspectorLifecycleAgent.cpp +++ b/src/bun.js/bindings/InspectorLifecycleAgent.cpp @@ -11,9 +11,12 @@ #include #include #include "ConsoleObject.h" +#include namespace Inspector { +WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorLifecycleAgent); + // Zig bindings implementation extern "C" { diff --git a/src/bun.js/bindings/InspectorLifecycleAgent.h b/src/bun.js/bindings/InspectorLifecycleAgent.h index 5990b833f60840..8f2d9ebc0a9d22 100644 --- a/src/bun.js/bindings/InspectorLifecycleAgent.h +++ b/src/bun.js/bindings/InspectorLifecycleAgent.h @@ -18,6 +18,7 @@ enum class DisconnectReason; class InspectorLifecycleAgent final : public InspectorAgentBase, public Inspector::LifecycleReporterBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorLifecycleAgent); + WTF_MAKE_TZONE_ALLOCATED(InspectorLifecycleAgent); public: InspectorLifecycleAgent(JSC::JSGlobalObject&); diff --git a/src/bun.js/bindings/InspectorTestReporterAgent.cpp b/src/bun.js/bindings/InspectorTestReporterAgent.cpp index 00d8bbc7daa37b..f93097cc46318b 100644 --- a/src/bun.js/bindings/InspectorTestReporterAgent.cpp +++ b/src/bun.js/bindings/InspectorTestReporterAgent.cpp @@ -11,9 +11,12 @@ #include "ZigGlobalObject.h" #include "ModuleLoader.h" +#include namespace Inspector { +WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorTestReporterAgent); + // Zig bindings implementation extern "C" { From 22365265a01f046e68ed1f0d05d8bcaa5a418cec Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 7 Jan 2025 21:09:58 -0800 Subject: [PATCH 06/15] Update SetupWebKit.cmake --- cmake/tools/SetupWebKit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index d9dc593585780a..512a503ce9fb84 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 3cb28b31a96dcd075b356739d07947ce0ece8773) + set(WEBKIT_VERSION d2b0aa2a8e61ebc7640f1a821793c0c430c5485d) endif() if(WEBKIT_LOCAL) From 415c77f58a797328dc5c2a9d6f42e67d027a1814 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 00:45:09 -0800 Subject: [PATCH 07/15] tweaks to match webkit changes --- .vscode/launch.json | 8 ++++ src/bun.js/bindings/BunDebugger.cpp | 4 +- src/bun.js/bindings/BunPlugin.h | 2 +- src/bun.js/bindings/DOMWrapperWorld-class.h | 2 +- src/bun.js/bindings/JSCTaskScheduler.h | 4 +- .../bindings/ScriptExecutionContext.cpp | 43 ++++++++++++++++++- src/bun.js/bindings/ScriptExecutionContext.h | 30 ++++--------- src/bun.js/bindings/ZigGlobalObject.cpp | 6 ++- src/bun.js/bindings/ZigGlobalObject.h | 6 +-- .../bindings/webcore/BroadcastChannel.cpp | 1 + .../bindings/webcore/MessagePortChannel.h | 2 +- src/bun.js/javascript.zig | 4 +- src/js_ast.zig | 1 + 13 files changed, 75 insertions(+), 38 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 817b7533d3e3a2..abb2ef8a7f7367 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,6 +16,14 @@ "args": ["test", "${file}"], "cwd": "${workspaceFolder}", "env": { + // "DYLD_INSERT_LIBRARIES": "/Users/jarred/Code/bun/build/debug/libBun.dylib", + // ADd LIBGMALLOC + "DYLD_INSERT_LIBRARIES": "/usr/lib/libgmalloc.dylib", + "MALLOC_PROTECT_BEFORE": "1", + "MALLOC_STRICT_SIZE": "1", + "MallocScribble": "1", + "MallocGuardEdges": "1", + "BUN_JSC_randomIntegrityAuditRate": "1.0", "BUN_DEBUG_QUIET_LOGS": "1", "BUN_DEBUG_jest": "1", "BUN_GARBAGE_COLLECTOR_LEVEL": "1", diff --git a/src/bun.js/bindings/BunDebugger.cpp b/src/bun.js/bindings/BunDebugger.cpp index 9b9759591779a9..c0aeba45eb5447 100644 --- a/src/bun.js/bindings/BunDebugger.cpp +++ b/src/bun.js/bindings/BunDebugger.cpp @@ -26,7 +26,7 @@ class BunInspectorConnection; static WebCore::ScriptExecutionContext* debuggerScriptExecutionContext = nullptr; static WTF::Lock inspectorConnectionsLock = WTF::Lock(); -static WTF::HashMap>* inspectorConnections = nullptr; +static WTF::UncheckedKeyHashMap>* inspectorConnections = nullptr; static bool waitingForConnection = false; extern "C" void Debugger__didConnect(); @@ -487,7 +487,7 @@ extern "C" unsigned int Bun__createJSDebugger(Zig::GlobalObject* globalObject) { Locker locker(inspectorConnectionsLock); if (inspectorConnections == nullptr) { - inspectorConnections = new WTF::HashMap>(); + inspectorConnections = new WTF::UncheckedKeyHashMap>(); } inspectorConnections->add(globalObject->scriptExecutionContext()->identifier(), Vector()); diff --git a/src/bun.js/bindings/BunPlugin.h b/src/bun.js/bindings/BunPlugin.h index 09562f90f59680..ed54f2ff42e2eb 100644 --- a/src/bun.js/bindings/BunPlugin.h +++ b/src/bun.js/bindings/BunPlugin.h @@ -15,7 +15,7 @@ using namespace JSC; class BunPlugin { public: - using VirtualModuleMap = WTF::HashMap>; + using VirtualModuleMap = WTF::UncheckedKeyHashMap>; // This is a list of pairs of regexps and functions to match against class Group { diff --git a/src/bun.js/bindings/DOMWrapperWorld-class.h b/src/bun.js/bindings/DOMWrapperWorld-class.h index 75d14bfaf9969d..29b10884793f9b 100644 --- a/src/bun.js/bindings/DOMWrapperWorld-class.h +++ b/src/bun.js/bindings/DOMWrapperWorld-class.h @@ -50,7 +50,7 @@ class DOMWrapperWorld : public RefCounted { private: JSC::VM& m_vm; - HashSet m_jsWindowProxies; + UncheckedKeyHashSet m_jsWindowProxies; DOMObjectWrapperMap m_wrappers; String m_name; diff --git a/src/bun.js/bindings/JSCTaskScheduler.h b/src/bun.js/bindings/JSCTaskScheduler.h index 29660c406d2bea..24e8eb56e3f6b0 100644 --- a/src/bun.js/bindings/JSCTaskScheduler.h +++ b/src/bun.js/bindings/JSCTaskScheduler.h @@ -22,8 +22,8 @@ class JSCTaskScheduler { public: Lock m_lock; - HashSet> m_pendingTicketsKeepingEventLoopAlive; - HashSet> m_pendingTicketsOther; + UncheckedKeyHashSet> m_pendingTicketsKeepingEventLoopAlive; + UncheckedKeyHashSet> m_pendingTicketsOther; }; } diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp index 34534d6369b048..4fc4ab352aa8a7 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.cpp +++ b/src/bun.js/bindings/ScriptExecutionContext.cpp @@ -7,12 +7,51 @@ #include "_libusockets.h" #include "BunClientData.h" #include "EventLoopTask.h" - +#include "BunBroadcastChannelRegistry.h" +#include extern "C" void Bun__startLoop(us_loop_t* loop); namespace WebCore { +static constexpr ScriptExecutionContextIdentifier INITIAL_IDENTIFIER_INTERNAL = 1; + +static std::atomic lastUniqueIdentifier = INITIAL_IDENTIFIER_INTERNAL; + +#if ASSERT_ENABLED +static ScriptExecutionContextIdentifier initialIdentifier() +{ + static bool hasCalledInitialIdentifier = false; + ASSERT_WITH_MESSAGE(!hasCalledInitialIdentifier, "ScriptExecutionContext::initialIdentifier() cannot be called more than once. Use generateIdentifier() instead."); + hasCalledInitialIdentifier = true; + return INITIAL_IDENTIFIER_INTERNAL; +} +#else +static ScriptExecutionContextIdentifier initialIdentifier() +{ + return INITIAL_IDENTIFIER_INTERNAL; +} +#endif -static std::atomic lastUniqueIdentifier = 0; +ScriptExecutionContext::ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject) + : m_vm(vm) + , m_globalObject(globalObject) + , m_identifier(initialIdentifier()) + , m_broadcastChannelRegistry([](auto& owner, auto& lazyRef) { + lazyRef.set(BunBroadcastChannelRegistry::create()); + }) +{ + addToContextsMap(); +} + +ScriptExecutionContext::ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject, ScriptExecutionContextIdentifier identifier) + : m_vm(vm) + , m_globalObject(globalObject) + , m_identifier(identifier == std::numeric_limits::max() ? ++lastUniqueIdentifier : identifier) + , m_broadcastChannelRegistry([](auto& owner, auto& lazyRef) { + lazyRef.set(BunBroadcastChannelRegistry::create()); + }) +{ + addToContextsMap(); +} WTF_MAKE_ISO_ALLOCATED_IMPL(EventLoopTask); WTF_MAKE_ISO_ALLOCATED_IMPL(ScriptExecutionContext); diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h index 23bca74153877b..66d99f8b52c033 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.h +++ b/src/bun.js/bindings/ScriptExecutionContext.h @@ -3,7 +3,6 @@ #include "root.h" #include "ActiveDOMObject.h" #include "ContextDestructionObserver.h" -#include "BunBroadcastChannelRegistry.h" #include #include #include @@ -13,6 +12,7 @@ #include #include "CachedScript.h" #include +#include namespace uWS { template @@ -26,6 +26,7 @@ struct us_loop_t; namespace WebCore { class WebSocket; +class BunBroadcastChannelRegistry; class MessagePort; class ScriptExecutionContext; @@ -37,23 +38,8 @@ class ScriptExecutionContext : public CanMakeWeakPtr { WTF_MAKE_ISO_ALLOCATED(ScriptExecutionContext); public: - ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject) - : m_vm(vm) - , m_globalObject(globalObject) - , m_identifier(0) - , m_broadcastChannelRegistry(BunBroadcastChannelRegistry::create()) - { - regenerateIdentifier(); - } - - ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject, ScriptExecutionContextIdentifier identifier) - : m_vm(vm) - , m_globalObject(globalObject) - , m_identifier(identifier) - , m_broadcastChannelRegistry(BunBroadcastChannelRegistry::create()) - { - addToContextsMap(); - } + ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject); + ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject, ScriptExecutionContextIdentifier identifier); ~ScriptExecutionContext(); @@ -156,7 +142,7 @@ class ScriptExecutionContext : public CanMakeWeakPtr { m_vm = &globalObject->vm(); } - BunBroadcastChannelRegistry& broadcastChannelRegistry() { return m_broadcastChannelRegistry; } + BunBroadcastChannelRegistry& broadcastChannelRegistry() { return m_broadcastChannelRegistry.get(*this); } static ScriptExecutionContext* getMainThreadScriptExecutionContext(); @@ -166,10 +152,10 @@ class ScriptExecutionContext : public CanMakeWeakPtr { WTF::URL m_url = WTF::URL(); ScriptExecutionContextIdentifier m_identifier; - HashSet m_messagePorts; - HashSet m_destructionObservers; + UncheckedKeyHashSet m_messagePorts; + UncheckedKeyHashSet m_destructionObservers; Vector> m_processMessageWithMessagePortsSoonHandlers; - Ref m_broadcastChannelRegistry; + LazyRef m_broadcastChannelRegistry; bool m_willProcessMessageWithMessagePortsSoon { false }; diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 98a3a38286b754..f1a048b03b15cc 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -1,6 +1,5 @@ #include "root.h" -#include "JavaScriptCore/PropertySlot.h" #include "ZigGlobalObject.h" #include "helpers.h" #include "JavaScriptCore/ArgList.h" @@ -862,6 +861,9 @@ void Zig::GlobalObject::resetOnEachMicrotaskTick() } } +// executionContextId: -1 for main thread +// executionContextId: maxInt32 for macros +// executionContextId: >-1 for workers extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(void* console_client, int32_t executionContextId, bool miniMode, bool evalMode, void* worker_ptr) { auto heapSize = miniMode ? JSC::HeapType::Small : JSC::HeapType::Large; @@ -878,7 +880,7 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(void* console_client, WebCore::JSVMClientData::create(&vm, Bun__getVM()); const auto createGlobalObject = [&]() -> Zig::GlobalObject* { - if (UNLIKELY(executionContextId > -1)) { + if (UNLIKELY(executionContextId == std::numeric_limits::max() || executionContextId > -1)) { auto* structure = Zig::GlobalObject::createStructure(vm); if (UNLIKELY(!structure)) { return nullptr; diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index c556cd86888ea4..7c7e1bfa881ebc 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -72,8 +72,8 @@ namespace Zig { class JSCStackTrace; -using JSDOMStructureMap = HashMap>; -using DOMGuardedObjectSet = HashSet; +using JSDOMStructureMap = UncheckedKeyHashMap>; +using DOMGuardedObjectSet = UncheckedKeyHashSet; #define ZIG_GLOBAL_OBJECT_DEFINED @@ -450,7 +450,7 @@ class GlobalObject : public Bun::GlobalScope { // This increases the cache hit rate for JSC::VM's SourceProvider cache // It also avoids an extra allocation for the SourceProvider // The key is a pointer to the source code - WTF::HashMap> sourceProviderMap; + WTF::UncheckedKeyHashMap> sourceProviderMap; size_t reloadCount = 0; void reload(); diff --git a/src/bun.js/bindings/webcore/BroadcastChannel.cpp b/src/bun.js/bindings/webcore/BroadcastChannel.cpp index dbd4df5ff41ae7..4b344d5f0e7e50 100644 --- a/src/bun.js/bindings/webcore/BroadcastChannel.cpp +++ b/src/bun.js/bindings/webcore/BroadcastChannel.cpp @@ -28,6 +28,7 @@ #include "BunClientData.h" #include "BroadcastChannelRegistry.h" +#include "BunBroadcastChannelRegistry.h" #include "EventNames.h" #include "EventTarget.h" #include "MessageEvent.h" diff --git a/src/bun.js/bindings/webcore/MessagePortChannel.h b/src/bun.js/bindings/webcore/MessagePortChannel.h index d50105badb3cce..c9786a094ed254 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannel.h +++ b/src/bun.js/bindings/webcore/MessagePortChannel.h @@ -75,7 +75,7 @@ class MessagePortChannel : public RefCounted { std::optional m_processes[2]; RefPtr m_entangledToProcessProtectors[2]; Vector m_pendingMessages[2]; - HashSet> m_pendingMessagePortTransfers[2]; + UncheckedKeyHashSet> m_pendingMessagePortTransfers[2]; RefPtr m_pendingMessageProtectors[2]; uint64_t m_messageBatchesInFlight { 0 }; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 4029ab0fbb7409..dc8c9744a13fd3 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1951,7 +1951,7 @@ pub const VirtualMachine = struct { } vm.global = ZigGlobalObject.create( vm.console, - -1, + if (opts.is_main_thread) -1 else std.math.maxInt(i32), false, false, null, @@ -2061,7 +2061,7 @@ pub const VirtualMachine = struct { vm.global = ZigGlobalObject.create( vm.console, - -1, + if (opts.is_main_thread) -1 else std.math.maxInt(i32), opts.smol, opts.eval, null, diff --git a/src/js_ast.zig b/src/js_ast.zig index fe7456598e30ba..e4e666fad4386c 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -8095,6 +8095,7 @@ pub const Macro = struct { .allocator = default_allocator, .args = resolver.opts.transform_options, .log = log, + .is_main_thread = false, .env_loader = env, }); From 92fa5323dc69cec648e9cb5828ccb8de13a639a9 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 03:37:18 -0800 Subject: [PATCH 08/15] Update launch.json --- .vscode/launch.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index abb2ef8a7f7367..817b7533d3e3a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,14 +16,6 @@ "args": ["test", "${file}"], "cwd": "${workspaceFolder}", "env": { - // "DYLD_INSERT_LIBRARIES": "/Users/jarred/Code/bun/build/debug/libBun.dylib", - // ADd LIBGMALLOC - "DYLD_INSERT_LIBRARIES": "/usr/lib/libgmalloc.dylib", - "MALLOC_PROTECT_BEFORE": "1", - "MALLOC_STRICT_SIZE": "1", - "MallocScribble": "1", - "MallocGuardEdges": "1", - "BUN_JSC_randomIntegrityAuditRate": "1.0", "BUN_DEBUG_QUIET_LOGS": "1", "BUN_DEBUG_jest": "1", "BUN_GARBAGE_COLLECTOR_LEVEL": "1", From 1c89cb3910b9303c105f1c31b2a7a5ffa69f1ca5 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 03:55:13 -0800 Subject: [PATCH 09/15] Update SetupWebKit.cmake --- cmake/tools/SetupWebKit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 512a503ce9fb84..ab84c812042077 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION d2b0aa2a8e61ebc7640f1a821793c0c430c5485d) + set(WEBKIT_VERSION 5ebbd7b2e6661972c40f816321863eb14b837feb) endif() if(WEBKIT_LOCAL) From 47812d8aeb135bae0e7047fb85869f42bd4e5a76 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 07:10:00 -0800 Subject: [PATCH 10/15] Revert --- cmake/tools/SetupWebKit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index ab84c812042077..512a503ce9fb84 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 5ebbd7b2e6661972c40f816321863eb14b837feb) + set(WEBKIT_VERSION d2b0aa2a8e61ebc7640f1a821793c0c430c5485d) endif() if(WEBKIT_LOCAL) From 0d68804da00870bf3f801e4a93302680e0ba3ef6 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 08:04:21 -0800 Subject: [PATCH 11/15] wip --- .../bindings/ScriptExecutionContext.cpp | 37 +++-- src/bun.js/bindings/ScriptExecutionContext.h | 14 +- src/bun.js/bindings/ZigGlobalObject.cpp | 1 + .../bindings/webcore/BroadcastChannel.cpp | 8 +- .../webcore/ContextDestructionObserver.cpp | 8 +- .../webcore/ContextDestructionObserver.h | 7 +- src/bun.js/bindings/webcore/MessagePort.cpp | 130 +++++++++--------- src/bun.js/bindings/webcore/MessagePort.h | 25 ++-- .../bindings/webcore/MessagePortChannel.h | 3 +- .../webcore/MessagePortChannelProvider.h | 13 +- .../MessagePortChannelProviderImpl.cpp | 10 +- .../webcore/MessagePortChannelProviderImpl.h | 1 + .../webcore/MessagePortChannelRegistry.cpp | 35 ++--- .../webcore/MessagePortChannelRegistry.h | 9 +- src/bun.js/bindings/webcore/Worker.cpp | 16 ++- src/bun.js/test/jest.zig | 2 +- .../worker_threads/worker_threads.test.ts | 6 +- .../broadcast-channel.test.ts | 48 +++++-- 18 files changed, 224 insertions(+), 149 deletions(-) diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp index 4fc4ab352aa8a7..58aa1153cda29c 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.cpp +++ b/src/bun.js/bindings/ScriptExecutionContext.cpp @@ -31,6 +31,8 @@ static ScriptExecutionContextIdentifier initialIdentifier() } #endif +DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ScriptExecutionContext); + ScriptExecutionContext::ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject) : m_vm(vm) , m_globalObject(globalObject) @@ -39,6 +41,7 @@ ScriptExecutionContext::ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* lazyRef.set(BunBroadcastChannelRegistry::create()); }) { + relaxAdoptionRequirement(); addToContextsMap(); } @@ -50,11 +53,15 @@ ScriptExecutionContext::ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* lazyRef.set(BunBroadcastChannelRegistry::create()); }) { + relaxAdoptionRequirement(); addToContextsMap(); } WTF_MAKE_ISO_ALLOCATED_IMPL(EventLoopTask); + +#if !ENABLE(MALLOC_BREAKDOWN) WTF_MAKE_ISO_ALLOCATED_IMPL(ScriptExecutionContext); +#endif static Lock allScriptExecutionContextsMapLock; static HashMap& allScriptExecutionContextsMap() WTF_REQUIRES_LOCK(allScriptExecutionContextsMapLock) @@ -123,10 +130,13 @@ ScriptExecutionContext::~ScriptExecutionContext() { checkConsistency(); +#if ASSERT_ENABLED { Locker locker { allScriptExecutionContextsMapLock }; ASSERT_WITH_MESSAGE(!allScriptExecutionContextsMap().contains(m_identifier), "A ScriptExecutionContext subclass instance implementing postTask should have already removed itself from the map"); } + m_inScriptExecutionContextDestructor = true; +#endif // ASSERT_ENABLED auto postMessageCompletionHandlers = WTFMove(m_processMessageWithMessagePortsSoonHandlers); for (auto& completionHandler : postMessageCompletionHandlers) @@ -134,6 +144,10 @@ ScriptExecutionContext::~ScriptExecutionContext() while (auto* destructionObserver = m_destructionObservers.takeAny()) destructionObserver->contextDestroyed(); + +#if ASSERT_ENABLED + m_inScriptExecutionContextDestructor = false; +#endif // ASSERT_ENABLED } bool ScriptExecutionContext::postTaskTo(ScriptExecutionContextIdentifier identifier, Function&& task) @@ -150,12 +164,17 @@ bool ScriptExecutionContext::postTaskTo(ScriptExecutionContextIdentifier identif void ScriptExecutionContext::didCreateDestructionObserver(ContextDestructionObserver& observer) { - // ASSERT(!m_inScriptExecutionContextDestructor); +#if ASSERT_ENABLED + ASSERT(!m_inScriptExecutionContextDestructor); +#endif // ASSERT_ENABLED m_destructionObservers.add(&observer); } void ScriptExecutionContext::willDestroyDestructionObserver(ContextDestructionObserver& observer) { +#if ASSERT_ENABLED + ASSERT(!m_inScriptExecutionContextDestructor); +#endif // ASSERT_ENABLED m_destructionObservers.remove(&observer); } @@ -207,7 +226,7 @@ bool ScriptExecutionContext::ensureOnMainThread(Function&& completionHandler) @@ -251,16 +270,14 @@ void ScriptExecutionContext::dispatchMessagePortEvents() void ScriptExecutionContext::checkConsistency() const { - // for (auto* messagePort : m_messagePorts) - // ASSERT(messagePort->scriptExecutionContext() == this); +#if ASSERT_ENABLED + for (auto* messagePort : m_messagePorts) + ASSERT(messagePort->scriptExecutionContext() == this); - // for (auto* destructionObserver : m_destructionObservers) - // ASSERT(destructionObserver->scriptExecutionContext() == this); + for (auto* destructionObserver : m_destructionObservers) + ASSERT(destructionObserver->scriptExecutionContext() == this); - // for (auto* activeDOMObject : m_activeDOMObjects) { - // ASSERT(activeDOMObject->scriptExecutionContext() == this); - // activeDOMObject->assertSuspendIfNeededWasCalled(); - // } +#endif // ASSERT_ENABLED } void ScriptExecutionContext::createdMessagePort(MessagePort& messagePort) diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h index 66d99f8b52c033..6122948614cdbb 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.h +++ b/src/bun.js/bindings/ScriptExecutionContext.h @@ -11,6 +11,7 @@ #include #include #include "CachedScript.h" +#include "wtf/ThreadSafeWeakPtr.h" #include #include @@ -33,9 +34,14 @@ class ScriptExecutionContext; class EventLoopTask; using ScriptExecutionContextIdentifier = uint32_t; +DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ScriptExecutionContext); -class ScriptExecutionContext : public CanMakeWeakPtr { +class ScriptExecutionContext : public CanMakeWeakPtr, public RefCounted { +#if ENABLE(MALLOC_BREAKDOWN) + WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ScriptExecutionContext); +#else WTF_MAKE_ISO_ALLOCATED(ScriptExecutionContext); +#endif public: ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject); @@ -63,6 +69,8 @@ class ScriptExecutionContext : public CanMakeWeakPtr { static ScriptExecutionContext* getScriptExecutionContext(ScriptExecutionContextIdentifier identifier); void refEventLoop(); void unrefEventLoop(); + using RefCounted::deref; + using RefCounted::ref; const WTF::URL& url() const { @@ -188,6 +196,10 @@ class ScriptExecutionContext : public CanMakeWeakPtr { return m_connected_client_websockets_ctx; } } + +#if ASSERT_ENABLED + bool m_inScriptExecutionContextDestructor = false; +#endif }; ScriptExecutionContext* executionContext(JSC::JSGlobalObject*); diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 4c0965ef47a724..ee45efdc0f3e4c 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -1211,6 +1211,7 @@ GlobalObject::~GlobalObject() if (auto* ctx = scriptExecutionContext()) { ctx->removeFromContextsMap(); + ctx->deref(); } } diff --git a/src/bun.js/bindings/webcore/BroadcastChannel.cpp b/src/bun.js/bindings/webcore/BroadcastChannel.cpp index 4b344d5f0e7e50..d52911bb789e59 100644 --- a/src/bun.js/bindings/webcore/BroadcastChannel.cpp +++ b/src/bun.js/bindings/webcore/BroadcastChannel.cpp @@ -54,16 +54,16 @@ namespace WebCore { WTF_MAKE_ISO_ALLOCATED_IMPL(BroadcastChannel); static Lock allBroadcastChannelsLock; -static HashMap& allBroadcastChannels() WTF_REQUIRES_LOCK(allBroadcastChannelsLock) +static UncheckedKeyHashMap& allBroadcastChannels() WTF_REQUIRES_LOCK(allBroadcastChannelsLock) { - static NeverDestroyed> map; + static NeverDestroyed> map; return map; } static Lock channelToContextIdentifierLock; -static HashMap& channelToContextIdentifier() +static UncheckedKeyHashMap& channelToContextIdentifier() { - static NeverDestroyed> map; + static NeverDestroyed> map; return map; } diff --git a/src/bun.js/bindings/webcore/ContextDestructionObserver.cpp b/src/bun.js/bindings/webcore/ContextDestructionObserver.cpp index 72e6a85c497529..1de690c45a3d7f 100644 --- a/src/bun.js/bindings/webcore/ContextDestructionObserver.cpp +++ b/src/bun.js/bindings/webcore/ContextDestructionObserver.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "ContextDestructionObserver.h" +#include #include "ScriptExecutionContext.h" @@ -42,6 +43,11 @@ ContextDestructionObserver::~ContextDestructionObserver() observeContext(nullptr); } +RefPtr ContextDestructionObserver::protectedScriptExecutionContext() const +{ + return m_context.get(); +} + void ContextDestructionObserver::observeContext(ScriptExecutionContext* scriptExecutionContext) { if (m_context) { @@ -49,7 +55,7 @@ void ContextDestructionObserver::observeContext(ScriptExecutionContext* scriptEx m_context->willDestroyDestructionObserver(*this); } - m_context = scriptExecutionContext; + m_context = WeakPtr { scriptExecutionContext, EnableWeakPtrThreadingAssertions::No }; if (m_context) { ASSERT(m_context->isContextThread()); diff --git a/src/bun.js/bindings/webcore/ContextDestructionObserver.h b/src/bun.js/bindings/webcore/ContextDestructionObserver.h index 7408b5f2728680..f206ad80354e16 100644 --- a/src/bun.js/bindings/webcore/ContextDestructionObserver.h +++ b/src/bun.js/bindings/webcore/ContextDestructionObserver.h @@ -13,7 +13,8 @@ class ContextDestructionObserver { public: WEBCORE_EXPORT virtual void contextDestroyed(); - ScriptExecutionContext* scriptExecutionContext() const { return m_context; } + ScriptExecutionContext* scriptExecutionContext() const { return m_context.get(); } + RefPtr protectedScriptExecutionContext() const; protected: WEBCORE_EXPORT ContextDestructionObserver(ScriptExecutionContext*); @@ -21,7 +22,7 @@ class ContextDestructionObserver { void observeContext(ScriptExecutionContext*); private: - ScriptExecutionContext* m_context; + WeakPtr m_context; }; -} \ No newline at end of file +} diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp index aa05ebbbbb11d0..fb8406c0e9693c 100644 --- a/src/bun.js/bindings/webcore/MessagePort.cpp +++ b/src/bun.js/bindings/webcore/MessagePort.cpp @@ -49,47 +49,25 @@ extern "C" void Bun__eventLoop__incrementRefConcurrently(void* bunVM, int delta) namespace WebCore { +#if ENABLE(MALLOC_BREAKDOWN) +DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MessagePort); +#else WTF_MAKE_ISO_ALLOCATED_IMPL(MessagePort); +#endif static Lock allMessagePortsLock; -static HashMap& allMessagePorts() WTF_REQUIRES_LOCK(allMessagePortsLock) +static UncheckedKeyHashMap>& allMessagePorts() WTF_REQUIRES_LOCK(allMessagePortsLock) { - static NeverDestroyed> map; + static NeverDestroyed>> map; return map; } -static HashMap& portToContextIdentifier() WTF_REQUIRES_LOCK(allMessagePortsLock) +static UncheckedKeyHashMap& portToContextIdentifier() WTF_REQUIRES_LOCK(allMessagePortsLock) { - static NeverDestroyed> map; + static NeverDestroyed> map; return map; } -void MessagePort::ref() const -{ - ++m_refCount; -} - -void MessagePort::deref() const -{ - // This custom deref() function ensures that as long as the lock to allMessagePortsLock is taken, no MessagePort will be destroyed. - // This allows notifyMessageAvailable to easily query the map and manipulate MessagePort instances. - - if (!--m_refCount) { - Locker locker { allMessagePortsLock }; - - if (m_refCount) - return; - - auto iterator = allMessagePorts().find(m_identifier); - if (iterator != allMessagePorts().end() && iterator->value == this) { - allMessagePorts().remove(iterator); - portToContextIdentifier().remove(m_identifier); - } - - delete this; - } -} - bool MessagePort::hasPendingActivity() const { return m_refCount > 0; @@ -101,29 +79,20 @@ bool MessagePort::isMessagePortAliveForTesting(const MessagePortIdentifier& iden return allMessagePorts().contains(identifier); } -ScriptExecutionContextIdentifier MessagePort::contextIdForMessagePortId(MessagePortIdentifier messagePortId) -{ - Locker locker { allMessagePortsLock }; - return portToContextIdentifier().get(messagePortId); -} - void MessagePort::notifyMessageAvailable(const MessagePortIdentifier& identifier) { - ScriptExecutionContextIdentifier scriptExecutionContextIdentifier; + std::optional scriptExecutionContextIdentifier; + ThreadSafeWeakPtr weakPort; { Locker locker { allMessagePortsLock }; - scriptExecutionContextIdentifier = portToContextIdentifier().get(identifier); + scriptExecutionContextIdentifier = portToContextIdentifier().getOptional(identifier); + weakPort = allMessagePorts().get(identifier); } if (!scriptExecutionContextIdentifier) return; - ScriptExecutionContext::ensureOnContextThread(scriptExecutionContextIdentifier, [identifier](auto&) { - RefPtr port; - { - Locker locker { allMessagePortsLock }; - port = allMessagePorts().get(identifier); - } - if (port) + ScriptExecutionContext::ensureOnContextThread(*scriptExecutionContextIdentifier, [weakPort = WTFMove(weakPort)](auto&) { + if (RefPtr port = weakPort.get()) port->messageAvailable(); }); } @@ -157,15 +126,23 @@ MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const M MessagePort::~MessagePort() { - // LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, WebCore::Process::identifier().toUInt64()); - ASSERT(allMessagePortsLock.isLocked()); + Locker locker { allMessagePortsLock }; + + auto iterator = allMessagePorts().find(m_identifier); + if (iterator != allMessagePorts().end()) { + // ThreadSafeWeakPtr::get() returns null as soon as the object has started destruction. + if (RefPtr messagePort = iterator->value.get(); !messagePort) { + allMessagePorts().remove(iterator); + portToContextIdentifier().remove(m_identifier); + } + } if (m_entangled) close(); - if (auto contextId = portToContextIdentifier().get(m_identifier)) - ScriptExecutionContext::getScriptExecutionContext(contextId)->destroyedMessagePort(*this); + if (auto* context = scriptExecutionContext()) + context->destroyedMessagePort(*this); } void MessagePort::entangle() @@ -191,7 +168,7 @@ ExceptionOr MessagePort::postMessage(JSC::JSGlobalObject& state, JSC::JSVa if (!ports.isEmpty()) { for (auto& port : ports) { if (port->identifier() == m_identifier || port->identifier() == m_remoteIdentifier) - return Exception { DataCloneError }; + return Exception { ExceptionCode::DataCloneError }; } auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports)); @@ -202,12 +179,7 @@ ExceptionOr MessagePort::postMessage(JSC::JSGlobalObject& state, JSC::JSVa MessageWithMessagePorts message { messageData.releaseReturnValue(), WTFMove(transferredPorts) }; - // LOG(MessagePorts, "Actually posting message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data()); - - ScriptExecutionContextIdentifier contextId = contextIdForMessagePortId(m_remoteIdentifier); - - MessagePortChannelProvider::fromContext(*ScriptExecutionContext::getScriptExecutionContext(contextId)).postMessageToRemote(WTFMove(message), m_remoteIdentifier); - + MessagePortChannelProvider::fromContext(*protectedScriptExecutionContext()).postMessageToRemote(WTFMove(message), m_remoteIdentifier); return {}; } @@ -273,7 +245,7 @@ void MessagePort::dispatchMessages() // The HTML5 spec specifies that any messages sent to a document that is not fully active should be dropped, so this behavior is OK. ASSERT(started()); - auto* context = scriptExecutionContext(); + RefPtr context = scriptExecutionContext(); if (!context || context->activeDOMObjectsAreSuspended() || !isEntangled()) return; @@ -282,26 +254,34 @@ void MessagePort::dispatchMessages() // LOG(MessagePorts, "MessagePort %s (%p) dispatching %zu messages", m_identifier.logString().utf8().data(), this, messages.size()); - auto* context = scriptExecutionContext(); - if (!context || !context->jsGlobalObject()) + RefPtr context = scriptExecutionContext(); + if (!context || !context->globalObject()) return; - // ASSERT(context->isContextThread()); + ASSERT(context->isContextThread()); + auto* globalObject = defaultGlobalObject(context->globalObject()); + Ref vm = globalObject->vm(); + auto scope = DECLARE_CATCH_SCOPE(vm); - // bool contextIsWorker = is(*context); for (auto& message : messages) { // close() in Worker onmessage handler should prevent next message from dispatching. - // if (contextIsWorker && downcast(*context).isClosing()) - // return; + if (Zig::GlobalObject::scriptExecutionStatus(globalObject, globalObject) != ScriptExecutionStatus::Running) + return; auto ports = MessagePort::entanglePorts(*context, WTFMove(message.transferredPorts)); + auto event = MessageEvent::create(*globalObject, message.message.releaseNonNull(), {}, {}, {}, WTFMove(ports)); + if (UNLIKELY(scope.exception())) { + // Currently, we assume that the only way we can get here is if we have a termination. + RELEASE_ASSERT(vm->hasPendingTerminationException()); + return; + } // Per specification, each MessagePort object has a task source called the port message queue. // queueTaskKeepingObjectAlive(context, *this, TaskSource::PostedMessageQueue, [this, event = WTFMove(event)] { // dispatchEvent(event.event); // }); - ScriptExecutionContext::postTaskTo(contextIdForMessagePortId(m_identifier), [protectedThis = Ref { *this }, ports = WTFMove(ports), message = WTFMove(message)](ScriptExecutionContext& context) mutable { + ScriptExecutionContext::postTaskTo(context->identifier(), [protectedThis = Ref { *this }, ports = WTFMove(ports), message = WTFMove(message)](ScriptExecutionContext& context) mutable { auto event = MessageEvent::create(*context.jsGlobalObject(), message.message.releaseNonNull(), {}, {}, {}, WTFMove(ports)); protectedThis->dispatchEvent(event.event); }); @@ -392,6 +372,14 @@ Vector> MessagePort::entanglePorts(ScriptExecutionContext& c }); } +void MessagePort::contextDestroyed() +{ + ASSERT(scriptExecutionContext()); + + close(); + // ActiveDOMObject::contextDestroyed(); +} + void MessagePort::onDidChangeListenerImpl(EventTarget& self, const AtomString& eventType, OnDidChangeListenerKind kind) { if (eventType == eventNames().messageEvent) { @@ -399,19 +387,25 @@ void MessagePort::onDidChangeListenerImpl(EventTarget& self, const AtomString& e switch (kind) { case Add: if (port.m_messageEventCount == 0) { - port.scriptExecutionContext()->refEventLoop(); + auto* context = port.scriptExecutionContext(); + if (context) + context->refEventLoop(); } port.m_messageEventCount++; break; case Remove: port.m_messageEventCount--; if (port.m_messageEventCount == 0) { - port.scriptExecutionContext()->unrefEventLoop(); + auto* context = port.scriptExecutionContext(); + if (context) + context->unrefEventLoop(); } break; case Clear: if (port.m_messageEventCount > 0) { - port.scriptExecutionContext()->unrefEventLoop(); + auto* context = port.scriptExecutionContext(); + if (context) + context->unrefEventLoop(); } port.m_messageEventCount = 0; break; @@ -461,6 +455,7 @@ void MessagePort::jsRef(JSGlobalObject* lexicalGlobalObject) { if (!m_hasRef) { m_hasRef = true; + ref(); Bun__eventLoop__incrementRefConcurrently(WebCore::clientData(lexicalGlobalObject->vm())->bunVM, 1); } } @@ -469,6 +464,7 @@ void MessagePort::jsUnref(JSGlobalObject* lexicalGlobalObject) { if (m_hasRef) { m_hasRef = false; + deref(); Bun__eventLoop__incrementRefConcurrently(WebCore::clientData(lexicalGlobalObject->vm())->bunVM, -1); } } diff --git a/src/bun.js/bindings/webcore/MessagePort.h b/src/bun.js/bindings/webcore/MessagePort.h index d4532433fe4ed3..aa386fb27a8fd1 100644 --- a/src/bun.js/bindings/webcore/MessagePort.h +++ b/src/bun.js/bindings/webcore/MessagePort.h @@ -47,9 +47,15 @@ class WebCoreOpaqueRoot; struct StructuredSerializeOptions; -class MessagePort final : /* public ActiveDOMObject, */ public ContextDestructionObserver, public EventTarget { +DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MessagePort); + +class MessagePort final : /* public ActiveDOMObject, */ public ContextDestructionObserver, public EventTarget, public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr { WTF_MAKE_NONCOPYABLE(MessagePort); +#if ENABLE(MALLOC_BREAKDOWN) + WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(MessagePort); +#else WTF_MAKE_ISO_ALLOCATED(MessagePort); +#endif public: static Ref create(ScriptExecutionContext&, const MessagePortIdentifier& local, const MessagePortIdentifier& remote); @@ -82,15 +88,21 @@ class MessagePort final : /* public ActiveDOMObject, */ public ContextDestructio const MessagePortIdentifier& identifier() const { return m_identifier; } const MessagePortIdentifier& remoteIdentifier() const { return m_remoteIdentifier; } - WEBCORE_EXPORT void ref() const; - WEBCORE_EXPORT void deref() const; + void ref() const + { + ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr::ref(); + } + void deref() const + { + ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr::deref(); + } // EventTarget. EventTargetInterface eventTargetInterface() const final { return MessagePortEventTargetInterfaceType; } - ScriptExecutionContext* scriptExecutionContext() const final { return ScriptExecutionContext::getScriptExecutionContext(contextIdForMessagePortId(m_identifier)); } + ScriptExecutionContext* scriptExecutionContext() const final { return this->ContextDestructionObserver::scriptExecutionContext(); } void refEventTarget() final { ref(); } void derefEventTarget() final { deref(); } @@ -103,8 +115,6 @@ class MessagePort final : /* public ActiveDOMObject, */ public ContextDestructio bool hasPendingActivity() const; - static ScriptExecutionContextIdentifier contextIdForMessagePortId(MessagePortIdentifier); - void jsRef(JSGlobalObject*); void jsUnref(JSGlobalObject*); bool jsHasRef() { return m_hasRef; } @@ -117,8 +127,7 @@ class MessagePort final : /* public ActiveDOMObject, */ public ContextDestructio // ActiveDOMObject // const char* activeDOMObjectName() const final; - // void contextDestroyed() final; - // void stop() final { close(); } + void contextDestroyed() final; // bool virtualHasPendingActivity() const final; EventTargetData* eventTargetData() final { return &m_eventTargetData; } diff --git a/src/bun.js/bindings/webcore/MessagePortChannel.h b/src/bun.js/bindings/webcore/MessagePortChannel.h index c9786a094ed254..1f3e408b61e38a 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannel.h +++ b/src/bun.js/bindings/webcore/MessagePortChannel.h @@ -32,12 +32,13 @@ #include #include #include +#include namespace WebCore { class MessagePortChannelRegistry; -class MessagePortChannel : public RefCounted { +class MessagePortChannel : public RefCountedAndCanMakeWeakPtr { public: static Ref create(MessagePortChannelRegistry&, const MessagePortIdentifier& port1, const MessagePortIdentifier& port2); diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProvider.h b/src/bun.js/bindings/webcore/MessagePortChannelProvider.h index 26ddfd460c1db3..843171df627f64 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProvider.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelProvider.h @@ -31,17 +31,25 @@ #include #include +namespace WebCore { +class MessagePortChannelProvider; +} + +namespace WTF { +template struct IsDeprecatedWeakRefSmartPointerException; +template<> struct IsDeprecatedWeakRefSmartPointerException : std::true_type {}; +} + namespace WebCore { class ScriptExecutionContext; struct MessagePortIdentifier; struct MessageWithMessagePorts; -class MessagePortChannelProvider { +class MessagePortChannelProvider : public CanMakeWeakPtr { public: static MessagePortChannelProvider& fromContext(ScriptExecutionContext&); static MessagePortChannelProvider& singleton(); - // WEBCORE_EXPORT static void setSharedProvider(MessagePortChannelProvider&); virtual ~MessagePortChannelProvider() {} @@ -53,7 +61,6 @@ class MessagePortChannelProvider { virtual void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler&&, CompletionHandler&&)>&&) = 0; virtual std::optional tryTakeMessageForPort(const MessagePortIdentifier&) = 0; - virtual void postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget) = 0; }; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp index b569c0d18de232..e92883b17c6e11 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp @@ -22,7 +22,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ - +#include "root.h" #include "config.h" #include "MessagePortChannelProviderImpl.h" @@ -32,9 +32,7 @@ namespace WebCore { -MessagePortChannelProviderImpl::MessagePortChannelProviderImpl() -{ -} +MessagePortChannelProviderImpl::MessagePortChannelProviderImpl() = default; MessagePortChannelProviderImpl::~MessagePortChannelProviderImpl() { @@ -48,7 +46,7 @@ void MessagePortChannelProviderImpl::createNewMessagePortChannel(const MessagePo void MessagePortChannelProviderImpl::entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) { - m_registry.didEntangleLocalToRemote(local, remote, WebCore::Process::identifier()); + m_registry.didEntangleLocalToRemote(local, remote, Process::identifier()); } void MessagePortChannelProviderImpl::messagePortDisentangled(const MessagePortIdentifier& local) @@ -71,7 +69,7 @@ void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIde { // It is the responsibility of outerCallback to get itself to the appropriate thread (e.g. WebWorker thread) auto callback = [outerCallback = WTFMove(outerCallback)](Vector&& messages, CompletionHandler&& messageDeliveryCallback) mutable { - // ASSERT(isMainThread()); + ASSERT(isMainThread()); outerCallback(WTFMove(messages), WTFMove(messageDeliveryCallback)); }; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h index 17429b0d5e6ffb..fd029672c84616 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h @@ -25,6 +25,7 @@ #pragma once +#include #include "MessagePortChannelProvider.h" #include "MessagePortChannelRegistry.h" #include "MessageWithMessagePorts.h" diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp index a92262f6301717..2bb2732b15883b 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp @@ -24,6 +24,8 @@ */ #include "config.h" + +#include #include "MessagePortChannelRegistry.h" // #include "Logging.h" @@ -35,6 +37,8 @@ namespace WebCore { +WTF_MAKE_ISO_ALLOCATED_IMPL(MessagePortChannelRegistry); + MessagePortChannelRegistry::MessagePortChannelRegistry() = default; MessagePortChannelRegistry::~MessagePortChannelRegistry() @@ -54,15 +58,11 @@ void MessagePortChannelRegistry::messagePortChannelCreated(MessagePortChannel& c { // ASSERT(isMainThread()); - auto result = m_openChannels.ensure(channel.port1(), [channel = &channel] { - return channel; - }); - ASSERT(result.isNewEntry); + auto result = m_openChannels.add(channel.port1(), channel); + ASSERT_UNUSED(result, result.isNewEntry); - result = m_openChannels.ensure(channel.port2(), [channel = &channel] { - return channel; - }); - ASSERT(result.isNewEntry); + result = m_openChannels.add(channel.port2(), channel); + ASSERT_UNUSED(result, result.isNewEntry); } void MessagePortChannelRegistry::messagePortChannelDestroyed(MessagePortChannel& channel) @@ -83,7 +83,7 @@ void MessagePortChannelRegistry::didEntangleLocalToRemote(const MessagePortIdent // ASSERT(isMainThread()); // The channel might be gone if the remote side was closed. - auto* channel = m_openChannels.get(local); + RefPtr channel = m_openChannels.get(local); if (!channel) return; @@ -97,11 +97,8 @@ void MessagePortChannelRegistry::didDisentangleMessagePort(const MessagePortIden // ASSERT(isMainThread()); // The channel might be gone if the remote side was closed. - auto* channel = m_openChannels.get(port); - if (!channel) - return; - - channel->disentanglePort(port); + if (RefPtr channel = m_openChannels.get(port)) + channel->disentanglePort(port); } void MessagePortChannelRegistry::didCloseMessagePort(const MessagePortIdentifier& port) @@ -110,7 +107,7 @@ void MessagePortChannelRegistry::didCloseMessagePort(const MessagePortIdentifier // LOG(MessagePorts, "Registry: MessagePort %s closed in registry", port.logString().utf8().data()); - auto* channel = m_openChannels.get(port); + RefPtr channel = m_openChannels.get(port); if (!channel) return; @@ -132,7 +129,7 @@ bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts& // LOG(MessagePorts, "Registry: Posting message to MessagePort %s in registry", remoteTarget.logString().utf8().data()); // The channel might be gone if the remote side was closed. - auto* channel = m_openChannels.get(remoteTarget); + RefPtr channel = m_openChannels.get(remoteTarget); if (!channel) { // LOG(MessagePorts, "Registry: Could not find MessagePortChannel for port %s; It was probably closed. Message will be dropped.", remoteTarget.logString().utf8().data()); return false; @@ -143,12 +140,10 @@ bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts& void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler&&, CompletionHandler&&)>&& callback) { - // ASSERT(isMainThread()); - - // LOG(MessagePorts, "Registry: Taking all messages for MessagePort %s", port.logString().utf8().data()); + ASSERT(isMainThread()); // The channel might be gone if the remote side was closed. - auto* channel = m_openChannels.get(port); + RefPtr channel = m_openChannels.get(port); if (!channel) { callback({}, [] {}); return; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h index 43880ea913e4f5..1bbf560339f4fd 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h @@ -30,10 +30,15 @@ #include "MessagePortIdentifier.h" #include "ProcessIdentifier.h" #include +#include +#include namespace WebCore { -class MessagePortChannelRegistry { +class MessagePortChannelRegistry final : public CanMakeWeakPtr, public CanMakeCheckedPtr { + WTF_MAKE_ISO_ALLOCATED(MessagePortChannelRegistry); + WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(MessagePortChannelRegistry); + public: WEBCORE_EXPORT MessagePortChannelRegistry(); @@ -53,7 +58,7 @@ class MessagePortChannelRegistry { WEBCORE_EXPORT void messagePortChannelDestroyed(MessagePortChannel&); private: - HashMap m_openChannels; + UncheckedKeyHashMap> m_openChannels; }; } // namespace WebCore diff --git a/src/bun.js/bindings/webcore/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index a9f8fdae5d2c07..3b5d322b0bf64e 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -418,18 +418,26 @@ void Worker::forEachWorker(const Functionref(); worker->dispatchExit(exitCode); + worker->deref(); if (globalObject) { JSC::VM& vm = globalObject->vm(); vm.setHasTerminationRequest(); - // clang-tidy is smart enough to realize that deref() leads to freeing - // but it's not smart enough to realize that `hasOneRef()` ensures its safety - while (!vm.hasOneRef()) // NOLINT - vm.derefSuppressingSaferCPPChecking(); // NOLINT + { + globalObject->esmRegistryMap()->clear(globalObject); + globalObject->requireMap()->clear(globalObject); + vm.deleteAllCode(JSC::DeleteAllCodeEffort::PreventCollectionAndDeleteAllCode); + gcUnprotect(globalObject); + globalObject = nullptr; + } + + vm.heap.collectNow(JSC::Sync, JSC::CollectionScope::Full); vm.derefSuppressingSaferCPPChecking(); // NOLINT + vm.derefSuppressingSaferCPPChecking(); // NOLINT } } extern "C" void WebWorker__dispatchOnline(Worker* worker, Zig::GlobalObject* globalObject) diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index 4be73143aa7ef1..ab6c6163ebd6eb 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -1931,7 +1931,7 @@ fn formatLabel(globalThis: *JSGlobalObject, label: string, function_args: []JSVa .quote_strings = true, }; const value_fmt = current_arg.toFmt(&formatter); - const test_index_str = std.fmt.allocPrint(allocator, "{any}", .{value_fmt}) catch bun.outOfMemory(); + const test_index_str = std.fmt.allocPrint(allocator, "{}", .{value_fmt}) catch bun.outOfMemory(); defer allocator.free(test_index_str); list.appendSlice(allocator, test_index_str) catch bun.outOfMemory(); idx += 1; diff --git a/test/js/node/worker_threads/worker_threads.test.ts b/test/js/node/worker_threads/worker_threads.test.ts index 6ed8af8acee368..38857a83fda884 100644 --- a/test/js/node/worker_threads/worker_threads.test.ts +++ b/test/js/node/worker_threads/worker_threads.test.ts @@ -151,12 +151,12 @@ test("receiveMessageOnPort works across threads", async () => { let sharedBufferView = new Int32Array(sharedBuffer); let msg = { sharedBuffer }; worker.postMessage(msg); - expect(Atomics.wait(sharedBufferView, 0, 0)).toBe("ok"); + expect(await Atomics.waitAsync(sharedBufferView, 0, 0).value).toBe("ok"); const message = receiveMessageOnPort(port1); expect(message).toBeDefined(); expect(message!.message).toBe("done!"); await worker.terminate(); -}); +}, 9999999); test("receiveMessageOnPort works as FIFO", () => { const { port1, port2 } = new MessageChannel(); @@ -188,7 +188,7 @@ test("receiveMessageOnPort works as FIFO", () => { receiveMessageOnPort(value); }).toThrow(); } -}); +}, 9999999); test("you can override globalThis.postMessage", async () => { const worker = new Worker(new URL("./worker-override-postMessage.js", import.meta.url).href); diff --git a/test/js/web/broadcastchannel/broadcast-channel.test.ts b/test/js/web/broadcastchannel/broadcast-channel.test.ts index 918bbd36b3d504..b37d295e1dea3b 100644 --- a/test/js/web/broadcastchannel/broadcast-channel.test.ts +++ b/test/js/web/broadcastchannel/broadcast-channel.test.ts @@ -178,20 +178,38 @@ test("Closing a channel in onmessage prevents already queued tasks from firing o c1.postMessage("done"); }); -test("broadcast channel used with workers", done => { - var bc = new BroadcastChannel("hello test"); - var count = 0; - var workersCount = 100; - bc.onmessage = (e: MessageEvent) => { - expect(e).toBeInstanceOf(MessageEvent); - expect(e.target).toBe(bc); - expect(e.data).toBe("hello from worker"); - if (++count == workersCount) { - bc.close(); - done(); +test.only("broadcast channel used with workers", async () => { + const batchSize = 1; + for (let total = 0; total < 100; total++) { + let bc = new BroadcastChannel("hello test"); + + let promises: Promise[] = []; + let resolveFns = []; + + for (var i = 0; i < batchSize; i++) { + const { promise, resolve } = Promise.withResolvers(); + promises.push(promise); + resolveFns.push(resolve); } - }; - for (var i = 0; i < workersCount; i++) { - new Worker(new URL("./broadcast-channel-worker.ts", import.meta.url).href); + bc.onmessage = (e: MessageEvent) => { + expect(e).toBeInstanceOf(MessageEvent); + expect(e.target).toBe(bc); + expect(e.data).toBe("hello from worker"); + const resolve = resolveFns.shift(); + if (resolve) { + resolve(); + } else { + console.warn("resolve fn not found"); + } + console.count("resolve fn called"); + }; + + for (let i = 0; i < batchSize; i++) { + new Worker(new URL("./broadcast-channel-worker.ts", import.meta.url).href); + } + + await Promise.all(promises); + bc.close(); + console.count("Batch complete"); } -}); +}, 99999); From 74e082d691c1bb163bc69b8c6d84fdf35949151e Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 8 Jan 2025 20:23:57 -0800 Subject: [PATCH 12/15] Revert "Revert" This reverts commit 47812d8aeb135bae0e7047fb85869f42bd4e5a76. --- cmake/tools/SetupWebKit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 512a503ce9fb84..ab84c812042077 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION d2b0aa2a8e61ebc7640f1a821793c0c430c5485d) + set(WEBKIT_VERSION 5ebbd7b2e6661972c40f816321863eb14b837feb) endif() if(WEBKIT_LOCAL) From dad69bc166b1b902555e338f4ea88d45f4ce4558 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 9 Jan 2025 03:58:02 -0800 Subject: [PATCH 13/15] Update runner.node.mjs --- scripts/runner.node.mjs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/runner.node.mjs b/scripts/runner.node.mjs index b530ba94831a69..041404ab5898d9 100755 --- a/scripts/runner.node.mjs +++ b/scripts/runner.node.mjs @@ -198,7 +198,7 @@ async function runTests() { failure ||= result; flaky ||= true; - if (attempt >= maxAttempts) { + if (attempt >= maxAttempts || isAlwaysFailure(error)) { flaky = false; failedResults.push(failure); } @@ -862,7 +862,7 @@ function isJavaScriptTest(path) { * @returns {boolean} */ function isNodeParallelTest(testPath) { - return testPath.replaceAll(sep, "/").includes("js/node/test/parallel/") + return testPath.replaceAll(sep, "/").includes("js/node/test/parallel/"); } /** @@ -1541,6 +1541,13 @@ function getExitCode(outcome) { return 1; } +// A flaky segfault, sigtrap, or sigill must never be ignored. +// If it happens in CI, it will happen to our users. +function isAlwaysFailure(error) { + error = ((error || "") + "").toLowerCase().trim(); + return error.includes("segmentation fault") || error.includes("sigill") || error.includes("sigtrap"); +} + /** * @param {string} signal */ From 9e48557b7e7c8a3a907230b5c701b971557ab3e1 Mon Sep 17 00:00:00 2001 From: Kai Tamkun Date: Thu, 9 Jan 2025 14:51:43 -0800 Subject: [PATCH 14/15] MessagePort fixes --- src/bun.js/bindings/webcore/MessagePort.cpp | 11 +++++++++-- .../webcore/MessagePortChannelProviderImpl.cpp | 2 +- .../bindings/webcore/MessagePortChannelRegistry.cpp | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp index fb8406c0e9693c..3acb2416868f23 100644 --- a/src/bun.js/bindings/webcore/MessagePort.cpp +++ b/src/bun.js/bindings/webcore/MessagePort.cpp @@ -70,7 +70,15 @@ static UncheckedKeyHashMap 0; + // If the ScriptExecutionContext has been shut down on this object close()'ed, we can GC. + if (!scriptExecutionContext() || m_isDetached) + return false; + + // If this MessagePort has no message event handler then there is no point in keeping it alive. + if (!m_hasMessageEventListener) + return false; + + return m_entangled; } bool MessagePort::isMessagePortAliveForTesting(const MessagePortIdentifier& identifier) @@ -269,7 +277,6 @@ void MessagePort::dispatchMessages() return; auto ports = MessagePort::entanglePorts(*context, WTFMove(message.transferredPorts)); - auto event = MessageEvent::create(*globalObject, message.message.releaseNonNull(), {}, {}, {}, WTFMove(ports)); if (UNLIKELY(scope.exception())) { // Currently, we assume that the only way we can get here is if we have a termination. RELEASE_ASSERT(vm->hasPendingTerminationException()); diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp index e92883b17c6e11..62b9818bbbe1ea 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp @@ -69,7 +69,7 @@ void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIde { // It is the responsibility of outerCallback to get itself to the appropriate thread (e.g. WebWorker thread) auto callback = [outerCallback = WTFMove(outerCallback)](Vector&& messages, CompletionHandler&& messageDeliveryCallback) mutable { - ASSERT(isMainThread()); + // ASSERT(isMainThread()); outerCallback(WTFMove(messages), WTFMove(messageDeliveryCallback)); }; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp index 2bb2732b15883b..e4e9b82bd5f9a5 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp @@ -140,7 +140,7 @@ bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts& void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler&&, CompletionHandler&&)>&& callback) { - ASSERT(isMainThread()); + // ASSERT(isMainThread()); // The channel might be gone if the remote side was closed. RefPtr channel = m_openChannels.get(port); From 391a7295a73d25ff275d40a0649f4b478a8a08d1 Mon Sep 17 00:00:00 2001 From: Kai Tamkun Date: Thu, 9 Jan 2025 17:59:06 -0800 Subject: [PATCH 15/15] The main thread's script execution context has ID 1, not 2 --- src/bun.js/bindings/ScriptExecutionContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp index 58aa1153cda29c..326aa556ba7949 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.cpp +++ b/src/bun.js/bindings/ScriptExecutionContext.cpp @@ -226,7 +226,7 @@ bool ScriptExecutionContext::ensureOnMainThread(Function&& completionHandler)