-
Notifications
You must be signed in to change notification settings - Fork 247
Description
When I run this Jsonnet program on the following input with a stack size lower than about 3000, I get a stack overflow error which consists mostly of lines like <std>:231:22-42 thunk from <thunk from <function <build>>>. The build function in std uses tailstrict for recursive calls, but it doesn't seem to be working in this case. Maybe the + operation in the arguments is causing the issue? tailstrict is working in general; when run with a stack size of 3000 this program completes successfully, but if the tailstrict calls within the program are removed, it overflows even that stack size, with lots of bifurcate instances in the stack.
The bifurcate function recursively passes a stack of work to perform as the last argument to the function. local cur = stack[0] examines the top item on the stack; if it doesn't need to recurse further then it updates a cache and recurses with stack[1:]. If cur needs additional work, its sub-problems are put into an array and it recurses with next + stack. This is a Lisp cons style approach, but Jsonnet arrays aren't single-linked lists, so I'm not surprised that it's inefficient, just that the intended tail call elimination isn't happening.
Input (/tmp/day10/line7.txt), which is one challenging line of input from https://adventofcode.com/2025/day/10:
[.#.....##.] (0,3,6,9) (1,2,4,6,7,8,9) (0,5,9) (0,1,2,4,7,8) (0,6,7,8,9) (3,4,5,6,7,8) (0,3,5,7) (2,3,4,6,7) (2,3,4,5,6,7,8) (1,2,6,9) (2,7,8) (0) (0,2,3,4,5,6,7,9) {71,46,95,181,172,148,199,205,151,71}
Run: jsonnet -t 128 -s 1000 -S ./runner.jsonnet --tla-code-file 'solve=day10/day10.jsonnet' --tla-code 'files=[{name:'\''/tmp/day10/line7.txt'\'', content:importstr '\''/tmp/day10/line7.txt'\'', },]'
Output:
RUNTIME ERROR: max stack frames exceeded.
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
...
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
<std>:231:22-42 thunk from <thunk from <function <build>>>
day10/day10.jsonnet:83:17-25 thunk <cur> from <function <bifurcate>>
day10/day10.jsonnet:84:32-35
day10/day10.jsonnet:66:80-82 thunk from <function <levelParity>>
day10/day10.jsonnet:66:38-83
day10/day10.jsonnet:66:25-84 function <levelParity>
day10/day10.jsonnet:84:20-43 thunk <parity> from <function <bifurcate>>
day10/day10.jsonnet:85:43-49 thunk from <thunk <ways> from <function <bifurcate>>>
<std>:1545:24-25 thunk from <function <anonymous>>
<std>:1545:5-33 function <anonymous>
day10/day10.jsonnet:85:21-50 thunk <ways> from <function <bifurcate>>
day10/day10.jsonnet:90:16-20 thunk <halves> from <function <bifurcate>>
day10/day10.jsonnet:(86:20)-(90:77)
day10/day10.jsonnet:91:54-60 thunk from <function <bifurcate>>
day10/day10.jsonnet:91:16-61
<std>:1642:24-27 thunk from <function <anonymous>>
<std>:32:25-26 thunk from <function <anonymous>>
<std>:32:16-27 function <anonymous>
<std>:1642:12-28 function <anonymous>
day10/day10.jsonnet:91:8-62 function <bifurcate>
day10/day10.jsonnet:95:7-54 function <bifurcate>
day10/day10.jsonnet:102:3-101 function <solvePart2>
day10/day10.jsonnet:109:12-33 object <anonymous>
day10/day10.jsonnet:114:15-22 thunk from <thunk from <object <anonymous>>>
day10/day10.jsonnet:29:47-48 function <anonymous>
day10/day10.jsonnet:29:18-57 function <sum>
day10/day10.jsonnet:114:10-43 object <anonymous>
runner.jsonnet:56:54-71 thunk from <object <anonymous>>
runner.jsonnet:57:25-51 object <anonymous>
runner.jsonnet:61:38-73 function <anonymous>
<std>:259:50-62 function <anonymous>
runner.jsonnet:61:3-82 function <anonymous>
Top-level function call