fix(hir): class field/element initializer test262 parity (v2, native-region-safe)#4779
Merged
Conversation
…region-safe)
Lifts language/{statements,expressions}/class/elements parity 50.1% → 75.5%
(+722 tests) on the test262 class/elements suite, with the native-region-proof
compiler-output-regression gate green and zero real regressions.
Root causes fixed:
1. `this` was undefined inside static methods. A static method invoked as
`C.m()` binds `this` to the class constructor; codegen now seeds the
static-method `this` slot with the class-ref value and sets `class_stack`,
so `this.x` / `this.#x()` / `this[k]` resolve. (compile_static_method)
2. Private (`#x`) elements leaked into reflection. They physically live in a
class instance's keys_array / on the static side but are never reflectable.
Hidden (gated on class_id != 0, so `{"#fff":1}` literals stay visible) from
Object.keys/values/entries, getOwnPropertyNames, getOwnPropertyDescriptor,
hasOwnProperty, JSON.stringify, and object spread / Object.assign — on both
instances and the class constructor (class-ref).
3. Static field/element initializers never ran for class EXPRESSIONS
(`var C = class { static x = 1 }`): the `var C = class {…}` fast path and
the general class-expression arm emitted the ClassRef binding but not the
inline static-field/static-block init the declaration path emits, so reads
saw the uninitialized (0.0) slot. They now emit inline StaticFieldSet /
ClassStaticSymbolSet / static-block calls in source order; the per-evaluation
ClassExprFresh path is reserved for class expressions inside function bodies
(factories) where freshness is actually needed.
4. Dynamic property get/set on a runtime class-ref VALUE returned/dropped
silently. `C[key]` / `C[key] = v` where `C` is a runtime class-ref (e.g. a
function parameter — propertyHelper's `isWritable(C, name)`) fell through to
the not-a-pointer `undefined`/no-op path. js_dyn_index_get/set now handle the
0x7FFE tag; the codegen index get/set paths preserve class-ref tag bits at
runtime (classref_preserving_handle) for runtime-unknown receivers; and the
array string-key setter guards class-ref receivers (routing to the by-name
object setter) instead of dereferencing them as a GC header.
Native-region-proof: the compiler-output-regression `native-region-proof` suite
reports status: pass with NO failed_workloads on a debug build locally (the
config CI uses). The class-field codegen change (static-method `this` slot +
runtime class-ref tag select on dynamic property access) does not perturb the
generic array/buffer native-region proofs.
Zero regressions: broad `built-ins language` shard 0/12 went 76.9% → 77.9%
(+61 gains); the 40 apparent shard "regressions" all pass in isolation on both
this branch and origin/main (parallel-run timeout flakiness), confirmed by
re-running each individually.
Files:
perry-codegen: codegen/method.rs, expr/index_get.rs, expr/index_set.rs
perry-hir: lower/lower_expr.rs, lower/stmt.rs
perry-runtime: object/{descriptors,object_ops,field_get_set,alloc}.rs,
json/stringify.rs, value/dyn_index.rs, array/indexing.rs,
typed_feedback.rs
Out of scope (separate feature areas, left for follow-up PRs): async-generator
`yield*` / async-iterator delegation semantics, and parser-level grammar
early-errors (invalid private-name SyntaxErrors).
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.
Re-do of #4764 (correct on test262 but failed the
compiler-output-regression/ native-region-proof gate). This version keeps that gate green and scopes changes to class field/element semantics.Results
language/statements/class/elements+language/expressions/class/elements: 50.1% → 75.5% (+722 tests; 1420 → 2142 pass).status: pass, NOfailed_workloadson a debug build locally (the config CI uses). The class-field codegen change does not perturb the generic array/buffer native-region proofs.built-ins languageshard 0/12 went 76.9% → 77.9% (+61 gains). The 40 apparent shard "regressions" each pass in isolation on both this branch and origin/main — parallel-run timeout flakiness (the shard ran while a build saturated the shared box), confirmed by re-running all 40 individually (isolated-pass=40, isolated-fail=0).Root causes fixed
thisundefined in static methods.C.m()bindsthisto the class;compile_static_methodnow seeds thethisslot with the class-ref value and setsclass_stack, sothis.x/this.#x()/this[k]resolve.#x) elements leaked into reflection. Now hidden (gated onclass_id != 0, so{"#fff":1}literals stay visible) fromObject.keys/values/entries,getOwnPropertyNames,getOwnPropertyDescriptor,hasOwnProperty,JSON.stringify, and object spread /Object.assign— on instances and the class constructor (class-ref).var C = class { static x = 1 }). Thevar C = class {…}fast path and the general class-expression arm now emit inlineStaticFieldSet/ClassStaticSymbolSet/static-block calls in source order (matching declarations); the per-evaluationClassExprFreshpath is reserved for class expressions inside function bodies (factories).C[key]/C[key]=vwhereCis e.g. a function param — propertyHelper'sisWritable(C, name)).js_dyn_index_get/setnow handle the0x7FFEtag; codegen preserves class-ref tag bits at runtime for runtime-unknown receivers (classref_preserving_handle); the array string-key setter guards class-ref receivers instead of dereferencing them as a GC header.Files
codegen/method.rs,expr/index_get.rs,expr/index_set.rslower/lower_expr.rs,lower/stmt.rsobject/{descriptors,object_ops,field_get_set,alloc}.rs,json/stringify.rs,value/dyn_index.rs,array/indexing.rs,typed_feedback.rsOut of scope (separate feature areas; follow-up PRs)
yield*/ async-iterator delegation semantics (the largest remaining class/elements cluster, but a generator-runtime feature)SyntaxErrors)