aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp16
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h3
-rw-r--r--src/bun.js/bindings/exports.zig3
-rw-r--r--src/bun.js/bindings/headers.h2
-rw-r--r--src/bun.js/bindings/headers.zig2
-rw-r--r--src/bun.js/bindings/webcore/JSWorker.cpp117
-rw-r--r--src/bun.js/bindings/webcore/Worker.cpp13
-rw-r--r--src/bun.js/bindings/webcore/Worker.h2
-rw-r--r--src/bun.js/bindings/webcore/WorkerOptions.h1
-rw-r--r--src/bun.js/javascript.zig3
-rw-r--r--src/bun.js/web_worker.zig11
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;