mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Clones now cover more recursive number shapes: - Recursion over array indices: a function may take number arrays it borrows (the caller keeps them alive for the call) and read `length` and elements. An element inside the array's hole-free prefix that is exactly an int32 is read inline; holes, other indices and other numbers bail to the ordinary body. Borrowed entries get dispatchers too. - Mutual tail recursion: tail calls between members of a recursive component return the callee's result as is, so LLVM inlines them into one loop (isEven/isOdd), as it already does for the ordinary body. - The proven int32-slots ranges of number parameters (valid at every call site, recursive ones included) become `llvm.assume`s in each activation, so `%` of non-negative values divides unsigned without -0 handling (gcd). A clone now overflows the stack where the ordinary body would, instead of bailing after 2^14 loop iterations. LLVM turns the ordinary body's plain tail calls into loops, so the clone's plain tail calls (self or mutual) run unchecked too: endless tail recursion runs forever on either path, as it did before clones. An accumulating call (`1 + f(n - 1)`, fib's `f(n - 1) + f(n - 2)`) is real recursion in the ordinary body, because a double sum is not associative. Its clone loop carries a virtual stack pointer that starts at the real one (an inlined activation one frame below its parent's) and drops 32 bytes, about an ordinary frame of these functions, per iteration; passing the stack guard throws the stack-overflow RangeError. Deep finite chains stay on the fast path, and `1 + down(n - 1)` with n = 1e7 still throws like Node (4984-generator-exceptions, corpus 5342). Corpus 5343 covers array-index recursion, binomials, holes and non-integer elements.