Native executables used to terminate with a signal when recursion
exhausted the stack. Functions that can take part in unbounded recursion
now compare the stack pointer against a per-stack guard on entry and
throw Node's `RangeError: Maximum call stack size exceeded` through the
ordinary exception path, so catch handlers, finally blocks, worker error
events and the uncaught-error exit code behave as they do under Node.
- The checked set is every function on a cycle of the call graph, where
operations that can reenter compiled code indirectly (indirect calls,
callbacks, dynamic and library operations) reach closure targets and
class members. Non-recursive functions, including leaf callbacks, stay
check-free, and the may-throw analysis accounts for the new throw.
- The runtime installs the guard per context (main thread from the stack
rlimit, workers from their thread attributes) and per async fiber, with
a reserve for the throw, unwinding and error reporting. Worker threads
now get an explicit 8 MiB stack.
- Scalar call results pass through the unwind path as its dummy value, so
calls in tail position keep tail-call and recursion elimination.