diff options
author | 2023-08-02 18:12:12 -0700 | |
---|---|---|
committer | 2023-08-02 18:12:12 -0700 | |
commit | 207c7eb50955eb6f8f4b92fbf5a5955c23ec7e65 (patch) | |
tree | 4c0a1cdb53ec617e2c0ca13db161d6755752fd31 /src/bun.js/bindings/ZigGlobalObject.cpp | |
parent | 505e77c2d0a5cafb0b2b321e30086de7e9944302 (diff) | |
download | bun-207c7eb50955eb6f8f4b92fbf5a5955c23ec7e65.tar.gz bun-207c7eb50955eb6f8f4b92fbf5a5955c23ec7e65.tar.zst bun-207c7eb50955eb6f8f4b92fbf5a5955c23ec7e65.zip |
Implement `node:worker_threads` (#3923)
* Start to implement `worker_threads`
* more
* more!!
* more
* Update bundle_v2.zig
* delete outdated tests
* `receiveMessageOnPort`
* props test and export default
* fix merge
* not implemented tests
* individual imports
* `receiveMessageOnPort` tests
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Diffstat (limited to 'src/bun.js/bindings/ZigGlobalObject.cpp')
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 849cee27b..d2e3416fc 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -237,7 +237,7 @@ public: }; } - +extern "C" WebCore::Worker* WebWorker__getParentWorker(void*); extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(const char* ptr, size_t length)) { if (has_loaded_jsc) @@ -1586,18 +1586,46 @@ JSC_DEFINE_HOST_FUNCTION(functionCallNotImplemented, return JSC::JSValue::encode(JSC::JSValue {}); } +JSC_DEFINE_HOST_FUNCTION(jsReceiveMessageOnPort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (callFrame->argumentCount() < 1) { + throwTypeError(lexicalGlobalObject, scope, "receiveMessageOnPort needs 1 argument"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + auto port = callFrame->argument(0); + + if (!port.isObject()) { + throwTypeError(lexicalGlobalObject, scope, "the \"port\" argument must be a MessagePort instance"_s); + return JSC::JSValue::encode(jsUndefined()); + } + + if (auto* messagePort = jsDynamicCast<JSMessagePort*>(port)) { + return JSC::JSValue::encode(messagePort->wrapped().tryTakeMessage(lexicalGlobalObject)); + } else if (auto* broadcastChannel = jsDynamicCast<JSBroadcastChannel*>(port)) { + // TODO: support broadcast channels + return JSC::JSValue::encode(jsUndefined()); + } + + throwTypeError(lexicalGlobalObject, scope, "the \"port\" argument must be a MessagePort instance"_s); + return JSC::JSValue::encode(jsUndefined()); +} + // we're trying out a new way to do this lazy loading // this is $lazy() in js code static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) { -JSC: + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); VM& vm = globalObject->vm(); switch (callFrame->argumentCount()) { case 0: { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSC::throwTypeError(globalObject, scope, "lazyLoad needs 1 argument (a string)"_s); scope.release(); return JSC::JSValue::encode(JSC::JSValue {}); @@ -1607,7 +1635,6 @@ JSC: if (moduleName.isNumber()) { switch (moduleName.toInt32(globalObject)) { case 0: { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s); scope.release(); return JSC::JSValue::encode(JSC::JSValue {}); @@ -1634,7 +1661,6 @@ JSC: auto string = moduleName.toWTFString(globalObject); if (string.isNull()) { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s); scope.release(); return JSC::JSValue::encode(JSC::JSValue {}); @@ -1644,6 +1670,32 @@ JSC: return JSC::JSValue::encode(JSSQLStatementConstructor::create(vm, globalObject, JSSQLStatementConstructor::createStructure(vm, globalObject, globalObject->m_functionPrototype.get()))); } + if (string == "worker_threads"_s) { + + JSValue workerData = jsUndefined(); + JSValue threadId = jsNumber(0); + + if (auto* worker = WebWorker__getParentWorker(globalObject->bunVM())) { + auto& options = worker->options(); + if (worker && options.bun.data) { + auto ports = MessagePort::entanglePorts(*ScriptExecutionContext::getScriptExecutionContext(worker->clientIdentifier()), WTFMove(options.bun.dataMessagePorts)); + RefPtr<WebCore::SerializedScriptValue> serialized = WTFMove(options.bun.data); + JSValue deserialized = serialized->deserialize(*globalObject, globalObject, WTFMove(ports)); + RETURN_IF_EXCEPTION(scope, {}); + workerData = deserialized; + } + + threadId = jsNumber(worker->clientIdentifier()); + } + + JSArray* array = constructEmptyArray(globalObject, nullptr); + array->push(globalObject, workerData); + array->push(globalObject, threadId); + array->push(globalObject, JSFunction::create(vm, globalObject, 1, "receiveMessageOnPort"_s, jsReceiveMessageOnPort, ImplementationVisibility::Public, NoIntrinsic)); + + return JSC::JSValue::encode(array); + } + if (string == "pathToFileURL"_s) { return JSValue::encode( JSFunction::create(vm, globalObject, 1, pathToFileURLString, functionPathToFileURL, ImplementationVisibility::Public, NoIntrinsic)); @@ -3551,7 +3603,6 @@ void GlobalObject::finishCreation(VM& vm) consoleObject->putDirectBuiltinFunction(vm, this, clientData->builtinNames().writePublicName(), consoleObjectWriteCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete); } -extern "C" WebCore::Worker* WebWorker__getParentWorker(void*); JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, (JSC::JSGlobalObject * leixcalGlobalObject, JSC::CallFrame* callFrame)) { @@ -3596,7 +3647,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, } Vector<RefPtr<MessagePort>> ports; - ExceptionOr<Ref<SerializedScriptValue>> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), ports); + ExceptionOr<Ref<SerializedScriptValue>> 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()); |