Skip to content

Fix nested class scope index#4592

Merged
jedel1043 merged 2 commits intoboa-dev:mainfrom
regularkevvv:fix-nested-class-scope-index
Feb 23, 2026
Merged

Fix nested class scope index#4592
jedel1043 merged 2 commits intoboa-dev:mainfrom
regularkevvv:fix-nested-class-scope-index

Conversation

@regularkevvv
Copy link
Contributor

@regularkevvv regularkevvv commented Jan 30, 2026

This Pull Request closes #4555.

How to reproduce:

// Class expression constructor with nested class
new (class{constructor(){class D{}}})();

// Static block with nested class
(class{static{class D{}}});

Both crash with: index out of bounds: the len is 0 but the index is 0

Additional patterns that trigger the bug:

// Constructor variants
[new (class{constructor(){class D{}}})()]
({x: new (class{constructor(){class D{}}})()})
new (class{ m(){} constructor(){class D{}} })()
new (class{ static m(){} constructor(){class D{}} })()
new (class{ get g(){return 1} constructor(){class D{}} })()
new (class{ #m(){} constructor(){class D{}} })()
new (class{ ['p']=1; constructor(){class D{}} })()

// Static block variants
(class{ static{let v=1} static{class D{}} })
(class{static{let v=1;((v)=>{class D{}})(v)}})

It changes the following:

  • Fixed ScopeIndexVisitor::visit_class_expression_mut to call visit_function_like with force_function_scope: true for constructors, matching visit_class_declaration_mut. Previously it called visit_function_expression_mut, which forwards contains_direct_eval() as the last argument (not an unconditional false). For class constructors we must force function scope regardless of direct eval to match bytecode compilation.
  • Fixed ScopeIndexVisitor::visit_class_element_mut for StaticBlock to pass true for force_function_scope. Previously it passed contains_direct_eval, which is correct for escape analysis but not for scope-index layout in ScopeIndexVisitor.
  • This change only affects scope-index layout (ScopeIndexVisitor). Escape analysis still uses contains_direct_eval in BindingEscapeAnalyzer, so direct eval-based binding escape behavior is unchanged.

Both class expression constructors and static blocks always have HAS_FUNCTION_SCOPE set during bytecode compilation, so the scope analyzer must account for this when assigning scope indices.

Added two regression tests covering both cases

@github-actions
Copy link

github-actions bot commented Jan 30, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,862 52,862 0
Passed 49,472 49,472 0
Ignored 2,249 2,249 0
Failed 1,141 1,141 0
Panics 0 0 0
Conformance 93.59% 93.59% 0.00%

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.82%. Comparing base (6ddc2b4) to head (73cb7bb).
⚠️ Report is 668 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4592      +/-   ##
==========================================
+ Coverage   47.24%   56.82%   +9.57%     
==========================================
  Files         476      548      +72     
  Lines       46892    60008   +13116     
==========================================
+ Hits        22154    34097   +11943     
- Misses      24738    25911    +1173     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@regularkevvv regularkevvv force-pushed the fix-nested-class-scope-index branch from b6fbad8 to 1b58f2a Compare February 21, 2026 16:45
@jedel1043
Copy link
Member

The force_function_scope parameter in visit_function_like doesn't exist...

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@jedel1043 jedel1043 added this pull request to the merge queue Feb 23, 2026
Merged via the queue into boa-dev:main with commit 46e92c7 Feb 23, 2026
18 checks passed
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.

Panic index out of bounds: the len is 0 but the index is 0 in core/engine/src/vm/opcode/define/mod.rs

2 participants