diff --git a/scripts/build/buildOptionsRs.ts b/scripts/build/buildOptionsRs.ts index 2768f71bf0ea..70ab863a4101 100644 --- a/scripts/build/buildOptionsRs.ts +++ b/scripts/build/buildOptionsRs.ts @@ -68,7 +68,6 @@ export function generateBuildOptionsRs(cfg: Config): string { "pub const ENABLE_LOGS: bool = cfg!(bun_debug);", "pub const ENABLE_ASAN: bool = cfg!(bun_asan);", "pub const ENABLE_TINYCC: bool = !cfg!(any(", - ` all(windows, target_arch = "aarch64"),`, ` target_os = "android",`, ` target_os = "freebsd",`, "));", diff --git a/scripts/build/config.ts b/scripts/build/config.ts index 20b5a2382771..237bd8fdcc4c 100644 --- a/scripts/build/config.ts +++ b/scripts/build/config.ts @@ -863,10 +863,9 @@ export function resolveConfig(partial: PartialConfig, toolchain: Toolchain): Con // failure is loud ("cannot find -l:libatomic.a") and the fix is obvious. const staticLibatomic = partial.staticLibatomic ?? true; - // TinyCC: off on Windows ARM64 (not supported), Android (no upstream - // bionic support; FFI cc() falls back to dlopen-only), and FreeBSD - // (oven-sh/tinycc has no FreeBSD target). - const tinycc = partial.tinycc ?? !((windows && arm64) || abi === "android" || freebsd); + // TinyCC: off on Android (no upstream bionic support; FFI cc() falls back + // to dlopen-only) and FreeBSD (oven-sh/tinycc has no FreeBSD target). + const tinycc = partial.tinycc ?? !(abi === "android" || freebsd); const valgrind = partial.valgrind ?? false; const fuzzilli = partial.fuzzilli ?? false; diff --git a/scripts/build/deps/tinycc.ts b/scripts/build/deps/tinycc.ts index 499a83bc16df..83a38725af51 100644 --- a/scripts/build/deps/tinycc.ts +++ b/scripts/build/deps/tinycc.ts @@ -2,8 +2,6 @@ * TinyCC — small embeddable C compiler. Powers bun:ffi's JIT-compile path, * where user-provided C gets compiled and linked at runtime. * - * Disabled on windows-arm64 (tinycc doesn't have an arm64-coff backend). - * * Built via DirectBuild — no cmake sub-process. The old overlay * CMakeLists.txt had two recurring ASAN workarounds for the c2str host * tool (Linux ASLR/shadow-map, macOS 26.4 dyld deadlock); DirectBuild's @@ -12,14 +10,12 @@ import type { Dependency, DirectBuild } from "../source.ts"; -const TINYCC_COMMIT = "12882eee073cfe5c7621bcfadf679e1372d4537b"; +const TINYCC_COMMIT = "c49c2204b07c526c9ad935fabfcaf3802cae1346"; export const tinycc: Dependency = { name: "tinycc", versionMacro: "TINYCC", - // The cfg.tinycc flag already encodes the windows-arm64 exclusion - // (see config.ts: `tinycc ?? !(windows && arm64)`). enabled: cfg => cfg.tinycc, source: () => ({ diff --git a/scripts/build/source.ts b/scripts/build/source.ts index 92fc48cfac75..4685f7054079 100644 --- a/scripts/build/source.ts +++ b/scripts/build/source.ts @@ -446,7 +446,7 @@ export interface Dependency { /** * Whether this dep participates in the build at all. Defaults to always-on. - * E.g. libuv is windows-only, tinycc is disabled on windows-arm64. + * E.g. libuv is windows-only. */ enabled?: (cfg: Config) => boolean; diff --git a/src/tcc_sys/tcc.rs b/src/tcc_sys/tcc.rs index 8d2337567850..7df0904854fe 100644 --- a/src/tcc_sys/tcc.rs +++ b/src/tcc_sys/tcc.rs @@ -12,9 +12,8 @@ pub type TCCErrorFunc = Option = unsafe extern "C" fn(ctx: *mut Ctx, msg: *const c_char); // `libtcc.a` is only built where `cfg.tinycc` is true (`scripts/build/config.ts`): -// not Windows/aarch64 (TinyCC has no aarch64-pe-coff backend), not Android, not -// FreeBSD (the vendored fork doesn't support those targets). On those platforms -// these `extern "C"` decls would be undefined at link: +// not Android, not FreeBSD (the vendored fork doesn't support those targets). +// On those platforms these `extern "C"` decls would be undefined at link: // `bun_runtime::ffi::ffi_body::{Source::add, // CompileC::compile}` are reachable from `extern "C"` JS bindings and the // monomorphized refs land in `libbun_rust.a` regardless of any @@ -27,12 +26,12 @@ pub type ErrorFunc = unsafe extern "C" fn(ctx: *mut Ctx, msg: *const c_char // Keep this predicate in sync with `cfg.tinycc` in `scripts/build/config.ts`. macro_rules! tcc_externs { ($($(#[$attr:meta])* fn $name:ident($($arg:ident: $ty:ty),* $(,)?) $(-> $ret:ty)?;)*) => { - #[cfg(not(any(target_os = "android", target_os = "freebsd", all(windows, target_arch = "aarch64"))))] + #[cfg(not(any(target_os = "android", target_os = "freebsd")))] unsafe extern "C" { $($(#[$attr])* fn $name($($arg: $ty),*) $(-> $ret)?;)* } $( - #[cfg(any(target_os = "android", target_os = "freebsd", all(windows, target_arch = "aarch64")))] + #[cfg(any(target_os = "android", target_os = "freebsd"))] #[allow(unused_variables, clippy::missing_safety_doc)] unsafe extern "C" fn $name($($arg: $ty),*) $(-> $ret)? { unreachable!(concat!( diff --git a/test/js/bun/ffi/cc.test.ts b/test/js/bun/ffi/cc.test.ts index 15b959aa9c18..4c1c9922014b 100644 --- a/test/js/bun/ffi/cc.test.ts +++ b/test/js/bun/ffi/cc.test.ts @@ -1,16 +1,13 @@ import { cc, CString, JSCallback, ptr, type FFIFunction, type Library } from "bun:ffi"; import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { promises as fs } from "fs"; -import { bunEnv, bunExe, isArm64, isASAN, isWindows, normalizeBunSnapshot, tempDir, tempDirWithFiles } from "harness"; +import { bunEnv, bunExe, isASAN, isWindows, normalizeBunSnapshot, tempDir, tempDirWithFiles } from "harness"; import path from "path"; -// TinyCC (and all of bun:ffi) is disabled on Windows ARM64 -const isFFIUnavailable = isWindows && isArm64; - // TODO: we need to install build-essential and Apple SDK in CI. // It can't find includes. It can on machines with that enabled. // TinyCC's setjmp/longjmp error handling conflicts with ASan. -it.todoIf(isWindows || isASAN || isFFIUnavailable)("can run a .c file", () => { +it.todoIf(isWindows || isASAN)("can run a .c file", () => { const result = Bun.spawnSync({ cmd: [bunExe(), path.join(__dirname, "cc-fixture.js")], cwd: __dirname, @@ -22,8 +19,7 @@ it.todoIf(isWindows || isASAN || isFFIUnavailable)("can run a .c file", () => { }); // TinyCC's setjmp/longjmp error handling conflicts with ASan. -// TinyCC is disabled on Windows ARM64. -describe.skipIf(isASAN || isFFIUnavailable)("given an add(a, b) function", () => { +describe.skipIf(isASAN)("given an add(a, b) function", () => { const source = /* c */ ` int add(int a, int b) { return a + b; @@ -391,7 +387,7 @@ describe.skipIf(isWindows || isASAN)("threadsafe JSCallback invoked from a forei // Pins GC liveness: compiled trampolines survive the library wrapper being // collected, and a JSCallback's closure stays alive until close(). // TinyCC's setjmp/longjmp error handling conflicts with ASan. -describe.skipIf(isASAN || isFFIUnavailable)("GC liveness of compiled symbols and callbacks", () => { +describe.skipIf(isASAN)("GC liveness of compiled symbols and callbacks", () => { it("keeps symbol functions and callback closures alive across forced GC", async () => { using dir = tempDir("bun-ffi-cc-gc-liveness", { "lib.c": /* c */ ` @@ -457,7 +453,7 @@ describe.skipIf(isASAN || isFFIUnavailable)("GC liveness of compiled symbols and }); }); -describe.skipIf(isFFIUnavailable)("double <-> JSValue conversions", () => { +describe("double <-> JSValue conversions", () => { // JSC NaN-boxes doubles, so a NaN whose payload collides with the tag space // ("impure NaN", see JSC's PureNaN.h) must never be encoded as-is: it would // decode as a native-chosen JSValue (true, undefined, an Int32, or a cell diff --git a/test/js/bun/ffi/ffi-error-messages.test.ts b/test/js/bun/ffi/ffi-error-messages.test.ts index 70dae5e2a7c9..23cf35c76454 100644 --- a/test/js/bun/ffi/ffi-error-messages.test.ts +++ b/test/js/bun/ffi/ffi-error-messages.test.ts @@ -1,11 +1,8 @@ import { dlopen, linkSymbols } from "bun:ffi"; import { describe, expect, test } from "bun:test"; -import { isArm64, isMusl, isWindows } from "harness"; +import { isMusl } from "harness"; -// TinyCC (and all of bun:ffi) is disabled on Windows ARM64 -const isFFIUnavailable = isWindows && isArm64; - -describe.skipIf(isFFIUnavailable)("FFI error messages", () => { +describe("FFI error messages", () => { test("dlopen shows library name when library cannot be opened", () => { // Try to open a non-existent library try { diff --git a/test/js/bun/ffi/ffi-viewSource-non-object.test.ts b/test/js/bun/ffi/ffi-viewSource-non-object.test.ts index a875ab7e3499..8a37a2d0094d 100644 --- a/test/js/bun/ffi/ffi-viewSource-non-object.test.ts +++ b/test/js/bun/ffi/ffi-viewSource-non-object.test.ts @@ -1,9 +1,6 @@ import { describe, expect, test } from "bun:test"; -import { isArm64, isWindows } from "harness"; -const isFFIUnavailable = isWindows && isArm64; - -describe.skipIf(isFFIUnavailable)("FFI viewSource", () => { +describe("FFI viewSource", () => { test("rejects non-object symbol descriptor values", () => { // These should throw a TypeError because each symbol descriptor // must be an object like { args: [...], returns: "void" }. diff --git a/test/js/bun/ffi/ffi.test.js b/test/js/bun/ffi/ffi.test.js index 1a66bae5d943..9025a2c68a73 100644 --- a/test/js/bun/ffi/ffi.test.js +++ b/test/js/bun/ffi/ffi.test.js @@ -1,6 +1,6 @@ import { afterAll, describe, expect, it } from "bun:test"; import { existsSync } from "fs"; -import { bunEnv, bunExe, isArm64, isGlibcVersionAtLeast, isWindows, tempDir } from "harness"; +import { bunEnv, bunExe, isGlibcVersionAtLeast, tempDir } from "harness"; import { platform } from "os"; import { @@ -677,12 +677,9 @@ it(".ptr is not leaked", () => { } }); -// TinyCC, which implements JSCallback and CFunction, is unavailable on Windows ARM64. -const isFFIUnavailable = isWindows && isArm64; - // Runs in a subprocess: `bun test`'s exit path does not finalize the CFunction's native handle, // which the ASan lane's leak checker then reports against this file. -it.skipIf(isFFIUnavailable)("JSCallback exceptions propagate out of the native call", async () => { +it("JSCallback exceptions propagate out of the native call", async () => { await using proc = Bun.spawn({ cmd: [ bunExe(), @@ -719,7 +716,7 @@ it.skipIf(isFFIUnavailable)("JSCallback exceptions propagate out of the native c // worker.terminate() delivered inside a threadsafe JSCallback used to trip // "ASSERTION FAILED: !isTerminationException(exception) || hasTerminationRequest()" // in JSC::VM::setException on the worker thread and re-enter the terminated VM. -it.skipIf(isFFIUnavailable)("JSCallback tolerates worker.terminate() arriving inside the callback", async () => { +it("JSCallback tolerates worker.terminate() arriving inside the callback", async () => { using dir = tempDir("ffi-jscallback-terminate", { "main.js": ` import { join } from "node:path"; diff --git a/test/js/node/fs/cp.test.ts b/test/js/node/fs/cp.test.ts index d4e11c89a286..d554096a6cf4 100644 --- a/test/js/node/fs/cp.test.ts +++ b/test/js/node/fs/cp.test.ts @@ -1,6 +1,6 @@ import { describe, expect, jest, test } from "bun:test"; import fs from "fs"; -import { bunEnv, bunExe, isArm64, isLinux, isPosix, isWindows, tempDir, tempDirWithFiles } from "harness"; +import { bunEnv, bunExe, isLinux, isPosix, isWindows, tempDir, tempDirWithFiles } from "harness"; import { mkfifo } from "mkfifo"; import { isAbsolute, join } from "path"; @@ -434,8 +434,8 @@ test("cp with missing callback throws", () => { // source symlink to resolve its target via GetFinalPathNameByHandleW. Previously // that handle was never closed, leaking one OS handle per symlink copied. Over a // large tree (e.g. node_modules with junctions) this eventually exhausts the -// process handle table. bun:ffi (TinyCC) is unavailable on Windows arm64. -test.skipIf(!isWindows || isArm64)("cpSync over symlinks does not leak Windows handles", () => { +// process handle table. +test.skipIf(!isWindows)("cpSync over symlinks does not leak Windows handles", () => { const { dlopen } = require("bun:ffi"); const k32 = dlopen("kernel32.dll", { GetCurrentProcess: { args: [], returns: "ptr" }, diff --git a/test/js/node/fs/fs-writeSync-stdio-windows.test.ts b/test/js/node/fs/fs-writeSync-stdio-windows.test.ts index 8ec25e4fb867..5fd09ddf3e88 100644 --- a/test/js/node/fs/fs-writeSync-stdio-windows.test.ts +++ b/test/js/node/fs/fs-writeSync-stdio-windows.test.ts @@ -8,14 +8,11 @@ // Now `fromJS`/`fromJSValidated` return `.fromUV(0|1|2)` directly, and // `FD.uv()` checks the cached stdio handles before `GetStdHandle`. import { describe, expect, test } from "bun:test"; -import { bunEnv, bunExe, isArm64, isWindows, tempDir } from "harness"; +import { bunEnv, bunExe, isWindows, tempDir } from "harness"; import { join } from "node:path"; describe.concurrent.skipIf(!isWindows)("fs.writeSync on Windows stdio/handles", () => { - // bun:ffi (TinyCC) is unavailable on Windows arm64, so this repro can only - // run on x64. The second test below covers the plain openSync→writeSync path - // on all Windows arches. - test.skipIf(isArm64)("fs.writeSync(1, ...) does not panic after SetStdHandle swaps stdout", async () => { + test("fs.writeSync(1, ...) does not panic after SetStdHandle swaps stdout", async () => { const fixture = ` const fs = require("node:fs"); const { dlopen } = require("bun:ffi"); diff --git a/test/js/node/process/process.test.js b/test/js/node/process/process.test.js index 05b8e1bc8dbb..91933d58201a 100644 --- a/test/js/node/process/process.test.js +++ b/test/js/node/process/process.test.js @@ -336,7 +336,7 @@ it("process.versions", () => { mimalloc: "afb41757285694f832e7a2f164d35f5717457f96", picohttpparser: "066d2b1e9ab820703db0837a7255d92d30f0c9f5", zlib: "12731092979c6d07f42da27da673a9f6c7b13586", - tinycc: "12882eee073cfe5c7621bcfadf679e1372d4537b", + tinycc: "c49c2204b07c526c9ad935fabfcaf3802cae1346", lolhtml: "77127cd2b8545998756e8d64e36ee2313c4bb312", ares: "3ac47ee46edd8ea40370222f91613fc16c434853", libdeflate: "c8c56a20f8f621e6a966b716b31f1dedab6a41e3", diff --git a/test/napi/napi-value-ffi.test.ts b/test/napi/napi-value-ffi.test.ts index 808d92f9aee8..323339580520 100644 --- a/test/napi/napi-value-ffi.test.ts +++ b/test/napi/napi-value-ffi.test.ts @@ -1,14 +1,13 @@ import { spawnSync } from "bun"; import { cc, dlopen } from "bun:ffi"; import { beforeAll, describe, expect, it } from "bun:test"; -import { bunEnv, bunExe, canBuildNodeAddons, isArm64, isASAN, isWindows } from "harness"; +import { bunEnv, bunExe, canBuildNodeAddons, isASAN, isWindows } from "harness"; import { join } from "path"; import source from "./napi-app/ffi_addon_1.c" with { type: "file" }; -// TinyCC (and all of bun:ffi) is disabled on Windows ARM64; the napi-app -// fixture needs a toolchain that can compile the reported Node headers. -const isFFIUnavailable = (isWindows && isArm64) || !canBuildNodeAddons(); +// The napi-app fixture needs a toolchain that can compile the Node headers. +const isFFIUnavailable = !canBuildNodeAddons(); const symbols = { set_instance_data: {