v2.0.0 #41
minirang
announced in
Announcements
v2.0.0
#41
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Description
Nesting depth ceiling raised to 512 (from 256, introduced in v1.6.0). Scoped specifically to source-level nesting — parentheses, list/map literals,
if/loop/or_elseblocks — not the string/collection/size limits from the previous release, which are unchanged. Raising the counter alone would have been unsafe on a small stack: measured empirically, 512 levels of nested parentheses can need over 1 MiB of native stack, more than Windows' 1 MiB default thread stack, since the parser recurses on the real C++ stack. The parser now also carries a stack-pointer safety net (primed fresh at the start of every parse, including a module's own parse) mirroring the interpreter's existing one, so it fails cleanly with the sameE2008instead of crashing on a small stack, on any platform.availableStackBytes()(the real-stack-size query this relies on) is now implemented on Windows and macOS as well as Linux, not just Linux — a general robustness improvement, not just a v1.7.0 side effect.New:
constant list— a read-only, Python-tuple-style list.set constant list NAME to [...]freezes a list: adding, removing, or index-assigning into it is a runtime error (ConstantReassignment), and — unlike a naive implementation — this can't be bypassed by assigning it to another variable or passing it into a function, since the immutability lives on the list value itself, not on one variable's name. Declaring one always makes an independent copy first, soset constant list A to existing_listfreezes onlyA, neverexisting_list. Matches Python tuples exactly in one respect worth knowing: it's shallow — a plain list or map found inside a frozen one is still fully mutable through its own reference. No new value type was added;listgained one internal flag.constantcontinues to require ALL-CAPS names for every type, as before;constant mapwas not added.Keyword:
function→func. A straight rename, not an alias —set function x() do:no longer parses; it'sset func x() do:now. Every script in this repository (examples, tests, docs) was updated; existing external scripts need the same one-word find-and-replace.New:
purefunctions — no global-scope access.set pure func f() do: ... end(freely combinable withreturnable/asyncin any order). Apurefunction's body cannot read or write a top-level global variable — including via thechange x to globalbridge — and fails immediately with a new error,PureFunctionGlobalAccess(E4027), that names the variable and reminds you removingpureis the fix. The restriction is on that function's own body only: apurefunction calling a non-pureone is fine, and the callee's own purity governs its own body, the same per-call scopingreturnableandasyncalready had.New:
DLC:network— real HTTP (not a stub anymore).get(url)andpost(url, body[, content_type]), returning{"status", "ok", "body"}. A from-scratch, dependency-free HTTP/1.1 client (POSIX sockets on Linux/macOS, Winsock2 on Windows) handling chunked encoding,Content-Lengthframing, and redirects. Plain HTTP only —https://fails with a clear error rather than silently talking plaintext to an HTTPS port. Connection/DNS/timeout failures raiseNetworkRequestFailed(E4028), catchable withor_elselike any other runtime error. Security-relevant defaults, please readSECURITY.md's new "DLC:network" section before deploying: network access is on by default (unlike the module sandbox); every request is checked against loopback/private/link-local addresses (including169.254.169.254, the common cloud-metadata address) and blocked unless explicitly widened. New:CuffEngine::Options::networkEnabled/--no-network(turnDLC:networkoff entirely — do this before hosting untrusted scripts) andallowPrivateNetworkTargets/--allow-private-network(widen the address check). Response size, connect timeout, total timeout, and redirect count are all capped (engine/common/Limits.h).Windows build fix (found via this release's new mingw-w64 cross-compile check — see Verification below).
<windows.h>#definesTRUE,FALSE, andINas plain macros, which was silently corruptingTokenType::TRUE/FALSE/INwherever the stack-introspection header was included first, breaking the Windows build outright. Fixed withWIN32_LEAN_AND_MEAN/NOMINMAXand targeted#undefs. This means the Windows build had not actually been verified against a real toolchain before now.Performance. Two changes, kept because both are measured improvements with no downside: dispatch in the interpreter's hot paths uses
std::get_ifinstead ofstd::get(skips exception-handling machinery the kind-check already makes unnecessary), and function calls now recycle their argument vector and the callee's local-variable storage across calls instead of allocating fresh each time. Net effect is modest — recursive/call-heavy code is about 7% faster; pure arithmetic loops (no allocations to begin with) are unchanged. In the interest of not overclaiming: two more aggressive ideas (non-atomic reference counting; broader allocation pooling) were built and benchmarked, then not kept, because on this toolchain (glibc 2.39) both turned out to duplicate optimizations glibc already does transparently (single-threadedshared_ptris already non-atomic in practice; the allocator's per-thread cache already does the pooling). A tree-walking evaluator's per-node cost was already close to its practical floor after v1.6.0; going further would mean the bytecode VM this project is deliberately deferring, not a tuning pass.Added error codes:
E4027(PureFunctionGlobalAccess),E4028(NetworkRequestFailed).Tests: 12 new checks added directly to
tests/unit/limits_test.cpp(the raised depth ceiling, both at and near the new ceiling), 2 new script cases (pure_functions,constant_list_tuple) and 10 new error cases (constant-list mutation via direct name/index/alias/argument,pureread/write violations, andDLC:network's SSRF/HTTPS/malformed-URL/disabled-network error paths).tests/run.shgained support for a per-test.argsfile (extra CLI flags), used by the network-disabled test. The suite now has 106 checks (was 94).DLC:network's success paths (GET, POST, redirects, chunked decoding, JSON round-trip) were verified manually against a local test server, including under AddressSanitizer + UBSan, but aren't part of the automated suite, which shouldn't depend on live network access.Verification. Full suite + a battery of hostile/stress scripts run clean under AddressSanitizer + UBSan (176 files, 0 findings), including the new socket-handling code. Windows: this release added a real
x86_64-w64-mingw32-g++cross-compile check (previously the Windows build was never actually compiled), which is how the macro-collision bug above was caught; the cross-compile is clean, but running the resulting binary could not be verified in this environment (no working Windows/Wine runtime available) — compilation only. macOS: not cross-compiled (no toolchain available here); the new platform-specific code follows the same POSIX APIs already used on Linux, with the two known Linux/macOS differences (SO_NOSIGPIPEvsMSG_NOSIGNAL, andpthread_get_stackaddr_np/pthread_get_stacksize_npvspthread_getattr_np) handled explicitly, but this is unverified by actual compilation or execution.This discussion was created from the release v2.0.0.
All reactions