diff options
Diffstat (limited to '')
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 16 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.zig | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/JSWorker.cpp | 117 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/Worker.cpp | 13 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/Worker.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/WorkerOptions.h | 1 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 3 | ||||
-rw-r--r-- | src/bun.js/web_worker.zig | 11 |
11 files changed, 113 insertions, 60 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 3f4a8d044..3de7d3daa 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -429,7 +429,7 @@ static String computeErrorInfo(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsi } extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObjectClass, int count, - void* console_client, int32_t executionContextId, bool miniMode) + void* console_client, int32_t executionContextId, bool miniMode, void* worker_ptr) { auto heapSize = miniMode ? JSC::HeapType::Small : JSC::HeapType::Large; @@ -448,6 +448,20 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje vm, Zig::GlobalObject::createStructure(vm, JSC::JSGlobalObject::create(vm, JSC::JSGlobalObject::createStructure(vm, JSC::jsNull())), JSC::jsNull()), static_cast<ScriptExecutionContextIdentifier>(executionContextId)); + + if (auto* worker = static_cast<WebCore::Worker*>(worker_ptr)) { + auto& options = worker->options(); + if (options.bun.env) { + auto map = *options.bun.env; + auto size = map.size(); + auto env = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), size > 63 ? 63 : size); + for (auto k : map) { + env->putDirect(vm, JSC::Identifier::fromString(vm, WTFMove(k.key)), JSC::jsString(vm, WTFMove(k.value))); + } + map.clear(); + globalObject->m_processEnvObject.set(vm, globalObject, env); + } + } } else { globalObject = Zig::GlobalObject::create( vm, diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 9d84e5214..1d82cd0f3 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -457,6 +457,8 @@ public: Bun::JSMockModule mockModule; + LazyProperty<JSGlobalObject, JSObject> m_processEnvObject; + #include "ZigGeneratedClasses+lazyStructureHeader.h" private: @@ -519,7 +521,6 @@ private: LazyProperty<JSGlobalObject, JSObject> m_JSHTTPSResponseControllerPrototype; LazyProperty<JSGlobalObject, JSObject> m_navigatorObject; LazyProperty<JSGlobalObject, JSObject> m_performanceObject; - LazyProperty<JSGlobalObject, JSObject> m_processEnvObject; LazyProperty<JSGlobalObject, JSObject> m_processObject; LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject; LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController; diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index 6d57798fd..265ada40a 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -46,8 +46,9 @@ pub const ZigGlobalObject = extern struct { console: *anyopaque, context_id: i32, mini_mode: bool, + worker_ptr: ?*anyopaque, ) *JSGlobalObject { - var global = shim.cppFn("create", .{ class_ref, count, console, context_id, mini_mode }); + var global = shim.cppFn("create", .{ class_ref, count, console, context_id, mini_mode, worker_ptr }); Backtrace.reloadHandlers() catch unreachable; return global; } diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index 9a6d1b72a..63ae6c3a4 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -579,7 +579,7 @@ ZIG_DECL JSC__JSValue Crypto__timingSafeEqual__slowpath(JSC__JSGlobalObject* arg #pragma mark - Zig::GlobalObject -CPP_DECL JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* arg0, int32_t arg1, void* arg2, int32_t arg3, bool arg4); +CPP_DECL JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* arg0, int32_t arg1, void* arg2, int32_t arg3, bool arg4, void* arg5); CPP_DECL void* Zig__GlobalObject__getModuleRegistryMap(JSC__JSGlobalObject* arg0); CPP_DECL bool Zig__GlobalObject__resetModuleRegistryMap(JSC__JSGlobalObject* arg0, void* arg1); diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig index d39793c07..2b25c0f5b 100644 --- a/src/bun.js/bindings/headers.zig +++ b/src/bun.js/bindings/headers.zig @@ -351,7 +351,7 @@ pub extern fn Reader__intptr__put(arg0: *bindings.JSGlobalObject, JSValue1: JSC_ pub extern fn Crypto__getRandomValues__put(arg0: *bindings.JSGlobalObject, JSValue1: JSC__JSValue) void; pub extern fn Crypto__randomUUID__put(arg0: *bindings.JSGlobalObject, JSValue1: JSC__JSValue) void; pub extern fn Crypto__timingSafeEqual__put(arg0: *bindings.JSGlobalObject, JSValue1: JSC__JSValue) void; -pub extern fn Zig__GlobalObject__create(arg0: [*c]JSClassRef, arg1: i32, arg2: ?*anyopaque, arg3: i32, arg4: bool) *bindings.JSGlobalObject; +pub extern fn Zig__GlobalObject__create(arg0: [*c]JSClassRef, arg1: i32, arg2: ?*anyopaque, arg3: i32, arg4: bool, arg5: ?*anyopaque) *bindings.JSGlobalObject; pub extern fn Zig__GlobalObject__getModuleRegistryMap(arg0: *bindings.JSGlobalObject) ?*anyopaque; pub extern fn Zig__GlobalObject__resetModuleRegistryMap(arg0: *bindings.JSGlobalObject, arg1: ?*anyopaque) bool; pub extern fn Bun__Path__create(arg0: *bindings.JSGlobalObject, arg1: bool) JSC__JSValue; diff --git a/src/bun.js/bindings/webcore/JSWorker.cpp b/src/bun.js/bindings/webcore/JSWorker.cpp index 434249068..1b65cba47 100644 --- a/src/bun.js/bindings/webcore/JSWorker.cpp +++ b/src/bun.js/bindings/webcore/JSWorker.cpp @@ -128,7 +128,7 @@ template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor::const EnsureStillAliveScope argument1 = callFrame->argument(1); auto options = WorkerOptions {}; - options.bun.unref = true; + options.bun.unref = false; if (JSObject* optionsObject = JSC::jsDynamicCast<JSC::JSObject*>(argument1.value())) { if (auto nameValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "name"_s))) { @@ -138,61 +138,93 @@ template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor::const } } - if (auto* bunObject = optionsObject) { - if (auto miniModeValue = bunObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "smol"_s))) { - options.bun.mini = miniModeValue.toBoolean(lexicalGlobalObject); - RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); - } + if (auto miniModeValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "smol"_s))) { + options.bun.mini = miniModeValue.toBoolean(lexicalGlobalObject); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + } - if (auto ref = bunObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "ref"_s))) { - options.bun.unref = !ref.toBoolean(lexicalGlobalObject); - RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); - } + if (auto ref = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "ref"_s))) { + options.bun.unref = !ref.toBoolean(lexicalGlobalObject); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + } - auto workerData = bunObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "workerData"_s)); - if (!workerData) { - workerData = bunObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "data"_s)); - } + auto workerData = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "workerData"_s)); + if (!workerData) { + workerData = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "data"_s)); + } - if (workerData) { - Vector<RefPtr<MessagePort>> ports; - Vector<JSC::Strong<JSC::JSObject>> transferList; - - if (JSValue transferListValue = bunObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transferList"_s))) { - if (transferListValue.isObject()) { - JSC::JSObject* transferListObject = transferListValue.getObject(); - if (auto* transferListArray = jsDynamicCast<JSC::JSArray*>(transferListObject)) { - for (unsigned i = 0; i < transferListArray->length(); i++) { - JSC::JSValue transferListValue = transferListArray->get(lexicalGlobalObject, i); - if (transferListValue.isObject()) { - JSC::JSObject* transferListObject = transferListValue.getObject(); - transferList.append(JSC::Strong<JSC::JSObject>(vm, transferListObject)); - } + if (workerData) { + Vector<RefPtr<MessagePort>> ports; + Vector<JSC::Strong<JSC::JSObject>> transferList; + + if (JSValue transferListValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transferList"_s))) { + if (transferListValue.isObject()) { + JSC::JSObject* transferListObject = transferListValue.getObject(); + if (auto* transferListArray = jsDynamicCast<JSC::JSArray*>(transferListObject)) { + for (unsigned i = 0; i < transferListArray->length(); i++) { + JSC::JSValue transferListValue = transferListArray->get(lexicalGlobalObject, i); + if (transferListValue.isObject()) { + JSC::JSObject* transferListObject = transferListValue.getObject(); + transferList.append(JSC::Strong<JSC::JSObject>(vm, transferListObject)); } } } } + } + + ExceptionOr<Ref<SerializedScriptValue>> serialized = SerializedScriptValue::create(*lexicalGlobalObject, workerData, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); + if (serialized.hasException()) { + WebCore::propagateException(*lexicalGlobalObject, throwScope, serialized.releaseException()); + return encodedJSValue(); + } - ExceptionOr<Ref<SerializedScriptValue>> serialized = SerializedScriptValue::create(*lexicalGlobalObject, workerData, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); - if (serialized.hasException()) { - WebCore::propagateException(*lexicalGlobalObject, throwScope, serialized.releaseException()); + Vector<TransferredMessagePort> transferredPorts; + + if (!ports.isEmpty()) { + auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports)); + if (disentangleResult.hasException()) { + WebCore::propagateException(*lexicalGlobalObject, throwScope, disentangleResult.releaseException()); return encodedJSValue(); } + transferredPorts = disentangleResult.releaseReturnValue(); + } - Vector<TransferredMessagePort> transferredPorts; + options.bun.data = WTFMove(serialized.releaseReturnValue()); + options.bun.dataMessagePorts = WTFMove(transferredPorts); + } - if (!ports.isEmpty()) { - auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports)); - if (disentangleResult.hasException()) { - WebCore::propagateException(*lexicalGlobalObject, throwScope, disentangleResult.releaseException()); - return encodedJSValue(); - } - transferredPorts = disentangleResult.releaseReturnValue(); - } + auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject); + auto envValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "env"_s)); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + JSObject* envObject = nullptr; + + if (envValue && envValue.isCell()) { + envObject = jsDynamicCast<JSC::JSObject*>(envValue); + } else if (globalObject->m_processEnvObject.isInitialized()) { + envObject = globalObject->processEnvObject(); + } - options.bun.data = WTFMove(serialized.releaseReturnValue()); - options.bun.dataMessagePorts = WTFMove(transferredPorts); + if (envObject) { + if (!envObject->staticPropertiesReified()) { + envObject->reifyAllStaticProperties(globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); } + + JSC::PropertyNameArray keys(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude); + envObject->methodTable()->getOwnPropertyNames(envObject, lexicalGlobalObject, keys, JSC::DontEnumPropertiesMode::Exclude); + RETURN_IF_EXCEPTION(throwScope, {}); + + HashMap<String, String> env; + + for (const auto& key : keys) { + JSValue value = envObject->get(lexicalGlobalObject, key); + RETURN_IF_EXCEPTION(throwScope, {}); + String str = value.toWTFString(lexicalGlobalObject).isolatedCopy(); + RETURN_IF_EXCEPTION(throwScope, {}); + env.add(key.impl()->isolatedCopy(), str); + } + + options.bun.env = std::make_unique<HashMap<String, String>>(WTFMove(env)); } } @@ -390,6 +422,7 @@ JSC_DEFINE_CUSTOM_SETTER(setJSWorker_onerror, (JSGlobalObject * lexicalGlobalObj static inline JSC::EncodedJSValue jsWorkerPrototypeFunction_terminateBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWorker>::ClassParameter castedThis) { + printf("bruh \n"); auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); UNUSED_PARAM(throwScope); diff --git a/src/bun.js/bindings/webcore/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index ea64811e0..f2694b59f 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -61,7 +61,7 @@ #include "MessageEvent.h" #include <JavaScriptCore/HashMapImplInlines.h> #include "BunWorkerGlobalScope.h" - +#include "CloseEvent.h" namespace WebCore { WTF_MAKE_ISO_ALLOCATED_IMPL(Worker); @@ -210,6 +210,7 @@ ExceptionOr<void> Worker::postMessage(JSC::JSGlobalObject& state, JSC::JSValue m void Worker::terminate() { + printf("terminate\n"); // m_contextProxy.terminateWorkerGlobalScope(); m_wasTerminated = true; WebWorker__terminate(impl_); @@ -339,19 +340,19 @@ void Worker::dispatchError(WTF::String message) protectedThis->dispatchEvent(event); }); } -void Worker::dispatchExit() +void Worker::dispatchExit(int32_t exitCode) { auto* ctx = scriptExecutionContext(); if (!ctx) return; - ScriptExecutionContext::postTaskTo(ctx->identifier(), [protectedThis = Ref { *this }](ScriptExecutionContext& context) -> void { + ScriptExecutionContext::postTaskTo(ctx->identifier(), [exitCode, protectedThis = Ref { *this }](ScriptExecutionContext& context) -> void { protectedThis->m_isOnline = false; protectedThis->m_isClosing = true; protectedThis->setKeepAlive(false); if (protectedThis->hasEventListeners(eventNames().closeEvent)) { - auto event = Event::create(eventNames().closeEvent, Event::CanBubble::No, Event::IsCancelable::No); + auto event = CloseEvent::create(exitCode == 0, static_cast<unsigned short>(exitCode), exitCode == 0 ? "Worker terminated normally"_s : "Worker exited abnormally"_s); protectedThis->dispatchEvent(event); } }); @@ -377,6 +378,8 @@ void Worker::forEachWorker(const Function<Function<void(ScriptExecutionContext&) extern "C" void WebWorker__dispatchExit(Zig::GlobalObject* globalObject, Worker* worker, int32_t exitCode) { + worker->dispatchExit(exitCode); + if (globalObject) { auto* ctx = globalObject->scriptExecutionContext(); if (ctx) { @@ -398,8 +401,6 @@ extern "C" void WebWorker__dispatchExit(Zig::GlobalObject* globalObject, Worker* vm.notifyNeedTermination(); vm.deferredWorkTimer->doWork(vm); } - - worker->dispatchExit(); } extern "C" void WebWorker__dispatchOnline(Worker* worker, Zig::GlobalObject* globalObject) { diff --git a/src/bun.js/bindings/webcore/Worker.h b/src/bun.js/bindings/webcore/Worker.h index e0f328dbb..a296fa4a8 100644 --- a/src/bun.js/bindings/webcore/Worker.h +++ b/src/bun.js/bindings/webcore/Worker.h @@ -94,7 +94,7 @@ public: void drainEvents(); void dispatchOnline(Zig::GlobalObject* workerGlobalObject); void dispatchError(WTF::String message); - void dispatchExit(); + void dispatchExit(int32_t exitCode); ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } ScriptExecutionContextIdentifier clientIdentifier() const { return m_clientIdentifier; } WorkerOptions& options() { return m_options; } diff --git a/src/bun.js/bindings/webcore/WorkerOptions.h b/src/bun.js/bindings/webcore/WorkerOptions.h index 0c307d18e..79eabef98 100644 --- a/src/bun.js/bindings/webcore/WorkerOptions.h +++ b/src/bun.js/bindings/webcore/WorkerOptions.h @@ -12,6 +12,7 @@ struct BunOptions { bool unref { false }; RefPtr<SerializedScriptValue> data; Vector<TransferredMessagePort> dataMessagePorts; + std::unique_ptr<HashMap<String, String>> env { nullptr }; }; struct WorkerOptions { diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 1c8d91d52..741affa6a 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -910,6 +910,7 @@ pub const VirtualMachine = struct { vm.console, -1, false, + null, ); vm.regular_event_loop.global = vm.global; vm.regular_event_loop.virtual_machine = vm; @@ -1014,6 +1015,7 @@ pub const VirtualMachine = struct { vm.console, -1, smol, + null, ); vm.regular_event_loop.global = vm.global; vm.regular_event_loop.virtual_machine = vm; @@ -1118,6 +1120,7 @@ pub const VirtualMachine = struct { vm.console, @as(i32, @intCast(worker.execution_context_id)), worker.mini, + worker.cpp_worker, ); vm.regular_event_loop.global = vm.global; vm.regular_event_loop.virtual_machine = vm; diff --git a/src/bun.js/web_worker.zig b/src/bun.js/web_worker.zig index 73f42b089..bbe708d18 100644 --- a/src/bun.js/web_worker.zig +++ b/src/bun.js/web_worker.zig @@ -341,22 +341,20 @@ pub const WebWorker = struct { if (this.requested_terminate) { return; } - - this.allowed_to_exit = false; _ = this.requestTerminate(); } pub fn setRef(this: *WebWorker, value: bool) callconv(.C) void { - if (this.requested_terminate and value) { + if (this.requested_terminate and !value) { this.parent_poll_ref.unref(this.parent); return; } this.allowed_to_exit = !value; - if (value) { - this.parent_poll_ref.ref(this.parent); - } else { + if (this.allowed_to_exit) { this.parent_poll_ref.unref(this.parent); + } else { + this.parent_poll_ref.ref(this.parent); } if (this.vm) |vm| { @@ -404,6 +402,7 @@ pub const WebWorker = struct { } fn requestTerminate(this: *WebWorker) bool { + this.setRef(false); var vm = this.vm orelse { this.requested_terminate = true; return false; |