Very low syntactic nesting limit: 29 nested function expressions (or 70 nested array literals) fail to compile with "InternalError: too much recursion"

未关闭
#357 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
c, wasm

调研方向

Start by reading cmake/compile-flags.cmake and runtime/engine.cpp, which the report identifies as unchanged on main; then check how the WASI stack limit and SpiderMonkey’s native stack quota are configured. Reproduce the failure with the nested IIFE generator or test262’s language/statements/function/S13.2.1_A1_T1.js. Done means the reported nesting compiles and runs without weakening runtime recursion protection.

由索引模型根据 Issue 内容生成。

描述

Summary

StarlingMonkey fails to compile scripts with modest syntactic nesting. 29 nested function expressions, or 70 nested
array literals, make the whole script fail with InternalError: too much recursion and no source location. The same
code compiles in SpiderMonkey's own shell. test262's language/statements/function/S13.2.1_A1_T1.js (32 nested
function expressions) fails for this reason.

Environment

  • StarlingMonkey v0.4.0 release starling.wasm, wasmtime 50.0.1, --legacy-script.
  • cmake/compile-flags.cmake and runtime/engine.cpp are unchanged on main (54b3329b).
  • Checked on 2026-11-03. Reference: SpiderMonkey jsshell 147.0.4 (the SpiderMonkey version StarlingMonkey v0.4.0 embeds).

Reproduction

Generate N nested IIFEs:

// node gen.js 29 > nested.js
const d = +process.argv[2];
console.log("(function(){".repeat(d) + "console.log('ok');" + "})()".repeat(d) + ";");
input StarlingMonkey jsshell 147.0.4
28 nested IIFEs ok ok
29 nested IIFEs InternalError: too much recursion ok
69 nested array literals [[[…]]] ok ok
70 nested array literals InternalError: too much recursion ok
the 29-level code inside if (false) { … } (never executed) InternalError: too much recursion ok

The last row shows that the limit is hit while compiling (parser / bytecode emitter), not while running. Runtime
recursion is fine (function f(n){return n?1+f(n-1):0} f(50000) works). Through indirect eval inside try the
error is catchable, so it is a regular over-recursion check, not a crash.

Why it matters

ECMA-262 allows implementation limits, but 29 nested functions is easily reached by real code: bundler output (module
wrapper, UMD wrapper, nested callbacks), generated parsers, and deeply nested inline callback chains. Such a script
currently fails as a whole, with no location.

Likely cause

cmake/compile-flags.cmake links with -Wl,-z,stack-size=1048576 -Wl,--stack-first, a 1 MiB stack, and no native
stack quota is configured for the context. SpiderMonkey's recursive-descent parser and BytecodeEmitter use a lot of
stack per nesting level, so the recursion check trips after a few dozen levels. (I have not confirmed where the
effective limit for the WASI build is computed; maintainers will know better.)

Suggested fix (sketch)

Raise the stack size (for example to 8 MiB, the usual native default) and set a matching quota after context creation
(JS_SetNativeStackQuota(cx, stack_size - safety_margin)), or make the stack size a build option so embedders can
trade memory for depth. A regression test can be the generator above or test262's S13.2.1_A1_T1.js.

Related

  • #298 (silent failure when the runtime call-stack limit is exceeded in async handlers; different symptom).
  • bytecodealliance/ComponentizeJS#206 (minimum stack size for AOT builds).
主要语言
C
星标
297
派生
64
平均合并
1 天 17 小时
30 天内合并 PR
16

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

bytecodealliance/StarlingMonkey 的其他 Issue

查看 bytecodealliance/StarlingMonkey 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。