diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp index 316e7c15ec..87de0125a0 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.cpp +++ b/src/bun.js/bindings/ScriptExecutionContext.cpp @@ -211,11 +211,11 @@ void ScriptExecutionContext::dispatchMessagePortEvents() void ScriptExecutionContext::checkConsistency() const { - for (auto* messagePort : m_messagePorts) - ASSERT(messagePort->scriptExecutionContext() == this); + // 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); diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 70eda44744..8b32547f8f 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -1,156 +1,166 @@ - #include "root.h" #include "ZigGlobalObject.h" -#include #include "helpers.h" -#include "BunClientData.h" -#include "JavaScriptCore/JSCJSValue.h" -#include "JavaScriptCore/AggregateError.h" -#include "JavaScriptCore/JSObjectInlines.h" -#include "JavaScriptCore/InternalFieldTuple.h" -#include "JavaScriptCore/BytecodeIndex.h" -#include "JavaScriptCore/CallFrameInlines.h" + +#include "wtf/text/Base64.h" +#include "JavaScriptCore/BuiltinNames.h" +#include "JavaScriptCore/CallData.h" +#include "JavaScriptCore/CatchScope.h" #include "JavaScriptCore/ClassInfo.h" #include "JavaScriptCore/CodeBlock.h" #include "JavaScriptCore/Completion.h" +#include "JavaScriptCore/DeferredWorkTimer.h" #include "JavaScriptCore/Error.h" #include "JavaScriptCore/ErrorInstance.h" #include "JavaScriptCore/Exception.h" #include "JavaScriptCore/ExceptionScope.h" #include "JavaScriptCore/FunctionConstructor.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/GetterSetter.h" +#include "JavaScriptCore/GlobalObjectMethodTable.h" #include "JavaScriptCore/HashMapImpl.h" #include "JavaScriptCore/HashMapImplInlines.h" #include "JavaScriptCore/Heap.h" #include "JavaScriptCore/Identifier.h" #include "JavaScriptCore/InitializeThreading.h" -#include "JavaScriptCore/IteratorOperations.h" +#include "JavaScriptCore/InternalFieldTuple.h" +#include "JavaScriptCore/InternalFunction.h" #include "JavaScriptCore/JSArray.h" -#include "JavaScriptCore/JSGlobalProxyInlines.h" -#include "JavaScriptCore/JSCallbackConstructor.h" -#include "JavaScriptCore/JSCallbackObject.h" #include "JavaScriptCore/JSCast.h" -#include "JavaScriptCore/JSClassRef.h" -#include "JavaScriptCore/JSMicrotask.h" -#include "ConsoleObject.h" -// #include "JavaScriptCore/JSContextInternal.h" -#include "JavaScriptCore/CatchScope.h" -#include "JavaScriptCore/DeferredWorkTimer.h" +#include "JavaScriptCore/JSCJSValue.h" +#include "JavaScriptCore/JSGlobalProxyInlines.h" #include "JavaScriptCore/JSInternalPromise.h" #include "JavaScriptCore/JSLock.h" #include "JavaScriptCore/JSMap.h" +#include "JavaScriptCore/JSMicrotask.h" #include "JavaScriptCore/JSModuleLoader.h" #include "JavaScriptCore/JSModuleNamespaceObject.h" #include "JavaScriptCore/JSModuleNamespaceObjectInlines.h" #include "JavaScriptCore/JSModuleRecord.h" #include "JavaScriptCore/JSNativeStdFunction.h" #include "JavaScriptCore/JSObject.h" +#include "JavaScriptCore/JSObjectInlines.h" #include "JavaScriptCore/JSPromise.h" -#include "JavaScriptCore/JSSet.h" +#include "JavaScriptCore/JSScriptFetchParameters.h" #include "JavaScriptCore/JSSourceCode.h" #include "JavaScriptCore/JSString.h" -#include "JavaScriptCore/JSValueInternal.h" -#include "JavaScriptCore/JSVirtualMachineInternal.h" #include "JavaScriptCore/JSWeakMap.h" +#include "JavaScriptCore/LazyClassStructure.h" +#include "JavaScriptCore/LazyClassStructureInlines.h" #include "JavaScriptCore/ObjectConstructor.h" -#include "JavaScriptCore/OptionsList.h" -#include "JavaScriptCore/ParserError.h" #include "JavaScriptCore/ScriptExecutable.h" +#include "JavaScriptCore/ScriptFetchParameters.h" #include "JavaScriptCore/SourceOrigin.h" #include "JavaScriptCore/StackFrame.h" #include "JavaScriptCore/StackVisitor.h" #include "JavaScriptCore/VM.h" -#include "JavaScriptCore/WasmFaultSignalHandler.h" -#include "wtf/Assertions.h" -#include "wtf/Gigacage.h" -#include "wtf/URL.h" -#include "wtf/text/ExternalStringImpl.h" -#include "wtf/text/StringCommon.h" -#include "wtf/text/StringImpl.h" -#include "wtf/text/StringView.h" -#include "wtf/text/WTFString.h" -#include "JavaScriptCore/JSScriptFetchParameters.h" -#include "JavaScriptCore/ScriptFetchParameters.h" -#include "wtf/text/Base64.h" -// #include "JavaScriptCore/CachedType.h" -#include "JavaScriptCore/JSCallbackObject.h" -#include "JavaScriptCore/JSClassRef.h" -#include "JavaScriptCore/CallData.h" -#include "GCDefferalContext.h" - -#include "BunClientData.h" - -#include "ZigSourceProvider.h" - -#include "JSDOMURL.h" -#include "JSURLSearchParams.h" -#include "JSDOMException.h" -#include "JSEventTarget.h" -#include "JSEventEmitter.h" -#include "EventTargetConcrete.h" -#include "JSAbortSignal.h" -#include "JSCustomEvent.h" -#include "JSAbortController.h" -#include "JSEvent.h" -#include "JSErrorEvent.h" -#include "JSCloseEvent.h" -#include "JSFetchHeaders.h" -#include "JSStringDecoder.h" -#include "JSReadableState.h" -#include "JSReadableHelper.h" -#include "JSPerformance.h" -#include "Performance.h" -#include "JSPerformanceObserver.h" -#include "JSPerformanceObserverEntryList.h" -#include "JSPerformanceEntry.h" -#include "JSPerformanceMeasure.h" -#include "JSPerformanceMark.h" -#include "BunProcess.h" +#include "AddEventListenerOptions.h" #include "AsyncContextFrame.h" - -#include "WebCoreJSBuiltins.h" +#include "BunClientData.h" +#include "BunClientData.h" +#include "BunObject.h" +#include "BunPlugin.h" +#include "BunProcess.h" +#include "BunWorkerGlobalScope.h" +#include "CallSite.h" +#include "CallSitePrototype.h" +#include "CommonJSModuleRecord.h" +#include "ConsoleObject.h" +#include "DOMWrapperWorld-class.h" +#include "ErrorStackTrace.h" +#include "IDLTypes.h" +#include "ImportMetaObject.h" +#include "JS2Native.h" +#include "JSAbortAlgorithm.h" +#include "JSAbortController.h" +#include "JSAbortSignal.h" +#include "JSBroadcastChannel.h" #include "JSBuffer.h" #include "JSBufferList.h" -#include "JSFFIFunction.h" -#include "JavaScriptCore/InternalFunction.h" -#include "JavaScriptCore/LazyClassStructure.h" -#include "JavaScriptCore/LazyClassStructureInlines.h" -#include "JavaScriptCore/FunctionPrototype.h" -#include "JavaScriptCore/GetterSetter.h" -#include "napi.h" -#include "JSSQLStatement.h" -#include "ModuleLoader.h" -#include "NodeVM.h" -#include "ProcessIdentifier.h" -#include "SerializedScriptValue.h" -#include "NodeTTYModule.h" - -#include "ZigGeneratedClasses.h" -#include "JavaScriptCore/DateInstance.h" - -#include "JS2Native.h" - -#include "BunPlugin.h" -#include "JSEnvironmentVariableMap.h" -#include "DOMIsoSubspaces.h" -#include "BunWorkerGlobalScope.h" -#include "JSWorker.h" -#include "JSMessageChannel.h" -#include "JSMessagePort.h" -#include "JSBroadcastChannel.h" - +#include "JSByteLengthQueuingStrategy.h" +#include "JSCloseEvent.h" +#include "JSCountQueuingStrategy.h" +#include "JSCustomEvent.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMException.h" #include "JSDOMFile.h" - +#include "JSDOMFormData.h" +#include "JSDOMURL.h" +#include "JSEnvironmentVariableMap.h" +#include "JSErrorEvent.h" +#include "JSEvent.h" +#include "JSEventEmitter.h" +#include "JSEventListener.h" +#include "JSEventTarget.h" +#include "JSFetchHeaders.h" +#include "JSFFIFunction.h" +#include "JSMessageChannel.h" +#include "JSMessageEvent.h" +#include "JSMessagePort.h" +#include "JSNextTickQueue.h" +#include "JSPerformance.h" +#include "JSPerformanceEntry.h" +#include "JSPerformanceMark.h" +#include "JSPerformanceMeasure.h" +#include "JSPerformanceObserver.h" +#include "JSPerformanceObserverEntryList.h" +#include "JSReadableByteStreamController.h" +#include "JSReadableHelper.h" +#include "JSReadableState.h" +#include "JSReadableStream.h" +#include "JSReadableStreamBYOBReader.h" +#include "JSReadableStreamBYOBRequest.h" +#include "JSReadableStreamDefaultController.h" +#include "JSReadableStreamDefaultReader.h" +#include "JSSink.h" +#include "JSSocketAddress.h" +#include "JSSQLStatement.h" +#include "JSStringDecoder.h" +#include "JSTextEncoder.h" +#include "JSTransformStream.h" +#include "JSTransformStreamDefaultController.h" +#include "JSURLSearchParams.h" +#include "JSWebSocket.h" +#include "JSWorker.h" +#include "JSWritableStream.h" +#include "JSWritableStreamDefaultController.h" +#include "JSWritableStreamDefaultWriter.h" +#include "libusockets.h" +#include "ModuleLoader.h" +#include "napi_external.h" +#include "napi.h" +#include "NodeHTTP.h" +#include "NodeVM.h" +#include "Performance.h" #include "ProcessBindingConstants.h" +#include "ProcessBindingTTYWrap.h" +#include "ProcessIdentifier.h" +#include "ReadableStream.h" +#include "SerializedScriptValue.h" +#include "StructuredClone.h" +#include "WebCoreJSBuiltins.h" +#include "webcrypto/JSCryptoKey.h" +#include "webcrypto/JSSubtleCrypto.h" +#include "ZigGeneratedClasses.h" +#include "ZigSourceProvider.h" #if ENABLE(REMOTE_INSPECTOR) #include "JavaScriptCore/RemoteInspectorServer.h" #endif -#include "BunObject.h" -#include "JSNextTickQueue.h" -#include "NodeHTTP.h" -#include "napi_external.h" +#if !OS(WINDOWS) +#include +#endif + +#ifdef __APPLE__ +#include +#elif defined(__linux__) +// for sysconf +#include +#endif + using namespace Bun; extern "C" JSC__JSValue Bun__NodeUtil__jsParseArgs(JSC::JSGlobalObject*, JSC::CallFrame*); @@ -172,83 +182,8 @@ using JSObject = JSC::JSObject; using JSNonFinalObject = JSC::JSNonFinalObject; namespace JSCastingHelpers = JSC::JSCastingHelpers; -#if !OS(WINDOWS) -#include -#endif - -#include "IDLTypes.h" - -#include "JSAbortAlgorithm.h" -#include "JSDOMAttribute.h" -#include "JSByteLengthQueuingStrategy.h" -#include "JSCountQueuingStrategy.h" -#include "JSReadableByteStreamController.h" -#include "JSReadableStream.h" -#include "JSReadableStreamBYOBReader.h" -#include "JSReadableStreamBYOBRequest.h" -#include "JSReadableStreamDefaultController.h" -#include "JSReadableStreamDefaultReader.h" -#include "JSTransformStream.h" -#include "JSTransformStreamDefaultController.h" -#include "JSWritableStream.h" -#include "JSWritableStreamDefaultController.h" -#include "JSWritableStreamDefaultWriter.h" -#include "JavaScriptCore/BuiltinNames.h" -#include "JSTextEncoder.h" -#include "StructuredClone.h" -#include "JSWebSocket.h" -#include "JSMessageEvent.h" -#include "JSEventListener.h" - -#include "ReadableStream.h" -#include "JSSink.h" -#include "ImportMetaObject.h" - -#include -#include "DOMJITIDLConvert.h" -#include "DOMJITIDLType.h" -#include "DOMJITIDLTypeFilter.h" -#include "DOMJITHelpers.h" -#include - -#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 "JSSocketAddress.h" - -#include "ErrorStackTrace.h" -#include "CallSite.h" -#include "CallSitePrototype.h" -#include "DOMWrapperWorld-class.h" -#include "CommonJSModuleRecord.h" -#include -#include -#include "simdutf.h" -#include "libusockets.h" -#include "KeyObject.h" -#include "webcrypto/JSCryptoKey.h" -#include "webcrypto/JSSubtleCrypto.h" - constexpr size_t DEFAULT_ERROR_STACK_TRACE_LIMIT = 10; -#ifdef __APPLE__ -#include -#elif defined(__linux__) -// for sysconf -#include -#endif - -#include "ProcessBindingTTYWrap.h" - // #include static bool has_loaded_jsc = false; @@ -1713,10 +1648,6 @@ JSC_DEFINE_CUSTOM_SETTER(noop_setter, return true; } -// If you are looking for $lazy / functionLazyLoad -// it is moved to JS2Native.cpp, and is called $cpp and $zig -// see .md for more information - static inline JSC::EncodedJSValue jsFunctionAddEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Zig::GlobalObject* castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); @@ -3038,76 +2969,6 @@ void GlobalObject::finishCreation(VM& vm) ASSERT(classInfo()); } -JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, - (JSC::JSGlobalObject * leixcalGlobalObject, JSC::CallFrame* callFrame)) -{ - JSC::VM& vm = leixcalGlobalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - Zig::GlobalObject* globalObject = jsDynamicCast(leixcalGlobalObject); - if (UNLIKELY(!globalObject)) - return JSValue::encode(jsUndefined()); - - Worker* worker = WebWorker__getParentWorker(globalObject->bunVM()); - if (worker == nullptr) - return JSValue::encode(jsUndefined()); - - ScriptExecutionContext* context = worker->scriptExecutionContext(); - - if (!context) - return JSValue::encode(jsUndefined()); - - auto throwScope = DECLARE_THROW_SCOPE(vm); - - JSC::JSValue value = callFrame->argument(0); - JSC::JSValue options = callFrame->argument(1); - - Vector> transferList; - - if (options.isObject()) { - JSC::JSObject* optionsObject = options.getObject(); - JSC::JSValue transferListValue = optionsObject->get(globalObject, vm.propertyNames->transfer); - if (transferListValue.isObject()) { - JSC::JSObject* transferListObject = transferListValue.getObject(); - if (auto* transferListArray = jsDynamicCast(transferListObject)) { - for (unsigned i = 0; i < transferListArray->length(); i++) { - JSC::JSValue transferListValue = transferListArray->get(globalObject, i); - if (transferListValue.isObject()) { - JSC::JSObject* transferListObject = transferListValue.getObject(); - transferList.append(JSC::Strong(vm, transferListObject)); - } - } - } - } - } - - Vector> ports; - ExceptionOr> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); - if (serialized.hasException()) { - WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); - return JSValue::encode(jsUndefined()); - } - - ExceptionOr> disentangledPorts = MessagePort::disentanglePorts(WTFMove(ports)); - if (disentangledPorts.hasException()) { - WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); - return JSValue::encode(jsUndefined()); - } - - MessageWithMessagePorts messageWithMessagePorts { serialized.releaseReturnValue(), disentangledPorts.releaseReturnValue() }; - - ScriptExecutionContext::postTaskTo(context->identifier(), [message = messageWithMessagePorts, protectedThis = Ref { *worker }, ports](ScriptExecutionContext& context) mutable { - Zig::GlobalObject* globalObject = jsCast(context.jsGlobalObject()); - - auto ports = MessagePort::entanglePorts(context, WTFMove(message.transferredPorts)); - auto event = MessageEvent::create(*globalObject, message.message.releaseNonNull(), std::nullopt, WTFMove(ports)); - - protectedThis->dispatchEvent(event.event); - }); - - return JSValue::encode(jsUndefined()); -} - JSC_DEFINE_CUSTOM_GETTER(JSDOMFileConstructor_getter, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName)) { Zig::GlobalObject* bunGlobalObject = jsCast(globalObject); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 3d662c811d..3c124046e1 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -41,7 +41,6 @@ class InternalModuleRegistry; #include "BunPlugin.h" #include "JSMockFunction.h" #include "InternalModuleRegistry.h" -#include "ProcessBindingConstants.h" #include "WebCoreJSBuiltins.h" #include "headers-handwritten.h" #include "BunCommonStrings.h" diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp index b463791df3..a69728ad7f 100644 --- a/src/bun.js/bindings/webcore/MessagePort.cpp +++ b/src/bun.js/bindings/webcore/MessagePort.cpp @@ -286,7 +286,7 @@ void MessagePort::dispatchMessages() if (!context || !context->jsGlobalObject()) return; - ASSERT(context->isContextThread()); + // ASSERT(context->isContextThread()); // bool contextIsWorker = is(*context); for (auto& message : messages) { diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp index 4fc0dddc56..0a21936a30 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp @@ -71,7 +71,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/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index 16eb1e109f..40f3fa4350 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -488,4 +488,74 @@ JSValue createNodeWorkerThreadsBinding(Zig::GlobalObject* globalObject) return array; } +JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, + (JSC::JSGlobalObject * leixcalGlobalObject, JSC::CallFrame* callFrame)) +{ + JSC::VM& vm = leixcalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + Zig::GlobalObject* globalObject = jsDynamicCast(leixcalGlobalObject); + if (UNLIKELY(!globalObject)) + return JSValue::encode(jsUndefined()); + + Worker* worker = WebWorker__getParentWorker(globalObject->bunVM()); + if (worker == nullptr) + return JSValue::encode(jsUndefined()); + + ScriptExecutionContext* context = worker->scriptExecutionContext(); + + if (!context) + return JSValue::encode(jsUndefined()); + + auto throwScope = DECLARE_THROW_SCOPE(vm); + + JSC::JSValue value = callFrame->argument(0); + JSC::JSValue options = callFrame->argument(1); + + Vector> transferList; + + if (options.isObject()) { + JSC::JSObject* optionsObject = options.getObject(); + JSC::JSValue transferListValue = optionsObject->get(globalObject, vm.propertyNames->transfer); + if (transferListValue.isObject()) { + JSC::JSObject* transferListObject = transferListValue.getObject(); + if (auto* transferListArray = jsDynamicCast(transferListObject)) { + for (unsigned i = 0; i < transferListArray->length(); i++) { + JSC::JSValue transferListValue = transferListArray->get(globalObject, i); + if (transferListValue.isObject()) { + JSC::JSObject* transferListObject = transferListValue.getObject(); + transferList.append(JSC::Strong(vm, transferListObject)); + } + } + } + } + } + + Vector> ports; + ExceptionOr> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); + if (serialized.hasException()) { + WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); + return JSValue::encode(jsUndefined()); + } + + ExceptionOr> disentangledPorts = MessagePort::disentanglePorts(WTFMove(ports)); + if (disentangledPorts.hasException()) { + WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); + return JSValue::encode(jsUndefined()); + } + + MessageWithMessagePorts messageWithMessagePorts { serialized.releaseReturnValue(), disentangledPorts.releaseReturnValue() }; + + ScriptExecutionContext::postTaskTo(context->identifier(), [message = messageWithMessagePorts, protectedThis = Ref { *worker }, ports](ScriptExecutionContext& context) mutable { + Zig::GlobalObject* globalObject = jsCast(context.jsGlobalObject()); + + auto ports = MessagePort::entanglePorts(context, WTFMove(message.transferredPorts)); + auto event = MessageEvent::create(*globalObject, message.message.releaseNonNull(), std::nullopt, WTFMove(ports)); + + protectedThis->dispatchEvent(event.event); + }); + + return JSValue::encode(jsUndefined()); +} + } // namespace WebCore diff --git a/src/bun.js/bindings/webcore/Worker.h b/src/bun.js/bindings/webcore/Worker.h index 15d1b7f082..cc54ff6488 100644 --- a/src/bun.js/bindings/webcore/Worker.h +++ b/src/bun.js/bindings/webcore/Worker.h @@ -142,4 +142,6 @@ private: JSValue createNodeWorkerThreadsBinding(Zig::GlobalObject* globalObject); +JSC_DECLARE_HOST_FUNCTION(jsFunctionPostMessage); + } // namespace WebCore diff --git a/src/js/node/worker_threads.ts b/src/js/node/worker_threads.ts index 7754f244da..04da787fc5 100644 --- a/src/js/node/worker_threads.ts +++ b/src/js/node/worker_threads.ts @@ -124,9 +124,10 @@ function fakeParentPort() { }, }); + const postMessage = $newCppFunction("ZigGlobalObject.cpp", "jsFunctionPostMessage", 1); Object.defineProperty(fake, "postMessage", { value(...args: [any, any]) { - return self.postMessage(...args); + return postMessage(...args); }, }); diff --git a/test/js/node/worker_threads/worker-override-postMessage.js b/test/js/node/worker_threads/worker-override-postMessage.js new file mode 100644 index 0000000000..3640c9f9d7 --- /dev/null +++ b/test/js/node/worker_threads/worker-override-postMessage.js @@ -0,0 +1,15 @@ +import { isMainThread, parentPort, workerData } from "worker_threads"; + +if (parentPort === null) throw new Error("worker_threads.parentPort is null"); + +if (isMainThread) throw new Error("worker_threads.isMainThread is wrong"); + +Object.assign(global, { + postMessage: message => { + parentPort.postMessage(message); + }, +}); + +parentPort.on("message", m => { + postMessage("Hello from worker!"); +}); diff --git a/test/js/node/worker_threads/worker_threads.test.ts b/test/js/node/worker_threads/worker_threads.test.ts index 3fd164a889..96ce37ef5a 100644 --- a/test/js/node/worker_threads/worker_threads.test.ts +++ b/test/js/node/worker_threads/worker_threads.test.ts @@ -176,3 +176,13 @@ test("receiveMessageOnPort works as FIFO", () => { }).toThrow(); } }); + +test("you can override globalThis.postMessage", async () => { + const worker = new Worker(new URL("./worker-override-postMessage.js", import.meta.url).href); + const message = await new Promise(resolve => { + worker.on("message", resolve); + worker.postMessage("Hello from worker!"); + }); + expect(message).toBe("Hello from worker!"); + await worker.terminate(); +});