diff --git a/src/bun.js/bindings/BunProcess.cpp b/src/bun.js/bindings/BunProcess.cpp index 8330841b78..8226978723 100644 --- a/src/bun.js/bindings/BunProcess.cpp +++ b/src/bun.js/bindings/BunProcess.cpp @@ -546,13 +546,17 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionChdir, return JSC::JSValue::encode(result); } -#if !OS(WINDOWS) + static HashMap* signalNameToNumberMap = nullptr; static HashMap* signalNumberToNameMap = nullptr; -// signal number to array of script execution context ids that care about the signal -static HashMap>* signalToContextIdsMap = nullptr; -static Lock signalToContextIdsMapLock; +// On windows, signals need to have a handle to the uv_signal_t. When sigaction is used, this is kept track globally for you. +struct SignalHandleValue { +#if OS(WINDOWS) + uv_signal_t* handle; +#endif +}; +static HashMap* signalToContextIdsMap = nullptr; static const NeverDestroyed signalNames[] = { MAKE_STATIC_STRING_IMPL("SIGHUP"), @@ -599,31 +603,69 @@ static void loadSignalNumberMap() signalNameToNumberMap->add(signalNames[1], SIGINT); signalNameToNumberMap->add(signalNames[2], SIGQUIT); signalNameToNumberMap->add(signalNames[3], SIGILL); +#ifdef SIGTRAP signalNameToNumberMap->add(signalNames[4], SIGTRAP); +#endif signalNameToNumberMap->add(signalNames[5], SIGABRT); +#ifdef SIGIOT signalNameToNumberMap->add(signalNames[6], SIGIOT); +#endif +#ifdef SIGBUS signalNameToNumberMap->add(signalNames[7], SIGBUS); +#endif signalNameToNumberMap->add(signalNames[8], SIGFPE); signalNameToNumberMap->add(signalNames[9], SIGKILL); +#ifdef SIGUSR1 signalNameToNumberMap->add(signalNames[10], SIGUSR1); +#endif signalNameToNumberMap->add(signalNames[11], SIGSEGV); +#ifdef SIGUSR2 signalNameToNumberMap->add(signalNames[12], SIGUSR2); +#endif +#ifdef SIGPIPE signalNameToNumberMap->add(signalNames[13], SIGPIPE); +#endif +#ifdef SIGALRM signalNameToNumberMap->add(signalNames[14], SIGALRM); +#endif signalNameToNumberMap->add(signalNames[15], SIGTERM); +#ifdef SIGCHLD signalNameToNumberMap->add(signalNames[16], SIGCHLD); +#endif +#ifdef SIGCONT signalNameToNumberMap->add(signalNames[17], SIGCONT); +#endif +#ifdef SIGSTOP signalNameToNumberMap->add(signalNames[18], SIGSTOP); +#endif +#ifdef SIGTSTP signalNameToNumberMap->add(signalNames[19], SIGTSTP); +#endif +#ifdef SIGTTIN signalNameToNumberMap->add(signalNames[20], SIGTTIN); +#endif +#ifdef SIGTTOU signalNameToNumberMap->add(signalNames[21], SIGTTOU); +#endif +#ifdef SIGURG signalNameToNumberMap->add(signalNames[22], SIGURG); +#endif +#ifdef SIGXCPU signalNameToNumberMap->add(signalNames[23], SIGXCPU); +#endif +#ifdef SIGXFSZ signalNameToNumberMap->add(signalNames[24], SIGXFSZ); +#endif +#ifdef SIGVTALRM signalNameToNumberMap->add(signalNames[25], SIGVTALRM); +#endif +#ifdef SIGPROF signalNameToNumberMap->add(signalNames[26], SIGPROF); +#endif signalNameToNumberMap->add(signalNames[27], SIGWINCH); +#ifdef SIGIO signalNameToNumberMap->add(signalNames[28], SIGIO); +#endif #ifdef SIGINFO signalNameToNumberMap->add(signalNames[29], SIGINFO); #endif @@ -631,153 +673,209 @@ static void loadSignalNumberMap() #ifndef SIGINFO signalNameToNumberMap->add(signalNames[29], 255); #endif +#ifdef SIGSYS signalNameToNumberMap->add(signalNames[30], SIGSYS); +#endif }); } +#if OS(WINDOWS) +extern "C" uv_signal_t* Bun__UVSignalHandle__init(JSC::JSGlobalObject* lexicalGlobalObject, int signalNumber, void (*callback)(uv_signal_t*, int)); +extern "C" uv_signal_t* Bun__UVSignalHandle__close(uv_signal_t*); +#endif + +#if !OS(WINDOWS) +void signalHandler(int signalNumber) +#else +void signalHandler(uv_signal_t* signal, int signalNumber) +#endif +{ + if (UNLIKELY(signalNumberToNameMap->find(signalNumber) == signalNumberToNameMap->end())) + return; + + SignalHandleValue signal_handle = signalToContextIdsMap->get(signalNumber); + + auto* context = ScriptExecutionContext::getMainThreadScriptExecutionContext(); + if (UNLIKELY(!context)) + return; + + JSGlobalObject* lexicalGlobalObject = context->jsGlobalObject(); + Zig::GlobalObject* globalObject = jsCast(lexicalGlobalObject); + + Process* process = jsCast(globalObject->processObject()); + + String signalName = signalNumberToNameMap->get(signalNumber); + Identifier signalNameIdentifier = Identifier::fromString(globalObject->vm(), signalName); + MarkedArgumentBuffer args; + args.append(jsNumber(signalNumber)); + // TODO(@paperdave): add an ASSERT(isMainThread()); + // This should be true on posix if I understand sigaction right + // On Windows it should be true if the uv_signal is created on the main thread's loop + // + // I would like to assert this because if that assumption is not true, + // this call will probably cause very confusing bugs. + process->wrapped().emitForBindings(signalNameIdentifier, args); +}; + static void onDidChangeListeners(EventEmitter& eventEmitter, const Identifier& eventName, bool isAdded) { - if (eventName.string() == "message"_s) { - if (isAdded) { - if (Bun__GlobalObject__hasIPC(eventEmitter.scriptExecutionContext()->jsGlobalObject()) - && eventEmitter.listenerCount(eventName) == 1) { - eventEmitter.scriptExecutionContext()->refEventLoop(); - eventEmitter.m_hasIPCRef = true; - } - } else { - if (eventEmitter.listenerCount(eventName) == 0 && eventEmitter.m_hasIPCRef) { - eventEmitter.scriptExecutionContext()->unrefEventLoop(); - } - } - return; - } - - loadSignalNumberMap(); - - static std::once_flag signalNumberToNameMapOnceFlag; - std::call_once(signalNumberToNameMapOnceFlag, [] { - signalNumberToNameMap = new HashMap(); - signalNumberToNameMap->reserveInitialCapacity(31); - signalNumberToNameMap->add(SIGHUP, signalNames[0]); - signalNumberToNameMap->add(SIGINT, signalNames[1]); - signalNumberToNameMap->add(SIGQUIT, signalNames[2]); - signalNumberToNameMap->add(SIGILL, signalNames[3]); - signalNumberToNameMap->add(SIGTRAP, signalNames[4]); - signalNumberToNameMap->add(SIGABRT, signalNames[5]); - signalNumberToNameMap->add(SIGIOT, signalNames[6]); - signalNumberToNameMap->add(SIGBUS, signalNames[7]); - signalNumberToNameMap->add(SIGFPE, signalNames[8]); - signalNumberToNameMap->add(SIGKILL, signalNames[9]); - signalNumberToNameMap->add(SIGUSR1, signalNames[10]); - signalNumberToNameMap->add(SIGSEGV, signalNames[11]); - signalNumberToNameMap->add(SIGUSR2, signalNames[12]); - signalNumberToNameMap->add(SIGPIPE, signalNames[13]); - signalNumberToNameMap->add(SIGALRM, signalNames[14]); - signalNumberToNameMap->add(SIGTERM, signalNames[15]); - signalNumberToNameMap->add(SIGCHLD, signalNames[16]); - signalNumberToNameMap->add(SIGCONT, signalNames[17]); - signalNumberToNameMap->add(SIGSTOP, signalNames[18]); - signalNumberToNameMap->add(SIGTSTP, signalNames[19]); - signalNumberToNameMap->add(SIGTTIN, signalNames[20]); - signalNumberToNameMap->add(SIGTTOU, signalNames[21]); - signalNumberToNameMap->add(SIGURG, signalNames[22]); - signalNumberToNameMap->add(SIGXCPU, signalNames[23]); - signalNumberToNameMap->add(SIGXFSZ, signalNames[24]); - signalNumberToNameMap->add(SIGVTALRM, signalNames[25]); - signalNumberToNameMap->add(SIGPROF, signalNames[26]); - signalNumberToNameMap->add(SIGWINCH, signalNames[27]); - signalNumberToNameMap->add(SIGIO, signalNames[28]); -#ifdef SIGINFO - signalNumberToNameMap->add(SIGINFO, signalNames[29]); -#endif - signalNumberToNameMap->add(SIGSYS, signalNames[30]); - }); - - if (!signalToContextIdsMap) { - signalToContextIdsMap = new HashMap>(); - } - - if (auto signalNumber = signalNameToNumberMap->get(eventName.string())) { - if (signalNumber != SIGKILL && signalNumber != SIGSTOP) { - uint32_t contextId = eventEmitter.scriptExecutionContext()->identifier(); - Locker lock { signalToContextIdsMapLock }; - + if (eventEmitter.scriptExecutionContext()->isMainThread()) { + // IPC handlers + if (eventName.string() == "message"_s) { if (isAdded) { - if (!signalToContextIdsMap->contains(signalNumber)) { - HashSet contextIds; - contextIds.add(contextId); - signalToContextIdsMap->set(signalNumber, contextIds); - - lock.unlockEarly(); - - struct sigaction action; - memset(&action, 0, sizeof(struct sigaction)); - - // Set the handler in the action struct - action.sa_handler = [](int signalNumber) { - if (UNLIKELY(signalNumberToNameMap->find(signalNumber) == signalNumberToNameMap->end())) - return; - - Locker lock { signalToContextIdsMapLock }; - if (UNLIKELY(signalToContextIdsMap->find(signalNumber) == signalToContextIdsMap->end())) - return; - auto contextIds = signalToContextIdsMap->get(signalNumber); - - for (int contextId : contextIds) { - auto* context = ScriptExecutionContext::getScriptExecutionContext(contextId); - if (UNLIKELY(!context)) - continue; - - JSGlobalObject* lexicalGlobalObject = context->jsGlobalObject(); - Zig::GlobalObject* globalObject = jsCast(lexicalGlobalObject); - - Process* process = jsCast(globalObject->processObject()); - - context->postCrossThreadTask(*process, &Process::emitSignalEvent, signalNumber); - } - }; - - // Clear the sa_mask - sigemptyset(&action.sa_mask); - sigaddset(&action.sa_mask, signalNumber); - action.sa_flags = SA_RESTART; - - sigaction(signalNumber, &action, nullptr); - } else { - auto contextIds = signalToContextIdsMap->get(signalNumber); - contextIds.add(contextId); - signalToContextIdsMap->set(signalNumber, contextIds); + if (Bun__GlobalObject__hasIPC(eventEmitter.scriptExecutionContext()->jsGlobalObject()) + && eventEmitter.listenerCount(eventName) == 1) { + eventEmitter.scriptExecutionContext()->refEventLoop(); + eventEmitter.m_hasIPCRef = true; } } else { - if (signalToContextIdsMap->find(signalNumber) != signalToContextIdsMap->end()) { - HashSet contextIds = signalToContextIdsMap->get(signalNumber); - contextIds.remove(contextId); - if (contextIds.isEmpty()) { + if (eventEmitter.listenerCount(eventName) == 0 && eventEmitter.m_hasIPCRef) { + eventEmitter.scriptExecutionContext()->unrefEventLoop(); + } + } + return; + } + + // Signal Handlers + loadSignalNumberMap(); + static std::once_flag signalNumberToNameMapOnceFlag; + std::call_once(signalNumberToNameMapOnceFlag, [] { + signalNumberToNameMap = new HashMap(); + signalNumberToNameMap->reserveInitialCapacity(31); + signalNumberToNameMap->add(SIGHUP, signalNames[0]); + signalNumberToNameMap->add(SIGINT, signalNames[1]); + signalNumberToNameMap->add(SIGQUIT, signalNames[2]); + signalNumberToNameMap->add(SIGILL, signalNames[3]); +#ifdef SIGTRAP + signalNumberToNameMap->add(SIGTRAP, signalNames[4]); +#endif + signalNumberToNameMap->add(SIGABRT, signalNames[5]); +#ifdef SIGIOT + signalNumberToNameMap->add(SIGIOT, signalNames[6]); +#endif +#ifdef SIGBUS + signalNumberToNameMap->add(SIGBUS, signalNames[7]); +#endif + signalNumberToNameMap->add(SIGFPE, signalNames[8]); + signalNumberToNameMap->add(SIGKILL, signalNames[9]); +#ifdef SIGUSR1 + signalNumberToNameMap->add(SIGUSR1, signalNames[10]); +#endif + signalNumberToNameMap->add(SIGSEGV, signalNames[11]); +#ifdef SIGUSR2 + signalNumberToNameMap->add(SIGUSR2, signalNames[12]); +#endif +#ifdef SIGPIPE + signalNumberToNameMap->add(SIGPIPE, signalNames[13]); +#endif +#ifdef SIGALRM + signalNumberToNameMap->add(SIGALRM, signalNames[14]); +#endif + signalNumberToNameMap->add(SIGTERM, signalNames[15]); +#ifdef SIGCHLD + signalNumberToNameMap->add(SIGCHLD, signalNames[16]); +#endif +#ifdef SIGCONT + signalNumberToNameMap->add(SIGCONT, signalNames[17]); +#endif +#ifdef SIGSTOP + signalNumberToNameMap->add(SIGSTOP, signalNames[18]); +#endif +#ifdef SIGTSTP + signalNumberToNameMap->add(SIGTSTP, signalNames[19]); +#endif +#ifdef SIGTTIN + signalNumberToNameMap->add(SIGTTIN, signalNames[20]); +#endif +#ifdef SIGTTOU + signalNumberToNameMap->add(SIGTTOU, signalNames[21]); +#endif +#ifdef SIGURG + signalNumberToNameMap->add(SIGURG, signalNames[22]); +#endif +#ifdef SIGXCPU + signalNumberToNameMap->add(SIGXCPU, signalNames[23]); +#endif +#ifdef SIGXFSZ + signalNumberToNameMap->add(SIGXFSZ, signalNames[24]); +#endif +#ifdef SIGVTALRM + signalNumberToNameMap->add(SIGVTALRM, signalNames[25]); +#endif +#ifdef SIGPROF + signalNumberToNameMap->add(SIGPROF, signalNames[26]); +#endif + signalNumberToNameMap->add(SIGWINCH, signalNames[27]); +#ifdef SIGIO + signalNumberToNameMap->add(SIGIO, signalNames[28]); +#endif +#ifdef SIGINFO + signalNumberToNameMap->add(SIGINFO, signalNames[29]); +#endif +#ifdef SIGSYS + signalNumberToNameMap->add(SIGSYS, signalNames[30]); +#endif + }); + + if (!signalToContextIdsMap) { + signalToContextIdsMap = new HashMap(); + } + + if (auto signalNumber = signalNameToNumberMap->get(eventName.string())) { +#if !OS(WINDOWS) + if (signalNumber != SIGKILL && signalNumber != SIGSTOP) { +#else + if (signalNumber != SIGKILL) { // windows has no SIGSTOP +#endif + uint32_t contextId = eventEmitter.scriptExecutionContext()->identifier(); + + if (isAdded) { + if (!signalToContextIdsMap->contains(signalNumber)) { + SignalHandleValue signal_handle = { +#if OS(WINDOWS) + .handle = nullptr, +#endif + }; +#if !OS(WINDOWS) + struct sigaction action; + memset(&action, 0, sizeof(struct sigaction)); + + // Set the handler in the action struct + action.sa_handler = signalHandler; + + // Clear the sa_mask + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, signalNumber); + action.sa_flags = SA_RESTART; + + sigaction(signalNumber, &action, nullptr); +#else + signal_handle.handle = Bun__UVSignalHandle__init( + eventEmitter.scriptExecutionContext()->jsGlobalObject(), + signalNumber, + &signalHandler); + + if (UNLIKELY(!signal_handle.handle)) + return; +#endif + + signalToContextIdsMap->set(signalNumber, signal_handle); + } + } else { + if (signalToContextIdsMap->find(signalNumber) != signalToContextIdsMap->end()) { + SignalHandleValue signal_handle = signalToContextIdsMap->get(signalNumber); +#if !OS(WINDOWS) signal(signalNumber, SIG_DFL); +#else + Bun__UVSignalHandle__close(signal_handle.handle); +#endif signalToContextIdsMap->remove(signalNumber); - } else { - signalToContextIdsMap->set(signalNumber, contextIds); } } } } } } -#endif - -void Process::emitSignalEvent(int signalNumber) -{ -#if !OS(WINDOWS) - - String signalName = signalNumberToNameMap->get(signalNumber); - Identifier signalNameIdentifier = Identifier::fromString(vm(), signalName); - MarkedArgumentBuffer args; - args.append(jsNumber(signalNumber)); - wrapped().emitForBindings(signalNameIdentifier, args); -#else - UNUSED_PARAM(signalNumber); -#endif -} Process::~Process() { @@ -786,7 +884,6 @@ Process::~Process() JSC_DEFINE_HOST_FUNCTION(Process_functionAbort, (JSGlobalObject * globalObject, CallFrame*)) { abort(); - __builtin_unreachable(); } JSC_DEFINE_HOST_FUNCTION(Process_emitWarning, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) @@ -2633,9 +2730,7 @@ void Process::finishCreation(JSC::VM& vm) { Base::finishCreation(vm); -#ifndef WIN32 wrapped().onDidChangeListener = &onDidChangeListeners; -#endif m_cpuUsageStructure.initLater([](const JSC::LazyProperty::Initializer& init) { init.set(constructCPUUsageStructure(init.vm, init.owner->globalObject())); diff --git a/src/bun.js/bindings/BunProcess.h b/src/bun.js/bindings/BunProcess.h index 1615aabdd3..160827fdf0 100644 --- a/src/bun.js/bindings/BunProcess.h +++ b/src/bun.js/bindings/BunProcess.h @@ -27,8 +27,6 @@ public: { } - void emitSignalEvent(int signalNumber); - DECLARE_EXPORT_INFO; static void destroy(JSC::JSCell* cell) diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp index 61dd76e710..3259649c87 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.cpp +++ b/src/bun.js/bindings/ScriptExecutionContext.cpp @@ -154,8 +154,7 @@ bool ScriptExecutionContext::ensureOnContextThread(ScriptExecutionContextIdentif bool ScriptExecutionContext::ensureOnMainThread(Function&& task) { - Locker locker { allScriptExecutionContextsMapLock }; - auto* context = allScriptExecutionContextsMap().get(1); + auto* context = ScriptExecutionContext::getMainThreadScriptExecutionContext(); if (!context) { return false; @@ -165,6 +164,12 @@ bool ScriptExecutionContext::ensureOnMainThread(Function&& completionHandler) { ASSERT(isContextThread()); diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h index 9dc70bfd74..cc94ecae77 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.h +++ b/src/bun.js/bindings/ScriptExecutionContext.h @@ -217,6 +217,8 @@ public: BunBroadcastChannelRegistry& broadcastChannelRegistry() { return m_broadcastChannelRegistry; } + static ScriptExecutionContext* getMainThreadScriptExecutionContext(); + private: JSC::VM* m_vm = nullptr; JSC::JSGlobalObject* m_globalObject = nullptr; diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 4898602324..393df8ba00 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -4450,6 +4450,15 @@ void JSC__JSValue__getClassName(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1 *arg2 = Zig::toZigString(view); } +bool JSC__JSValue__getClassInfoName(JSValue value, BunString* out) +{ + if (auto info = value.classInfoOrNull()) { + *out = Bun::toString(info->className); + return true; + } + return false; +} + void JSC__JSValue__getNameProperty(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, ZigString* arg2) { JSC::JSObject* obj = JSC::JSValue::decode(JSValue0).getObject(); diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 47c5594763..2069325d18 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -5322,6 +5322,20 @@ pub const JSValue = enum(JSValueReprInt) { pub fn getProxyInternalField(this: JSValue, field: ProxyInternalField) JSValue { return Bun__ProxyObject__getInternalField(this, field); } + + extern fn JSC__JSValue__getClassInfoName(value: JSValue, out: *bun.String) bool; + + /// Returned memory is read-only memory of the s_info assigned to a JSCell + pub fn getClassInfoName(this: JSValue) ?[]const u8 { + var out: bun.String = undefined; + if (!JSC__JSValue__getClassInfoName(this, &out)) return null; + // we assume the class name is ASCII text + const data = out.latin1(); + if (bun.Environment.allow_assert) { + std.debug.assert(bun.strings.isAllASCII(data)); + } + return data; + } }; extern "c" fn AsyncContextFrame__withAsyncContextIfNeeded(global: *JSGlobalObject, callback: JSValue) JSValue; diff --git a/src/bun.js/bindings/c-bindings.cpp b/src/bun.js/bindings/c-bindings.cpp index 27eb3cb350..c16f67a34c 100644 --- a/src/bun.js/bindings/c-bindings.cpp +++ b/src/bun.js/bindings/c-bindings.cpp @@ -32,11 +32,7 @@ extern "C" void bun_warn_avx_missing(const char* url) strcpy(buf + len + strlen(url), "\n\0"); write(STDERR_FILENO, buf, strlen(buf)); } -#else -extern "C" void bun_warn_avx_missing(char* url) -{ -} -#endif // CPU(X86_64) +#endif extern "C" int32_t get_process_priority(uint32_t pid) { @@ -59,12 +55,9 @@ extern "C" int32_t set_process_priority(uint32_t pid, int32_t priority) #endif // OS(WINDOWS) } +#if !OS(WINDOWS) extern "C" bool is_executable_file(const char* path) { -#if OS(WINDOWS) - return false; -#else - #if defined(O_EXEC) // O_EXEC is macOS specific int fd = open(path, O_EXEC | O_CLOEXEC, 0); @@ -80,8 +73,8 @@ extern "C" bool is_executable_file(const char* path) // regular file and user can execute return S_ISREG(st.st_mode) && (st.st_mode & S_IXUSR); -#endif // OS(WINDOWS) } +#endif extern "C" void bun_ignore_sigpipe() { diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index dc7d0cf3b0..424bab6363 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -636,7 +636,7 @@ comptime { pub const DeferredRepeatingTask = *const (fn (*anyopaque) bool); pub const EventLoop = struct { - tasks: if (JSC.is_bindgen) void else Queue = undefined, + tasks: Queue = undefined, /// setImmediate() gets it's own two task queues /// When you call `setImmediate` in JS, it queues to the start of the next tick diff --git a/src/bun.zig b/src/bun.zig index dfa870098e..2a23afb166 100644 --- a/src/bun.zig +++ b/src/bun.zig @@ -176,7 +176,7 @@ pub const RefCount = @import("./ref_count.zig").RefCount; pub const MAX_PATH_BYTES: usize = if (Environment.isWasm) 1024 else std.fs.MAX_PATH_BYTES; pub const PathBuffer = [MAX_PATH_BYTES]u8; -pub const WPathBuffer = [windows.PATH_MAX_WIDE]u16; +pub const WPathBuffer = [std.os.windows.PATH_MAX_WIDE]u16; pub const OSPathChar = if (Environment.isWindows) u16 else u8; pub const OSPathSliceZ = [:0]const OSPathChar; pub const OSPathSlice = []const OSPathChar; @@ -2413,7 +2413,7 @@ pub const HeapBreakdown = if (is_heap_breakdown_enabled) @import("./heap_breakdo /// Globally-allocate a value on the heap. /// -/// When used, yuo must call `bun.destroy` to free the memory. +/// When used, you must call `bun.destroy` to free the memory. /// default_allocator.destroy should not be used. /// /// On macOS, you can use `Bun.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump()` diff --git a/src/deps/libuv.zig b/src/deps/libuv.zig index c07b7f6ea0..2c616353bc 100644 --- a/src/deps/libuv.zig +++ b/src/deps/libuv.zig @@ -1410,7 +1410,7 @@ const union_unnamed_433 = extern union { reserved: [4]?*anyopaque, }; pub const uv_signal_t = struct_uv_signal_s; -pub const uv_signal_cb = ?*const fn ([*c]uv_signal_t, c_int) callconv(.C) void; +pub const uv_signal_cb = ?*const fn (*uv_signal_t, c_int) callconv(.C) void; const struct_unnamed_434 = extern struct { rbe_left: [*c]struct_uv_signal_s, rbe_right: [*c]struct_uv_signal_s, @@ -2203,10 +2203,10 @@ pub extern fn uv_fs_poll_init(loop: *uv_loop_t, handle: *uv_fs_poll_t) c_int; pub extern fn uv_fs_poll_start(handle: *uv_fs_poll_t, poll_cb: uv_fs_poll_cb, path: [*:0]const u8, interval: c_uint) c_int; pub extern fn uv_fs_poll_stop(handle: *uv_fs_poll_t) c_int; pub extern fn uv_fs_poll_getpath(handle: *uv_fs_poll_t, buffer: [*]u8, size: [*c]usize) c_int; -pub extern fn uv_signal_init(loop: *uv_loop_t, handle: *uv_signal_t) c_int; -pub extern fn uv_signal_start(handle: *uv_signal_t, signal_cb: uv_signal_cb, signum: c_int) c_int; -pub extern fn uv_signal_start_oneshot(handle: *uv_signal_t, signal_cb: uv_signal_cb, signum: c_int) c_int; -pub extern fn uv_signal_stop(handle: *uv_signal_t) c_int; +pub extern fn uv_signal_init(loop: *uv_loop_t, handle: *uv_signal_t) ReturnCode; +pub extern fn uv_signal_start(handle: *uv_signal_t, signal_cb: uv_signal_cb, signum: c_int) ReturnCode; +pub extern fn uv_signal_start_oneshot(handle: *uv_signal_t, signal_cb: uv_signal_cb, signum: c_int) ReturnCode; +pub extern fn uv_signal_stop(handle: *uv_signal_t) ReturnCode; pub extern fn uv_loadavg(avg: [*c]f64) void; pub const UV_FS_EVENT_WATCH_ENTRY: c_int = 1; pub const UV_FS_EVENT_STAT: c_int = 2; @@ -2414,13 +2414,14 @@ pub const ReturnCode = enum(c_int) { if (this.errEnum()) |err| { try writer.writeAll(@tagName(err)); } else { - try writer.print("{d}", .{this.value}); + try writer.print("{d}", .{this}); } } pub inline fn int(this: ReturnCode) c_int { return @intFromEnum(this); } + pub inline fn errno(this: ReturnCode) ?@TypeOf(@intFromEnum(bun.C.E.ACCES)) { return if (this.int() < 0) switch (this.int()) { diff --git a/src/js_ast.zig b/src/js_ast.zig index c536410cce..93e532a144 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -7049,8 +7049,8 @@ pub const Macro = struct { this.source, this.caller.loc, this.allocator, - "cannot coerce {s} to Bun's AST. Please return a simpler type", - .{@tagName(value.jsType())}, + "cannot coerce {s} ({s}) to Bun's AST. Please return a simpler type", + .{ value.getClassInfoName() orelse "unknown", @tagName(value.jsType()) }, ) catch unreachable; break :brk error.MacroFailed; }, diff --git a/src/main.zig b/src/main.zig index d6a41e68ea..625b542fc5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -70,7 +70,7 @@ pub fn main() void { Output.Source.set(&output_source); defer Output.flush(); - if (Environment.isX64 and Environment.enableSIMD) { + if (Environment.isX64 and Environment.enableSIMD and Environment.isPosix) { bun_warn_avx_missing(@import("./cli/upgrade_command.zig").Version.Bun__githubBaselineURL.ptr); } diff --git a/src/string.zig b/src/string.zig index 0cea9d4643..c9017bbd01 100644 --- a/src/string.zig +++ b/src/string.zig @@ -733,8 +733,10 @@ pub const String = extern struct { } pub inline fn utf8(self: String) []const u8 { - if (comptime bun.Environment.allow_assert) + if (comptime bun.Environment.allow_assert) { + std.debug.assert(self.tag == .ZigString or self.tag == .StaticZigString); std.debug.assert(self.canBeUTF8()); + } return self.value.ZigString.slice(); } diff --git a/src/sys.zig b/src/sys.zig index 5198430bd9..3e268c9b10 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -936,8 +936,6 @@ pub fn openatOSPath(dirfd: bun.FileDescriptor, file_path: bun.OSPathSliceZ, flag }, }; } - - unreachable; } pub fn openat(dirfd: bun.FileDescriptor, file_path: [:0]const u8, flags: bun.Mode, perm: bun.Mode) Maybe(bun.FileDescriptor) { diff --git a/src/windows.zig b/src/windows.zig index b605f37234..8c97645c87 100644 --- a/src/windows.zig +++ b/src/windows.zig @@ -3139,3 +3139,43 @@ pub const INPUT_RECORD = extern struct { FocusEvent: FOCUS_EVENT_RECORD, }, }; + +fn Bun__UVSignalHandle__init( + global: *bun.JSC.JSGlobalObject, + signal_num: i32, + callback: *const fn (sig: *libuv.uv_signal_t, num: c_int) callconv(.C) void, +) callconv(.C) ?*libuv.uv_signal_t { + const signal = bun.new(libuv.uv_signal_t, undefined); + + var rc = libuv.uv_signal_init(global.bunVM().uvLoop(), signal); + if (rc.errno()) |_| { + bun.destroy(signal); + return null; + } + + rc = libuv.uv_signal_start(signal, callback, signal_num); + if (rc.errno()) |_| { + libuv.uv_close(@ptrCast(signal), &freeWithDefaultAllocator); + return null; + } + + libuv.uv_unref(@ptrCast(signal)); + + return signal; +} + +fn freeWithDefaultAllocator(signal: *anyopaque) callconv(.C) void { + bun.destroy(@as(*libuv.uv_signal_t, @alignCast(@ptrCast(signal)))); +} + +fn Bun__UVSignalHandle__close(signal: *libuv.uv_signal_t) callconv(.C) void { + _ = libuv.uv_signal_stop(signal); + libuv.uv_close(@ptrCast(signal), &freeWithDefaultAllocator); +} + +comptime { + if (Environment.isWindows) { + @export(Bun__UVSignalHandle__init, .{ .name = "Bun__UVSignalHandle__init" }); + @export(Bun__UVSignalHandle__close, .{ .name = "Bun__UVSignalHandle__close" }); + } +}