Repository navigation
[TS] Bind lexical this when calling stored arrow functions #440
Description
Resolution (2026-10-14)
Audited against usvm main at 19866c959d.
The native frontend captures lexical this in arrow closure environments, and USVM uses that captured value when a stored arrow is called through another object. Ordinary stored functions retain their dynamic receiver. Implementation: usvm #470, usvm #432.
Validation: The issue's lexical-this example returned 12 in symbolic execution and Node replay; all 3 StoredFunctionCall regressions passed. The temporary replay fixture desugared the constructor parameter property without changing its semantics.
Original report and acceptance context, retained for traceability
Problem
A stored arrow function is called with the receiver of the property access instead of the this captured where the arrow was created. This is independent of the object-array symbolic-input problem that remains in #419.
Minimal TypeScript example
class Box {
callback!: (value: number) => number;
constructor(public offset: number) {}
installOn(target: Box): void {
target.callback = (value: number) => this.offset + value;
}
call(value: number): number {
return this.callback(value);
}
}
export function lexicalThis(): number {
const source = new Box(11);
const target = new Box(100);
source.installOn(target);
return target.call(1);
}lexicalThis() returns 12 in TypeScript/Node.js. The related StoredFunctionCall test reported in #419 on the #418 head returned 101 in USVM, using the target receiver instead of the source receiver. This standalone snippet has not yet been replayed through USVM.
Dependency and source evidence
- [TS] Preserve lexical this of arrow function values in EtsIR jacodb#391 tracks preserving the arrow/function distinction and lexical receiver in EtsIR. This issue owns the USVM call binding after that representation is available.
- Function-reference creation constructs the reference from the lifted method and closure environment.
- Indirect call resolution uses
callee.thisInstancefor the call.
The source links are pinned to USVM main 53dce8f3. The related failure was observed on the #418 head; it is not claimed as a fresh main-branch replay.
Acceptance criteria
- A stored arrow retains its lexical
thiswhen assigned to and called through another object; the example returns12. - An ordinary stored function expression still uses its dynamic call receiver.
- A focused test checks the USVM result and confirms a concrete TypeScript/Node.js replay.
Activity