fix: class constructor scope index mismatch and arguments binding slot allocation#5352
Open
acsses wants to merge 3 commits intoboa-dev:mainfrom
Open
fix: class constructor scope index mismatch and arguments binding slot allocation#5352acsses wants to merge 3 commits intoboa-dev:mainfrom
acsses wants to merge 3 commits intoboa-dev:mainfrom
Conversation
…cation Two bugs caused a runtime panic in class constructors: 1. `num_bindings_non_local()` in `boa_ast/src/scope.rs` excluded the `arguments` binding because it lacks the `ESCAPES` flag, resulting in `FunctionEnvironment` being created with 0 slots while the bytecode emitted `PutLexicalValue(index=0)`. 2. `compile_class()` in `boa_engine/src/bytecompiler/class.rs` always pushed the constructor's function scope to `constant_scope(0)`, while `scope_analyzer` assigned it a higher index via `visit_function_like`, causing a mismatch at runtime. Fix (1) by counting `arguments` bindings unconditionally in `num_bindings_non_local()`. Fix (2) by applying the same scope push logic as `FunctionCompiler`: push `name_scope` first if non-local, then conditionally push `function_scope` based on `all_bindings_local()` and `requires_function_scope()`. Fixes boa-dev#5351
Test262 conformance changes
New panics (7):Tested main commit: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5352 +/- ##
===========================================
+ Coverage 47.24% 59.95% +12.71%
===========================================
Files 476 566 +90
Lines 46892 62829 +15937
===========================================
+ Hits 22154 37671 +15517
- Misses 24738 25158 +420 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR fixes two related bugs in the bytecode compiler that caused a panic
(
index out of bounds: the len is 0 but the index is 0) when executingesbuild-bundled JavaScript code targeting ES2020.
Bug 1:
argumentsbinding missing slot inFunctionEnvironmentRoot cause:
scope_analyzer.rsalways creates anargumentsbinding in the functionscope, but without the
ESCAPESflag:num_bindings_non_local()only counts bindings withESCAPES=true, so theargumentsbinding was excluded from the slot count. This causedFunctionEnvironmentto be created with 0 bindings, while the bytecode stillemitted
PutLexicalValue(index=0)for it, resulting in a panic at runtime.Fix (
boa_ast/src/scope.rs):Include the
argumentsbinding in the slot count unconditionally:Bug 2: Class constructor scope index mismatch
Root cause:
scope_analyzer.rsassigns scope indices to class constructor scopes viavisit_function_like, which incrementsself.indexbefore callingfunction_scope.set_index(self.index). For example, whenfunction_scope.all_bindings_local()is false:However,
compile_class()inclass.rsalways calledpush_scope()exactlyonce for the function scope, placing it at
constant_scope(0). At runtime,function_constructusescode.constant_scope(last_env)to retrieve thefunction scope. Since the
function_scopehadscope_index=1but was storedat
constant_scope(0), the wrong (or nonexistent) scope was accessed, causinga panic.
This is in contrast to
function.rs(FunctionCompiler), which correctlymirrors the scope index assignment by:
name_scopefirst if it has non-local bindingsfunction_scopebased onall_bindings_local()andrequires_function_scope()Fix (
boa_engine/src/bytecompiler/class.rs):Apply the same scoping logic as
FunctionCompilerto the class constructor:Test cases
How it was found
The panic was triggered by esbuild-bundled code with
--target=es2020, whichtransforms class fields into
__publicField()helper calls. The combinationof multiple
__publicFieldcalls followed byconstdeclarations in a classconstructor exposed both bugs simultaneously.