Skip to content

[TS] Bind lexical this when calling stored arrow functions #440

Closed

Description

@CaelmBleidd

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

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 this when assigned to and called through another object; the example returns 12.
  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions