Summary
Inside a class constructor, new.target returns the f64 NaN bit pattern instead of the constructor function reference. Surfaced by test-files/test_gap_class_advanced.ts. Reproduces on main (v0.5.503) and HEAD~5 (v0.5.498) — pre-existing.
Minimal repro
class MyConstructable {
constructor() {
console.log("new.target:", new.target?.name ?? "undefined");
}
}
new MyConstructable();
| Runtime |
Output |
node --experimental-strip-types |
new.target: MyConstructable |
perry |
new.target: NaN |
Why this matters
new.target is the standard mechanism for:
- Detecting whether a function was called via
new vs. as a regular call
- Distinguishing the most-derived constructor in a
super() chain (essential for any class-factory or framework that does class.name-based registration)
NaN here is a leaked NaN-boxing tag value — new.target is being lowered to the literal IEEE-754 NaN bit pattern instead of the constructor's class metadata pointer. The fix probably lives near the meta-property lowering site that v0.5.502 touched for import.meta.
Summary
Inside a class constructor,
new.targetreturns the f64 NaN bit pattern instead of the constructor function reference. Surfaced bytest-files/test_gap_class_advanced.ts. Reproduces onmain(v0.5.503) and HEAD~5 (v0.5.498) — pre-existing.Minimal repro
node --experimental-strip-typesnew.target: MyConstructableperrynew.target: NaNWhy this matters
new.targetis the standard mechanism for:newvs. as a regular callsuper()chain (essential for any class-factory or framework that doesclass.name-based registration)NaNhere is a leaked NaN-boxing tag value —new.targetis being lowered to the literal IEEE-754 NaN bit pattern instead of the constructor's class metadata pointer. The fix probably lives near the meta-property lowering site that v0.5.502 touched forimport.meta.