Repository navigation
Releases: funlang/fun
Releases · funlang/fun
Release list
v9.4.5 released
Fun 9.4.5 Manifest-driven packages and project-aware runs. Highlights since v9.4.4: - `fun package init/add/remove/tidy` manage a `package.fun` manifest, install exact git revisions into a shared `~/.fun` cache, verify git tree hashes, and record a generated `resolved` block. Path dependencies are used in place; only git dependencies need `git`. - `fun run [args...]` runs the manifest `bin` from the project root with its dependencies available. In a package directory, a plain `fun <script>` takes the same project-aware path, and `FUN_PACKAGE_READY=1` opts out. Runs stay read-only and refuse a missing or stale dependency. - `fun pack` now defaults to the manifest `bin`, resolves paths against the project root, and embeds resolved dependencies, so a bundle runs without `~/.fun`. - Bundled console apps keep their output when stdout is redirected, unless `-gui` is requested. - Packages are documented in both READMEs with a runnable `fun/demos/package-demo`, and covered by an end-to-end regression test. Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.4.4 released
Fun 9.4.4 Single-file bundling with `fun pack`, plus Netif() and a macOS DNS fix. Highlights since v9.4.3: - `fun pack <entry.fun>` bundles the interpreter, project files and declared resources into one executable. It extracts to a temp directory at startup and shifts script arguments so 2.arg() is the first real argument. Builds can omit it (-dFunPack) or emit a consumer-only runtime (FUNPACK=user). - Netif() enumerates IPv4 network interfaces on Linux and macOS. - macOS DNS lookup no longer loses resolver pointers above 4 GB. - Opt-in startup profiling via -dFunStartupTiming. - The interpreter no longer links Classes (~120 KiB smaller on Linux x86_64); generated assembler tables use .fd2 so hosts stop counting them as roff. Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.4.3 released
Fun 9.4.3 Variable declarations with initializers now reuse parse-time assignment specialization. Highlights since v9.4.2: - Variable declarations with an initializer now use the same parse-time assignment specialization as plain assignments. A var inside a loop resolves its slot once and reuses it instead of repeating the generic assign and scope-push chain. On the bundled Linux x86_64 build var d = i drops from ~57 to ~38 ns/iter, matching a plain assignment in the same scope. Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.4.2 released
Fun 9.4.2 Regex matching and variable assignment stop repeating work on every run. Highlights since v9.4.1: - Regex patterns are compiled once. Compiled PCRE code is shared through a small LRU cache keyed by pattern text and options, with reference counting so a lazy match object always keeps its code alive; each regex literal holds its own reference, so the hot path skips the cache lookup. A pattern used a second time is upgraded to PCRE's JIT engine, with the upgrade deferred so a one-shot toRegex() pays no JIT cost. - Global match/replace write into one growable buffer instead of splicing the subject once per match, turning the former O(n^2) replacement loop into a single pass. On the bundled Linux x86_64 build, 200 global replacements over a ~100 KB subject drop from ~7.3 s to ~0.24 s, repeated literal matching improves by ~1.4-1.5x, and a global match by ~3x. Literal replacements without $ or \ references skip the per-match replacement scan, making them another 25-40% faster. - Global replacement computes $_ (and the other subject references) from the original subject. The old in-place loop rewrote the subject between matches, so 'abcabc'.replace(/b/g, '[$_]') produced a[abcabc]ca[a[abcabc]cabc]c; it now yields a[abcabc]ca[abcabc]c. - Plain variable assignments are specialized at parse time. The first run resolves the target slot once; later runs read simple CId sources and write the scalar slot directly instead of repeating the virtual assign and scope push. On the bundled Linux x86_64 build, x = i drops from ~56 to ~38 ns/iter and a global gx = i from ~52 to ~33 ns/iter. Fields, indices, self-assignments and scope entries that still need a push keep the generic path. Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.4.1 released
Fun 9.4.1 Bug-fix release for 9.4.0. Highlights since v9.4.0: - Integer comparison no longer overflows int32. varComp and the CalcOpt fast paths for <, >, <=, >=, <> and = computed a - b before testing the sign; that difference overflowed int32 and reversed the result, so for example 2147483647 > -1 returned false. They now compare the operands directly. Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.4.0 released
Fun 9.4.0 Performance and hot-path release. Highlights since v9.3.4: - Scalar values stay out of the Variant RTL: comparison and logical operators write varBoolean directly, scalar assignment fast-paths Boolean/Double as well as Integer, and CCtwo no longer builds a temporary CValue while keeping recursive re-entry safe. - Integer div/mod gain guarded fast paths. Zero divisors and Low(Integer) div/mod -1 still fall through to the Variant RTL, preserving the existing exception behavior. On the shipped benchmark, 1>2 drops from about 193 to 130 ns/iteration, if 1>2 from about 166 to 130 ns, not 1>2 from about 343 to 196 ns, and 7 div 3 roughly halves. - Arithmetic fast paths are enabled on Linux x86_64; x/0 still raises on AArch64, and the CalcOpt fallback checks the divisor. - More hot-path trimming for compare, assignment, and string concat. - AArch64 assembler coverage: cmn, sp-relative access, imm12 boundary, and the bl label call. - The HTTP server/client stack and the variadic getapi mark are included; funcmd reports the missing script by name. - linux-arm64 snapshot and lib-asm-a64 test enabled; CI keeps the full diff in failure annotations. - New calc-fastpath regression covers Boolean results, scalar copies, and integer div/mod edge cases. Verified by the five-platform regression workflow: https://github.com/funlang/fun/actions/runs/39031232338 Full list: CHANGELOG.md / CHANGELOG.zh.md.
v9.3.4 released
The HTTP stack lands in the standard library. Highlights since v9.3.3: - lib/http-server: a single-threaded, platform-neutral HTTP server. Route patterns (literal / :name / * tail, 405 with Allow, 404 otherwise), route groups, global / group / per-route middleware, params and query strings, static files, json / text / html responses and an access logger; driven by its own poll loop (run) or one step at a time (runOnce). HTTP framing and keep-alive live in lib-winsock-base.fun; the Linux/macOS poll backend is wired, the Windows message-pump driver is still a follow-up. - lib/http-client: a one-call blocking client, HttpClient(args) -> [rc, code, message, headers, body], over the host's lib-ajax backend. - lib-ajax.fun (Windows) gains the same Http(args) helper as lib-ajax-unx, so HttpClient is one call on every platform: it forces the synchronous transfer, exposes the final response block as Ajax.headers (lowercased keys) and returns the same five-field result set. - getapi accepts a variadic: <n> mark (libffi ffi_prep_cif_var), required on Darwin arm64; curl_easy_setopt uses it, so the lib-ajax test runs on macOS. - funcmd names the file it cannot find (not found: <file>) instead of failing silently; lib-winsock renames HttpServer -> HttpServerBase (kept as Server.HTTP / Server.HTP), fixing the duplicated HTP assignment. See CHANGELOG.md / CHANGELOG.zh.md for the full list (the portability entries before the HTTP work are still under Unreleased).
v9.3.3 released
Windows joins the gate, and the last portability gaps close.
Highlights since v9.3.2:
- win64 has regex. PCRE 8.45 is built there with the runner's MinGW gcc into
pcre3.dll beside funcmd.exe and imported by name (-dPCRE_WinDLL), because
neither FPC linker can pull in the bcc32 or the MinGW PCRE objects. Two
engine fixes came with it: the __llmul stub is 32-bit only (win64 has no
System.__llmul), and PCRE memory returns through pcre_free_substring, since
the DLL allocates from its own CRT (FreeMem corrupted the heap after a
match). The 8 regex tests and the portability probe run on Windows now
instead of skipping.
- win64 has getapi. FPC's bundled ffi unit already targets WIN64, so -dWinFFI
(mapped onto the engine's existing UnixFFI symbol) selects the libffi-backed
lffi unit and CI copies ffi.dll from MSYS2 next to funcmd.exe; a bare
library name now falls back to name + '.dll'.
- The portable FFI suite runs on win64 and earned its keep: four of the five
cases use the shared snapshots, and the fifth found a real bug - kernel32
exports GetCommandLineA/W, so lffi.pas now retries name + 'A' for unsuffixed
Windows API names, as io.GetProc already did. windows-x64 is 55/55, 37
skipped.
- Windows-only engine divergences fixed ({$IfDef FPC} branches, Delphi sources
untouched by them): the ISO time literal parses directly instead of through
FPC's locale-dependent VarToDateTime; DefaultFormatSettings is pinned to the
Unix formats so date and number output is host-independent; stdout goes
through a new raw-byte WriteOut instead of the RTL text file, which
re-encoded every non-ASCII byte to the console codepage; and a named script
forces console mode, so a redirected run prints again (AttachConsole is
false without a parent console). Also: 0x literals stay 32-bit unsigned on
Win64, and the FPC-only divergences that broke the Windows build are gone.
- macOS: the lib-proc backend (libproc + mach VM) lands with its test enabled
(#14); lib-asm-a64 gains live JIT on arm64 (#13) and all b.cond condition
codes (#4); the lib-crypt-unx hashes go through CommonCrypto (#6).
- CI: every platform gates the build (windows-arm64 stays disabled, FPC 3.2.2
has no such target), the FPC toolchain is cached on all of them, and the
Windows runner reports regex/getapi availability as annotations.
- pcrd's dynamic branch (-dPCRE_LINKDLL) no longer breaks the Delphi build:
dynlibs is FPC-only and the non-FPC side keeps the same behaviour through
the Win32 loading calls, so dcc32 builds funcmd.dpr again.
Verified: linux x86_64 regression 92/92. The Delphi (dcc32) build of
funcmd.dpr compiles again; -dPCRE_WinDLL/-dPCRE_LINKDLL paths are unchanged.
v9.3.2 released
Fun 9.3.2 macOS reaches the standard library, and Linux arm64 gets a build. Highlights since v9.3.1: - lib: macOS port. getapi works through the libffi backend (-dLinuxFFI generalises to UnixFFI, -dDarwinFFI selects Darwin), and the library layer that differed only by library name moves to lib-*-unx.fun (os, cmdline, unicode, ado, ado-schema, xml, crypt, ajax, winsock, jsonrpc, orm-rpc), with lib-*-lnx.fun kept as thin wrappers. lib-host.fun gains IsMac()/IsUnix(); Darwin gets .dylib names, proc_pidpath, the Darwin sockaddr_in layout, __error and Homebrew/MacPorts libcrypto probing. - build: fun/funcmd-linux-aarch64 is cross-compiled on x86_64 from a bootstrapped aarch64 RTL through Zig clang/lld shims, with no aarch64 binutils or glibc. The artifact is static, stripped and reproducible; it is the core interpreter for now (no PCRE or getapi). - darwin/ld forwards -dead_strip and the strip request to lld, shrinking the Mach-O binaries from 2.6/2.7 MB to 0.86/0.94 MB with LC_MAIN, the dylib loads and the arm64 ad-hoc signature intact. - funcmd usability: no script argument prints the usage and exits 0 instead of trying to run its own executable, a named-but-missing script stays an error, and the usage line says fun rather than fun.exe on non-Windows hosts. - test: fractal-asm-x64 exercises the x86_64 SysV lib-asm path against the fractal benchmark output.
v9.3.1 released
Fun 9.3.1
The interpreter cross-compiles for macOS on a Linux host.
Highlights since v9.3.0:
- bootstrap-darwin-cross.sh builds a full FPC 3.2.2 darwin cross toolchain
(ppcrossx64/ppcrossa64 plus the RTL, the rtl-objpas/hash units and PCRE) and
fetches Zig; make-darwin.sh compiles funcmd.dpr into fun/funcmd-darwin-<cpu>.
- Mach-O assembly and linking go through the darwin/clang and darwin/ld shims
over Zig's bundled clang/lld, so no macOS SDK is required.
- The engine's {$IfDef Linux} guards that really meant "not Windows" now use
FPC's built-in UNIX symbol: core/{base,fun,io}, parse/parse, utils/utils, the
lib helpers, regex/pcre/* and funcmd.dpr. host.arg() reports os macos, Darwin
gets clock_gettime/gettimeofday and cdecl PCRE externals.
- Linux is unchanged: the regression suite stays at 91/91. The Fun-level -lnx
libraries and the getapi FFI backend are not ported yet.