Skip to content

Compiler: classify captured loop bindings in one AST pass #616

Description

@chrisbbreuer

Parent: #465
Related: #493, #496, #615

Problem

Plain-function admission currently determines whether a lexical for or for-in/of head needs per-iteration Environment Records by walking the loop head, condition, update, iterable, and body separately for every bound identifier. A wide declaration/destructuring head combined with a large closure-free body therefore performs binding-count × AST-size classifier work before bytecode emission.

This is distinct from #615: #615 scans pending TDZ names once. This child owns repeated loop-capture classification while preserving the exact CreatePerIterationEnvironment / ForIn/OfBodyEvaluation boundary.

Scope

  • Collect lexical loop-head binding names once, without treating binding positions as references.
  • Traverse each relevant loop region once and match nested function/arrow references against exact binding membership.
  • Preserve conservative shadowing and deferred-class behavior unless exact scope information proves a narrower answer.
  • Preserve ordinary frame-slot lowering for uncaptured heads and Environment Record lowering for genuinely captured heads.
  • Cover declaration groups, object/array destructuring, defaults/computed keys, initializers, condition/update expressions, iterable expressions, nested closures, classes, and nested loops.
  • Measure clear, unrelated, early/late capture, and destructuring growth using production parse + admission/compile work with exact structural checksums and allocation replay.

No-workaround rules

  • No skipped syntax, source rewriting, heuristic size cutoffs, guessed shadowing, test exclusions, or semantic fallback presented as an optimization.
  • A one-binding common case must not pay an attacker-sized temporary structure.
  • Any newly shared classifier state must remain compile-owned and allocation/lifetime explicit.

Acceptance

  • Exact semantic fixtures prove captured heads still use fresh per-iteration bindings and uncaptured heads remain slot-backed in tree-walker and required-bytecode execution.
  • Parent → candidate growth evidence demonstrates bounded classifier scaling for wide heads and large unrelated bodies, with all control shapes and allocation metrics.
  • Full unit, focused TSan where applicable, and relevant Test262 subtrees pass with exact before → after failure accounting.
  • Evidence and parent issues are cross-linked; published claims name the scored boundary and exact revisions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestjitBytecode, baseline JIT, optimizer, and code generationperformanceMeasured runtime, memory, scaling, or build performanceruntimeJavaScript runtime and builtin implementation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions