Skip to content

fix: translate deeply nested files instead of overflowing the stack - #65

Merged
ylluminate merged 1 commit into
vlang:masterfrom
ylluminate:fix-deep-nesting
Nov 13, 2026
Merged

ylluminate merged 1 commit into
vlang:masterfrom
ylluminate:fix-deep-nesting

Conversation

@ylluminate

@ylluminate ylluminate commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

py2v crashed with V panic: stack overflow on files that nest deeply: about 70 nested blocks, an if/elif chain of 70 branches (Python nests each elif inside the else before it), or one expression about 200 levels deep, such as a sum of 196 terms. The transpiler walks the tree by recursion on the main thread's stack. The crash can't be caught, so in --package it ends the whole run.

The work now runs on a thread with a 64 MiB stack, set with #flag -DV_THREAD_STACK_SIZE=67108864, which V's generated C reads when it creates a thread (@[spawn_stack] had no effect when I tried it). The translation itself isn't touched.

64 MiB is twice the smallest stack size I tested successfully. V's json2 rejects JSON deeper than 512 nested levels. For an elif chain that means 250 branches translate (with 32 MiB; 16 overflows) and 256 exit 1 with Invalid json: Syntax: exceeded the maximum nesting depth. Other shapes have other limits: a sum of 1001 terms exits 1 with a RecursionError from the frontend, which this doesn't change, as does sympy's polys/numberfields/resolvent_lookup.py (569 levels). The macro applies to every thread V starts, so the --check workers get 64 MiB stacks too; on Windows, where a thread's stack size is committed up front, that is about 576 MiB with the default eight workers. I measured on macOS arm64 only.

Separately, V refuses an expression nested more than 100 levels when it compiles the output (expr level > 100), so a sum of 401 terms now translates to V that doesn't build.

I ran into it on sympy, where polys/polyquinticconst.py (230 levels) crashes on master and translates with this.

Test plan

  • Two new checks in tests/run_tests.vsh: an elif chain of 120 branches and a sum of 401 terms must translate. Master's py2v exits 139 on both.
  • The translated elif chain builds and prints 5, as Python does.
  • The 184 Python files under tests/ give the same output and exit status with master's py2v and with this change.
  • v tests/run_tests.vsh: 180 passed, 0 failed (178 before, plus the two checks).

@ylluminate
ylluminate merged commit 7652cd9 into vlang:master Nov 13, 2026
2 checks passed
@ylluminate
ylluminate deleted the fix-deep-nesting branch November 13, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant