diff options
Diffstat (limited to 'src')
m--------- | src/bun.js/WebKit | 0 | ||||
-rw-r--r-- | src/bun.js/bindings/BunClientData.cpp | 8 | ||||
-rw-r--r-- | src/bun.js/bindings/BunClientData.h | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/JSCTaskScheduler.cpp | 101 | ||||
-rw-r--r-- | src/bun.js/bindings/JSCTaskScheduler.h | 25 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 10 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 1 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.zig | 1 | ||||
-rw-r--r-- | src/bun.js/event_loop.zig | 52 | ||||
-rw-r--r-- | src/bun.js/web_worker.zig | 4 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 2 | ||||
-rw-r--r-- | src/bun.js/webcore/streams.zig | 2 | ||||
-rw-r--r-- | src/cli/test_command.zig | 1 | ||||
-rw-r--r-- | src/deps/uws.zig | 12 | ||||
-rw-r--r-- | src/js/bun/wasi-runner.js | 15 | ||||
-rw-r--r-- | src/js/out/modules/bun/wasi-runner.js | 11 | ||||
-rw-r--r-- | src/napi/napi.zig | 6 | ||||
-rw-r--r-- | src/tagged_pointer.zig | 4 |
20 files changed, 227 insertions, 42 deletions
diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit -Subproject 5e65b9ae7756b6353cfeac5206f7076b00e9ecf +Subproject ecf1b9c4bc2247020add7b14a732bb0085f25d5 diff --git a/src/bun.js/bindings/BunClientData.cpp b/src/bun.js/bindings/BunClientData.cpp index 2cdd8b25a..9af17d638 100644 --- a/src/bun.js/bindings/BunClientData.cpp +++ b/src/bun.js/bindings/BunClientData.cpp @@ -21,6 +21,7 @@ #include "JavaScriptCore/JSCInlines.h" #include "JSDOMWrapper.h" +#include <JavaScriptCore/DeferredWorkTimer.h> namespace WebCore { using namespace JSC; @@ -69,9 +70,14 @@ JSVMClientData::~JSVMClientData() ASSERT(m_normalWorld->hasOneRef()); m_normalWorld = nullptr; } -void JSVMClientData::create(VM* vm) +void JSVMClientData::create(VM* vm, void* bunVM) { JSVMClientData* clientData = new JSVMClientData(*vm); + clientData->bunVM = bunVM; + vm->deferredWorkTimer->onAddPendingWork = Bun::JSCTaskScheduler::onAddPendingWork; + vm->deferredWorkTimer->onScheduleWorkSoon = Bun::JSCTaskScheduler::onScheduleWorkSoon; + vm->deferredWorkTimer->onCancelPendingWork = Bun::JSCTaskScheduler::onCancelPendingWork; + vm->clientData = clientData; // ~VM deletes this pointer. clientData->m_normalWorld = DOMWrapperWorld::create(*vm, DOMWrapperWorld::Type::Normal); diff --git a/src/bun.js/bindings/BunClientData.h b/src/bun.js/bindings/BunClientData.h index e3c2d3748..0bee575df 100644 --- a/src/bun.js/bindings/BunClientData.h +++ b/src/bun.js/bindings/BunClientData.h @@ -24,6 +24,7 @@ class DOMWrapperWorld; #include "JavaScriptCore/IsoSubspacePerVM.h" #include "wtf/StdLibExtras.h" #include "WebCoreJSBuiltins.h" +#include "JSCTaskScheduler.h" namespace Zig { } @@ -80,7 +81,7 @@ public: virtual ~JSVMClientData(); - static void create(JSC::VM*); + static void create(JSC::VM*, void*); JSHeapData& heapData() { return *m_heapData; } BunBuiltinNames& builtinNames() { return m_builtinNames; } @@ -107,6 +108,9 @@ public: func(*space); } + void* bunVM; + Bun::JSCTaskScheduler deferredWorkTimer; + private: BunBuiltinNames m_builtinNames; JSBuiltinFunctions m_builtinFunctions; diff --git a/src/bun.js/bindings/JSCTaskScheduler.cpp b/src/bun.js/bindings/JSCTaskScheduler.cpp new file mode 100644 index 000000000..436be4c0a --- /dev/null +++ b/src/bun.js/bindings/JSCTaskScheduler.cpp @@ -0,0 +1,101 @@ +#include "config.h" +#include <JavaScriptCore/VM.h> +#include "JSCTaskScheduler.h" +#include "BunClientData.h" + +using Ticket = JSC::DeferredWorkTimer::Ticket; +using Task = JSC::DeferredWorkTimer::Task; +using TicketData = JSC::DeferredWorkTimer::TicketData; + +namespace Bun { +using namespace JSC; + +extern "C" void Bun__queueJSCDeferredWorkTaskConcurrently(void* bunVM, void* task); +extern "C" void Bun__eventLoop__incrementRefConcurrently(void* bunVM, int delta); + +class JSCDeferredWorkTask { +public: + JSCDeferredWorkTask(Ticket ticket, Task&& task) + : ticket(ticket) + , task(WTFMove(task)) + { + } + + Ticket ticket; + Task task; + + WTF_MAKE_FAST_ALLOCATED; +}; + +static JSC::VM& getVM(Ticket ticket) +{ + return ticket->scriptExecutionOwner.get()->vm(); +} + +void JSCTaskScheduler::onAddPendingWork(std::unique_ptr<TicketData> ticket, JSC::DeferredWorkTimer::WorkKind kind) +{ + JSC::VM& vm = getVM(ticket.get()); + auto clientData = WebCore::clientData(vm); + auto& scheduler = clientData->deferredWorkTimer; + LockHolder holder { scheduler.m_lock }; + if (kind != DeferredWorkTimer::WorkKind::Other) { + + Bun__eventLoop__incrementRefConcurrently(clientData->bunVM, 1); + scheduler.m_pendingTicketsKeepingEventLoopAlive.add(WTFMove(ticket)); + } else { + scheduler.m_pendingTicketsOther.add(WTFMove(ticket)); + } +} +void JSCTaskScheduler::onScheduleWorkSoon(Ticket ticket, Task&& task) +{ + auto* job = new JSCDeferredWorkTask(ticket, WTFMove(task)); + Bun__queueJSCDeferredWorkTaskConcurrently(WebCore::clientData(getVM(ticket))->bunVM, job); +} + +void JSCTaskScheduler::onCancelPendingWork(Ticket ticket) +{ + auto& scheduler = WebCore::clientData(getVM(ticket))->deferredWorkTimer; + + LockHolder holder { scheduler.m_lock }; + bool isKeepingEventLoopAlive = scheduler.m_pendingTicketsKeepingEventLoopAlive.removeIf([ticket](const auto& pendingTicket) { + return pendingTicket.get() == ticket; + }); + + if (isKeepingEventLoopAlive) { + holder.unlockEarly(); + JSC::VM& vm = getVM(ticket); + Bun__eventLoop__incrementRefConcurrently(WebCore::clientData(vm)->bunVM, -1); + } else { + scheduler.m_pendingTicketsOther.removeIf([ticket](const auto& pendingTicket) { + return pendingTicket.get() == ticket; + }); + } +} + +static void runPendingWork(void* bunVM, Bun::JSCTaskScheduler& scheduler, JSCDeferredWorkTask* job) +{ + LockHolder holder { scheduler.m_lock }; + auto pendingTicket = scheduler.m_pendingTicketsKeepingEventLoopAlive.take(job->ticket); + if (!pendingTicket) { + pendingTicket = scheduler.m_pendingTicketsOther.take(job->ticket); + } else { + Bun__eventLoop__incrementRefConcurrently(bunVM, -1); + } + holder.unlockEarly(); + + if (pendingTicket && !pendingTicket->isCancelled()) { + job->task(job->ticket); + } + + delete job; +} + +extern "C" void Bun__runDeferredWork(Bun::JSCDeferredWorkTask* job) +{ + auto& vm = getVM(job->ticket); + auto clientData = WebCore::clientData(vm); + + runPendingWork(clientData->bunVM, clientData->deferredWorkTimer, job); +} + +} diff --git a/src/bun.js/bindings/JSCTaskScheduler.h b/src/bun.js/bindings/JSCTaskScheduler.h new file mode 100644 index 000000000..3257eb9c8 --- /dev/null +++ b/src/bun.js/bindings/JSCTaskScheduler.h @@ -0,0 +1,25 @@ +#pragma once + +#include <JavaScriptCore/DeferredWorkTimer.h> + +namespace Bun { + +class JSCTaskScheduler { +public: + JSCTaskScheduler() + : m_pendingTicketsKeepingEventLoopAlive() + , m_pendingTicketsOther() + { + } + + static void onAddPendingWork(std::unique_ptr<JSC::DeferredWorkTimer::TicketData> ticket, JSC::DeferredWorkTimer::WorkKind kind); + static void onScheduleWorkSoon(JSC::DeferredWorkTimer::Ticket ticket, JSC::DeferredWorkTimer::Task&& task); + static void onCancelPendingWork(JSC::DeferredWorkTimer::Ticket ticket); + +public: + Lock m_lock; + HashSet<std::unique_ptr<JSC::DeferredWorkTimer::TicketData>> m_pendingTicketsKeepingEventLoopAlive; + HashSet<std::unique_ptr<JSC::DeferredWorkTimer::TicketData>> m_pendingTicketsOther; +}; + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index f267fcbb7..52f633f3d 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -431,7 +431,7 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje // This must happen before JSVMClientData::create vm.heap.acquireAccess(); - WebCore::JSVMClientData::create(&vm); + WebCore::JSVMClientData::create(&vm, Bun__getVM()); JSC::JSLockHolder locker(vm); Zig::GlobalObject* globalObject; diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 55f718207..9fb0c18d5 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -9,7 +9,6 @@ #include "JavaScriptCore/BytecodeIndex.h" #include "JavaScriptCore/CodeBlock.h" #include "JavaScriptCore/Completion.h" -#include "JavaScriptCore/DeferredWorkTimer.h" #include "JavaScriptCore/ErrorInstance.h" #include "JavaScriptCore/ExceptionHelpers.h" #include "JavaScriptCore/ExceptionScope.h" @@ -3893,11 +3892,6 @@ void JSC__VM__deleteAllCode(JSC__VM* arg1, JSC__JSGlobalObject* globalObject) arg1->heap.reportAbandonedObjectGraph(); } -void JSC__VM__doWork(JSC__VM* vm) -{ - vm->deferredWorkTimer->doWork(*vm); -} - void JSC__VM__deinit(JSC__VM* arg1, JSC__JSGlobalObject* globalObject) {} void JSC__VM__drainMicrotasks(JSC__VM* arg0) { arg0->drainMicrotasks(); } diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index edd1be1a9..924eb27a1 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -5083,14 +5083,6 @@ pub const VM = extern struct { }); } - pub fn doWork( - vm: *VM, - ) void { - return cppFn("doWork", .{ - vm, - }); - } - pub fn externalMemorySize(vm: *VM) usize { return cppFn("externalMemorySize", .{vm}); } @@ -5101,7 +5093,7 @@ pub const VM = extern struct { return cppFn("blockBytesAllocated", .{vm}); } - pub const Extern = [_][]const u8{ "collectAsync", "externalMemorySize", "blockBytesAllocated", "heapSize", "releaseWeakRefs", "throwError", "doWork", "deferGC", "holdAPILock", "runGC", "generateHeapSnapshot", "isJITEnabled", "deleteAllCode", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks", "whenIdle", "shrinkFootprint", "setExecutionTimeLimit", "clearExecutionTimeLimit" }; + pub const Extern = [_][]const u8{ "collectAsync", "externalMemorySize", "blockBytesAllocated", "heapSize", "releaseWeakRefs", "throwError", "deferGC", "holdAPILock", "runGC", "generateHeapSnapshot", "isJITEnabled", "deleteAllCode", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks", "whenIdle", "shrinkFootprint", "setExecutionTimeLimit", "clearExecutionTimeLimit" }; }; pub const ThrowScope = extern struct { diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index 8cce986dc..05c708a48 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -419,7 +419,6 @@ CPP_DECL JSC__VM* JSC__VM__create(unsigned char HeapType0); CPP_DECL void JSC__VM__deferGC(JSC__VM* arg0, void* arg1, void(* ArgFn2)(void* arg0)) __attribute__((nonnull (2))); CPP_DECL void JSC__VM__deinit(JSC__VM* arg0, JSC__JSGlobalObject* arg1); CPP_DECL void JSC__VM__deleteAllCode(JSC__VM* arg0, JSC__JSGlobalObject* arg1); -CPP_DECL void JSC__VM__doWork(JSC__VM* arg0); CPP_DECL void JSC__VM__drainMicrotasks(JSC__VM* arg0); CPP_DECL bool JSC__VM__executionForbidden(JSC__VM* arg0); CPP_DECL size_t JSC__VM__externalMemorySize(JSC__VM* arg0); diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig index e87e59946..fbca33a30 100644 --- a/src/bun.js/bindings/headers.zig +++ b/src/bun.js/bindings/headers.zig @@ -313,7 +313,6 @@ pub extern fn JSC__VM__create(HeapType0: u8) *bindings.VM; pub extern fn JSC__VM__deferGC(arg0: *bindings.VM, arg1: ?*anyopaque, ArgFn2: ?*const fn (?*anyopaque) callconv(.C) void) void; pub extern fn JSC__VM__deinit(arg0: *bindings.VM, arg1: *bindings.JSGlobalObject) void; pub extern fn JSC__VM__deleteAllCode(arg0: *bindings.VM, arg1: *bindings.JSGlobalObject) void; -pub extern fn JSC__VM__doWork(arg0: *bindings.VM) void; pub extern fn JSC__VM__drainMicrotasks(arg0: *bindings.VM) void; pub extern fn JSC__VM__executionForbidden(arg0: *bindings.VM) bool; pub extern fn JSC__VM__externalMemorySize(arg0: *bindings.VM) usize; diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index 2dbe88d47..6688eaeea 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -73,7 +73,7 @@ pub fn ConcurrentPromiseTask(comptime Context: type) type { } pub fn onFinish(this: *This) void { - this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this)); + this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this, .manual_deinit)); } pub fn deinit(this: *This) void { @@ -136,7 +136,7 @@ pub fn WorkTask(comptime Context: type, comptime async_io: bool) type { } pub fn onFinish(this: *This) void { - this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this)); + this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this, .manual_deinit)); } pub fn deinit(this: *This) void { @@ -221,6 +221,35 @@ pub const CppTask = opaque { Bun__performTask(global, this); } }; +pub const JSCScheduler = struct { + pub const JSCDeferredWorkTask = opaque { + extern fn Bun__runDeferredWork(task: *JSCScheduler.JSCDeferredWorkTask) void; + pub const run = Bun__runDeferredWork; + }; + + export fn Bun__eventLoop__incrementRefConcurrently(jsc_vm: *VirtualMachine, delta: c_int) void { + JSC.markBinding(@src()); + + if (delta > 0) { + jsc_vm.uws_event_loop.?.refConcurrently(); + } else { + jsc_vm.uws_event_loop.?.unrefConcurrently(); + } + } + + export fn Bun__queueJSCDeferredWorkTaskConcurrently(jsc_vm: *VirtualMachine, task: *JSCScheduler.JSCDeferredWorkTask) void { + JSC.markBinding(@src()); + var loop = jsc_vm.eventLoop(); + var concurrent_task = bun.default_allocator.create(ConcurrentTask) catch @panic("out of memory!"); + loop.enqueueTaskConcurrent(concurrent_task.from(task, .auto_deinit)); + } + + comptime { + _ = Bun__eventLoop__incrementRefConcurrently; + _ = Bun__queueJSCDeferredWorkTaskConcurrently; + } +}; + const ThreadSafeFunction = JSC.napi.ThreadSafeFunction; const MicrotaskForDefaultGlobalObject = JSC.MicrotaskForDefaultGlobalObject; const HotReloadTask = JSC.HotReloader.HotReloadTask; @@ -228,6 +257,7 @@ const FSWatchTask = JSC.Node.FSWatcher.FSWatchTask; const PollPendingModulesTask = JSC.ModuleLoader.AsyncModule.Queue; // const PromiseTask = JSInternalPromise.Completion.PromiseTask; const GetAddrInfoRequestTask = JSC.DNS.GetAddrInfoRequest.Task; +const JSCDeferredWorkTask = JSCScheduler.JSCDeferredWorkTask; pub const Task = TaggedPointerUnion(.{ FetchTasklet, Microtask, @@ -244,6 +274,8 @@ pub const Task = TaggedPointerUnion(.{ PollPendingModulesTask, GetAddrInfoRequestTask, FSWatchTask, + JSCDeferredWorkTask, + // PromiseTask, // TimeoutTasklet, }); @@ -255,10 +287,15 @@ pub const ConcurrentTask = struct { pub const Queue = UnboundedQueue(ConcurrentTask, .next); - pub fn from(this: *ConcurrentTask, of: anytype) *ConcurrentTask { + pub const AutoDeinit = enum { + manual_deinit, + auto_deinit, + }; + pub fn from(this: *ConcurrentTask, of: anytype, auto_deinit: AutoDeinit) *ConcurrentTask { this.* = .{ .task = Task.init(of), .next = null, + .auto_delete = auto_deinit == .auto_deinit, }; return this; } @@ -457,6 +494,11 @@ pub const EventLoop = struct { transform_task.*.runFromJS(); transform_task.deinit(); }, + @field(Task.Tag, bun.meta.typeBaseName(@typeName(JSCDeferredWorkTask))) => { + var jsc_task: *JSCDeferredWorkTask = task.get(JSCDeferredWorkTask).?; + JSC.markBinding(@src()); + jsc_task.run(); + }, @field(Task.Tag, @typeName(WriteFileTask)) => { var transform_task: *WriteFileTask = task.get(WriteFileTask).?; transform_task.*.runFromJS(); @@ -627,10 +669,6 @@ pub const EventLoop = struct { break; } - // TODO: unify the event loops - // This needs a hook into JSC to schedule timers - this.global.vm().doWork(); - while (this.tickWithCount() > 0) { this.tickConcurrent(); } diff --git a/src/bun.js/web_worker.zig b/src/bun.js/web_worker.zig index 504b0adeb..130e99be1 100644 --- a/src/bun.js/web_worker.zig +++ b/src/bun.js/web_worker.zig @@ -141,7 +141,7 @@ pub const WebWorker = struct { var any_task = bun.default_allocator.create(JSC.AnyTask) catch @panic("OOM"); any_task.* = AnyTask.init(this); var concurrent_task = bun.default_allocator.create(JSC.ConcurrentTask) catch @panic("OOM"); - this.parent.eventLoop().enqueueTaskConcurrent(concurrent_task.from(any_task)); + this.parent.eventLoop().enqueueTaskConcurrent(concurrent_task.from(any_task, .auto_deinit)); } pub fn startWithErrorHandling( @@ -413,7 +413,7 @@ pub const WebWorker = struct { var concurrent_task = bun.default_allocator.create(JSC.ConcurrentTask) catch @panic("OOM"); var task = bun.default_allocator.create(JSC.AnyTask) catch @panic("OOM"); task.* = JSC.AnyTask.New(WebWorker, onTerminate).init(this); - vm.eventLoop().enqueueTaskConcurrent(concurrent_task.from(task)); + vm.eventLoop().enqueueTaskConcurrent(concurrent_task.from(task, .auto_deinit)); return true; } }; diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index ab2a6010d..a70a4f0ee 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -979,7 +979,7 @@ pub const Fetch = struct { pub fn callback(task: *FetchTasklet, result: HTTPClient.HTTPClientResult) void { task.response_buffer = result.body.?.*; task.result = result; - task.javascript_vm.eventLoop().enqueueTaskConcurrent(task.concurrent_task.from(task)); + task.javascript_vm.eventLoop().enqueueTaskConcurrent(task.concurrent_task.from(task, .manual_deinit)); } }; diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index 03b1dcdc9..5dc4ea830 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -4168,7 +4168,7 @@ pub const File = struct { pub fn scheduleMainThreadTask(this: *File) void { this.concurrent.main_thread_task.ctx = this; - this.loop.enqueueTaskConcurrent(this.concurrent.concurrent_task.from(&this.concurrent.main_thread_task)); + this.loop.enqueueTaskConcurrent(this.concurrent.concurrent_task.from(&this.concurrent.main_thread_task, .manual_deinit)); } fn runAsync(this: *File) void { diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig index f53c8121c..14eca012e 100644 --- a/src/cli/test_command.zig +++ b/src/cli/test_command.zig @@ -806,7 +806,6 @@ pub const TestCommand = struct { vm.global.vm().drainMicrotasks(); vm.global.handleRejectedPromises(); } - vm.global.vm().doWork(); } const file_end = reporter.jest.files.len; diff --git a/src/deps/uws.zig b/src/deps/uws.zig index 6e9d43e5f..15e6eaa68 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -760,6 +760,18 @@ pub const Loop = extern struct { this.num_polls += 1; this.active += 1; } + pub fn refConcurrently(this: *Loop) void { + log("ref", .{}); + _ = @atomicRmw(@TypeOf(this.num_polls), &this.num_polls, .Add, 1, .Monotonic); + _ = @atomicRmw(@TypeOf(this.active), &this.active, .Add, 1, .Monotonic); + } + + pub fn unrefConcurrently(this: *Loop) void { + log("unref", .{}); + _ = @atomicRmw(@TypeOf(this.num_polls), &this.num_polls, .Sub, 1, .Monotonic); + _ = @atomicRmw(@TypeOf(this.active), &this.active, .Sub, 1, .Monotonic); + } + pub fn unref(this: *Loop) void { log("unref", .{}); this.num_polls -= 1; diff --git a/src/js/bun/wasi-runner.js b/src/js/bun/wasi-runner.js index a292c6380..9f7b469e1 100644 --- a/src/js/bun/wasi-runner.js +++ b/src/js/bun/wasi-runner.js @@ -11,7 +11,12 @@ if (!filePath) { // The module specifier is the resolved path to the wasm file -var { WASM_CWD = process.cwd(), WASM_ROOT_DIR = "/", WASM_ENV_STR = undefined, WASM_USE_ASYNC_INIT = "" } = process.env; +var { + WASM_CWD = process.cwd(), + WASM_ROOT_DIR = "/", + WASM_ENV_STR = undefined, + WASM_USE_ASYNC_INIT = "1", +} = process.env; var env = process.env; if (WASM_ENV_STR?.length) { @@ -34,10 +39,12 @@ if (!source) { source = fs.readFileSync(file); } -const wasm = new WebAssembly.Module(source); -const instance = !WASM_USE_ASYNC_INIT +const wasm = await WebAssembly.compile(source); + +const instance = !Number(WASM_USE_ASYNC_INIT) ? new WebAssembly.Instance(wasm, wasi.getImports(wasm)) : await WebAssembly.instantiate(wasm, wasi.getImports(wasm)); + wasi.start(instance); -process.exit(0); +process.reallyExit(0); diff --git a/src/js/out/modules/bun/wasi-runner.js b/src/js/out/modules/bun/wasi-runner.js index 9dfd27b23..47c5ade3c 100644 --- a/src/js/out/modules/bun/wasi-runner.js +++ b/src/js/out/modules/bun/wasi-runner.js @@ -1,7 +1,12 @@ var filePath = process.argv.at(1); if (!filePath) throw err = new Error("To run a wasm file with Bun, the first argument must be a path to a .wasm file"), err.name = "WasmFileNotFound", err; -var err, { WASM_CWD = process.cwd(), WASM_ROOT_DIR = "/", WASM_ENV_STR = void 0, WASM_USE_ASYNC_INIT = "" } = process.env, env = process.env; +var err, { + WASM_CWD = process.cwd(), + WASM_ROOT_DIR = "/", + WASM_ENV_STR = void 0, + WASM_USE_ASYNC_INIT = "1" +} = process.env, env = process.env; if (WASM_ENV_STR?.length) env = JSON.parse(WASM_ENV_STR); var wasi = new WASI({ @@ -16,6 +21,6 @@ if (!source) { const fs = Bun.fs(), file = import.meta.path; source = fs.readFileSync(file); } -var wasm = new WebAssembly.Module(source), instance = !WASM_USE_ASYNC_INIT ? new WebAssembly.Instance(wasm, wasi.getImports(wasm)) : await WebAssembly.instantiate(wasm, wasi.getImports(wasm)); +var wasm = await WebAssembly.compile(source), instance = !Number(WASM_USE_ASYNC_INIT) ? new WebAssembly.Instance(wasm, wasi.getImports(wasm)) : await WebAssembly.instantiate(wasm, wasi.getImports(wasm)); wasi.start(instance); -process.exit(0); +process.reallyExit(0); diff --git a/src/napi/napi.zig b/src/napi/napi.zig index bb8f19df2..abe8316ad 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -962,7 +962,7 @@ pub const napi_async_work = struct { this.execute.?(this.global, this.ctx); this.status.store(@intFromEnum(Status.completed), .SeqCst); - this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this)); + this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this, .manual_deinit)); } pub fn schedule(this: *napi_async_work) void { @@ -1338,7 +1338,7 @@ pub const ThreadSafeFunction = struct { } } - this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this)); + this.event_loop.enqueueTaskConcurrent(this.concurrent_task.from(this, .manual_deinit)); } pub fn finalize(opaq: *anyopaque) void { @@ -1387,7 +1387,7 @@ pub const ThreadSafeFunction = struct { if (this.owning_threads.count() == 0) { this.finalizer_task = JSC.AnyTask{ .ctx = this, .callback = finalize }; - this.event_loop.enqueueTaskConcurrent(this.concurrent_finalizer_task.from(&this.finalizer_task)); + this.event_loop.enqueueTaskConcurrent(this.concurrent_finalizer_task.from(&this.finalizer_task, .manual_deinit)); return; } } diff --git a/src/tagged_pointer.zig b/src/tagged_pointer.zig index 6c2462139..b5555a8b4 100644 --- a/src/tagged_pointer.zig +++ b/src/tagged_pointer.zig @@ -159,6 +159,10 @@ pub fn TaggedPointerUnion(comptime Types: anytype) type { pub inline fn init(_ptr: anytype) This { const Type = std.meta.Child(@TypeOf(_ptr)); + return initWithType(Type, _ptr); + } + + pub inline fn initWithType(comptime Type: type, _ptr: anytype) This { const name = comptime typeBaseName(@typeName(Type)); // there will be a compiler error if the passed in type doesn't exist in the enum |