Skip to content

Latest commit

 

History

History
553 lines (504 loc) · 317 KB

File metadata and controls

553 lines (504 loc) · 317 KB

Bytecode Progress Map

Date: 2026-06-08

This page is a compact map of where unified bytecode is now and what still needs to be handled before the engine can reasonably claim full bytecode execution.

The finite checklist source of truth remains docs/plans/bytecode-burndown-checklist.md; source-checked drift inventories remain in docs/unified-bytecode-expansion-contract.md. This page is the overview.

The checklist now also carries the finite open-row inventory for A1/A2, the remaining A51 leaves, B24h, B36, E4, and E5. That ledger is the compact handoff for owner source surfaces, proof-anchor families, and dynamic-residue versus ordinary fallback classification.

The executable proof index is docs/plans/bytecode-proof-manifest.json, checked by BytecodeProofManifestTests. A checklist/Faktorial item is not closed just because a broad row was investigated: every closure claim needs a manifest row that proves admission, hard quarantine, fallback retirement, or a still-open blocker. Full bytecode-only completion requires the manifest's E4/E5 source absence rows to pass: legacy AST/expression evaluation bridges and ExecutionPlanRunner entry points must be gone from source, and the suite must still pass.

Legend

  • Green: handled for the current production-unified-bytecode boundary.
  • Red: still needs admission, semantic ownership, or migration before full bytecode execution.

Overview

flowchart TB
    Source["JavaScript source"]
    Parser["Parser and typed AST"]
    Lowering["ExecutionPlanBuilder and emitters"]
    Plan["ExecutionPlan\nstatement IR plus expression payloads"]

    Source --> Parser --> Lowering --> Plan

    Plan --> Gate["Production route gates\nCanUseProductionUnifiedBytecodeFastPath\nUnifiedBytecodeProductionEligibility"]

    Gate -->|accepted ordinary sync shape| UBC["UnifiedBytecodeCompiler"]
    UBC --> Program["UnifiedBytecodeProgram\n131 opcodes"]
    Program --> VM["UnifiedBytecodeVirtualMachine\nall-or-nothing execution"]

    Gate -->|pre-gate or decline| Fallback["Existing execution routes"]
    Fallback --> ExprVM["ExpressionProgram VM\n77 expression ops"]
    Fallback --> IRRunner["ExecutionPlanRunner\n43 statement IR kinds"]
    Fallback --> AstBridge["Legacy AST / dynamic bridge\ncorrectness fallback only"]

    VM --> Result["JsValue / completion result"]
    ExprVM --> Result
    IRRunner --> Result
    AstBridge --> Result

    subgraph GreenHandled["Handled production-bytecode areas"]
        G1["Accepted ordinary sync functions route to VM before simple IR and generic IR"]
        G2["Unified opcode inventory has VM switch coverage"]
        G3["General expression lowering gaps: none"]
        G4["Direct slot/literal/binary/control flow and loop shapes"]
        G5["Owned property read/write/update/delete families inside admitted boundaries"]
        G6["Selected calls, constructs, super calls, optional calls, and spread calls"]
        G7["Selected destructuring via lowered ApplyBindingTarget executor"]
        G8["Selected sync generator / yield* resumable bytecode"]
    end

    subgraph RedRemaining["Needs handling before full bytecode execution"]
        R1["Activation model gaps remaining\nasync-like, broad generators, lexical-this arrows,\nreal arguments object, runtime defaults/destructuring"]
        R2["Wider call invocation remaining\ncomplex receivers, keys, eval, private-adjacent targets,\nreceiver-binding-sensitive families"]
        R3["Dynamic lookup beyond admitted ordinary/direct-eval/with-backed lanes"]
        R4["Property and assignment neighbors remaining\nricher computed keys, optional/super/private mutation,\nunsupported RHS spans"]
        R5["Driver states\nremaining driver slot/topology gaps,\nmulti-driver labeled cleanup"]
        R6["Destructuring model gaps remaining\ndefaults, nested patterns, generic declarations,\nunsupported targets"]
        R7["Top-level/script remains\npropertyaccess/simplearithmetic/var-destructuring now route green"]
        R8["Delete Tier 1 ExpressionProgram VM and Tier 2 statement IR runner"]
    end

    Gate -. current accepted boundary .-> GreenHandled
    Gate -. remaining declines .-> RedRemaining
    Fallback -. full-execution target removes most of this .-> RedRemaining

    classDef green fill:#d8f5dc,stroke:#17803d,color:#073b17,stroke-width:2px;
    classDef red fill:#ffe0e0,stroke:#c32020,color:#5d0000,stroke-width:2px;
    classDef neutral fill:#eef2f7,stroke:#59677a,color:#172033,stroke-width:1px;
    classDef core fill:#e8f1ff,stroke:#2457a7,color:#071d43,stroke-width:2px;

    class UBC,Program,VM,G1,G2,G3,G4,G5,G6,G7,G8 green;
    class R1,R2,R3,R4,R5,R6,R7,R8 red;
    class Source,Parser,Lowering,Plan,Gate,Result core;
    class Fallback,ExprVM,IRRunner,AstBridge neutral;
Loading

What This Means

The unified-bytecode VM is real and now owns a large production surface, but the engine is still multi-tier. Accepted production programs execute all-or-nothing in UnifiedBytecodeVirtualMachine; anything outside the current admitted boundary still falls back to existing expression-bytecode, statement IR, or dynamic/legacy routes.

The biggest remaining gap is not missing VM switch arms. The current contract states that the opcode inventory and VM switch are expected to stay in lockstep. The remaining work is mostly semantic admission: activation, calls, dynamic lookup, driver state, class-definition state, and fallback-route retirement.

The current ExecutionPlanRunner reachability baseline for E5 is explicit and classification-only, not a retirement claim. Ordinary sync functions no longer construct the runner inside TryInvokeIrFast; unsupported ordinary sync shapes decline there and then the outer invocation path remains the classified runner fallback after the production unified-bytecode selector, specialized parameter/binary routes, SyncIrCallTrampoline, and constructor/class invocation bridges decline. The old generic simple-return-expression branch in TryInvokeIrFast no longer executes ExpressionProgram; it now declines to the classified fallback too. The final Batch 5 retrospective confirms that the closed E5b child did not close the whole E5 batch. ADR 0371 converted the broad runner-entry anchors into source allowlists, but the manifest and checklist intentionally keep E5b, E5c, E5d, and E5e open until the classified script/static-block, ordinary function/constructor, resumable declined-body, and terminal dynamic-residue owners are either retired or tombstoned by their own proof rows. Top-level scripts now classify production declines before the old IR runner path: eligible scripts still route through the production VM, and every declined script reaches ExecutionPlanRunner.RunScript only through the classified RunScriptViaClassifiedIrFallback bridge with the stable decline code, reason, and instruction count logged. Async functions and sync generators still construct runner-backed fallbacks when EvaluateResumable declines. Async generators no longer construct the old declined-body runner fallback or the renamed _fallbackRunner / ExecuteFallbackRunnerStep bridge; declined async-generator bodies now fail explicitly until the VM admits the missing semantics. Static-block-only class expressions can now route through resumable LoadClassLiteral, and eligible static-block bodies now attempt production unified bytecode first. Declined static-block bodies, including closure-producing blocks, still fall back to ExecutionPlanRunner.RunScript. ExecutionPlanRunner.EvaluateStandaloneExpressionProgram, TypedAstEvaluator.EvaluateLoweredExpressionProgram, and TypedAstEvaluator.EvaluateDynamicExpressionProgram are deleted. Standalone and dynamic ExpressionProgram payloads now execute through UnifiedBytecodeExpressionProgramExecutor, which compiles them to standalone unified bytecode and executes the unified VM. Lowered binding-target helpers no longer construct ExecutionPlanRunner; external lowered binding-target calls route through the static binding-target core and expression payloads on that external path execute through standalone unified bytecode. Runner-internal binding-target calls still pass through the runner as part of E5 until the IR runner itself is retired. The profiler-only ExpressionProgram loop no longer constructs a runner; ProfileRunner now compiles its synthetic bytecode profile cases to standalone unified bytecode and executes the unified VM directly. Terminal dynamic residue remains outside ordinary E5 retirement work: multi-argument, spread, runtime-source, or declaration-injecting direct eval; awaited with object evaluation; retained live with scopes outside the admitted VM current-environment lane; eval-injected runtime bindings; and Function(...)-produced bodies. Non-awaited sync/resumable with through the VM current-environment lane and already-admitted declaration-free literal eval lanes are not parked as residue.

The remaining default-admission gaps are now inventoried directly. The sync prototype guard has 6 currently non-admitted resumable-only opcodes; the resumable opcode allowlist has 5 non-admitted opcodes; and the resumable instruction allowlist has 0 non-admitted IR instruction records. Those lists are drift-checked in ExpressionProgramCoverageMapTests, so future opcode or instruction additions cannot hide behind the old default buckets.

Phase 0 inventory closure is complete as of 2026-06-05. At that checkpoint, the burndown checklist had 145 finite items: 128 complete and 17 open. The last coarse leaves were split into A35a-A35e object-literal member opcode leaves and B24a-B24i class-expression semantic leaves.

Current Retrospective Accounting

The latest checklist recount is 137 / 161 complete. Across the concrete A+B+C+D sections, 127 / 146 are complete and 19 remain open. Phase B stands at 55 / 57 complete. The D5 non-residue ratchet has 0 known-open rows, the resumable opcode gap inventory has 5 remaining gaps, and the resumable instruction gap inventory has 0 remaining gaps.

Class Literal Resumable Parity now has one checklist-open B24 row: B24h. The maintained checklist marks B24a-B24g complete and B24i complete for the activation-safe public non-computed super subset, now including public static methods/accessors, public static field initializers with super, and mixed public non-computed static field plus static method/accessor class expressions whose field initializers compile as standalone unified bytecode and whose member bodies do not capture resumable activation slots. That B24i closure is not a claim of full class-definition bytecode execution. Computed, private, capturing, or static-block-neighbor super class-member shapes remain bounded by the same class-definition environment bridge as the B24h residue. Treat any parent plan item that marked the B24h child complete as partial-slice closure only; the source-of-truth checklist still keeps B24h open until non-production static-block plan ownership and the broader class-definition environment bridge are owned.

The remaining non-retirement work is concentrated in:

  • A1/A2 dynamic activation residue: captured closures now route for the admitted sync and resumable flat/nested/colliding closure lane, so the open residue is the dynamic-activation boundary around captured dynamic chains, direct-eval shapes that still depend on the implicit arguments object beyond the bounded admitted route, retained live-with closure chains, and async/generator parity for the dynamic activation lane. TypedAstEvaluator.UnifiedBytecodeResumableActivation.cs still declines direct eval in parameters/body when the resumable path cannot prove declaration-free dynamic activation, arguments-object safety, or absence of a live with object in the closure chain.
  • A51 compiler leaves: the remaining named UnsupportedPlanShape buckets for topology, slot layout, scope/environment, driver state, destructuring, expression-span, call-boundary, literal, property, mutation, and cleanup diagnostics.
  • B24h class-expression class-definition state: computed-name activation delete/construct residue, runtime-source direct eval, non-production static-block plan ownership, and the broader class-definition environment bridge. This is not the B36 class-declaration row. Activation-safe computed calls/IIFEs and declaration-free literal direct eval in static blocks are admitted slices, but the remaining class-definition environment and non-production static-block anchors stay open.
  • B36 resumable declarations: exact open manifest rows now keep dynamic eval helpers, arguments eval helpers, helper direct-eval cache declines, synthetic activation-capture declines, runtime-source direct eval, private instance fields/method captures/static methods/computed private neighbors, non-production static-block plans, static-block IR fallback, and private/static/computed class declaration neighbors outside the admitted public method/computed/super/static subsets visible while direct root helpers, recursive/sibling helper graphs, block/Annex B declarations, simple class declarations, plain extends declarations whose superclass expression compiles as standalone unified bytecode, activation-safe explicit public derived constructors, eligible static-block-only class declarations, activation-safe computed public class declarations, public instance computed-member extends declarations, public non-computed instance-method extends declarations, public instance super-member and super-field extends declarations, public static super-member extends declarations, public non-computed static-field extends declarations with bytecode-compilable initializers including closure-producing static fields, non-extends public non-computed static-field declarations and mixes with public non-computed static methods/accessors when field initializers compile as standalone unified bytecode and member bodies do not capture activation, and non-extends declarations that mix public non-computed static fields with eligible static blocks, are already accounted for as admitted partial progress. Current class-declaration computed-name activation-call admission is a B36 proof lane, not evidence that B24h owns declaration binding or the broader class-definition environment bridge.
  • E4/E5 retirement work: remove the remaining tier-1 ExpressionProgram hot path and tier-2 ExecutionPlanRunner hot path after A/B/C parity is actually proven. The current E5 reachability text is classification evidence, not a retirement claim.

Needs-Handling Progress

The red boxes are broad remaining buckets, not untouched work. A bucket stays red until every shape in that family is gone. Track progress inside those buckets here so partial burn-down is visible.

Bucket Still red because Concrete progress already removed
R1 Activation model gaps Async-like broadening, broad generators, lexical-this arrows outside the admitted route, real arguments object semantics, runtime-dependent default parameters, and destructured parameters still need VM-owned execution. Simple literal defaults and folded literal defaults route through VM slot initialization; final rest identifier parameters route through VM setup; bounded implicit arguments spans are admitted; simple literal/parameter/binary activation now tries production bytecode before the old public/simple-IR shortcuts. The resumable VM (ExecuteResumable) used by generator/async bodies now also handles the NON-SUSPENDING value-computation tier — property reads (GetNamedProperty, GetComputedProperty with its RequireObjectCoercible/ResolvePropertyKey prelude), typeof (TypeOf, TypeOfIdentifier), and unary operators (UnaryPlus/UnaryMinus/UnaryLogicalNot/UnaryBitwiseNot/UnaryVoid) — so suspendable functions that read properties or apply unary/typeof between suspension points are now admitted by EvaluateResumable instead of declining to the interpreter. The resumable VM now also DISPATCHES synchronous calls between suspension points — non-optional f(), o.m(), o[k]() via PrepareIdentifierCallTarget/PrepareNamedCallTarget/PrepareComputedCallTarget plus CallInvocationBoundary, calling the same ExecutePreparedCall helper as the sync route. The generator/async closure is threaded onto UnifiedBytecodeResumeState.CallingEnvironment so it survives suspension and feeds the call path; a callee that itself suspends/throws/recurses is handled as a separate frame (proof: UnifiedBytecodeResumableCallDispatchTests). The resumable VM now also handles OPTIONAL CHAINS and OPTIONAL CALLS between suspension points — o?.a, o?.[k], o?.m(), f?.() via GetNamedPropertyOptional/JumpIfNullishReplaceUndefined/JumpIfShortCircuited/PrepareIdentifierOptionalCallTarget/PrepareNamedOptionalCallTarget — backed by a new UnifiedBytecodeResumeState.OperandStackShortCircuitFlags column (allocated only when program.RequiresShortCircuitStackFlags) that persists short-circuit state across suspension in lockstep with the operand stack (proof: UnifiedBytecodeResumableOptionalChainTests). The resumable VM now also resolves FREE/DYNAMIC IDENTIFIERS between suspension points — a free variable READ (yield outerVar) via LoadDynamicIdentifier and a free function CALL target (yield helper(x)) via PrepareDynamicIdentifierCallTarget, resolved by name against the live closure environment threaded onto UnifiedBytecodeResumeState.CallingEnvironment, so closure-captured/global reads and free calls observe the CURRENT value after a resume and an uninitialized free binding still throws ReferenceError (proof: UnifiedBytecodeResumableDynamicIdentifierTests). The resumable VM now also performs PROPERTY WRITES between suspension points — o.x = v, o[k] = v, this.x = v via SetNamedProperty/SetComputedProperty, with the assignment value allowed to suspend and strict-only throw-on-non-writable decided by the body's own strictness (threaded onto a new UnifiedBytecodeResumeState.IsStrict and applied via a per-step ScopeKind.Function scope frame) (proof: UnifiedBytecodeResumablePropertyWriteTests). The resumable VM now also performs SLOT UPDATES and SLOT ASSIGNMENTS between suspension points — x++/x--/++x/--x via UpdateSlot and x = v via StoreSlot — for parameter, var, and lexical let/const targets. UnifiedBytecodeResumeState carries a const-slot bitmap seeded from UnifiedBytecodeProgram.ConstSlotIndices and extended by TdzHeadInit, so let writes update the flat slot while const writes route and raise the VM-owned TypeError before mutation/coercion (proof: UnifiedBytecodeResumableSlotUpdateTests). The resumable VM now also performs PROPERTY UPDATES and DELETES between suspension points — o.x++/o[k]-- (prefix and postfix) via UpdateNamedProperty/UpdateComputedProperty and delete o.x/delete o[k] via DeleteNamedProperty/DeleteComputedProperty — reusing the sync UpdatePropertyValue/DeleteNamedProperty/DeleteComputedProperty helpers under the body's own strictness (state.IsStrict), so a strict update of a read-only property and a strict delete of a non-configurable property both throw (proof: UnifiedBytecodeResumablePropertyUpdateDeleteTests). The resumable VM now also materializes REGEX LITERALS between suspension points — /pat/flags via LoadRegexLiteral, the literal twin of the sync handler (read the interned pattern string + encoded flags byte from the program and build a FRESH RegExp via RegExpHelper.CreateRegExpLiteral against context.RealmState); the opcode is a pure constant materialization with no AwaitedProgram and no operand-stack-across-suspension concern, and a distinct RegExp is built per evaluation so per-evaluation lastIndex independence holds across loop turns (proof: UnifiedBytecodeResumableRegexLiteralTests). The resumable VM now also materializes OBJECT and ARRAY LITERALS between suspension points — {a, b: v, [k]: v, ...spread} via CreateObject/DefineObjectProperty/DefineComputedObjectProperty/ObjectSpread (plus the method/accessor opcodes DefineObjectMethod/DefineComputedObjectMethod/DefineObjectAccessor/DefineComputedObjectAccessor, allowlisted with handlers but only reachable once nested function literals are admitted) and [a, , b, ...spread] via CreateArray/ArrayPush/ArrayPushHole/ArraySpread — each literal built bottom-up on the operand stack from a FRESH Create* receiver that survives any sub-expression suspension on UnifiedBytecodeResumeState.OperandStack, reusing the sync VM's Define*/ApplyObjectLiteralSpread/EnumerateSpread helpers so computed-key coercion, own-enumerable spread copy with getter order, and array-hole semantics are identical, and a new object/array is materialized per evaluation (proof: UnifiedBytecodeResumableLiteralTests). The resumable VM now also DISPATCHES synchronous constructs between suspension points — non-optional new C(args) via ConstructInvocationBoundary, calling the same ExecutePreparedConstruct helper as the sync route with the constructor itself as new.target (B11). The constructor value and its arguments are pushed by ordinary value-loading ops (no dedicated Prepare*ConstructTarget opcode exists) and survive the suspension that precedes the construct on UnifiedBytecodeResumeState.OperandStack, mirroring the admitted CallInvocationBoundary; this-binding/prototype wiring, the non-constructor TypeError, and a throwing constructor (surfacing as the resumable Throw step) are identical to the sync handler, and spread-onto-construct routes through the same handler's spread branch. Super-construct (SuperConstructInvocationBoundary) stays declined (proof: UnifiedBytecodeResumableConstructDispatchTests). Async generators now have a first production route: simple-parameter direct-yield async function* bodies can initialize UnifiedBytecodeResumeState in AsyncGeneratorInvoker and settle { value, done } results from ExecuteResumable without constructing the IR runner for accepted programs (proof: UnifiedBytecodeAsyncGeneratorRouteTests). The resumable VM now also queries typeof of a FREE/DYNAMIC identifier between suspension points — typeof freeVar of a module/global/captured-or-unbound name via TypeOfDynamicIdentifier (B25), resolved against the same live UnifiedBytecodeResumeState.CallingEnvironment the admitted free reads/calls use, reusing the sync TypeOfDynamicIdentifier helper so an unbound name yields "undefined" with NO ReferenceError and a bound one yields its live type (proof: UnifiedBytecodeResumableTypeOfDynamicTests). Async-generator delegated yield* now also covers awaited sources by compiling the source expression to AwaitValue before the existing YieldStar driver, so yield* await ... routes through ExecuteResumable instead of the IR runner (proof: UnifiedBytecodeAsyncGeneratorRouteTests). Computed optional-start calls (o?.[k]()), super-construct calls, super-property deletes, remaining class-definition-state shapes, and dynamic declaration opcodes remain outside the admitted subset.
R2 Wider call invocation Complex receivers, complex computed keys, eval-sensitive calls, private-adjacent targets, and receiver-binding-sensitive families still need owned call semantics. Simple calls, constructs, spread calls, optional calls, super calls, ordinary identifier/member tagged-template calls (tag\x`, box.tag`x`), simple property-read call arguments, baseline single-hop optional named property-read call arguments such as fn(box?.value), optional-start named read chain call arguments such as fn(box?.child.value), fn(box?.value?.nested), and fn(box?.child?.value), baseline optional computed property-read call arguments such as fn(box?.[key]), optional-computed read chain call arguments such as fn(box?.[key].value), fn(box?.[key]?.value), and fn(box?.[key]?.[key]), optional-named-then-computed read chain call arguments such as fn(box?.prop[key]), fn(box?.a.b[key]), and fn(box?.prop?.[key]), and embedded dynamic-global named member calls such as Math.sqrt(...)` in supported expression spans have been admitted into production unified bytecode.
R3 Dynamic lookup Non-admitted dynamic lookup, closure-sensitive lookup, and dynamic activation lanes still need explicit bytecode ownership or hard pre-VM declines. Ordinary activation-resolved identifiers, selected direct-eval/with-backed lanes, admitted lexical/local reads, and dynamic global identifier reads used by accepted top-level script expressions no longer force the old generic route for accepted programs.
R4 Property and assignment neighbors Optional/super/private mutation, control-expression keys with member-call branches, unproven multi-computed receiver-prefix mutation, and remaining update/delete/write variants outside the accepted spans still need VM-owned semantics. A51j is now split into seven property-mutation children in docs/unified-bytecode-expansion-contract.md: public writes, compound/logical writes, updates, deletes, name-inference quarantine, key/RHS spans, and private receiver-prefix mutation neighbors. Many activation-resolved property read/write/update/delete families now compile to owned unified bytecode, including nested named writes, nested named prefix plus computed writes (box.child[key] = value, box.child[key + 1] = value), nested named prefix plus computed compound and logical writes (box.child[key] += value, box.child[key] &&= value, `
R5 Driver states Remaining driver-state work is no longer the base async-iterator or awaited-source path. The open work is residual driver slot/topology ownership in compiler leaves, multi-driver labeled cleanup, and class/closure interactions around suspension. Admitted sync loop and selected sync driver routes are already green, including forloop and forofiteration route-hit coverage. The resumable VM now also computes property reads and unary/typeof values between suspension points, so generator/async bodies that interleave value-tier reads with yield/await (e.g. yield o.a; yield -o.b; yield typeof o.c;) route through resumable production bytecode rather than declining on the value tier. It now additionally dispatches synchronous calls between suspension points (yield helper(o.a); yield o.compute(2);), so call-bearing generator/async bodies route resumably instead of declining on CallInvocationBoundary. It now also handles optional chains/optional calls between suspension points (yield o?.a; yield o?.m();), including a nullish short-circuit that straddles a yield/await, by persisting short-circuit state on UnifiedBytecodeResumeState.OperandStackShortCircuitFlags. It now additionally resolves FREE/DYNAMIC identifiers between suspension points — free reads (yield outerVar) and free function calls (yield helper(x)) resolved live against UnifiedBytecodeResumeState.CallingEnvironment — so generator/async bodies that reference module/global/captured bindings route resumably instead of declining on DynamicLookupDependency/CapturedOrDynamicActivation; sync yield* over a free/dynamic iterable or free call target now routes through the same VM-owned delegation path. It now additionally performs PROPERTY WRITES between suspension points (o.x = yield v; this.count = yield v; o[k] = yield v;), persisting the write's base/key on the operand stack across the suspension and honoring the body's strictness for the strict/sloppy non-writable-property distinction. It now additionally performs PROPERTY UPDATES and DELETES between suspension points (o.x++, o[k]--, delete o.x, delete o[k]), with the base/key persisted on the operand stack across the suspension and the body's strictness enforcing the strict throw on a read-only update / non-configurable delete. Async-generator direct-yield, non-awaited delegated yield*, and awaited-source yield* await ... bodies now use the same resumable state/result contract to settle async iterator results; the awaited-source form compiles the source expression through AwaitValue before the existing YieldStar driver, so it is no longer an IR-runner-only gap. Base IteratorDriverKind.Await / for await...of routing, awaited for (x of await p), awaited for (k in await p), and async iterator close settlement are VM-owned and no longer count as open driver-state gates.
R6 Destructuring model gaps Defaults, nested patterns, generic declarations, parameter destructuring, and disposal-aware destructuring targets still need VM-owned binding semantics. Selected declaration and assignment destructuring now route through the ApplyBindingTarget bridge inside accepted bytecode spans. Additionally, top-level (script-scope) simple var / let / const destructuring (var {a,b}=o;, let [x,y]=arr;, const {x}=o, object/array rest, holes) now routes through the step-wise destructuring driver with synthetic driver-state slots. Dynamic script var targets store by name, while dynamic script let / const targets use the VM's dynamic lexical declare/initialize path against the hoist-time TDZ binding.
R7 Top-level/script and fallback route coverage Top-level script execution now routes admitted scripts through production unified bytecode and keeps the remaining RunScriptViaClassifiedIrFallback helper as an explicitly classified fallback for non-admitted ordinary scripts plus terminal dynamic residue such as eval-injected runtime bindings. Broad script completion, abrupt completion, module, and dynamic script routes still need bytecode-owned semantics before the old script runner can be retired. PR #3081 moved simple activation and function-call workloads out of the zero-hit bucket: activation-noargs-lite now reports 600,000 production route hits and functioncalls-lite reports 1,600,000. The first narrow script route now models script completion in unified bytecode, admits the propertyaccess top-level loop, and moves propertyaccess from 0 to 20 production route hits. Slotless top-level let declarations and embedded dynamic-global named member calls now admit simplearithmetic, moving it from 0 to 10,000 production route hits. Top-level simple var / let / const destructuring declarations now route through the production VM as well.
R8 Retire fallback tiers The expression VM and statement IR runner are still active for unsupported or not-yet-admitted non-dynamic code. Full bytecode execution requires deleting or quarantining these fallback tiers once all required semantics are admitted. Source gates now prove accepted production routes do not call back into ExpressionProgram, ExecutionPlanRunner, or AST evaluation; old simple IR shortcuts have been moved behind production-bytecode eligibility for admitted ordinary sync functions. The generic ordinary-sync simple-return-expression fallback no longer executes ExpressionProgram in TryInvokeIrFast; after production bytecode, parameter/binary fast paths, and SyncIrCallTrampoline decline, it falls through to the classified fallback. ExecutionPlanRunner.EvaluateStandaloneExpressionProgram, TypedAstEvaluator.EvaluateLoweredExpressionProgram, TypedAstEvaluator.EvaluateDynamicExpressionProgram, ExecutionPlanRunner.ApplyStandaloneBindingTargetProgram, and UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic are deleted. Standalone, external lowered binding-target, and legacy expression-node/statement/loop value payloads now execute cached lowered ExpressionProgram payloads through standalone unified bytecode; profiler-only expression-program loops also execute through the unified VM.

Latest Concrete Admissions

Use this section as the visible progress ledger. Add a row whenever a real source shape starts using the production unified-bytecode VM, a fallback route is removed, or a proof gate becomes stricter.

Date Gate surface Concrete movement Proof signal
2026-06-10 Resumable invocation owns IteratorBindingInitialization: non-simple generator/async-generator parameter lists route Generators and async generators with destructuring patterns, defaults, and rest parameters previously FAILED EXPLICITLY (the E6/E5d boundary deleted their IR bridges, leaving no route) — this was the dominant Test262 failure family (class/dstr, async-generator/dstr, object/dstr, generators/dstr clusters; thousands of tests). TryBindNonSimpleResumableParameters now performs eager IteratorBindingInitialization at invocation time: parameters bind via the shared BindFunctionParameters in a transient environment (binding errors throw at the CALL, per FunctionDeclarationInstantiation), then the bound values seed the flat parameter slots before materialization. Parameter expressions whose function literals capture the function's OWN parameters stay declined (ResumableParameterShapeAllowsEagerBinding — the transient environment is discarded, so a retained closure would desynchronize from slot mutations); non-capturing literals (fn-name inference, IIFE counters) are admitted. Direct eval in parameters stays declined. Test262 cluster runs: generators_dstr 744/744, asyncGenerator_dstr 1116/1116, class_dstr 7680/7681, object_dstr 1122/1122 (each previously ~0%); UnifiedBytecodeResumableParameterBindingTests (10 route-asserted shapes incl. call-time throw timing, cross-yield mutation of destructured params, default ordering); 12 explicit-fail pins flipped to value-asserting route tests across 6 internal test classes; internal suite 7151/7151.
2026-06-10 B24h class-expression lane: constructor activation captures admitted Relaxed the constructor FunctionCapturesActivationSlot guard in TryAdmitB24hComputedPublicClassLiteral to the same IsMaterializedResumableBodyEnvironmentCapture filter member bodies already use — the lane's lone constructor outlier (member bodies and field initializers already routed with activation captures). ExpressionProgramHasActivationCapturingClassLiteralCallable already walks definition.Constructor, so a capturing constructor in a routed class literal forces the materialized body environment (PlanNeedsMaterializedResumableBodyEnvironment), and the resumable call/construct boundaries re-sync the environment into flat slots: constructors read the live binding at construct time (across yield/mutation, not declaration time), constructor writes to captured bindings are visible to subsequent body reads, a throwing constructor leaves the captured binding at its last written value with the error catchable in-body, and activation-call computed names like [helper(read)] compose with capturing constructors that call the same captured bindings. Supersedes the guard's "needs the broader class-definition environment bridge" classification (ADR 0367's open classification for this lane); the bridge residue anchor B24h-deferred-class-definition-environment-bridge-stays-open stays open for the remaining non-constructor deferral. Manifest rows B24h-computed-member-constructor-captures-activation-routes and B24h-computed-member-constructor-activation-write-back-routes (flipped from B24h-computed-member-constructor-captures-activation-declines); UnifiedBytecodeResumableClassExpressionTests eligibility admit (EvaluateResumable_ClassExpressionComputedMemberConstructorCapturesActivation_AdmitsLoadClassLiteral) plus 4 route-asserted runtime shapes (live-binding read across mutation, write-back across two constructions, throwing constructor keeps last write, call-argument computed-name capture); internal suite green.
2026-06-10 B36 computed-public class-declaration lane: constructor activation captures admitted Removed the constructor FunctionCapturesActivationSlot guard from TryAdmitB36ComputedPublicClassDeclaration — the lane's last conservative-sequencing decline. Every admitted resumable class declaration already forces the materialized body environment (PlanNeedsMaterializedResumableClassDeclarationEnvironment in all three resumable invokers) and the call/construct boundaries re-sync the environment into flat slots, so computed-member and computed-field class declarations with capturing constructors are runtime-safe: constructors read the live binding at construct time (across yield/mutation), constructor writes to outer bindings are visible to subsequent body and member reads, computed names still evaluate once at declaration time while constructors read at construct time, throwing computed keys propagate before the class binding initializes, and class-binding TDZ ReferenceErrors match IR on the routed path. The flip also unlocks extends shapes whose explicit super() constructors capture activation, since TryAdmitB36ComputedPublicInstanceMemberExtendsClassDeclaration composes this gate. Supersedes the guard's "needs the materialized body environment route" classification. The originally scoped manifest rows (B36-class-declaration-computed-member-activation-capture-routes, B36-class-declaration-computed-field-activation-capture-routes, B36-class-declaration-extends-computed-public-member-routes) were already admitted by earlier sibling slices; this row records the remaining constructor capture-gate removal. Manifest rows B36-class-declaration-computed-member-capturing-constructor-routes, B36-class-declaration-computed-field-capturing-constructor-routes, and B36-class-declaration-extends-computed-member-capturing-super-constructor-routes; UnifiedBytecodeResumableClassDeclarationTests eligibility admit (EvaluateResumable_ClassDeclarationComputedMemberCapturingConstructor_AdmitsDeclareClass) plus 7 route-asserted runtime shapes (capturing constructor with computed member/field, extends + capturing super() constructor, constructor write-back, throwing computed key, declaration-time key vs construct-time read, TDZ); internal suite green.
2026-06-10 B36 public-static-field class-declaration lane: constructor and member-body activation captures admitted Removed the constructor FunctionCapturesActivationSlot guard from TryAdmitB36PublicStaticFieldClassDeclaration and relaxed the member-body capture check to the IsMaterializedResumableBodyEnvironmentCapture filter already used by the B24h class-expression walker. Every admitted resumable class declaration forces the materialized body environment (PlanNeedsMaterializedResumableClassDeclarationEnvironment in all three resumable invokers) and the call/construct boundaries re-sync the environment into flat slots, so static-field-lane constructors and static/instance member bodies that read or write captured generator bindings are runtime-safe: members observe post-yield mutations, member writes to outer bindings are visible to subsequent body reads, capturing static field initializers snapshot at declaration time while capturing constructors read the live binding at construct time, and class-binding TDZ ReferenceErrors match IR on the routed path. Supersedes both guards' "outside B36 until the materialized body environment route owns that dependency" classification. The originally scoped manifest rows (B36-class-declaration-public-static-field-routes, B36-class-declaration-static-field-closure-routes, B36-class-declaration-mixed-static-field-and-block-routes) were already admitted by earlier sibling slices; this row records the remaining capture-gate removal. Manifest rows B36-class-declaration-static-field-capturing-constructor-routes, B36-class-declaration-static-member-activation-capture-routes, and B36-class-declaration-static-member-activation-write-back-routes; UnifiedBytecodeResumableClassDeclarationTests eligibility admits (flipped ..MixedPublicStaticMemberCapturesActivation.. and ..StaticFieldClosureAndStaticMemberCapturesActivation.. declines plus new ..StaticFieldCapturingConstructorAndCapturingFieldClosure_AdmitsDeclareClass) plus 5 route-asserted runtime shapes (capturing constructor, member write-back, post-yield mutation visibility, declaration-time vs construct-time order, TDZ); internal suite green.
2026-06-10 B36 private-instance class-declaration lane: constructor activation captures admitted Removed the constructor FunctionCapturesActivationSlot guard from TryAdmitB36PrivateInstanceClassDeclaration — the lane's last conservative-sequencing decline. Every admitted resumable class declaration already forces the materialized body environment (PlanNeedsMaterializedResumableClassDeclarationEnvironment in all three resumable invokers) and the call/construct boundaries re-sync the environment into flat slots, so private-instance constructors that read or write captured generator bindings are runtime-safe: they read the live binding at construct time (across yield/mutation) and constructor writes to outer bindings are visible to subsequent body reads. Brand-check TypeErrors on foreign receivers and class-binding TDZ ReferenceErrors match IR on the routed path. Supersedes the guard's "outside B36 until the materialized body environment route owns that dependency" classification. Manifest rows B36-class-declaration-private-constructor-captures-activation-routes and B36-class-declaration-private-constructor-activation-write-back-routes; UnifiedBytecodeResumableClassDeclarationTests eligibility admit (EvaluateResumable_ClassDeclarationPrivateInstanceConstructorCapturesActivation_AdmitsDeclareClass) plus 4 route-asserted runtime shapes (live-binding read across yield, closure write-back, brand check, TDZ); internal suite green.
2026-06-10 Resumable VM correctness: closure writes to captured generator bindings reach the flat slots Two pre-existing write-back bugs on the routed path (reproduced on clean origin/main): (1) write-only captures were invisible — slot-target mutation instructions (AssignmentSlotInstruction, CompoundAssignmentSlotInstruction, LogicalCompoundAssignmentSlotInstruction, IncrementSlotInstruction) carry the written identifier as instruction metadata, not expression-program ops, so a nested helper whose only outer reference was p = 9 / p += 2 / p++ never triggered the materialized body environment and its write landed on a sloppy global (or threw ReferenceError for compound forms); FunctionCapturesActivationSlot now also inspects slot-target instruction metadata. (2) Even with materialization, the resumable call/construct boundaries never re-synced the environment into the flat slots, so member-method and constructor writes to captured bindings were silently lost to subsequent slot reads; both boundaries now run SyncEnvironmentToUnifiedSlots after returning when slot environments exist. Helper/member/constructor writes now match IR value-for-value, including across generator completion and derived-constructor super chains. UnifiedBytecodeResumableClosureWriteBackTests (8 route-asserted shapes: helper write-only param/local, helper compound write, member-call write, constructor write, construct-time live-binding read, capture surviving generator completion, derived-constructor capture); internal suite 7108/7108; test262 language regression pack 92/92.
2026-06-10 B36 widening: static-field lane admits private statics and instance mixes TryAdmitB36PublicStaticFieldClassDeclaration now counts static fields explicitly instead of requiring every field/member to be static-public-non-computed: private static non-computed fields route (initializers run at class-definition time in static-element order, including activation-capturing initializers and private-static-reading initializers like static total = Box.#base + 2), private static non-computed methods/accessors ride along, and instance members/fields mix freely with static fields — so the everyday class A { static D = 1; getX() {} } shape routes through DeclareClass in resumable bodies. Computed statics and activation-capturing member bodies in this lane keep declining. EvaluateResumable_ClassDeclarationStaticFieldWithInstanceMethod_AdmitsDeclareClass, GeneratorPrivateStaticFieldClassDeclaration_RoutesResumableAndReadsThroughStaticMethod, GeneratorPrivateStaticFieldCapturingInitializer_RunsAtDeclarationTime, GeneratorPrivateStaticFieldClassDeclaration_BrandCheckTypeErrorIsCatchable, GeneratorStaticFieldWithInstanceMethod_RoutesResumable, GeneratorStaticFieldWithInstanceFieldAndMethod_RoutesResumable, GeneratorStaticFieldWithPrivateStaticAndInstanceMix_RoutesResumable, GeneratorStaticFieldOrdering_LaterInitializerSeesEarlierPrivateStaticField, and BytecodeProofManifestTests rows B36-class-declaration-static-field-shape-guard-routes and B36-class-declaration-static-member-shape-guard-routes.
2026-06-10 B36 widening: activation-capturing computed member bodies and computed field initializers route in class declarations TryAdmitB36ComputedPublicClassDeclaration now tolerates ordinary activation captures in computed member bodies and computed instance/static field initializers via the same IsMaterializedResumableBodyEnvironmentCapture tolerance the B24h class-expression walker uses — every admitted resumable class declaration already forces the materialized body-environment route, so capturing computed members observe post-declaration slot mutations and capturing computed field initializers read the live binding at construct time, matching IR value-for-value. Synthetic <...>/nested-declaration-boundary captures keep declining. GeneratorComputedMemberBodyCapturesActivation_RoutesResumableAndObservesMutation, GeneratorComputedFieldInitializerCapturesActivation_ReadsLiveBindingAtConstructTime, GeneratorComputedStaticFieldInitializerCapturesActivation_RoutesResumable, and BytecodeProofManifestTests rows B36-class-declaration-computed-member-activation-capture-routes and B36-class-declaration-computed-field-activation-capture-routes.
2026-06-10 B36 widening: private neighbors ride inside computed-public class declarations TryAdmitB36ComputedPublicClassDeclaration now mirrors the B24h class-expression walker's private tolerance: non-computed private instance methods/getters/setters and non-computed private fields no longer disqualify a computed-public class declaration, so class Box { #value() {...} [key]() { return this.#value(); } } routes through DeclareClass in resumable bodies with brand semantics identical to IR. Private computed members and private computed fields keep declining; the chained construct-call shape new Box().value() keeps declining through the A51g3 call-target lane (pinned by EvaluateResumable_ClassDeclarationComputedNeighborChainedConstructCall_StillDeclinesViaCallLane). EvaluateResumable_ClassDeclarationPrivateInstanceMethodWithComputedNeighbor_AdmitsDeclareClass, GeneratorComputedPublicMemberWithPrivateNeighbor_RoutesResumable, GeneratorComputedPublicMemberWithPrivateFieldNeighbor_RoutesResumable, GeneratorComputedPublicAccessorWithPrivateAccessorNeighbor_RoutesResumable, and BytecodeProofManifestTests row B36-class-declaration-private-instance-method-computed-neighbor-routes.
2026-06-10 B36 widening: private static non-computed methods/accessors route in class declarations TryAdmitB36PrivateInstanceClassDeclaration no longer declines private static non-computed members: static private brand state is owned by the shared CreateClassValueFromDeclaration machinery the DeclareClass opcode already executes, so static #m() bodies, activation-capturing static private accessors, brand-check TypeErrors on foreign receivers (Box.read.call({})), and private static/instance mixes behave identically to IR on the production route. Private static/computed fields and private/computed member mixes stay open per ADR 0369. EvaluateResumable_ClassDeclarationPrivateStaticMethod_AdmitsDeclareClass, GeneratorPrivateStaticMethodClassDeclaration_RoutesResumableAndCallsStaticPrivate, GeneratorPrivateStaticMethodClassDeclaration_BrandCheckTypeErrorIsCatchable, GeneratorCapturingPrivateStaticAccessor_ObservesPostDeclarationMutation, GeneratorPrivateStaticAndInstanceMix_RoutesResumable, and BytecodeProofManifestTests rows B36-class-declaration-private-static-method-routes and B36-class-declaration-private-static-accessor-captures-activation-routes.
2026-06-10 Resumable VM correctness: call/construct/property throw dispatch reaches body try frames 45 ExecuteResumable opcode handlers (call/construct invocation boundaries, named/computed/optional property reads, destructuring drivers, dynamic-identifier ops, update/compound targets, yield* delegation steps) previously completed the resumable frame with an escaping Throw step when a callee or property access threw, bypassing the body's own try frames — try { boom(); } catch {} in a routed generator let the throw escape iterator.next(). Every such site now attempts TryHandleResumableContextThrow() (the established dispatch other handlers already used) before completing, so in-body try/catch/finally semantics match IR; non-throw stops (host cancellation) still complete the frame unchanged. GeneratorThrowingCallInsideTry_RoutesResumableAndBindsCatch, GeneratorThrowingConstructInsideTry_RoutesResumableAndBindsCatch, GeneratorThrowingPropertyReadInsideTry_RoutesResumableAndBindsCatch, GeneratorThrowingCallInsideTryFinally_RunsCleanupAndBindsCatch, and GeneratorPrivateFieldClassDeclaration_BrandCheckTypeErrorIsCatchable; full UnifiedBytecodeResumableTryCatchTests and UnifiedBytecodeResumableClassDeclarationTests packs green.
2026-06-10 B36 widening: private instance fields and activation-capturing private member bodies route in class declarations TryAdmitB36PrivateInstanceClassDeclaration now admits non-static/non-computed private instance fields (initializers must compile as standalone unified bytecode; activation-capturing initializers read the live materialized body environment at construct time, so two constructs across a binding mutation observe different values exactly like IR) and no longer declines activation-capturing member bodies — every admitted resumable class declaration already forces the materialized body-environment route, the same lane public capturing members use. Private brand-check TypeErrors from routed member calls are catchable in-body after the resumable throw-dispatch fix. Private static members and private/computed mixes stay open per ADR 0369; constructor-body activation captures stay declined until the class-definition environment bridge. EvaluateResumable_ClassDeclarationPrivateInstanceField_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationPrivateInstanceFieldCapturesActivation_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationPrivateInstanceMethodCapturesActivation_AdmitsDeclareClass, GeneratorPrivateInstanceFieldClassDeclaration_RoutesResumableAndInitializesField, GeneratorPrivateFieldCapturingInitializer_ReadsLiveBindingAtConstructTime, GeneratorCapturingPrivateMethod_ObservesPostDeclarationMutation, and BytecodeProofManifestTests rows B36-class-declaration-private-instance-field-routes, B36-class-declaration-private-field-capturing-initializer-routes, and B36-class-declaration-private-instance-method-captures-activation-routes.
2026-06-09 B24h widening: activation delete/construct computed names route The B24h computed-name walker now owns DeleteIdentifier as an activation operation (the synthesized class-literal environment and the materialized body environment both resolve the binding as a non-deletable declarative slot, and class computed names evaluate as strict code, so [delete key] throws the same strict-mode SyntaxError on the production route as on IR) and admits Construct boundaries over owned activation operands ([new MakeName()], [new MakeName(key)], [new MakeName(...args)] resolve the construct target and arguments through the synthesized class-literal environment; direct eval and Call/SuperConstruct combos keep declining through the call lane). This supersedes ADR 0368's open classification with positive route proof for both class expressions and class declarations. EvaluateResumable_ClassExpressionComputedNameActivationConstruct_RoutesLoadClassLiteral (+ argument/spread/field variants), GeneratorComputedNameActivationDelete_RoutesResumableAndThrowsStrictModeSyntaxError, GeneratorClassDeclarationComputedNameActivationDelete_RoutesResumableAndThrowsStrictModeSyntaxError, and BytecodeProofManifestTests rows B24h-computed-name-activation-delete-routes, B24h-computed-field-name-activation-delete-routes, B24h-computed-name-activation-construct-routes, B24h-computed-name-activation-construct-argument-routes, and B24h-computed-name-activation-construct-spread-routes.
2026-06-08 E4 closure: dynamic expression executor tombstoned The last live E4 dynamic expression payload bridge is removed. ExpressionNode now owns the cached lowered ExpressionProgram payload, LoweredExpressionProgramCache.ExecuteCached(...) routes value-only legacy operands through UnifiedBytecodeExpressionProgramExecutor.ExecuteStandalone(...), and the old executor-owned ConditionalWeakTable cache plus UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic(...) definition are deleted. E4 is now absence-ratcheted; remaining runner-internal expression execution stays in E5. PR #3513 merged commit 901ee8a809485e5383dbd464267ca6df5047bbfc; SourceGate_DynamicExpressionExecutor_IsCompletelyRemoved; BytecodeProofManifestTests rows E4-dynamic-expression-executor-call-sites-removed and E4-dynamic-expression-executor-definition-removed; focused build-stage verification passed diagnostics/manifest tests, AstFreeExecutionAssertionTests, git diff --check, and production source scans.
2026-06-08 A2 partial: resumable bounded arguments direct eval Resumable generators, async functions, and async generators now admit declaration-free single-literal direct eval that reads the caller's implicit arguments object, such as eval("arguments[0]") and eval("arguments.length"). The resumable route materializes the body environment and arguments object for the eval host while keeping declaration-bearing, runtime-source, spread/multi-arg eval, captured dynamic activation, and retained live-with closure chains on no-route rows. GeneratorDirectEvalArgumentsRead_RoutesResumableAndProducesValue, AsyncDirectEvalArgumentsRead_RoutesResumableAndResolves, AsyncGeneratorDirectEvalArgumentsRead_RoutesResumableAndSettles, and BytecodeProofManifestTests rows A2-resumable-generator-bounded-arguments-direct-eval-routes, A2-resumable-async-bounded-arguments-direct-eval-routes, and A2-resumable-async-generator-bounded-arguments-direct-eval-settles.
2026-06-08 B24h rebaseline: computed-name construct residue B24h computed class-expression name inventory now keeps activation-safe direct calls and immediate function-literal calls admitted while reclassifying activation-dependent new MakeName(...) computed-name shapes as no-route residue. The manifest construct rows now assert UnsupportedPlanShape with the activation-dependent call or construct reason instead of requiring the generator production fast-path log, matching the current class-definition environment boundary. Checklist totals stay unchanged because this is an inventory/proof rebaseline. EvaluateResumable_ClassExpressionComputedNameActivationConstruct_DeclinesLoadClassLiteral, EvaluateResumable_ClassExpressionComputedNameActivationConstructArgument_DeclinesLoadClassLiteral, EvaluateResumable_ClassExpressionComputedNameActivationConstructSpread_DeclinesLoadClassLiteral, and BytecodeProofManifestTests rows B24h-computed-name-activation-construct-declines, B24h-computed-name-activation-construct-argument-declines, and B24h-computed-name-activation-construct-spread-declines.
2026-06-08 A51f5 manifest closeout: private-neighbor proof anchors The proof manifest now carries the A51f5 row promised by the finite open-row inventory: admitted anchors for private reads as operands, single-hop optional private reads, private receiver-prefix named calls, public writes, and public updates, plus explicit open anchors for compound/private-terminal/deeper-prefix mutation neighbors. No checklist counts change; this is an inventory/proof rebaseline only. BytecodeProofManifestTests rows A51f5-private-read-operand-eligibility-anchor-present, A51f5-optional-private-read-eligibility-anchor-present, A51f5-private-receiver-prefix-call-anchor-present, A51f5-private-receiver-prefix-write-anchor-present, A51f5-private-receiver-prefix-update-anchor-present, A51f5-private-receiver-prefix-mutation-neighbors-stay-open, A51f5-private-terminal-write-neighbor-stays-open, and A51f5-deeper-private-prefix-update-neighbor-stays-open.
2026-06-07 A51f5 partial: private receiver-prefix public updates The one-hop private receiver-prefix public update shapes receiver.#child.value++ and receiver.#child[key]++ now route through production unified bytecode by composing a single non-optional private receiver read with UpdateNamedProperty / UpdateComputedProperty. The slice preserves receiver targeting, prefix/postfix update behavior, single computed-key coercion, and brand-check-before-key semantics; deeper private-prefix update chains plus compound/logical/private-terminal mutation neighbors remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_PrivateReceiverPrefixNamedUpdate_AcceptsOwnedPropertyOpcodes, Evaluate_PrivateReceiverPrefixComputedUpdate_AcceptsOwnedPropertyOpcodes, Evaluate_PrivateReceiverPrefixDeepNamedUpdate_StillDeclines, PrivateReceiverPrefixNamedPropertyUpdate_TargetsReceiverChildAndUsesUnifiedBytecodeProductionFastPath, PrivateReceiverPrefixComputedPropertyUpdate_EvaluatesKeyOnceOnProductionFastPath, and PrivateReceiverPrefixComputedPropertyUpdate_BrandFailureSkipsKey; focused private receiver-prefix pack passed 23 tests.
2026-06-07 B24c proof: static field closure initializers in class expressions Pure public non-computed static-field class expressions now route through resumable LoadClassLiteral even when a top-level static field initializer creates an activation-capturing function literal, such as static read = () => current. The class expression requests the materialized resumable body environment, so the closure observes later slot mutations; object-method/accessor and nested-class initializers inside static fields remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134 because B24c was already checked, but the B24c proof is now explicit in the manifest. EvaluateResumable_ClassExpressionStaticFieldClosureInitializer_AdmitsLoadClassLiteral, GeneratorStaticFieldClosureInitializer_RoutesResumableAndObservesLaterActivationMutation, still-declined EvaluateResumable_UnownedClassExpressionShapes_DeclineBeforeVm cases for object method/accessor and nested class initializers, and BytecodeProofManifestTests row B24c-static-field-closure-initializer-routes; focused B24 pack passed 8 tests.
2026-06-07 A51f5 partial: private receiver-prefix computed public writes The private receiver-prefix public computed write receiver.#child[key] = value now routes through production unified bytecode by composing one non-optional private receiver read with the existing computed-key span and SetComputedProperty. The slice preserves receiver targeting, single key coercion, and brand-check-before-key/RHS semantics; compound/logical/private-terminal, optional-private, and deeper private-prefix mutation neighbors remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_PrivateReceiverPrefixComputedWrite_AcceptsOwnedPropertyOpcodes, PrivateReceiverPrefixComputedPropertyWrite_TargetsReceiverChildAndUsesUnifiedBytecodeProductionFastPath, and PrivateReceiverPrefixComputedPropertyWrite_BrandFailureSkipsKeyAndRhs; focused private receiver-prefix pack passed 19 tests.
2026-06-07 A51f5 partial: private receiver-prefix named writes The minimal private receiver-prefix public named write receiver.#child.value = value now routes through production unified bytecode by composing one non-optional private receiver read with SetNamedProperty. The slice preserves brand-check-before-RHS semantics and writes to the child object of the receiver argument; compound/logical/private-terminal, optional-private, and deeper private-prefix mutation neighbors remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_PrivateReceiverPrefixNamedPropertyWrite_AcceptsOwnedPropertyOpcodes, still-declined neighbor tests for compound/logical/private-terminal writes, PrivateReceiverPrefixNamedPropertyWrite_TargetsReceiverChildAndUsesUnifiedBytecodeProductionFastPath, PrivateReceiverPrefixNamedPropertyWrite_PreservesBrandCheckOnProductionFastPath, and PrivateReceiverPrefixNamedPropertyWrite_BrandFailureSkipsRhs; focused private receiver-prefix pack passed 17 tests.
2026-06-07 B36 partial: static field closure initializers without extends Direct root class declarations without extends now route through resumable DeclareClass when a public non-computed static field initializer creates an activation-capturing closure. The closure is created against the materialized class-declaration/body environment and observes later resumable slot mutations; static member/constructor bodies that capture activation still decline. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. EvaluateResumable_ClassDeclarationStaticFieldClosureInitializer_AdmitsDeclareClass, GeneratorClassDeclarationStaticFieldClosureInitializer_RoutesResumableAndObservesLaterActivationMutation, EvaluateResumable_ClassDeclarationStaticFieldClosureAndStaticMemberCapturesActivation_StillDeclines, and BytecodeProofManifestTests row B36-class-declaration-static-field-closure-routes; focused static-field-closure pack passed 6 tests.
2026-06-07 A51f3 partial: zero-depth catch free stores Zero-depth catch/finally-region plain free identifier stores now enable the ordinary dynamic-name production route. The eligibility scanner admits only the statement-level AssignmentSlotInstruction shape, and the compiler emits ResolveDynamicIdentifierReference followed by StoreDynamicIdentifierReference; consumed assignment references, updates, compound/logical writes, and deletes remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. ContainsOrdinaryDynamicIdentifierDependency_ZeroDepthCatchFreeStore_EnablesOrdinaryDynamicNamePath, ContainsOrdinaryDynamicIdentifierDependency_ZeroDepthCatchConsumedFreeStore_DoesNotEnableOrdinaryDynamicNamePath, ContainsOrdinaryDynamicIdentifierDependency_ZeroDepthCatchFreeUpdate_DoesNotEnableOrdinaryDynamicNamePath, TryCatch_CatchOnlyFreeStore_UsesUnifiedBytecodeProductionFastPath, and BytecodeProofManifestTests row A51f3-zero-depth-catch-free-store-routes; focused A51f3 pack passed 8 tests.
2026-06-07 B36 partial: public static fields and static members without extends Direct root class declarations without extends now route through resumable DeclareClass when their class body contains public non-computed static fields, including mixes with public non-computed static methods/accessors. Static field initializers must compile as standalone unified bytecode; static member/constructor bodies must not capture resumable activation slots. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. EvaluateResumable_ClassDeclarationPublicStaticField_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationMixedPublicStaticFieldAndMethod_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationMixedPublicStaticFieldAndAccessor_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationMixedPublicStaticMemberCapturesActivation_StillDeclines, GeneratorClassDeclarationPublicStaticField_RoutesResumableAndReadsActivation, GeneratorClassDeclarationMixedPublicStaticFieldAndMethod_RoutesResumableAndInitializesInOrder, GeneratorClassDeclarationMixedPublicStaticFieldAndAccessor_RoutesResumableAndPreservesReceiver, and BytecodeProofManifestTests rows B36-class-declaration-public-static-field-routes, B36-class-declaration-mixed-static-public-field-and-method-routes, and B36-class-declaration-mixed-static-public-field-and-accessor-routes; focused static-field pack passed 19 tests.
2026-06-07 B36 partial: public instance accessors with extends Direct root extends class declarations now route through resumable DeclareClass when their class body contains public non-computed instance getters/setters without super, such as class Box extends Base { get value() { return seed + 1; } set value(next) { this.storage = next + seed; } }. This proves the outer class declaration route, superclass preservation, descriptor behavior, and materialized body-environment capture for accessor bodies. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. EvaluateResumable_ClassDeclarationExtendsPublicInstanceAccessor_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicInstanceAccessor_RoutesResumableAndPreservesDescriptor, and BytecodeProofManifestTests row B36-class-declaration-extends-public-accessor-routes; focused accessor pack passed 2 tests.
2026-06-07 B36 partial: public instance methods with extends Direct root extends class declarations now route through resumable DeclareClass when their class body contains ordinary public non-computed instance methods without super, such as class Box extends Base { value() { return seed + 1; } }. This proves the outer class declaration route, superclass construction, instanceof, and captured-value correctness; it does not claim member-body production routing. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. EvaluateResumable_ClassDeclarationExtendsPublicInstanceMethod_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsPrivateInstanceMethod_StillDeclines, and GeneratorClassDeclarationExtendsPublicInstanceMethodCapturesActivation_RoutesResumableAndPreservesSuperclass; focused B36 class-declaration pack passed 60 tests.
2026-06-07 A51f3 partial: zero-depth catch free typeof Zero-depth catch/finally-region typeof of a free identifier now enables the ordinary dynamic-name production route through a typeof-only exception-region scan. typeof externalValue and typeof missing route through TypeOfDynamicIdentifier, preserving "undefined" for unbound names. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. ContainsOrdinaryDynamicIdentifierDependency_ZeroDepthCatchFreeTypeOf_EnablesOrdinaryDynamicNamePath and TryCatch_CatchOnlyFreeTypeOf_UsesUnifiedBytecodeProductionFastPath; focused A51f3 pack passed 5 tests.
2026-06-07 A51f5 partial: private receiver-prefix named calls Private receiver-prefix named calls now route through production unified bytecode. The compiler lowers the private prefix read before PrepareNamedCallTarget, so receiver.#child.value() preserves the method receiver and brand checks while staying on the fast path. The later named/computed-write and named/computed-update rows above admit public mutations from the same one-hop prefix; compound/logical/private-terminal write neighbors, deeper private-prefix update chains, chained optional-private neighbors, and private super/member call-neighbor diagnostics remain declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_PrivateReceiverPrefixNamedCall_AcceptsCallTargetPreparation and PrivateReceiverPrefixNamedCall_PreservesReceiverAndUsesUnifiedBytecodeProductionFastPath; focused private receiver-prefix pack passed 8 tests.
2026-06-07 A51f3 partial: zero-depth catch free reads Zero-depth catch/finally-region free identifier reads now enable the ordinary dynamic-name production route through a read-only exception-region scan. try { throw 1; } catch (e) { return externalValue + e; } routes through LoadDynamicIdentifier. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. ContainsOrdinaryDynamicIdentifierDependency_ZeroDepthCatchFreeRead_EnablesOrdinaryDynamicNamePath and TryCatch_CatchOnlyFreeRead_UsesUnifiedBytecodeProductionFastPath; focused A51f3 pack passed 3 tests.
2026-06-07 A51f5 partial: single-hop optional private reads Single-hop optional private named reads now route through production unified bytecode via GetNamedPropertyOptional, reusing the VM's private-aware GetNamedPropertyValue path while preserving nullish short-circuiting. This admits receiver?.#field and keeps chained optional-private receiver neighbors, private mutation/call neighbors, and private super/member call neighbors declined. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_OptionalPrivateNamedPropertyRead_AcceptsOptionalNamedPropertyOpcode and OptionalPrivateNamedPropertyRead_UsesUnifiedBytecodeProductionFastPath; focused optional-private pack passed 2 tests.
2026-06-07 A51f5 partial: plain private reads as value operands Plain private named reads now route when used as simple nested value operands inside binary/RHS spans. This moves receiver.#field + delta, this.#x = this.#x + a, this.#x += this.#x, and private-read class-constructor RHS stores through production unified bytecode via the existing private-name-aware GetNamedProperty VM path. A51f5 remains open for private delete-defense/manual-plan diagnostics, chained optional-private receiver neighbors, private-adjacent compound/logical/private-terminal write and call shapes, deeper private-prefix update chains, and private super/member call-neighbor diagnostics. Checklist totals stay 128 / 145, A+B+C+D stays 120 / 134. Evaluate_PrivateNamedPropertyReadAsBinaryOperand_AcceptsNamedPropertyOpcode, PrivateNamedPropertyReadAsBinaryOperand_UsesUnifiedBytecodeProductionFastPath, BaseCtor_WithPrivateReadAsNestedOperand_RoutesAndIsCorrect, PrivateFieldWrite_ComplexRhsPrivateRead_RoutesAndComputes, and PrivateCompound_PrivateReadRhs_RoutesAndComputes; focused private-read pack passed 70 tests.
2026-06-07 A7 closure: private-name constructor activation Base and derived class constructors with private-name class state now route through production unified bytecode when the constructor body uses admitted private mutation shapes or only needs private brand/field initialization. The production constructor bridge initializes private brands/fields and enters own/captured private-name scopes before VM execution. The later A51f5 row above admits plain private-read RHS operands too. Checklist is now 128 / 145, A+B+C+D is 120 / 134, with 14 concrete A+B+C+D rows still open. BaseCtor_WithDirectPrivateFieldWrite_RoutesAndInitializesPrivateState, BaseCtor_WithPrivateBrandOnly_RoutesAndInitializesPrivateState, DerivedCtor_WithPrivateFieldWrite_RoutesAndInitializesPrivateState, DerivedCtor_WithPrivateBrandOnly_RoutesAndInitializesPrivateState, BaseCtor_WithPrivateReadAsNestedOperand_RoutesAndIsCorrect, and BytecodeProofManifestTests row A7-private-name-constructor-routes.
2026-06-07 B24h/B36 partial: declaration-free literal direct eval in static blocks Static blocks inside public-computed class expressions and direct root class declarations now route when they contain a declaration-free single-literal direct eval statement, such as eval("current = current + 1"). The eval statement runs inside the static-block production bytecode path, mutates the surrounding resumable binding, and still forbids the classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; the executable static-block eval residue moves to runtime-source eval. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockDirectEvalLiteral_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockDirectEvalLiteral_RoutesResumable, EvaluateResumable_ClassDeclarationStaticBlockDirectEvalLiteral_AdmitsDeclareClass, GeneratorClassDeclarationStaticBlockDirectEvalLiteral_RoutesResumable, and BytecodeProofManifestTests rows B24h-computed-static-block-direct-eval-literal-routes, B24h-computed-static-block-runtime-source-direct-eval-declines, B36-class-declaration-static-block-direct-eval-literal-routes, and B36-class-declaration-static-block-runtime-source-direct-eval-declines.
2026-06-07 B24h partial: activation construct spreads in computed names Resumable class expressions now route public computed member names whose name program directly constructs an activation-resolved constructor with spread arguments, such as [new MakeName(...args)]. The construct skipper still requires the activation-resolved constructor load and terminal Construct, while the existing production complex-call-argument walker validates each logical argument value and the compiler/VM carry the construct spread mask through ConstructInvocationBoundary. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; the static-block literal direct-eval row above narrows the executable B24h open proof to runtime-source eval. EvaluateResumable_ClassExpressionComputedNameActivationConstructSpread_AdmitsLoadClassLiteral, GeneratorComputedNameActivationConstructSpread_RoutesResumableAndSpreadsArguments, and BytecodeProofManifestTests row B24h-computed-name-activation-construct-spread-routes; later manifest rows own the current open proof IDs.
2026-06-07 B24h partial: activation construct arguments in computed names Resumable class expressions now route public computed member names whose name program directly constructs an activation-resolved constructor with non-spread arguments, such as [new MakeName(key)]. The B24h scanner validates the constructor argument region with the production complex-call-argument walker and only admits a terminal Construct, preserving constructor-then-argument evaluation; the follow-up spread row extends the same route to spread arguments. The runtime proof passes the computed name through the constructed object's toString. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; later static-block rows narrow the executable B24h open proof to runtime-source direct eval. EvaluateResumable_ClassExpressionComputedNameActivationConstructArgument_AdmitsLoadClassLiteral, GeneratorComputedNameActivationConstructArgument_RoutesResumable, and BytecodeProofManifestTests row B24h-computed-name-activation-construct-argument-routes.
2026-06-07 B24h partial: no-argument activation constructs in computed names Resumable class expressions now route public computed member names whose name program directly constructs an activation-resolved constructor with no arguments, such as [new MakeName()]. The B24h scanner recognizes the constructor load plus terminal Construct span as owned when the constructor identifier resolves to the resumable activation; the later argument/spread rows extend this construct path to argument-bearing constructs. The runtime proof checks the generator fast path and constructs a property-key object whose toString names the computed method. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; later static-block rows narrow the executable B24h open proof to runtime-source direct eval. EvaluateResumable_ClassExpressionComputedNameActivationConstruct_AdmitsLoadClassLiteral, GeneratorComputedNameActivationConstruct_RoutesResumable, and BytecodeProofManifestTests row B24h-computed-name-activation-construct-routes.
2026-06-07 B24h/B36 partial: activation-capturing static-block nested class declarations Static blocks may now contain nested class declarations whose constructor/member bodies capture outer resumable activation bindings. PlanNeedsMaterializedResumableBodyEnvironment detects those nested class declarations inside class static-block plans, so the surrounding resumable class route materializes the live body environment before class creation. The sync function production descriptor now allows the existing captured-closure path to use materialized-body-environment function/class-member bodies, and the captured nested class methods log production bytecode instead of ExecutionPlanRunner. Runtime proofs cover both a computed-member class expression and a mixed static-field/static-block class declaration, require the resumable generator fast path, unified-bytecode-production-fast-path static-block, a captured nested class method production fast-path log, and no classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; static-block nested class declarations are no longer a remaining B24h/B36 gate. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockClassDeclaration_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockNestedClassDeclarationCapturingActivation_RoutesResumable, EvaluateResumable_ClassDeclarationMixedStaticFieldAndBlockClassDeclaration_AdmitsDeclareClass, GeneratorClassDeclarationMixedStaticFieldAndBlockNestedClassDeclarationCapturingActivation_RoutesResumable, and BytecodeProofManifestTests rows B24h-computed-static-block-nested-class-captures-activation-routes and B36-class-declaration-mixed-static-field-and-block-nested-class-captures-activation-routes.
2026-06-07 B24h/B36 partial: noncapturing static-block nested class declarations Static blocks may now contain nested class declarations when the nested class definition does not capture an outer resumable activation binding. The B24d/B24h/B36 static-block validators were narrowed from rejecting all nested class declarations to admitting noncapturing nested classes through the existing DeclareClass opcode inside the static-block production VM path. Runtime proofs cover both a computed-member class expression and a mixed static-field/static-block class declaration, require the resumable generator fast path, unified-bytecode-production-fast-path static-block, a nested class method production fast-path log, and no classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; the later captured nested-class row removes the activation-capturing remainder. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockNestedClassDeclaration_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockNestedClassDeclaration_RoutesResumable, EvaluateResumable_ClassDeclarationMixedStaticFieldAndBlockNestedClassDeclaration_AdmitsDeclareClass, GeneratorClassDeclarationMixedStaticFieldAndBlockNestedClassDeclaration_RoutesResumable, and BytecodeProofManifestTests rows B24h-computed-static-block-nested-class-declaration-routes and B36-class-declaration-mixed-static-field-and-block-nested-class-declaration-routes.
2026-06-07 B24h/B36 partial: static-block function declarations Static blocks that contain descriptor-backed function declarations now stay on production bytecode when the surrounding resumable class route has a materialized body environment. The static-block body eligibility path allows materialized function declarations, static-block execution passes that same descriptor into the VM, and PlanNeedsMaterializedResumableBodyEnvironment now detects function declarations inside class static-block plans so closures observe later resumable slot mutations. Runtime proofs cover both a computed-member class expression and a mixed static-field/static-block class declaration; both require the resumable generator fast path, unified-bytecode-production-fast-path static-block, the nested readLater production fast path, and no classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134; the later nested-class rows supersede the earlier static-block class-declaration decline proofs. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockFunctionDeclaration_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockFunctionDeclaration_RoutesResumableAndObservesLaterActivationMutation, EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockClassDeclaration_AdmitsLoadClassLiteral, EvaluateResumable_ClassDeclarationMixedStaticFieldAndBlockFunctionDeclaration_AdmitsDeclareClass, GeneratorClassDeclarationMixedStaticFieldAndBlockFunctionDeclaration_RoutesResumableAndObservesLaterActivationMutation, EvaluateResumable_ClassDeclarationMixedStaticFieldAndBlockClassDeclaration_AdmitsDeclareClass, and BytecodeProofManifestTests rows B24h-computed-static-block-function-declaration-routes and B36-class-declaration-mixed-static-field-and-block-function-declaration-routes; later manifest rows own the current open proof IDs.
2026-06-07 B36 partial: mixed public static fields and static blocks Direct root class declarations now route through resumable DeclareClass when their static element order mixes public non-computed static fields with production-eligible static blocks. The B36 validator now checks static field/block order metadata, compiles every static field initializer as standalone unified bytecode, rejects non-public/computed/static-field variants, and keeps the remaining static-block boundary focused on non-production static-block plans. Runtime proof preserves class-definition order for static value = seed; static { Box.other = Box.value + 1; }, requires the resumable generator fast-path log plus unified-bytecode-production-fast-path static-block, and forbids the classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B36 still open for dynamic/eval helpers, non-production static blocks, B36-class-declaration-static-field-shape-guard-stays-open, B36-class-declaration-static-block-computed-static-field-declines, B36-class-declaration-static-member-shape-guard-stays-open, B36-class-declaration-computed-member-activation-capture-stays-open, and B36-class-declaration-computed-field-activation-capture-stays-open. EvaluateResumable_ClassDeclarationMixedStaticFieldAndBlock_AdmitsDeclareClass, GeneratorClassDeclarationMixedStaticFieldAndBlock_RoutesResumableAndPreservesOrder, and BytecodeProofManifestTests row B36-class-declaration-mixed-static-field-and-block-routes.
2026-06-08 B36 rebaseline: dynamic/eval helper decline anchors The B36 open residue is now split into exact executable/source anchors instead of one broad helper bucket. Hoisted helper declarations still decline when the surrounding resumable body has runtime-source direct eval or an arguments-dependent direct eval, and helper collection still keeps direct-eval helper bodies and synthetic activation captures outside the resumable route. This is taxonomy/test/manifest refinement only: no B36 route is widened and the checklist totals stay unchanged. GeneratorHoistedFunctionDeclarationWithRuntimeSourceEval_DeclinesExplicitly, GeneratorHoistedFunctionDeclarationWithArgumentsEval_DeclinesExplicitly, and BytecodeProofManifestTests rows B36-resumable-dynamic-eval-helper-activation-decline-stays-open, B36-resumable-arguments-eval-helper-decline-stays-open, B36-resumable-helper-direct-eval-cache-decline-anchor-stays-open, and B36-resumable-helper-synthetic-activation-capture-decline-anchor-stays-open.
2026-06-07 B24h partial: computed-name spread calls Resumable class expressions now route public computed member names whose activation-resolved call target uses a spread argument list, such as [read(...args)](). The B24h scanner now treats spread calls like other admitted activation-target calls after the production complex-call-argument walker validates the argument operands; the runtime proof checks the generator fast path and the production invocation of the spread-called function/method. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedNameSpreadCall_AdmitsLoadClassLiteral, GeneratorComputedNameSpreadCall_RoutesResumableAndSpreadsActivationArguments, and BytecodeProofManifestTests row B24h-computed-name-spread-call-routes; later manifest rows own the current open proof IDs.
2026-06-07 B24d/B24h partial: closure-producing static blocks Static-block-only class expressions and public computed-member class expressions now route static blocks that create activation-capturing closures when the static-block plan is production-bytecode eligible and contains no nested class declarations. PlanNeedsMaterializedResumableBodyEnvironment now detects LoadClassLiteral static-block plans that need the materialized body environment, and runtime proofs require the resumable generator fast-path log, unified-bytecode-production-fast-path static-block, the closure function production fast-path log, and no classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockClosureNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockClosureNeighbor_RoutesResumableAndObservesLaterActivationMutation, GeneratorStaticBlockClosure_RoutesResumableAndObservesLaterActivationMutation, and BytecodeProofManifestTests rows B24d-static-block-closure-routes and B24h-computed-static-block-closure-neighbor-routes.
2026-06-07 B24h partial: mixed static-block neighbors with computed members Resumable class expressions now route public computed members that coexist with eligible closure-free static blocks. The selector validates static element order, requires each static-block body to be production-unified-bytecode eligible before admitting the outer LoadClassLiteral, and the later row above extends this route to static blocks that create activation-capturing closures. The runtime proof requires both the resumable generator fast-path log and unified-bytecode-production-fast-path static-block, and forbids the classified static-block IR fallback. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithStaticBlockNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithStaticBlockNeighbor_RoutesResumableAndRunsStaticBlockBytecode, and BytecodeProofManifestTests row B24h-computed-static-block-neighbor-routes.
2026-06-07 B24h partial: private static field super initializers with computed members Resumable class expressions now route public computed members that coexist with private static fields whose initializers use super, such as static #value = super.value + 1. The runtime proof reads the private static value through a public static method after class creation, preserving the static receiver and private brand setup. The rows above extend B24h to eligible static-block neighbors. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateStaticFieldInitializerSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateStaticFieldInitializerSuper_RoutesResumableAndPreservesReceiver, and BytecodeProofManifestTests row B24h-computed-private-static-field-super-routes.
2026-06-07 B24h partial: private static field activation initializers with computed members Resumable class expressions now route public computed members that coexist with private static fields whose initializers read/write resumable activation slots, such as static #value = (current = current + 1). The runtime proof reads the private static slot through a public static method and checks the resumed current slot after class creation, so the class-literal slot environment and post-creation sync are both covered. The row above extends the same private-static initializer route to super. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateStaticFieldActivationInitializer_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateStaticFieldActivationInitializer_RoutesResumableAndSyncsPrivateStaticValue, and BytecodeProofManifestTests row B24h-computed-private-static-field-captures-activation-routes.
2026-06-07 B24h partial: private static field neighbors with computed members Resumable class expressions now route public computed members that coexist with activation-safe private static fields, such as ["read"]() { return 42; } next to static #value = 41. The runtime proof reads the private static slot through a public static method, so this proves class creation initializes private static state instead of merely ignoring the neighbor. Later rows extend that route to activation-reading/updating and super private static initializers. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateStaticFieldNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateStaticFieldNeighbor_RoutesResumableAndReadsPrivateStaticField, and BytecodeProofManifestTests row B24h-computed-private-static-field-neighbor-routes.
2026-06-07 B24h partial: private field initializer super with computed members Resumable class expressions now route public computed members that coexist with private instance fields whose initializer uses super, such as ["read"]() { return this.#value + 1; } next to #value = super.value. The same LoadClassLiteral path already owned public computed field super; the private field route now preserves the superclass receiver and private brand setup. Later rows extend the private field/static neighbor set to activation-safe private static fields and private static super initializers. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateFieldInitializerSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateFieldInitializerSuper_RoutesResumableAndPreservesReceiver, and BytecodeProofManifestTests row B24h-computed-private-field-initializer-super-routes.
2026-06-07 B24h partial: activation-capturing private field initializers with computed members Resumable class expressions now route public computed members that coexist with private instance fields whose initializers capture resumable activation bindings, such as ["read"]() { return this.#value + 1; } next to #value = current. The existing class-literal field-initializer materialized-environment detector already requested the live body environment; the B24h selector now allows that route for private instance fields, and the runtime proof constructs the class after resume so the private field observes a later slot mutation. The row above extends the same private field neighbor to super initializers. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateFieldInitializerCapturingActivation_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateFieldInitializerCapturingActivation_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests row B24h-computed-private-field-initializer-captures-activation-routes.
2026-06-07 B24h partial: activation-capturing private accessors with computed members Resumable class expressions now route public computed members that coexist with private instance accessors whose bodies capture resumable activation bindings, such as ["read"]() { return this.#value + 1; } next to get #value() { return current; }. The B24h selector now lets private method/accessor bodies use the same materialized body-environment route as public member bodies, and the runtime proof shows the private getter observing a later slot mutation after resume. The row above extends the private-neighbor materialized route to private field initializer captures. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateAccessorCapturingActivation_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateAccessorCapturingActivation_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests row B24h-computed-private-accessor-captures-activation-routes.
2026-06-07 B24h partial: private accessor neighbors with computed members Resumable class expressions route public computed members that coexist with noncapturing private instance accessors, such as ["read"]() { return this.#value + 1; } next to get #value() { return 41; }. The B24h shape gate permits non-static, non-computed private methods/getters/setters; the row above extends that same neighbor shape to activation-capturing private accessor bodies. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateAccessorNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateAccessorNeighbor_RoutesResumableAndReadsPrivateAccessor, and BytecodeProofManifestTests row B24h-computed-private-accessor-neighbor-routes.
2026-06-07 B24h partial: private field neighbors with computed members Resumable class expressions now route public computed members that coexist with activation-safe private instance fields, such as ["read"]() { return this.#value + 1; } next to #value = 41. Later rows extend the same B24h composition route to noncapturing and activation-capturing private accessors. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberWithPrivateFieldNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateFieldNeighbor_RoutesResumableAndReadsPrivateField, and BytecodeProofManifestTests row B24h-computed-private-field-neighbor-routes.
2026-06-07 B24h partial: private method neighbors with computed members Resumable class expressions now route public computed members that coexist with noncapturing private instance methods, such as ["read"]() { return 42; } next to #secret() { return 41; }. Later rows extend the same B24h composition route to activation-safe private fields and noncapturing or activation-capturing private accessors. The B24h shape gate still declines non-production static-block plans and the broader class-definition environment bridge before VM entry. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134. EvaluateResumable_ClassExpressionComputedMemberWithPrivateNeighbor_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberWithPrivateNeighbor_RoutesResumableAndInvokesComputedMethod, and BytecodeProofManifestTests row B24h-computed-private-method-neighbor-routes.
2026-06-07 B24h partial: computed super class elements Resumable class expressions now route public computed class members and field initializers that use super, such as ["value"]() { return super.value() + 1; } and ["field"] = super.value + 1. B24h no longer rejects extends outright; the existing activation-slot extends guard still protects activation-dependent superclass expressions before B24h, while public computed method and field super bodies now stay on LoadClassLiteral and preserve superclass receiver semantics. Later rows narrow the private-neighbor boundary through private methods, fields, accessors, and activation-capturing private accessor bodies. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedPublicMethodWithSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedPublicMethodWithSuper_RoutesResumableAndPreservesReceiver, EvaluateResumable_ClassExpressionComputedPublicFieldInitializerWithSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedPublicFieldInitializerWithSuper_RoutesResumableAndPreservesReceiver, and BytecodeProofManifestTests rows B24h-computed-member-super-routes and B24h-computed-field-super-routes.
2026-06-08 B24h rebaseline: computed constructor-body activation captures stay open Resumable class expressions still decline public computed classes whose constructor body captures a resumable activation binding, such as constructor() { this.value = current; }, before VM entry. Member bodies and field initializers can use the materialized body-environment route, but constructor activation captures still need the broader class-definition environment bridge so construction after a later mutation remains on the existing fallback path. Later rows continue to cover computed super members, private method/field/accessor neighbors, and activation-capturing private accessors. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberConstructorCapturesActivation_DeclinesBeforeVm, GeneratorClassExpressionComputedMemberConstructorCapturesActivation_FallsBackAndReadsLaterMutation, and BytecodeProofManifestTests row B24h-computed-member-constructor-captures-activation-declines.
2026-06-07 B24h partial: computed member-body activation captures Resumable class expressions now route public computed class members whose method body captures a resumable activation binding, such as ["read"]() { return current; }. PlanNeedsMaterializedResumableBodyEnvironment now detects activation-capturing member bodies under LoadClassLiteral; the resumable class literal then closes the member over the live materialized body environment, so the invoked method observes later slot mutations and logs production bytecode. Later rows extend neighboring admitted routes to computed super members, private method/accessor neighbors, and activation-capturing private accessors; constructor-body activation captures remain declined by the rebaseline row above. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedMemberBodyCapturesActivation_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedMemberBodyCapturesActivation_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests row B24h-computed-member-body-captures-activation-routes.
2026-06-07 B24h partial: closure-producing static computed-field initializers Resumable class expressions now route public computed static fields whose initializer creates an activation-capturing closure, such as static ["read"] = () => current. The same materialized body-environment path used by instance initializer closures is now requested for closure-producing static field initializer programs, so the static closure observes later resumable slot mutations and its invocation logs production bytecode. Later rows extend neighboring admitted environment routes to computed member bodies, computed super members, private method/accessor neighbors, and activation-capturing private accessors; constructor-body activation captures remain declined by the rebaseline row above. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedStaticFieldClosureInitializer_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedStaticFieldClosureInitializer_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests row B24h-computed-static-field-activation-closure-initializer-routes.
2026-06-07 B24h partial: static computed-field activation initializers Resumable class expressions now route public computed static fields whose initializer directly reads, writes, or updates resumable activation bindings. LoadClassLiteral already creates a slot-backed class-literal environment for computed/static class elements and syncs it back to VM slots after class creation, so static initializer writes such as static ["updated"] = (current = current + 1) now preserve both the static value and the resumed local binding. Later rows extend this to closure-producing static initializers, computed member bodies, computed super members, private method/accessor neighbors, and activation-capturing private accessors; constructor-body activation captures remain declined by the rebaseline row above. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedStaticFieldWithActivationInitializer_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedStaticFieldWithActivationInitializer_RoutesResumableAndSyncsStaticValue, and BytecodeProofManifestTests row B24h-computed-static-field-activation-initializer-routes.
2026-06-07 B24h partial: instance computed-field activation initializers Resumable class expressions now route public computed instance fields whose initializer reads a resumable activation binding or creates an activation-capturing function literal, even when the class escapes the generator and is constructed after the binding mutates. PlanNeedsMaterializedResumableBodyEnvironment now detects LoadClassLiteral instance field initializer programs that reference activation slots, so LoadClassLiteral creates the class against the live materialized body environment instead of a copied class-literal environment. Later rows extend this materialized route to static field initializer closures, computed member bodies, computed super members, private method/accessor neighbors, and activation-capturing private accessors; constructor-body activation captures remain declined by the rebaseline row above. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedFieldWithActivationInitializer_AdmitsLoadClassLiteral, GeneratorClassExpressionComputedFieldWithActivationInitializer_RoutesResumableAndEscapedClassReadsLaterMutation, GeneratorClassExpressionComputedFieldWithActivationClosureInitializer_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests rows B24h-computed-field-activation-initializer-routes and B24h-computed-field-activation-closure-initializer-routes.
2026-06-07 B36 partial: direct computed-name activation calls Direct root class declarations in resumable generator bodies now route computed member names whose name program calls an activation-slot function and stores the result into an activation slot, such as [key = read()]() { ... }. The B36 computed-public declaration guard now uses the same bounded direct activation-call allowance as the B24h class-literal guard, and the runtime proof checks that the outer generator logs the resumable fast path while the computed-name side effect updates the local key. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers plus class declarations outside the admitted public subsets. EvaluateResumable_ClassDeclarationComputedNameActivationCall_AdmitsDeclareClass, GeneratorClassDeclarationComputedNameActivationCall_RoutesResumable, and BytecodeProofManifestTests row B36-class-declaration-computed-name-activation-call-routes.
2026-06-07 B24h/B36 partial: escaping computed-name closures Resumable class expressions and direct root extends class declarations now route computed-name IIFEs that create an escaping activation-capturing closure, such as [(() => { leaked = function read() { return current; }; return "value"; })()]. The resumable body now materializes a body environment when class-literal computed-name programs create activation-capturing function literals; the resumable LoadClassLiteral path reuses that live environment instead of a copied class-literal environment and syncs class-definition assignments back to VM slots after creation. The escaped read function sees later activation mutations and logs production unified bytecode. Later rows extend the materialized route to field initializer, member-body, computed super captures, private method/accessor neighbors, and activation-capturing private accessors; constructor-body activation captures remain declined by the rebaseline row above. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, with B24h still open for non-production static-block plans and the broader class-definition environment bridge; B36 remains open for dynamic/eval helpers and class declarations outside the admitted public subsets. EvaluateResumable_ClassExpressionComputedNameNestedActivationCaptureEscapes_AdmitLoadClassLiteral, GeneratorClassExpressionComputedNameNestedActivationCaptureEscapes_RoutesResumableAndReadsLaterMutation, EvaluateResumable_ClassDeclarationExtendsComputedNameNestedActivationCaptureEscapes_AdmitsDeclareClass, GeneratorClassDeclarationExtendsComputedNameNestedActivationCaptureEscapes_RoutesResumableAndReadsLaterMutation, and BytecodeProofManifestTests rows B24h-computed-name-nested-activation-capture-escape-routes and B36-class-declaration-extends-computed-name-nested-activation-capture-escape-routes.
2026-06-07 B36 partial: closure-producing static blocks with extends Direct root extends class declarations now route static-block-only declarations whose block creates an activation-capturing closure, such as static { this.read = () => current; }. The resumable invoker now detects activation-capturing function literals inside class static-block plans and materializes the body environment before DeclareClass; named property name inference lowers to EnsureHasName before SetNamedProperty, so the closure keeps the inferred static property name while resolving the updated activation binding after resume. The mixed static-field/static-block row above admits the non-extends mixed-static subset. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. EvaluateResumable_ClassDeclarationStaticBlockClosure_AdmitsDeclareClass, GeneratorClassDeclarationStaticBlockClosure_RoutesResumableAndObservesLaterActivationMutation, and BytecodeProofManifestTests row B36-class-declaration-static-block-closure-routes.
2026-06-07 B36 partial: super-dependent static-field closures with extends Direct root extends class declarations now route public non-computed static-field initializers that create a closure whose body needs super, such as static read = () => super.value + seed. The produced arrow keeps the field-initializer super binding, the production invocation path materializes a call environment for the super opcodes, and the invoked closure logs production unified bytecode instead of dropping to ExecutionPlanRunner. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. GeneratorClassDeclarationExtendsStaticFieldSuperClosureInitializer_RoutesResumable and BytecodeProofManifestTests row B36-class-declaration-extends-static-field-super-closure-routes.
2026-06-06 B36 partial: closure-producing public static fields with extends Direct root extends class declarations now admit public non-computed static fields whose initializer creates a closure that captures a resumable activation binding, such as static read = () => seed + 1. The static field initializer executes through standalone unified bytecode against the class initialization environment, and the produced function routes through production bytecode when invoked. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. EvaluateResumable_ClassDeclarationExtendsStaticFieldClosureInitializer_AdmitsDeclareClass, GeneratorClassDeclarationExtendsStaticFieldClosureInitializer_RoutesResumable, and BytecodeProofManifestTests row B36-class-declaration-extends-static-field-closure-routes.
2026-06-06 B36 partial: captured explicit derived constructors with extends Direct root extends class declarations now admit activation-capturing explicit public derived constructors inside the existing B36 constructor shape. The constructor closes over the synced class declaration environment, executes on the production Box constructor route, and can pass the captured binding through super(...) while the outer generator stays on DeclareClass. Historical boundary: static-field closure state still stayed open at this checkpoint; the later closure-producing static-field row and static-block closure row above removed those boundaries. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. EvaluateResumable_ClassDeclarationExplicitDerivedConstructorCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExplicitDerivedConstructorCapturesActivation_RoutesResumable, and BytecodeProofManifestTests row B36-class-declaration-explicit-derived-constructor-captures-activation-routes.
2026-06-06 B36 partial: captured public super field initializers with extends Direct root extends class declarations now admit public instance fields whose initializer reads both super and a resumable activation binding. The initializer executes through the standalone unified expression-program executor inside the class-field initialization environment, whose parent is the synced class declaration environment; the outer generator stays on DeclareClass. Historical boundary: explicit derived constructor captures and static-field closure state still stayed open at this checkpoint; later rows removed both boundaries and the static-block closure row removed the declaration-side static-block closure boundary. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. EvaluateResumable_ClassDeclarationExtendsPublicFieldWithSuperCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicFieldWithSuperCapturesActivation_RoutesResumable, and BytecodeProofManifestTests row B36-class-declaration-extends-public-super-field-captures-activation-routes.
2026-06-06 B36 partial: captured public super member bodies with extends Direct root extends class declarations now admit public instance and static super-method bodies that capture resumable activation slots. DeclareClass syncs the materialized body environment before class creation, the class member closes over that environment, and the invoked method body logs production unified bytecode while resolving both super and the captured binding. Historical boundary: field-initializer, explicit-derived-constructor, and static-field closure captures still stayed open at this checkpoint; later rows removed those boundaries and the static-block closure row removed the declaration-side static-block closure boundary. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers, non-production static blocks, static-field/static-member shape guards, computed-member/field activation captures, and static-block/computed-static-field boundary. EvaluateResumable_ClassDeclarationExtendsPublicMethodWithSuperCapturesActivation_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsStaticPublicMethodWithSuperCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicMethodWithSuperCapturesActivation_RoutesResumable, GeneratorClassDeclarationExtendsStaticPublicMethodWithSuperCapturesActivation_RoutesResumable, and BytecodeProofManifestTests rows B36-class-declaration-extends-public-super-method-captures-activation-routes and B36-class-declaration-extends-static-public-super-method-captures-activation-routes.
2026-06-06 B36 partial: computed-name activation IIFEs with extends Direct root extends class declarations now compose the B24h immediate computed-name IIFE subset with the existing B36 superclass/constructor route. A class such as class Box extends Base { [(() => key)()]() { ... } } now routes through DeclareClass and preserves superclass behavior. The later 2026-06-07 row above extends that path to computed-name IIFEs that create escaping activation-capturing closures. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B36 remains open for dynamic/eval helpers plus class declarations outside the admitted public subsets. EvaluateResumable_ClassDeclarationExtendsComputedNameNestedActivationCaptureIife_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsComputedNameNestedActivationCaptureEscapes_AdmitsDeclareClass, GeneratorClassDeclarationExtendsComputedIifeName_RoutesResumableAndPreservesSuperclass, and BytecodeProofManifestTests rows B36-class-declaration-extends-computed-name-immediate-iife-capture-routes and B36-class-declaration-extends-computed-name-nested-activation-capture-escape-routes.
2026-06-06 B24h partial: immediate computed-name activation IIFEs Resumable generator bodies now admit LoadClassLiteral for public computed class-expression member names of the shape [(() => key)()] when the immediately invoked function literal captures a resumable activation slot; later rows extend that path to IIFEs that create escaping activation-capturing closures, private method/accessor neighbors, activation-capturing private accessors, and spread-call targets. The computed-name expression still runs as standalone unified bytecode against the synthetic class-literal environment, and the class-literal route syncs that environment back to resumable slots after creation. Historical boundary: construct/direct-eval/super call-target neighbors, private static initializer dependency/private computed neighbors, and static-block overlap still stayed open at this checkpoint; the 2026-06-07 spread-call row above removes the spread boundary. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134. EvaluateResumable_ClassExpressionComputedNameNestedActivationCaptureIife_AdmitLoadClassLiteral, EvaluateResumable_ClassExpressionComputedNameNestedActivationCaptureEscapes_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationIifeName_RouteResumableAndResolveName, and BytecodeProofManifestTests rows B24h-computed-name-immediate-iife-capture-routes and B24h-computed-name-nested-activation-capture-escape-routes.
2026-06-06 B24 partial: mixed public static field/member class expressions Resumable generator bodies now admit LoadClassLiteral for class expressions that combine public non-computed static fields with public non-computed static methods/accessors, when the static field initializers compile as standalone unified bytecode, do not create nested closures, and the static member/constructor bodies do not capture resumable activation slots. This covers initializer ordering such as static field = this.value() + 1 after static value() { ... }, including the extends form where the static method uses super; the non-capturing home-object static method body now logs production bytecode instead of dropping to ExecutionPlanRunner. Checklist totals stay 127 / 145, A+B+C+D stays 119 / 134, and B24h stays open for computed/private capturing/static-block neighbors and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionMixedPublicStaticFieldAndMethod_AdmitsLoadClassLiteral, EvaluateResumable_ClassExpressionMixedPublicStaticFieldAndAccessor_AdmitsLoadClassLiteral, EvaluateResumable_ClassExpressionMixedPublicStaticMemberCapturesActivation_DeclinesBeforeVm, GeneratorClassExpressionMixedPublicStaticFieldAndMethod_RoutesResumableAndInitializesInOrder, GeneratorClassExpressionMixedPublicStaticFieldAndMethodWithSuper_RoutesResumable, ClassMethodCreatedInsideFunctionWithoutCapturedNames_UsesProductionUnifiedBytecode, ClassMethodCreatedInsideFunctionWithCapturedName_UsesCapturedClosureProductionPath, and BytecodeProofManifestTests rows B24i-mixed-static-public-field-and-method-routes and B24i-mixed-static-public-field-and-super-method-routes.
2026-06-06 B24 partial: static public class-expression members and super fields Resumable generator bodies now admit LoadClassLiteral for public non-computed static class-expression methods/accessors whose bodies do not capture resumable activation slots, plus public non-computed static-field class expressions with extends when initializers compile as standalone unified bytecode and do not create closures. This removes the previous class-expression asymmetry where declaration-side static super methods/fields routed but expression-side static super methods/fields declined. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because B24h remains open for computed/private capturing/mixed class-definition state. EvaluateResumable_ClassExpressionStaticPublicAccessor_AdmitsLoadClassLiteral, EvaluateResumable_ClassExpressionStaticPublicMethodWithSuper_AdmitsLoadClassLiteral, EvaluateResumable_ClassExpressionStaticPublicFieldInitializerWithSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionStaticPublicAccessor_RoutesResumableAndPreservesReceiver, GeneratorClassExpressionStaticPublicMethodWithSuper_RoutesResumableAndPreservesSuperclass, GeneratorClassExpressionStaticPublicFieldWithSuper_RoutesResumableAndPreservesSuperclass, and BytecodeProofManifestTests rows B24i-static-public-accessor-routes, B24i-static-public-super-method-routes, and B24i-static-public-super-field-routes.
2026-06-06 B36 proof: static public super fields with extends The public static-field extends subset is now explicitly proved to include static field initializers that use super, such as class Box extends Base { static field = super.value + 1; }. No production code change was needed: the existing B36 static-field helper already admitted public non-computed static fields whose initializer compiles as standalone unified bytecode and does not create a nested closure. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134; this removes a stale remaining-boundary mention rather than closing B36. EvaluateResumable_ClassDeclarationExtendsStaticPublicFieldWithSuper_AdmitsDeclareClass, GeneratorClassDeclarationExtendsStaticPublicFieldWithSuper_RoutesResumableAndPreservesSuperclass, and BytecodeProofManifestTests row B36-class-declaration-extends-static-public-super-field-routes.
2026-06-06 B36 partial: static public super members with extends Resumable generator bodies now admit direct root extends class declarations whose class body contains public non-computed static methods/accessors that use super, such as class Box extends Base { static value() { return super.value() + 1; } }. This is a B36 declaration-side contraction; static super field initializers are covered by the public static-field proof row above, and the later captured-member row admits static member bodies that capture activation. The runtime proof requires both the outer DeclareClass generator route and the invoked static method body's production unified-bytecode route. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsStaticPublicMethodWithSuper_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsStaticPublicMethodWithSuperCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExtendsStaticPublicMethodWithSuper_RoutesResumableAndPreservesSuperclass, BytecodeProofManifestTests rows B36-class-declaration-extends-static-public-super-method-routes and B36-class-declaration-extends-static-public-super-method-captures-activation-routes.
2026-06-06 B36 partial: public instance super fields with extends Resumable generator bodies now admit direct root extends class declarations whose class body contains public non-computed instance fields initialized from super, such as class Box extends Base { field = super.value + 1; }. The selector checks the lowered initializer expression program for super ownership, and the later captured-field row admits initializers that also read resumable activation bindings. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsPublicFieldWithSuper_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsPublicFieldWithSuperCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicFieldWithSuper_RoutesResumableAndPreservesReceiver, BytecodeProofManifestTests rows B36-class-declaration-extends-public-super-field-routes and B36-class-declaration-extends-public-super-field-captures-activation-routes.
2026-06-06 B36 partial: public instance super members with extends Resumable generator bodies now admit direct root extends class declarations whose class body contains public non-computed instance methods/accessors that use super, such as class Box extends Base { value() { return super.value() + 1; } }. The runtime proof requires both the outer DeclareClass generator route and the invoked method body's production unified-bytecode route; the later captured-member row admits member bodies that capture activation too. Static, computed, and private neighbors remain separate B36/B24h boundaries. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsPublicMethodWithSuper_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsPublicMethodWithSuperCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicMethodWithSuper_RoutesResumableAndPreservesReceiver, BytecodeProofManifestTests rows B36-class-declaration-extends-public-super-method-routes and B36-class-declaration-extends-public-super-method-captures-activation-routes.
2026-06-06 B36 partial: public static fields with extends Resumable generator bodies now admit direct root extends class declarations whose class body contains public non-computed static fields, such as class Box extends Base { static value = seed + 1; }, when every static field initializer compiles as standalone unified bytecode. The B36 path composes the existing superclass-expression compile check, constructor predicate, and class-declaration environment sync; the later closure-producing static-field row above admits static field initializers that create captured closures too. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsPublicStaticField_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsStaticFieldClosureInitializer_AdmitsDeclareClass, GeneratorClassDeclarationExtendsPublicStaticField_RoutesResumableAndReadsActivation, BytecodeProofManifestTests rows B36-class-declaration-extends-public-static-field-routes and B36-class-declaration-extends-static-field-closure-routes.
2026-06-06 B36 partial: computed public instance members with extends Resumable generator bodies now admit direct root extends class declarations whose class body contains activation-safe public instance computed methods/accessors, such as class Box extends Base { [key = "value"]() { return 42; } }. The new B36 path composes the already-proven superclass-expression compile check, the B36 constructor route predicate, and the B24h computed public member gate; static members, fields/static elements, private members, and other B24h-neighbor shapes remained declined at that checkpoint. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsComputedPublicMember_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExtendsComputedNameNestedActivationCaptureEscapes_AdmitsDeclareClass, GeneratorClassDeclarationExtendsComputedPublicMember_RoutesResumableAndSyncsName, BytecodeProofManifestTests rows B36-class-declaration-extends-computed-public-member-routes and B36-class-declaration-extends-computed-name-nested-activation-capture-escape-routes.
2026-06-06 B36 partial: static-block-only class declarations Resumable generator bodies now admit direct root class declarations whose class body has only static blocks, including the plain extends form class Box extends Base { static { this.seed = seed + 1; } }, when every static block body is production-unified-bytecode eligible. DeclareClass still synchronizes VM flat slots into the materialized class declaration environment before class creation and back afterward, while each static block hits the existing unified-bytecode-production-fast-path static-block route instead of ExecutionPlanRunner.RunScript. Historical boundary: closure-producing static blocks stayed declined at this checkpoint; the 2026-06-07 row above admits declaration-side activation-capturing static-block closures. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExtendsStaticBlock_AdmitsDeclareClass, GeneratorClassDeclarationExtendsStaticBlock_RoutesResumableAndStaticBlockFastPath, and BytecodeProofManifestTests row B36-class-declaration-extends-static-block-routes.
2026-06-06 B36 partial: explicit derived class declaration constructors Resumable generator bodies now admit direct root plain extends class declarations with an explicit public derived constructor, such as class Box extends Base { constructor(seed) { super(seed); this.local = seed + 1; } }. The B36 gate now treats the extends declaration shell as eligible when there are no member, field, static element, or static-block class-definition neighbors, and the runtime proof requires both the outer generator DeclareClass path and the Box constructor's own production unified-bytecode route to hit. Historical boundary: constructor captures and static blocks still stayed open at this checkpoint; later rows removed activation-capturing constructors, eligible static-block-only declarations, and declaration-side activation-capturing static-block closures. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationExplicitDerivedConstructor_AdmitsDeclareClass, EvaluateResumable_ClassDeclarationExplicitDerivedConstructorCapturesActivation_AdmitsDeclareClass, GeneratorClassDeclarationExplicitDerivedConstructor_RoutesResumableAndConstructorFastPath, and BytecodeProofManifestTests rows B36-class-declaration-explicit-derived-constructor-routes and B36-class-declaration-explicit-derived-constructor-captures-activation-routes.
2026-06-06 B36 partial: activation superclass class declaration extends Resumable generator bodies now admit constructorless direct root class declarations whose superclass expression reads an activation binding, such as class Box extends Base {} where Base is a generator parameter. The B36 predicate now requires the superclass expression to compile as standalone unified bytecode, then lets DeclareClass synchronize flat slots into the materialized class-declaration environment before class creation. Historical boundary: explicit derived constructors, computed/static neighbors with extends, static blocks, and dynamic/eval helpers still stayed open at this checkpoint; the later explicit-derived row above removed the explicit constructor boundary. Checklist totals stay 127 / 145 and A+B+C+D stays 119 / 134 because this is a partial B36 contraction. EvaluateResumable_ClassDeclarationActivationExtends_AdmitsDeclareClass, GeneratorClassDeclarationActivationExtends_RoutesResumableAndPreservesSuperclass, focused UnifiedBytecodeResumableClassDeclarationTests (14), and clean build of Asynkron.JsEngine.csproj.
2026-06-06 B36 partial: simple class declaration extends Resumable generator bodies now admit constructorless direct root class declarations with a non-activation superclass expression, such as class Box extends Base {}. The existing DeclareClass VM path materializes the resumable body environment, synchronizes flat slots into the class declaration environment, evaluates the class through the shared class-definition path, and synchronizes the class binding back to VM slots; superclass construction and instanceof behavior are now pinned on the resumable fast path. Historical boundary: activation-dependent superclass expressions, explicit derived constructors, the current B36 static-field/static-member shape guards, computed-member/field activation captures, static-block/computed-static-field boundary, static blocks, and dynamic/eval helpers still stayed open at this checkpoint; the later activation-superclass row above removed the activation superclass boundary. Checklist totals stayed 127 / 145 and A+B+C+D stayed 119 / 134 because this was a partial B36 contraction. EvaluateResumable_ClassDeclarationExtends_AdmitsDeclareClass, GeneratorClassDeclarationExtends_RoutesResumableAndPreservesSuperclass, BytecodeProofManifestTests, focused UnifiedBytecodeResumableClassDeclarationTests (12), focused class-expression super neighbor check (2), and clean build of Asynkron.JsEngine.csproj.
2026-06-06 A51f4 implicit arguments expression-loop closure The arguments-specific compiler diagnostics for implicit arguments assignment references, complex-call-argument assignment references, complex-call-argument call targets, optional identifier call-target preparation, and typeof are gone from UnifiedBytecodeCompiler. The bounded implicit-arguments invoker path is now plan-driven rather than read-flag-driven, so expression-result assignment (return (arguments = 1)) and assignment as a complex call argument (reader(arguments = 7)) select the production VM. Nested arguments() inside a complex call argument routes through PrepareDynamicIdentifierCallTarget. Optional-call shapes such as arguments?.() still belong to the generic optional-chain/call-target boundary, not A51f4. Checklist now 127 / 145; concrete A+B+C+D open gates now 15; total open gates now 18. Focused eligibility proofs assert ResolveDynamicIdentifierReference / StoreDynamicIdentifierReference for expression-result and call-argument assignment, plus PrepareDynamicIdentifierCallTarget for nested arguments() call arguments. Runtime route-hit proofs assert unified-bytecode-production-fast-path for the assignment-expression and call-argument lanes. BytecodeProofManifestTests now pins those route hits and ratchets the removed A51f4 compiler templates as absent from UnifiedBytecodeCompiler.cs.
2026-06-06 A51f1 general expression-loop catch-all closure The general expression loop now has a manifest-backed source ratchet proving every declared ExpressionOpKind has a direct TryAppendExpressionProgramOps case. The remaining Unsupported expression op '{operation.Kind}'. default is classified as malformed/manual-op protection, while real helper diagnostics for unsupported simple operands, literal control spans, and property-read bases stay visible under A51h/A51i/A51k. Checklist now 126 / 145; concrete A+B+C+D open gates now 16; total open gates now 19. BytecodeProofManifestTests adds A51f1-general-expression-loop-has-no-opcode-gap, which reads ExpressionOp.cs and UnifiedBytecodeCompiler.cs, extracts ExpressionOpKind members and general-loop cases, and asserts the missing-case set is empty. ExpressionProgramCoverageMapTests.UnifiedBytecodeCompiler_GeneralExpressionLoopDeclinesOnlyDocumentedGaps remains the independent contract drift check.
2026-06-06 A51f2 binding-target expression context closure Generated expression-program compiler contexts now pass binding-target descriptor constants through the general expression loop, including UnifiedBytecodeCompiler.TryCompileStandaloneExpressionProgram. Standalone assignment-destructuring payloads lowered through ApplyBindingTarget now compile to unified bytecode with BindingTargetConstants instead of declining on missing context. The compiler diagnostic string remains as a defensive malformed/manual-helper guard, not a known generated production fallback. Checklist now 125 / 145; concrete A+B+C+D open gates now 17; total open gates now 20. ExpressionProgramLoweringTests.DestructuringAssignmentExpressionProgram_StandaloneUnifiedBytecodeCarriesBindingTargetConstants proves standalone compilation emits ApplyBindingTarget and non-empty BindingTargetConstants. BytecodeProofManifestTests now has A51f2-standalone-expression-compiler-carries-binding-target-constants, and a source scan over all TryAppendExpressionProgramOps call sites found 30 calls and 0 missing bindingTargetConstants.
2026-06-06 E5 partial: eligible static-block bodies route before RunScript fallback ClassDefinitionExtensions.ExecuteStaticBlock now evaluates the static-block ExecutionPlan with UnifiedBytecodeProductionEligibility and executes eligible static-block bodies through UnifiedBytecodeVirtualMachine before falling back to ExecutionPlanRunner.RunScript. This narrows the class/static-block bridge but does not retire it: class-name-dependent static-block bodies, closure-producing blocks, and other declined static-block plans still use the IR fallback. NestedClassDeclaration_UsesUnifiedBytecodeProductionFastPath now requires the unified-bytecode-production-fast-path static-block route log. The focused static-block pack passed 8 tests. docs/plans/bytecode-proof-manifest.json adds E5-static-block-body-routes-when-eligible as an admitted proof row while retaining the open E5 runner source-presence rows.
2026-06-06 E4 partial: binding-target runner bridge removed ExecutionPlanRunner.ApplyStandaloneBindingTargetProgram is deleted. TypedAstEvaluator.BindingTargetPrograms now calls the static lowered binding-target core directly instead of constructing a runner solely to apply a lowered BindingTargetProgram. External lowered binding-target expression payloads use UnifiedBytecodeExpressionProgramExecutor.ExecuteStandalone; runner-internal binding targets still pass the active runner instance and remain part of E5 until ExecutionPlanRunner itself is retired. E4 remains open because UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic still exists as the quarantined dynamic-expression payload route, and E5 remains open for the broad IR runner entry points. dotnet build src/Asynkron.JsEngine/Asynkron.JsEngine.csproj passed with 0 warnings. BytecodeProofManifestTests now source-gates absence of both old binding-target bridge callers and the bridge definition, while retaining UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic as the open E4 proof row. Focused verification: source/proof pack 71 tests passed with 0 warnings, binding/destructuring pack 221 tests passed, and AstFreeExecutionAssertionTests 116 tests passed with 0 warnings.
2026-06-06 E4 partial: dynamic expression evaluator bridge removed TypedAstEvaluator.EvaluateDynamicExpressionProgram and the containing TypedAstEvaluator.ExpressionPrograms.cs file are deleted. Legacy dynamic AST expression callers now call UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic, which keeps the same cache/lower/throw-on-lowering-failure behavior but executes through standalone unified bytecode from the execution layer. At this checkpoint, E4 remained open because the dynamic expression-program executor still existed as a tier-1 payload route, binding-target bridges still used ExecutionPlanRunner.ApplyStandaloneBindingTargetProgram, class/static-block IR bridges still called ExecutionPlanRunner.RunScript, and broad ExecutionPlanRunner entry points remained; the binding-target runner bridge was removed by the later row above. dotnet build src/Asynkron.JsEngine/Asynkron.JsEngine.csproj passed with 0 warnings. ExecutionPlanDiagnosticsTests / BytecodeProofManifestTests / ExpressionProgramCoverageMapTests passed 69 tests, and AstFreeExecutionAssertionTests passed 116 runtime tests. Production-source scan rg "EvaluateDynamicExpressionProgram\\(" src/Asynkron.JsEngine tools/ProfileRunner -g '*.cs' returned no matches. SourceGate_E4_DynamicExpressionProgramBridge_IsCompletelyRemoved tombstones the old method name, and SourceGate_DynamicExpressionExecutor_StaysInsideApprovedBoundarySurface limits the new dynamic executor to the quarantined legacy/dynamic owners.
2026-06-06 E4 partial: lowered expression evaluator bridge removed TypedAstEvaluator.EvaluateLoweredExpressionProgram is deleted. Class extends expressions, static and instance field initializers, computed property names, and the then-remaining dynamic-expression bridge call UnifiedBytecodeExpressionProgramExecutor.ExecuteStandalone, which compiles ExpressionProgram payloads with UnifiedBytecodeCompiler.TryCompileStandaloneExpressionProgram and executes UnifiedBytecodeVirtualMachine. The follow-up row above deletes EvaluateDynamicExpressionProgram; E4 remains open today because UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic, binding-target bridges, class/static-block IR bridges, and ExecutionPlanRunner entry points still exist. dotnet build src/Asynkron.JsEngine/Asynkron.JsEngine.csproj passed with 0 warnings. ExecutionPlanDiagnosticsTests / BytecodeProofManifestTests / ExpressionProgramCoverageMapTests passed 67 tests, and the class/activation proof pack passed 157 tests. Production-source scan rg "EvaluateLoweredExpressionProgram\\(" src/Asynkron.JsEngine -g '*.cs' returned no matches, and SourceGate_E4_LoweredExpressionProgramBridge_IsCompletelyRemoved now ratchets that absence.
2026-06-06 E4 partial: standalone expression runner bridge ExecutionPlanRunner.EvaluateStandaloneExpressionProgram is deleted. The then-remaining EvaluateLoweredExpressionProgram bridge compiled standalone ExpressionProgram payloads through UnifiedBytecodeCompiler.TryCompileStandaloneExpressionProgram with dynamic-identifier support and executed UnifiedBytecodeVirtualMachine.Execute; later follow-up rows delete both EvaluateLoweredExpressionProgram and EvaluateDynamicExpressionProgram. The standalone compiler/VM call boundary also owns bare no-explicit-this calls (callee(args)) via an implicit-undefined receiver bit, and optional-chain detection was narrowed to actual optional-chain opcodes so object-literal method calls route through the general expression loop instead of a stale special splitter. E4 remains open today because UnifiedBytecodeExpressionProgramExecutor.ExecuteDynamic, binding-target bridges, class/static-block IR bridges, and ExecutionPlanRunner entry points still exist. Class/activation proof pack passed 157 focused tests. Source scans found no production-source EvaluateStandaloneExpressionProgram method or call. This was a bridge-retirement contraction rather than bytecode-only completion; follow-up rows now also ratchet absence of EvaluateLoweredExpressionProgram and EvaluateDynamicExpressionProgram.
2026-06-06 E4 partial: profiler-only ExpressionProgram loop ProfileRunner's bytecode profile no longer delegates to TypedAstEvaluator.ProfileEvaluateLoweredExpressionProgramLoop or ExecutionPlanRunner.ProfileEvaluateExpressionProgramLoop. Each synthetic ExpressionProgram profile case is compiled once through UnifiedBytecodeCompiler.TryCompileStandaloneExpressionProgram and executed with UnifiedBytecodeVirtualMachine.Execute; the old profiling helper methods are deleted and source-gated as absent. E4/E5 remain open because standalone expression, binding-target, class-definition/class-field/class-property-name, dynamic expression bridges, and ExecutionPlanRunner routes still exist. dotnet build tools/ProfileRunner/ProfileRunner.csproj passed with 0 warnings; ./tools/profile bytecode passed with the CPU call-tree root at UnifiedBytecodeVirtualMachine.Execute; ExecutionPlanDiagnosticsTests, BytecodeProofManifestTests, and ExpressionProgramCoverageMapTests passed 67 focused tests. Source scans found no deleted profile method in src/Asynkron.JsEngine or tools/ProfileRunner and no raw AST-eval seam matches in TypedAstEvaluator.ExecutionPlanRunner*.
2026-06-06 E4 partial: ordinary sync simple-return expression bridge TryInvokeIrFast no longer creates a simple activation environment and executes SimpleReturnProgram through the lowered-expression bridge. Accepted ordinary sync bodies still try production unified bytecode first, the parameter/binary fast paths and SyncIrCallTrampoline remain, and the generic simple-return-expression residue now returns false so the existing classified fallback owns unsupported shapes until E5 retirement. Later rows above delete the lowered-expression, dynamic-expression, and binding-target runner bridges. The source gate first required zero fallback-only lowered-expression callers, then follow-up rows replaced that classifier with complete source absence. UnifiedBytecodeProductionInvocationTests.SourceGate_OrdinarySyncRouteAttemptsProductionUnifiedBytecodeBeforeSimpleIrAndRunnerFallback, ActivationSemanticsProofPackTests, and ExecutionPlanDiagnosticsTests passed 74 focused tests for the original slice.
2026-06-06 B24h/B36 partial: activation-delete computed class names Resumable generator bodies now compile public computed class expression and direct root class declaration names that delete an activation binding, such as [delete key], to LoadClassLiteral / DeclareClass instead of treating them as a B24h/B36 decline. Class computed names are strict, so this shape is a strict-error path rather than a value-producing class-name path: executing the source raises SyntaxError for the unqualified identifier delete. B24h remains open for unadmitted call-target shapes, nested activation-capturing computed-name literals, computed-super overlap, private static initializer dependency/private computed neighbors, static-block overlap, and the broader class-definition environment bridge. EvaluateResumable_ClassExpressionComputedNameActivationDelete_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationDelete_RejectsStrictIdentifierDelete, EvaluateResumable_ClassDeclarationComputedNameActivationDelete_AdmitsDeclareClass, GeneratorComputedPublicClassDeclarationActivationDelete_RejectsStrictIdentifierDelete, EvaluateResumable_ClassExpressionComputedNameNestedActivationCapture_DeclinesBeforeVm, BytecodeProofManifestTests, focused UnifiedBytecodeResumableClassExpressionTests / UnifiedBytecodeResumableClassDeclarationTests, clean git diff --check, and no runner AST-eval seam matches.
2026-06-06 B24h partial: activation-call argument computed class names Resumable generator bodies admitted public computed class elements whose computed name calls an activation-resolved target with an admitted argument region, such as [helper(read)]. The B24h selector consumes the call only when the production complex-call-argument walker validates the region. Historical boundary: direct eval, spreads, constructs/super constructs, activation deletes, nested activation-capturing literals, private/static-block overlap, activation-capturing field initializers, and capturing constructor/member bodies still declined to the later class-definition environment route; the activation-delete row above removed the delete boundary. Checklist totals stayed 124 / 145; B24h remained open. EvaluateResumable_ClassExpressionComputedNameActivationCallArgument_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationCallArgument_RouteResumableAndResolveName, EvaluateResumable_ClassExpressionComputedNameNestedActivationCapture_DeclinesBeforeVm, BytecodeProofManifestTests, focused UnifiedBytecodeResumableClassExpressionTests, clean git diff --check, and no runner AST-eval seam matches.
2026-06-06 B36 partial: computed public class declarations Resumable generator bodies admitted DeclareClass for activation-safe computed public class declarations, including public static computed fields and computed names that read/write activation slots through the existing class-definition slot sync. Historical boundary: plain extends, static blocks, computed-name calls, private/capturing member bodies, and activation-capturing field initializers still declined at this checkpoint; later rows removed the activation-delete, simple-extends, activation-superclass, explicit-derived-constructor, and direct computed-name activation-call boundaries. EvaluateResumable_ClassDeclarationComputedPublicElements_AdmitsDeclareClass, GeneratorComputedPublicClassDeclaration_RoutesResumableAndSyncsName, EvaluateResumable_ClassDeclarationComputedNameActivationDelete_AdmitsDeclareClass, later EvaluateResumable_ClassDeclarationComputedNameActivationCall_AdmitsDeclareClass, focused UnifiedBytecodeResumableClassDeclarationTests, clean git diff --check, and no runner AST-eval seam matches.
2026-06-06 B24i public non-computed class-element super closure Resumable generator bodies now have focused LoadClassLiteral proof for activation-safe public non-computed instance methods and field initializers that use super, completing the remaining public non-computed B24i route already opened for accessor bodies. The B24i guard now rejects member bodies and field initializer programs that capture resumable activation slots, so static/computed/private/capturing and otherwise mixed super-bearing class-definition shapes stay outside the admitted route until the materialized class-definition environment bridge owns them. Checklist now 124 / 145; concrete open gates now 18 and total open gates now 21. EvaluateResumable_ClassExpressionPublicMethodWithSuper_AdmitsLoadClassLiteral, EvaluateResumable_ClassExpressionPublicFieldInitializerWithSuper_AdmitsLoadClassLiteral, GeneratorClassExpressionPublicMethodWithSuper_RoutesResumableAndPreservesReceiver, GeneratorClassExpressionPublicFieldInitializerWithSuper_RoutesResumableAndPreservesReceiver, the capturing method/field-initializer decline rows, and focused UnifiedBytecodeResumableClassExpressionTests (54).
2026-06-06 A51e destructuring state-slot and target leaf closure A51e is now closed as a stale compiler-diagnostics leaf for the intended simple script declaration lane. Current compiler output proves array/object destructuring driver state receives synthetic activation slots and top-level var / let / const script targets carry dynamic target names and variable kind through driver descriptors. The broader R6 destructuring model boundaries remain unchanged: nested/default/parameter/disposal destructuring still stays under DestructuringDependency / UnsupportedPlanShape, and the destructuring profile remains blocked by the orthogonal non-iterating lexical block-environment gate. Checklist now 123 / 145; concrete A+B+C+D open gates now 19 and total open gates now 22. EvaluateScript_A51eSimpleScriptDestructuring_AllocatesStateSlotsAndDynamicTargets covers var/let/const object and array rows, plus the existing runtime route tests for top-level destructuring and the R6 boundary text in the expansion contract.
2026-06-06 B24h partial: direct activation-call computed class names Resumable generator bodies admitted public computed class elements whose computed name is a direct zero-argument activation call such as [read()]. Historical boundary: activation deletes, activation values passed into another call, constructs/super constructs, private/static-block overlap, activation-capturing field initializers, and capturing constructor/member bodies still declined to the later class-definition environment route; the activation-call argument row above removed the activation-value-argument boundary. Checklist then 123 / 145; concrete open gates then 21. EvaluateResumable_ClassExpressionComputedNameDirectActivationCall_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationCall_RouteResumableAndResolveName, EvaluateResumable_ClassExpressionComputedNameNestedActivationCapture_DeclinesBeforeVm, focused UnifiedBytecodeResumableClassExpressionTests (50), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.96 MB.
2026-06-06 B24h partial: activation write/update computed class names Resumable generator bodies admitted public static/instance computed class elements whose computed names write or update activation slots, using the slot-backed class-literal environment plus the post-creation sync back to unified VM slots. Historical boundary: computed-name calls, activation deletes, and nested literals that capture activation still declined, as did activation-capturing field initializers and constructor/member bodies; later rows removed the direct activation-call, activation-call argument, and activation-delete boundaries. Checklist totals stayed 122 / 145; concrete open gates stayed 23. EvaluateResumable_ClassExpressionComputedNameActivationWrite_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationWrite_RouteResumableAndSyncsName, GeneratorComputedPublicStaticActivationUpdate_RouteResumableAndSyncsName, EvaluateResumable_ClassExpressionComputedNameNestedActivationCapture_DeclinesBeforeVm, focused UnifiedBytecodeResumableClassExpressionTests (48), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.95 MB.
2026-06-06 B24h partial: activation-read computed class names Resumable generator bodies admitted public static/instance computed class elements whose computed names read activation slots such as key, while the VM creates a slot-backed class-literal environment for computed-name evaluation. Historical boundary: field initializers and constructor/member bodies that capture activation still declined, and computed names that wrote/updated/deleted activation bindings, materialized references, or prepared/called activation-dependent targets remained outside B24h; later rows removed the direct write/update, direct activation-call, activation-call argument, and activation-delete boundaries. Checklist totals stayed 122 / 145; concrete open gates stayed 23. EvaluateResumable_ClassExpressionComputedPublicAccessorWithActivationKey_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceActivationName_RouteResumableAndResolveName, GeneratorComputedPublicStaticActivationName_RouteResumableAndResolveName, EvaluateResumable_ClassExpressionComputedNameNestedActivationCapture_DeclinesBeforeVm, focused UnifiedBytecodeResumableClassExpressionTests (45), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.95 MB.
2026-06-06 B24h partial: static computed public class elements Resumable generator/async bodies admitted LoadClassLiteral for activation-safe public static computed fields/methods/accessors, plus mixes with the already-admitted public instance and non-computed public class-element neighbors under the same no-activation-capture rules. Historical boundary: static blocks still declined to B24d, and computed names or initializers that read resumable activation slots stayed declined until the activation-read row above removed the computed-name read boundary. Checklist totals stayed 122 / 145; concrete open gates stayed 23. EvaluateResumable_ClassExpressionComputedPublicStaticElements_AdmitLoadClassLiteral, EvaluateResumable_AsyncClassExpressionComputedPublicStaticElements_AdmitLoadClassLiteral, GeneratorComputedPublicStaticClassElements_RouteResumableAndResolveNames, EvaluateResumable_ClassExpressionComputedStaticFieldWithActivationInitializer_AdmitsLoadClassLiteral, focused UnifiedBytecodeResumableClassExpressionTests (43), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.96 MB.
2026-06-06 B24d static-block-only class expressions Resumable generator/async bodies now admit LoadClassLiteral for static-block-only class expressions whose static block bodies do not create nested closures. The route reuses the existing class-literal slot environment and sync-back bridge around ClassDefinitionExtensions.ExecuteStaticBlock, so static blocks can read and write activation bindings. A later E5 slice now routes eligible static-block bodies through the unified VM before falling back to ExecutionPlanRunner.RunScript; activation-capturing static-block closures stayed declined at this checkpoint, the later B24d/B24h rows admit closure-producing blocks, and later static-block nested-class rows admit nested class declarations too. EvaluateResumable_GeneratorStaticBlockClassExpression_AdmitsLoadClassLiteral, EvaluateResumable_AsyncStaticBlockClassExpression_AdmitsLoadClassLiteral, GeneratorStaticBlockClassExpression_RoutesResumableAndSyncsActivationWrites, AsyncStaticBlockClassExpression_RoutesResumableAndSyncsActivationWrites, GeneratorStaticBlockClosure_RoutesResumableAndObservesLaterActivationMutation, focused UnifiedBytecodeResumableClassExpressionTests (52).
2026-06-06 B24h partial: mixed computed/non-computed public instance class elements Resumable generator bodies admitted LoadClassLiteral for B24h class literals that mix activation-safe computed public instance elements with non-computed public instance fields/methods/accessors under the same no-activation-capture rules. This removed the previous all-elements-computed restriction. Historical boundary: static computed elements, activation-reading computed names, computed-super overlap, private computed neighbors, and the broader class-definition environment bridge remained open; the static-computed row above supersedes the static-computed boundary and later rows replace the private-accessor pin and then admit B24h-computed-static-block-closure-neighbor-routes. Checklist totals stayed 122 / 145; concrete open gates stayed 23. EvaluateResumable_ClassExpressionMixedComputedAndNonComputedPublicInstanceElements_AdmitsLoadClassLiteral, GeneratorMixedComputedAndNonComputedPublicInstanceClassElements_RouteResumable, focused UnifiedBytecodeResumableClassExpressionTests (39), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.96 MB.
2026-06-06 B24h partial: computed public instance class elements Resumable generator and async bodies admitted LoadClassLiteral for activation-safe public instance computed fields/methods/accessors. The admitted subset required computed name programs, field initializer programs, constructor bodies, and member bodies to avoid resumable activation-slot capture, so class creation could stay on the existing expression-program-backed class-definition machinery without materialized-environment semantics. Historical boundary: static computed elements, activation-reading computed names, computed-super overlap, private static initializer dependency/private computed neighbors, mixed non-computed neighbors, and the broader class-definition environment bridge remained open; the mixed row above supersedes the mixed-neighbor boundary. Checklist totals stayed 122 / 145; concrete open gates stayed 23. EvaluateResumable_ClassExpressionComputedPublicInstanceElements_AdmitLoadClassLiteral, EvaluateResumable_AsyncClassExpressionComputedPublicInstanceElements_AdmitLoadClassLiteral, GeneratorComputedPublicInstanceClassElements_RouteResumableAndResolveNames, focused UnifiedBytecodeResumableClassExpressionTests (36), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.96 MB.
2026-06-06 B23 nested literal inner declarations + D5 zero known-open ratchet Resumable nested function literals can now contain their own hoisted function declarations. The outer resumable VM still only creates the literal with LoadFunctionLiteral; the literal's normal invocation path owns declaration instantiation, while the eligibility analyzer now inspects direct nested declarations through the literal AST so an inner declaration that captures an outer resumable slot requests the existing materialized body-environment proof instead of triggering an opaque B23/B36 decline. The D5 non-residue ratchet now models the same invoker proofs used by runtime resumable entry points and has 0 known-open non-residue rows. Checklist remains 122 / 145; concrete open gates remain 23; A+B+C+D is 114 complete / 20 open; Phase B is 53 / 57. GeneratorNestedFunctionLiteralWithInnerDeclarationCapturingLocal_RoutesResumable, EvaluateResumable_NestedFunctionLiteralWithInnerDeclarationCapturingLocal_DeclinesWithoutEnvironmentProof, EvaluateResumable_NestedFunctionLiteralWithInnerDeclarationCapturingLocal_AdmitsWithMaterializedBodyEnvironmentProof, focused UnifiedBytecodeResumableNestedFunctionTests (31), BytecodeNonResidueDeclineRatchetTests (21), full UnifiedBytecodeProduction pack (1238), ExpressionProgramCoverageMapTests (14), clean git diff --check, no runner AST-eval seam matches, and forloop --memory at 6.96 MB.
2026-06-06 C3 top-level lexical destructuring Top-level (script-scope) simple let / const destructuring now routes through production unified bytecode instead of the classified script IR fallback. The step-wise destructuring driver descriptors now carry the target variable kind; dynamic script lexical targets initialize the hoist-time TDZ binding through the VM-owned dynamic lexical path, while dynamic var targets keep the existing dynamic assignment path. The same proof pass repaired a production-bytecode with neighbor: var x = init inside an active with now emits the dynamic declaration/reference sequence before the initializer, preserving pre-initializer reference resolution. The non-residue ratchet known-open count drops from 2 to 1; only the B23/B36 nested resumable declaration row remains. Checklist now 122 / 145; concrete open gates now 23. EvaluateScript_TopLevelConstDestructuring_AcceptsWithDynamicLexicalTargets, EvaluateScript_TopLevelLetArrayDestructuring_AcceptsWithDynamicLexicalTargets, TopLevelLexicalDestructuring_UsesUnifiedBytecodeProductionFastPath, TopLevelConstDestructuring_InitializesConstBindingOnce, TopLevelLexicalDestructuring_SourceExpressionSeesTargetTdz, WithVarInitializer_PreResolvesBindingBeforeInitializerOnProductionFastPath, full UnifiedBytecodeProduction pack (1238), and BytecodeNonResidueDeclineRatchetTests (20 rows).
2026-06-06 A32 optional-chain delete + D5 non-residue ratchet Optional-chain delete shapes now route through production unified bytecode for terminal optional named deletes, non-terminal optional named deletes, terminal optional computed deletes, and delete box?.[first][second] where the first optional computed read is the delete receiver. The compiler emits the VM-owned short-circuit flow (JumpIfNullishReplaceUndefined into JumpIfShortCircuited) so a nullish base returns true without evaluating later keys, while present-path deletes and null-intermediate TypeErrors stay owned by the VM. The non-residue ratchet also dropped the stale non-awaited resumable with dynamic-residue decline row. Checklist now 121 / 145; concrete open gates now 24. Evaluate_OptionalComputedReadThenComputedDeleteChain_AcceptsOwnedPropertyOpcodes, Evaluate_NonTerminalOptionalNamedPropertyDelete_AcceptsOwnedPropertyOpcodes, OptionalComputedReadThenComputedPropertyDelete_UsesUnifiedBytecodeProductionFastPathAndSkipsNullishKeys, NonTerminalOptionalNamedPropertyDelete_UsesUnifiedBytecodeProductionFastPathAndNullIntermediateStillThrows, and BytecodeNonResidueDeclineRatchetTests (20 rows).
2026-06-06 Resumable non-awaited with current environment Resumable generator and async-function bodies now admit plain with (obj) { ... } scopes through EnterWithInstruction/LeaveWithInstruction and the EnterWith/LeaveWith opcodes. UnifiedBytecodeResumeState.CurrentEnvironment persists the active dynamic environment across suspension, and dynamic reads/writes/calls plus closure/class creation resolve against that active environment instead of the original calling environment. Dynamic-scope functions now keep materialized activation-slot metadata even when normal slot rewriting is skipped, so with object expressions can still resolve parameters and locals before the with environment exists. Awaited with-object evaluation remains declined. The audited resumable opcode gap inventory drops from 7 to 5, and the instruction gap inventory drops from 2 to 0. UnifiedBytecodeResumableWithTests covers selector admission with EnterWith/LeaveWith, a generator route hit that yields inside the with body, an async-function route hit that awaits before entering with, and the parameter-only with(o) edge; these read and mutate the with object after suspension, restore the outer dynamic lookup after LeaveWith, and stay on their resumable fast paths. UnifiedBytecodeProductionEligibilityTests pins the positive selector boundary and the remaining awaited-with decline. ProductionRouteCoverageRatchetTests pins the new route rows. ExpressionProgramCoverageMapTests drift-checks the removed gap rows.
2026-06-06 B24 public instance accessor super class literals Resumable generator and async bodies now admit LoadClassLiteral for public non-computed instance getter/setter class expressions whose accessor bodies use super, as long as those accessor bodies do not capture resumable activation slots. This removes the old B24g/B24i overlap for accessor-super bodies; static/computed/private/capturing accessor neighbors and broader class-definition super shapes remain declined. This is semantic shape admission only: the audited opcode gap inventory stays 7 and the instruction gap inventory stays 2. UnifiedBytecodeResumableClassExpressionTests covers selector admission plus generator and async route hits that validate super getter/setter receiver behavior after suspension. UnifiedBytecodeResumableLiteralTests drops the stale accessor-super decline row, and ProductionRouteCoverageRatchetTests pins the route hit.
2026-06-06 B24 mixed public static+instance class fields Resumable generator bodies now admit LoadClassLiteral for class expressions that combine public non-computed static fields with public non-computed instance fields, when instance field initializers do not capture resumable activation slots. This composes the already-owned B24b/B24c field subsets through the existing class-literal slot-environment bridge; static blocks, computed/private/static-accessor members, activation-capturing instance initializers, and other B24h/B24d neighbors remain declined. This is semantic shape admission only: the audited opcode gap inventory stays 7 and the instruction gap inventory stays 2. UnifiedBytecodeResumableClassExpressionTests now covers selector admission plus a generator route hit that initializes static fields at class creation and instance fields per construction, while existing negative rows keep activation-capturing instance fields and static-block/computed/private neighbors off the resumable route.
2026-06-06 Resumable direct body using declarations Direct function-body sync using declarations in generator/async bodies now route through ExecuteResumable. The compiler emits DuplicateTop + RegisterDisposable before the binding store; the resumable invokers materialize the body environment when this shape is present, and completed/throwing resumable steps run sync disposal before surfacing the final result. Block-scoped resumable using remains declined until the VM owns a persisted environment stack, and await using remains declined until async-dispose settlement is VM-owned. The audited resumable opcode gap inventory drops from 8 to 7; the instruction gap inventory stays 2. UnifiedBytecodeResumableUsingDeclarationTests covers selector admission with RegisterDisposable, generator route hits with disposal on completion, non-object TypeError on the resumable route, async function route hits with disposal before resolution, and the block-scoped using no-route boundary. ExpressionProgramCoverageMapTests drift-checks the removed gap row.
2026-06-06 Resumable switch-body breakable markers Resumable generator bodies now admit switch-style BreakableEnterInstruction markers instead of declining before VM entry. The compiler already lowers switch control flow to owned jumps and completion targets, so EvaluateResumable can treat all breakable markers as compiler metadata and let the emitted Yield, Break, and Return opcodes drive execution in ExecuteResumable. This is semantic admission only: no opcode or instruction gap inventory count changes. EvaluateResumable_SwitchBody_AdmitsBreakableMarkers asserts resumable eligibility and emitted Yield/Return opcodes. UnifiedBytecodeResumableSwitchTests.GeneratorSwitchBreakReturnAndDefault_RoutesResumable asserts the unified-bytecode-resumable-generator-fast-path route while covering switch break, return, default, and post-switch yield behavior.
2026-06-06 Resumable flat-slot PushEnvironment Resumable generator bodies now admit flat-slot lexical block scopes through PushEnvironmentInstruction and the PushEnvironment opcode. ExecuteResumable owns TDZ reset, const-slot marking, and per-iteration copy slots directly in UnifiedBytecodeResumeState.Slots, so { let x = ...; yield x; } and for (let value of items) { yield value; } no longer need the IR runner. Materialized block environments across suspension remain declined before VM entry. The audited resumable opcode gap inventory drops from 9 to 8; the instruction gap inventory drops from 3 to 2. UnifiedBytecodeResumableLexicalScopeTests covers eligibility with PushEnvironment/PopEnvironment, generator route hits for block let, block const assignment throwing TypeError, and per-iteration for...of let routing. ExpressionProgramCoverageMapTests drift-checks the removed gap rows.
2026-06-06 Retired obsolete StoreDynamicIdentifier opcode StoreDynamicIdentifier was a declared opcode and resumable allowlist gap, but current compiler paths already lower dynamic writes through the explicit ResolveDynamicIdentifierReference -> StoreDynamicIdentifierReference pair. The dormant ExpressionOpKind.StoreIdentifier lowering now emits that same reference pair, the obsolete opcode/VM case is removed, and the drift inventory no longer counts a gap for an opcode that should not be emitted. The resumable opcode gap inventory drops from 10 to 9; the instruction gap inventory stays 3. ExpressionProgramCoverageMapTests covers the removed enum/gap row; dynamic write semantics stay covered by UnifiedBytecodeResumableFreeIdentifierMutationTests and the production dynamic identifier tests that assert StoreDynamicIdentifierReference.
2026-06-06 A51m measured property-read span rollback diagnostics The measured property-read span helpers are now source-guarded as compiler diagnostics: named, optional named, optional named-chain, and computed measured span helpers all pin rollback of unified instructions, literal constants, and string constants. The computed measured span helper now owns an explicit Failed to emit measured computed property read span. diagnostic after key-span emission rollback instead of surfacing a nested key-span reason. This is diagnostics/guardrail closure, not runtime widening. Checklist now 120 / 145; concrete open gates now 25. ExpressionProgramCoverageMapTests.UnifiedBytecodeCompiler_MeasuredPropertyReadSpanRollbackDiagnosticsAreSourceGuarded and ExpressionProgramCoverageMapTests.UnifiedBytecodeCompiler_DeclineReasonTemplatesMatchExpansionContract; focused rollback guard pack UnifiedBytecodeFirstBoundaryStackDepthGuardTests.
2026-06-06 Resumable opcode allowlist: ApplyBindingTarget assignment destructuring Resumable generator and async bodies now admit assignment destructuring lowered through ApplyBindingTarget. The handler mirrors the sync bridge: pop the source value from UnifiedBytecodeResumeState.OperandStack, sync VM slots into the materialized resumable calling environment, apply the lowered BindingTargetProgram, then sync written bindings back to flat slots for later VM reads. This keeps the bounded binding-target bridge explicit while removing the opcode allowlist gate for source-visible destructuring assignment after yield/await. The resumable opcode gap inventory drops from 11 to 10; the instruction gap inventory stays 3. UnifiedBytecodeResumableAssignmentDestructuringTests covers selector admission, generator route hits after yield, yielded-source destructuring with defaults, async route hits after await, and the removed opcode-gap row in ExpressionProgramCoverageMapTests.
2026-06-06 Resumable opcode allowlist: ThrowReferenceError The resumable VM now admits ThrowReferenceError at the opcode/handler level. The handler creates the ReferenceError, sends it through the same catch/finally abrupt-completion path as the normal Throw opcode, and returns a resumable throw step when no frame handles it. This is a synthetic opcode inventory cleanup: the source producer (delete super[...]) still declines before VM entry. The resumable opcode gap inventory drops from 12 to 11; the instruction gap inventory stays 3. UnifiedBytecodeResumableValueTierTests.EvaluateResumable_ThrowReferenceErrorExpression_AdmitsAndReturnsThrowStep covers selector admission, the ExecuteResumable throw step, and ReferenceError payload shape; ExpressionProgramCoverageMapTests covers the removed opcode-gap row.
2026-06-06 Resumable opcode allowlist: member compound assignment read halves Resumable generator and async bodies now admit GetNamedPropertyForCompoundSet and GetComputedPropertyForCompoundSet, so member compound assignments such as o.x += yield v, o[k] += yield v, and async compound assignment after an await run through ExecuteResumable instead of declining at the opcode allowlist. The handlers mirror the sync VM stack contract: named preserves [base, oldValue], computed preserves [base, key, oldValue], and the existing Set*Property handler consumes the RHS while leaving the assignment result. The resumable opcode gap inventory drops from 14 to 12; the instruction gap inventory stays 3. UnifiedBytecodeResumablePropertyWriteTests covers selector admission for named/computed compound get-for-set opcodes, generator route hits across yield, async route hits after await, and the removed opcode-gap rows in ExpressionProgramCoverageMapTests.
2026-06-06 Resumable instruction allowlist: SetCompletionValueInstruction Resumable generator and async bodies now admit SetCompletionValueInstruction, the completion-reset bookkeeping emitted around if branches. In function/resumable bodies there is no script-completion slot, so the compiler lowers the instruction as VM-owned control flow rather than a new runtime opcode. This slice did not change the opcode gap inventory at that checkpoint; the resumable instruction gap inventory dropped to 3. UnifiedBytecodeResumableSetCompletionValueTests covers selector admission, generator route hits for true/false branches, async route hits with an awaited branch, and the removed instruction-gap row in ExpressionProgramCoverageMapTests.
2026-06-06 B36 partial: direct root class declarations Resumable generator, async-function, and async-generator bodies now admit direct root simple class declarations through DeclareClass. The resumable invokers materialize the body environment so the lexical class binding is created in an environment-backed function body scope, then ExecuteResumable synchronizes that binding back to VM slots. Complex class-definition state (extends, computed names, static elements, and static blocks) remains declined before VM entry. Checklist totals stay 119 / 145 because B36 is still one partial row; the resumable opcode gap inventory drops to 14, and the resumable instruction gap inventory drops to 4. UnifiedBytecodeResumableClassDeclarationTests covers selector admission, generator/async/async-generator route hits, body-scope visibility, and a computed-name no-route neighbor. ExpressionProgramCoverageMapTests drift-checks the removed opcode and instruction gap rows.
2026-06-06 B23 partial: lexical-this/private nested literals Resumable nested function literals now admit lexical-this/private-name contexts. The invokers set an explicit context-proof flag after finding a nested literal that needs lexical this or private-name scopes, and force a per-call invocation environment so nested arrows capture the current this even for ordinary generators invoked with .call(receiver). Private scopes continue to be re-entered from UnifiedBytecodeResumeState.PrivateNameScopes. At this checkpoint, nested declarations inside literals were still the remaining B23 boundary; that was closed by the later B23 nested literal inner-declaration slice above. GeneratorNestedArrowUsesPrivateThis_RoutesResumable, GeneratorNestedArrowCapturesCallThis_RoutesResumable, and EvaluateResumable_NestedArrowLexicalThis_AdmitsWithContextProof; focused UnifiedBytecodeResumableNestedFunctionTests pack.
2026-06-06 B36 partial: recursive/sibling root helper graphs Resumable root hoisted function declarations now admit recursive and sibling helper graphs. The previous FunctionReferencesIdentifierNamed(... rootDeclarationNames ...) collector guard was stale: admitted helpers are all created against the shared declaration environment and the invoker fills their VM flat slots/environment slots before ExecuteResumable, so self/sibling references resolve at call time on the production resumable bytecode route. B36 remains partial for dynamic/eval helpers and complex class declarations; the B23 nested-literal declaration overlap was closed later by the slice above. Checklist totals stayed 119 / 145 at this checkpoint because B36 was still one partial row. GeneratorHoistedFunctionDeclarationRecursiveHelper_RoutesResumable, GeneratorHoistedFunctionDeclarationSiblingHelper_RoutesResumable, and EvaluateResumable_HoistedFunctionDeclarationHelperGraph_AdmitsWithActivationProof; focused UnifiedBytecodeResumableNestedFunctionTests pack.
2026-06-06 B23/B36 partial: async-generator captured nested closures Async-generator resumable bodies now use the materialized body-environment path for captured nested function literals and direct root hoisted helpers. Captured closures can cross await, yield values, resume, and observe post-resume slot mutations on the async-generator production bytecode route. Lexical-this/private-context captures, nested declarations inside literals, recursive/sibling helper graphs, dynamic/eval helpers, and complex class declarations remain open. Checklist totals stay 119 / 145 because B23 and B36 remain partial rows. AsyncGeneratorHoistedFunctionDeclarationCapturesLocal_RoutesResumable, AsyncGeneratorNestedArrowCapturesLocalAcrossYields_RoutesResumable, and EvaluateResumable_AsyncGeneratorNestedFunctionLiteralCapturingLocal_AdmitsWithMaterializedBodyEnvironmentProof; focused UnifiedBytecodeResumableNestedFunctionTests pack.
2026-06-06 B23/B36 partial: async-function captured nested closures Async-function resumable bodies now use the same materialized body-environment ownership that the generator route uses for captured nested closures. Captured nested function literals and direct root hoisted helpers can close over root body locals, cross await, observe post-resume slot mutations, and be called directly inside the async body on the production resumable bytecode route. Async-generator captured closures are superseded by the row above; lexical-this/private-context captures, nested declarations inside literals, recursive/sibling helper graphs, dynamic/eval helpers, and complex class declarations remain open. Checklist totals stay 119 / 145 because B23 and B36 remain partial rows. AsyncHoistedFunctionDeclarationCapturesLocalAndCallsInsideBody_RoutesResumable, AsyncNestedArrowCapturesLocalAndCallsInsideBody_RoutesResumable, and EvaluateResumable_AsyncNestedFunctionLiteralCapturingLocal_AdmitsWithMaterializedBodyEnvironmentProof; focused UnifiedBytecodeResumableNestedFunctionTests pack.
2026-06-06 A48/B13/B14/B41 stale gate closure Current source already admits async-kind iterator drivers and resumable super-property read/write/update. The checklist now marks A48, B13, B14, and B41 complete instead of treating them as open gates. This is docs/accounting progress, not new runtime code. Checklist now 119 / 145; concrete open gates now 26. IsSupportedIteratorInit_AsyncKind_Accepts, IsSupportedIteratorInit_AsyncKindWithAwaitedSource_Accepts, EvaluateResumable_ForAwaitOfDriver_AdmitsAsyncIteratorDriver, UnifiedBytecodeResumableForOfTests async for-await runtime proofs, UnifiedBytecodeResumableSuperPropertyReadTests, UnifiedBytecodeResumablePropertyWriteTests, and UnifiedBytecodeResumablePropertyUpdateDeleteTests.
2026-06-05 A42 sync using declaration admission Sync function-local using declarations now route through production unified bytecode. The compiler emits RegisterDisposable after initializer evaluation and before flat-slot or lowered binding-target storage, and the VM registers sync resources against the active environment, disposes them on normal/throw completion and block PopEnvironment, preserves null/undefined no-op behavior, and throws TypeError for non-object values. await using remains explicitly declined until async-dispose promise settlement is VM-owned. Checklist now 100 / 145; A+B+C checklist now 92 complete / 37 open; the new opcode is listed as a sync-only resumable allowlist gap. Evaluate_SyncUsingDeclaration_AcceptsWithDisposableRegistration, Evaluate_AwaitUsingDeclaration_StaysDeclined, SyncUsingDeclaration_UsesUnifiedBytecodeProductionFastPathAndDisposes, SyncUsingDeclaration_DisposesWhenUnifiedBytecodeBodyThrows, SyncUsingDeclaration_NonObjectThrowsOnUnifiedBytecodeProductionFastPath, AwaitUsingDeclaration_DoesNotUseUnifiedBytecodeProductionFastPath, and ExpressionProgramCoverageMapTests drift checks.
2026-06-05 B24g class-expression public accessors Resumable generator/async bodies admitted LoadClassLiteral for the public non-computed instance getter/setter class-expression subset whose accessor bodies did not capture activation slots and did not use super. The VM still delegated accessor creation to class-definition member assignment through the captured calling environment, so getter/setter descriptor flags and receiver binding stayed on the existing class machinery. Historical boundary: static accessors, computed accessors, private/mixed accessor shapes, activation-capturing accessor bodies, and accessor bodies using super remained declined at this checkpoint; the 2026-06-06 accessor-super row above supersedes that last boundary. Checklist then stood at 99 / 145; B bucket then stood at 42 / 57 complete. UnifiedBytecodeResumableClassExpressionTests covered generator and async eligibility with LoadClassLiteral, generator/async fast-path runtime behavior after yield/await, descriptor get/set presence plus enumerable/configurable flags, receiver-sensitive getter/setter calls, and no-route pins for computed/static/capturing/super/private accessor neighbors.
2026-06-05 B36 partial: sync-generator captured hoisted helpers Sync generator bodies now admit direct root hoisted helper declarations that capture root body locals. The generator invoker allows this subset only when it owns the materialized resumable body environment, creates the helper against that environment, mirrors the helper into the VM flat slot and environment slot, and relies on the existing slot/environment synchronization so the helper observes updated locals across yield/resume. Async-function and async-generator captured helpers are superseded by the 2026-06-06 B23/B36 rows. Recursive/sibling helper graphs, dynamic/eval helpers, descriptor-backed block/Annex B declarations, and complex class declarations remain declined. B36 remains partial; checklist totals and gap inventories are unchanged by this sub-slice. UnifiedBytecodeResumableNestedFunctionTests covers a generator route hit for function helper(){ return n; } reading 3 then 4 across yields, the historical async and async-generator captured-helper no-route pins before the follow-ups, and retained recursive/sibling-helper no-route boundaries.
2026-06-05 B23 partial: generator captured-local function literals Resumable generator bodies now admit nested function literals that capture root body locals. The generator invoker sets an explicit materialized-body-environment proof flag only when the plan contains such a captured literal, builds a function-scope body environment from the activation slot layout, mirrors the compiled VM flat slots into that environment, and ExecuteResumable synchronizes slot writes back into the environment so captured closures observe current values across yield/resume. Async-function and async-generator captured-local literals are superseded by the 2026-06-06 B23/B36 rows; lexical-this/private-context literals, nested declarations inside literals, recursive/sibling helper graphs, block/Annex B declarations, and complex class declarations were still declined at this checkpoint. The later 2026-06-06 nested literal inner-declaration slice closes the B23 part. UnifiedBytecodeResumableNestedFunctionTests covers a generator route hit for var f=()=>n reading 1 then 2 across yields, eligibility decline without the materialized-body proof flag, eligibility admission with the proof flag, and the retained nested-declaration/capturing-helper no-route boundaries.
2026-06-05 B33 break/continue across suspension Resumable generator and async bodies now admit BreakInstruction and ContinueInstruction through the plan-level instruction allowlist. The compiler already lowered both records to VM-owned Break/Continue opcodes, and ExecuteResumable already runs crossed-driver cleanup through TryCleanupDriverStatesForControlTargetResumable; the remaining fix was to keep sync generator iterator-close cleanup synchronous for plain Iterator.return() results while preserving async-step scheduling for async functions/generators. The resumable instruction gap inventory drops from 9 to 7. Checklist now 98 / 145; B bucket now 41 / 57 complete. UnifiedBytecodeProductionEligibilityTests covers generator and async break/continue admission. UnifiedBytecodeResumableForOfTests covers labeled generator break closing the iterator exactly once and labeled continue preserving the target iterator, both with unified-bytecode-resumable-generator-fast-path route hits. ExpressionProgramCoverageMapTests drift-checks the removed instruction-gap rows.
2026-06-05 B47a resumable yield* synthetic slot layout Verified the current compiler already adds generator-lowered synthetic resume/result and yield* driver-state symbols to the activation slot layout before flat-slot mapping. Sync generator yield* therefore stays eligible for resumable production bytecode and routes through ExecuteResumable; async-generator yield* is admitted by B39 for both direct delegated sources and awaited delegated sources. Checklist now 97 / 145; B bucket now 40 / 57 complete. Existing focused pins cover the route and boundary: EvaluateResumable_YieldStar_AcceptsAfterDelegatedAbruptResumeIsModeled, EvaluateResumable_ReturnYield_AcceptsSyntheticResumeSlot, TryCompile_SyncGeneratorYieldStar_ProducesResumableYieldStarOp, public UnifiedBytecodeProductionInvocationTests generator yield* route pins, and async-generator delegation route tests.
2026-06-05 B24b class-expression public instance fields Resumable generator/async bodies now admit LoadClassLiteral for class expressions whose class-definition surface is limited to public non-computed instance fields and whose field initializers do not capture activation slots. ExecuteResumable creates the class value from the captured calling environment, while activation-capturing field initializers stay declined until the resume state owns a materialized body environment. Static, private, computed, accessor/member, extends/super, and static-block class-expression shapes stay declined for the neighboring B24 leaves. Checklist now 96 / 145; B bucket now 39 / 57 complete; the resumable opcode gap inventory drops from 20 to 19. UnifiedBytecodeResumableClassExpressionTests covers eligibility, the LoadClassLiteral opcode, generator fast-path logging, field initializer values, undefined fields, constructor-order interaction, and non-B24b decline pins.
2026-06-05 B24a class expression constructor/default-constructor creation Resumable generator and async bodies now admit constructor-only class expressions through LoadClassLiteral. TryFindUnsupportedResumableOpcode gates the opcode by class shape so static fields, static blocks/elements, private members, accessors, computed members, member-super bodies, non-B24b field shapes, and extends expressions that read resumable activation slots remain declined for B24c-B24i / later class-definition environment work. ExecuteResumable creates the class value with the captured calling environment, translating class-creation throws to the resumable throw step; explicit constructors, implicit base constructors, and environment-resolved implicit derived constructors now preserve constructability, prototype wiring, class names, and super forwarding on the resumable route. Checklist then stood at 93 / 145; B bucket then stood at 38 / 57 complete. UnifiedBytecodeResumableLiteralTests covers eligibility and route hits for explicit constructors, implicit base defaults, implicit derived defaults, async-after-await class creation, and negative B24b-B24i class-member shapes.
2026-06-05 B36 partial: resumable root hoisted function declarations Resumable generator, async, and async-generator bodies now admit direct root function-scoped declarations when the helper is non-capturing and does not require dynamic/eval or block-declaration semantics. The resumable invokers collect the safe declarations before eligibility, set the activation proof flag, and pre-populate each helper into the compiled VM flat slot before ExecuteResumable starts; slot resolution uses the compiled UnifiedBytecodeProgram slot names so async synthetic resume slots cannot shift the binding. Later B36 sub-slices admit sync-generator, async-function, and async-generator helpers that capture root body locals through a materialized body environment, and the 2026-06-06 direct-root class-declaration row admits simple class declarations. Recursive/sibling helper dependencies, descriptor-backed block/Annex B declarations, and complex class declarations still declined at this checkpoint, so B36 remained open and checklist count remained 92 / 145; the resumable instruction gap inventory dropped from 10 to 9. UnifiedBytecodeResumableNestedFunctionTests covers generator route hits for declarations before and after the call, async route hits after await, async-generator route hits, activation-proof eligibility, and captured-helper boundary correctness. ExpressionProgramCoverageMapTests drift-checks the removed instruction-gap row.
2026-06-05 B29 resumable dynamic free compound/logical writes Resumable generator/async bodies now admit free/global and captured compound writes (freeVar += v, freeVar *= v) and logical compound writes (`freeVar
2026-06-05 B26 resumable dynamic free writes Resumable generator/async bodies now admit free/global plain writes (freeVar = v, including freeVar = yield v) through ResolveDynamicIdentifierReference -> StoreDynamicIdentifierReference. UnifiedBytecodeResumeState now persists the pending dynamic AssignmentReference, so the LHS target resolved before evaluating the RHS survives yield/await suspension and cannot be changed by RHS or outer-code side effects before the store. At the B26 checkpoint, compound/logical free-var writes still declined at their instruction gates; the B29 row above supersedes that historical boundary. Checklist then stood at 91 / 145; the resumable opcode gap inventory dropped from 33 to 29. UnifiedBytecodeResumableFreeIdentifierMutationTests covers eligibility, generator route hits for direct and suspending-RHS writes, async route hits, and the then-still-declined compound boundary. UnifiedBytecodeResumablePropertyWriteTests shares the B26 eligibility pin; ExpressionProgramCoverageMapTests drift-checks the four removed opcode gaps.
2026-06-05 B23 partial: non-capturing resumable function literals Resumable generator/async bodies now admit non-capturing nested function literals through LoadFunctionLiteral and EnsureHasName, with ExecuteResumable creating the function value against the captured closure environment and preserving name inference. Capturing literals still decline because body locals live in resume-state flat slots, not environment bindings; function declarations nested inside otherwise non-capturing literals also declined at this checkpoint until declaration instantiation was represented by the B36 partial route above. The same LoadFunctionLiteral admission unlocks object-literal method/accessor members in resumable literals, so A35b-e are now sync/resumable green. Checklist count remained 90 / 145 at this checkpoint, but the resumable opcode gap inventory dropped from 36 to 33 after also removing the already-admitted LoadTemplateObject stale row. UnifiedBytecodeResumableNestedFunctionTests covers generator and async non-capturing route hits, direct capture decline, nested-declaration-in-literal decline, and the then-current B36 declaration decline. UnifiedBytecodeResumableLiteralTests now covers static/computed methods and accessors in resumable object literals.
2026-06-05 B2 sync-generator yield* stale gate closure The old sync-generator yield* checklist row is now closed instead of staying red as a misleading umbrella. Local/param delegated iterables already route through ExecuteResumable, and the free/dynamic delegated iterable plus free-call target lane was closed by B38. Async-generator direct and awaited delegated-source shapes are tracked under B39; the historical resumable-only compiler-layout concern is tracked and closed under B47a. Existing route pins cover the closed sync-generator surface: ResumableAlreadyRoutingPinTests for local/param delegated iterables and UnifiedBytecodeProductionInvocationTests for free/dynamic delegated iterables, free-call targets, delegated return, and delegated throw. Checklist now 90 / 145 complete with 55 open.
2026-06-05 B32 resumable try/catch across suspension Simple and optional catch bindings now route through ExecuteResumable instead of falling back to the IR runner. UnifiedBytecodeResumeState owns a resumable try-frame stack that persists the try descriptor index, thrown value, catch-used flag, finally scheduling flag, and pending completion across yield/await boundaries. EnterCatch binds the preserved thrown value into the flat catch slot, explicit throw and generator .throw(...) resumes route through the active catch/finally frame before completing, and the catch cleanup PopEnvironment is admitted as a flat-slot no-op on the resumable route. Destructuring catch bindings remain declined because their binding-target environment semantics are not yet modeled in the resumable frame. UnifiedBytecodeResumableTryCatchTests covers explicit throw catch binding, .throw(...) resume catch binding, and following finally cleanup after a caught resume throw with route-hit assertions. UnifiedBytecodeProductionEligibilityTests.EvaluateResumable_TryCatchPlan_AcceptsOwnedCatchOpcode pins the EnterCatch admission. Focused plus drift pack green: 569 passed with existing nullable warnings.
2026-06-05 B8a resumable const-slot enforcement / lexical slot writes Resumable generator/async bodies now route lexical let/const slot assignment and update through production unified bytecode. UnifiedBytecodeResumeState carries a const-slot bitmap seeded from UnifiedBytecodeProgram.ConstSlotIndices and extended by TdzHeadInit; ExecuteResumable checks it in StoreSlot and UpdateSlot before mutation/coercion. The old broad lexical-slot assignment/update declines and expression-program slot-reference assignment guard are removed: let writes mutate the flat slot, while const writes route and throw from the VM. UnifiedBytecodeResumableSlotUpdateTests now covers let update/assignment fast-path routing plus const update/assignment fast-path TypeError behavior; focused pack green: 14 passed. Checklist now 89 / 145 complete with 56 open.
2026-06-05 B21 tagged-template / template-object calls Ordinary identifier and member tagged-template calls now stay on production unified bytecode on both sync and resumable routes. Bare identifier tags lower as LoadIdentifierCallTarget, LoadTemplateObject is modeled as a value-producing call argument, and tagged calls fall through to the generic expression compiler so the VM emits Prepare*CallTarget, LoadTemplateObject, substitutions, and CallInvocationBoundary in source order. ExecuteResumable now handles LoadTemplateObject through the same descriptor/callsite identity cache as the sync VM. UnifiedBytecodeTaggedTemplateProductionTests covers sync identifier/member tags, receiver preservation, generator tags, substitution across yield, and async tags after await; lowering proof FunctionPlan_IdentifierTaggedTemplateExpression_UsesIdentifierCallTarget; focused pack green: 16 passed. Checklist now 88 / 145 complete with 57 open.
2026-06-05 B38 sync generator yield* over free/dynamic iterable Sync generator yield* now stays on production resumable unified bytecode when the delegated iterable is a free/dynamic binding or a free call target (yield* values, yield* makeIterator()). The targeted YieldStarIterableHasFreeIdentifierDependency decline guard is deleted. The VM-owned YieldStar handler now preserves the original delegated iterator result object for done:false, sends undefined to the first delegated next() even when the outer first next(value) supplied a value, and synchronously unwraps promise-like delegated throw/return results so the previously IR-only semantics are owned by ExecuteResumable. The checklist is now 87 / 145 complete with 58 open. UnifiedBytecodeProductionInvocationTests adds free-iterable and free-call route coverage, including first next(undefined) and original-result preservation. Focused yield-star pack green: 98 passed for GeneratorTests/UnifiedBytecodeProductionInvocationTests/eligibility/routing pins.
2026-06-05 B39 async-generator yield* asyncIterable Async-generator yield* over a delegated async iterable now routes through production resumable unified bytecode for both direct delegated sources and yield* await ... awaited delegated sources. AsyncGeneratorInvoker marks the resumable frame as an async-generator frame; awaited delegated sources emit <awaited source> -> AwaitValue -> YieldStar; and ExecuteResumable initializes YieldStar with an async iterator driver, awaits delegated next/return/throw results through the existing PendingAwait promise-settlement bridge, sends undefined to the first delegated next(), and resumes the same driver state after each delegated promise settles. UnifiedBytecodeAsyncGeneratorRouteTests covers eligibility, opcode emission, route logging, first next(undefined), yielded values, and final completion for direct and awaited delegated sources. UnifiedBytecodeProductionInvocationTests covers delegated async .return(value) and .throw(value) through the async-generator awaited-source resumable route.
2026-06-05 A41 UnsupportedPlanShape — slot-resolved consumed identifier assignment references Explicit slot-resolved assignment references now stay on production unified bytecode when the assignment value is consumed: return (x = 5), var y = (x = 5), g(x = 5), and chained (x = z = 5). Eligibility and compiler lowering now carry pending identifier-reference side-state; ResolveIdentifierReference records the explicit activation slot and StoreResolvedIdentifier emits DuplicateTop + StoreSlot, preserving the assigned value while writing the flat slot. Complex call arguments share the same lowering, closing the g(x=v) residue. Name-only activation-slot matches remain declined because the compiler cannot prove dynamic/with shadowing from name lookup alone. The checklist is now 86 / 145 complete with 59 open. A41SlotReferenceAssignAdmissionTests asserts route-hit execution for return/var/call/chained assignments, direct eligibility, and the compiled DuplicateTop + StoreSlot sequence with no StoreDynamicIdentifierReference.
2026-06-05 A31 OptionalChainDependency — computed second-hop optional-chain call arguments Identifier calls now keep production unified bytecode when a logical argument is an optional computed-start chain with another computed or named optional hop, for example fn(box?.[key]?.[key]) and fn(box?.[key]?.value), and when an optional named-start chain continues through an optional computed hop, for example fn(box?.prop?.[key]). The call-argument span walkers (TryMeasureSimpleOptionalComputedPropertyReadOperandSpan, TryMeasureSimpleOptionalNamedThenComputedReadOperandSpan) now validate one boundary jump per optional computed hop, supported computed key spans, and optional/plain named continuations; the compiler emitters mirror that shape and backpatch every JumpIfNullishReplaceUndefined(end) to the same chain end. A31's known concrete call-argument residue is closed; remaining concrete OptionalChainDependency tests are the A32 optional-delete chain and the documented resumable-only optional-computed-hop call boundary. Eligibility Evaluate_IdentifierCallWithChainedOptionalComputedReadArgument_AcceptsComputedReadChain, Evaluate_IdentifierCallWithOptionalComputedThenOptionalNamedReadArgument_AcceptsNamedContinuation, and Evaluate_IdentifierCallWithOptionalNamedThenOptionalComputedReadArgument_AcceptsComputedContinuation assert two nullish jumps plus CallInvocationBoundary; runtime IdentifierCallWithChainedOptionalComputedReadArgument_UsesUnifiedBytecodeProductionFastPath, IdentifierCallWithOptionalComputedThenOptionalNamedReadArgument_UsesUnifiedBytecodeProductionFastPath, and IdentifierCallWithOptionalNamedThenOptionalComputedReadArgument_UsesUnifiedBytecodeProductionFastPath assert unified-bytecode-production-fast-path func=invoke argc=3 and nullish-hop correctness.
2026-06-05 A31 OptionalChainDependency — named second-hop optional-chain call arguments Identifier calls now keep production unified bytecode when a logical argument is an optional-start named chain with another named optional hop, for example fn(box?.value?.nested) and fn(box?.child?.value). The dependency scan now reuses the same measured optional-named call-argument span as the selector, and the compiler emits one JumpIfNullishReplaceUndefined(end) per optional hop before owned GetNamedProperty reads. The computed second-hop variants (fn(box?.[key]?.[key]), fn(box?.[key]?.value), fn(box?.prop?.[key])) are covered by the adjacent A31 computed call-argument row. Eligibility Evaluate_IdentifierCallWithChainedOptionalNamedPropertyReadArgument_AcceptsGetNamedPropertyChain and Evaluate_IdentifierCallWithOptionalThenOptionalNamedReadChainArgument_AcceptsGetNamedPropertyChain assert two nullish jumps plus CallInvocationBoundary; runtime IdentifierCallWithChainedOptionalNamedReadArgument_ShortCircuitsAtEachHop and ...DoesNotReadTrailingHopAfterShortCircuit assert unified-bytecode-production-fast-path func=invoke argc=2.
2026-06-05 P0.4 coarse-leaf decomposition Phase 0 is now closed: A35 is split into five concrete object-literal member opcode leaves (DefineComputedObjectProperty, DefineObjectMethod, DefineComputedObjectMethod, DefineObjectAccessor, DefineComputedObjectAccessor), and B24 is split into nine class-expression semantic leaves (constructor, instance/static fields, static blocks, private fields/methods, accessors, computed members, and super-in-members). At P0.4 closure the checklist stood at 85 / 145 complete with 60 open; the current count is tracked at the top of this document and by later ledger rows. ExpressionProgramCoverageMapTests.UnifiedBytecodeExpansionContract_ListsCoarseLeafDecomposition drift-checks the new contract headings; docs/plans/bytecode-burndown-checklist.md marks P0.4 complete and updates phase counts.
2026-06-05 P0.3 / E3 inventory closure The remaining default-admission surfaces are now machine-counted: sync prototype opcode guard gaps (6), resumable opcode allowlist gaps (33 after the B23 LoadFunctionLiteral / EnsureHasName partial and stale LoadTemplateObject removal), and resumable instruction allowlist gaps (12). This does not admit new runtime shapes by itself; it replaces stale default buckets with source-checked gap inventories in docs/unified-bytecode-expansion-contract.md. ExpressionProgramCoverageMapTests now compares UnifiedBytecodeOpCode and ExecutionInstruction inventories to TryFindPrototypeOnlyOpcode, TryFindUnsupportedResumableOpcode, ExecuteResumable, and IsSupportedResumableInstruction, and verifies the documented gap lists.
2026-06-06 A51j PropertyWriteDependency — property WRITE with a computed receiver prefix (TryIsFirstBoundaryComputedPrefixComputedPropertyWriteCandidate + TryAppendFirstBoundaryComputedPrefixComputedPropertySet, sync route only) Computed receiver-prefix mutation now routes through synchronous production unified bytecode for the computed-write terminal box[k1].child[k2] = value, compound terminal box[k1].child[k2] += value, and logical terminals box[k1].child[k2] &&= value / `
2026-06-04 A23 PropertyUpdateDependency — property UPDATE with a computed receiver prefix (TryIsFirstBoundaryComputedPrefixPropertyUpdateCandidate + TryAppendFirstBoundaryComputedPrefixComputedPropertyUpdate, sync route only) Property updates whose receiver is reached through a computed property read now route through synchronous production unified bytecode: the computed-update terminal box[k1].child[k2]++ / --box[k1].child[k2] / box[k1].child[k2]-- / ++box[k1].child[k2], and the named-update terminal box[k1].child++ / --box[k1].child. Before this slice these declined: the named-update terminal already lowered through the generic UpdateNamedProperty per-op path (the receiver-prefix reads flow generically onto the stack), but the COMPUTED-update terminal declined PropertyUpdateDependency at the eligibility gate and — even once admitted — failed to compile, because TryAppendFirstBoundaryNestedNamedComputedPropertyUpdate only owns a PLAIN-named receiver prefix (op 1 must be GetNamedProperty, but a computed prefix starts with the key/GetComputedProperty sequence) and TryAppendFirstBoundaryComputedPropertyUpdate mis-reads the whole prefix as a single key span (Unsupported computed property key span). This slice adds one self-contained eligibility candidate that resolves the computed-read receiver prefix ONCE via the shared TryMeasureSimpleComputedPropertyReadOperandSpan (so the prefix getter runs exactly once) and validates either a named update target or a trailing simple computed key span, plus one compiler emitter (TryAppendFirstBoundaryComputedPrefixComputedPropertyUpdate, wired BEFORE the simple computed-update emitter) that emits the prefix span (reusing TryAppendMeasuredSimpleComputedPropertyReadOperandSpan), then the computed key span, then UpdateComputedProperty. The shape is fully validated and IsSupportedComputedPropertyKeySpan-checked before any operand is staged (no emit-then-bail, crash class #3105) — a non-match rolls back the staged builders cleanly. Postfix returns the old value, prefix the new; ++/-- share the opcode via EncodeUpdateFlags. Computed-prefix compound/logical write terminals are covered by the later A51j PropertyWriteDependency row; a call inside the update prefix (box[k1]().child[k2]++) declines CallDependency. STAYS OUT of the resumable allowlist (TryFindUnsupportedResumableOpcode / ExecuteResumable untouched) — synchronous admission only; all emitted opcodes already have sync VM handlers. Eligibility (opcode shape): Evaluate_ComputedPrefixComputedPropertyUpdate_AcceptsOwnedPropertyOpcodes (box[k1].child[k2]++, --, ++, -- prefix/postfix — asserts GetComputedProperty + UpdateComputedProperty), Evaluate_ComputedPrefixNamedPropertyUpdate_AcceptsOwnedPropertyOpcodes (box[k1].child++ — asserts GetComputedProperty + UpdateNamedProperty); adversarial decline Evaluate_ComputedPrefixPropertyUpdateWithCallInPrefix_Declines (CallDependency). Runtime + ROUTING (all assert the unified-bytecode-production-fast-path func=update log so an interpreter fallback fails the test): ComputedPrefixComputedPropertyUpdate_PostfixReturnsOldValue (41:42), …PrefixReturnsNewValue (9:9), ComputedPrefixNamedPropertyUpdate (7:8), …ResolvesPrefixAndKeyExactlyOnce (prefix getter once, target getter once, setter once → 41,1,1,1,42), …ThrowsWhenPrefixHopIsNullish (TypeError); three representative shapes (o[k1].child[k2]++, o[k1].child++, --o[k1].child[k2]) added to ProductionRouteCoverageRatchetTests. Full internal suite 5668 passed / 0 failed / 2 skipped.
2026-06-04 A34 ObjectLiteralOrSpreadDependency — object spread with NON-simple source (TryMeasureSimpleSpreadSourceOperandSpan — the A33 source measurer renamed from TryMeasureSimpleArraySpreadSourceOperandSpan and now shared — plus the simple-object-literal-span escape hatch on the LoadIdentifierCallTarget and plain GetNamedProperty decline cases, sync route only) Object-literal spreads whose SOURCE is non-simple now route through synchronous production unified bytecode: a bare activation-resolved identifier call ({...f()}, {...gen()}), a plain named property read off such a call ({...f().inner}, {...f().a.b}), an admitted member call ({...o.make()}), and the same sources mixed with normal properties ({a, ...f(), c: 3}). Before this slice the object-literal spread gate accepted ONLY TryMeasureSimpleMemberCallOperandSpan before an ObjectSpread (so {...o.m()} worked but {...f()} and {...f().inner} declined): the LoadIdentifierCallTarget decline case carried only the array-literal-span escape hatch (A33), and the plain GetNamedProperty case likewise only checked the array-literal span. The widening is scoped strictly to spread sources: the existing (already validated) source measurer is reused — consulted in TryMeasureSimpleObjectLiteralSpan ONLY when the property terminates in ObjectSpread, so an ordinary value ({a: f()}) and a computed read off a call ({...f()[0]}) stay declined; the shape is fully validated before any operand is emitted (no emit-then-bail). The ObjectSpread opcode copies the source's own ENUMERABLE properties (getters fire in source order; non-enumerables skipped; null/undefined is a no-op), so the source span, built from already-admitted VM opcodes, needs no new VM handler. The two decline cases (LoadIdentifierCallTarget, GetNamedProperty) now consult IsOperationInSimpleObjectLiteralSpan alongside the array one. STAYS OUT of the resumable allowlist: TryFindUnsupportedResumableOpcode and ExecuteResumable are untouched. UnifiedBytecodeProductionObjectSpreadNonSimpleSourceTests: identifier-call, named-property-of-call, deep-named-property-of-call, member-call, mixed-normal-and-spread-with-override-order, getter-invocation-order, non-enumerable-skipped, null-no-op, undefined-no-op, and throw-in-chain (all assert correctness plus the unified-bytecode-production-fast-path func=build route-hit log so an interpreter fallback fails the test); three representative shapes ({...g()}, {...g().inner}, {a, ...g(), c:3}) also added to ProductionRouteCoverageRatchetTests. Full internal suite 5655 passed / 0 failed / 2 skipped (+10 A34 object-spread tests, +3 ratchet rows).
2026-06-04 A33 ObjectLiteralOrSpreadDependency — array spread with NON-simple source (TryMeasureSimpleArraySpreadSourceOperandSpan plus simple-array-literal-span escape hatch on the LoadIdentifierCallTarget and plain GetNamedProperty decline cases, sync route only) Array-literal spreads whose SOURCE is non-simple now route through synchronous production unified bytecode: a bare activation-resolved identifier call ([...f()], [...gen()]), a plain named property read off such a call ([...f().items], [...f().a.b]), and the same sources mixed with normal elements ([a, ...f(), c]). Before this slice these declined CallDependency ("Identifier call-target preparation is outside the first production invocation boundary") because the array-literal element gate only measured spread sources through TryMeasureSimpleLiteralValueOperandSpan (which admits member calls like [...o.m()] but NOT bare identifier calls or property reads off a call) and the LoadIdentifierCallTarget / GetNamedProperty decline cases lacked the simple-array-literal-span escape hatch that the member-call (LoadNamedCallTarget) and Call cases already carry. The widening is scoped strictly to spread sources: a new TryMeasureSimpleArraySpreadSourceOperandSpan (bare identifier call or member call, optionally followed by >=1 plain named read) is consulted in TryMeasureSimpleArrayLiteralSpan ONLY when the element terminates in ArraySpread, so an ordinary push element ([f()]) and a computed read off a call ([...f()[0]]) stay declined; the shape is fully validated before any operand is emitted (no emit-then-bail). The ArraySpread opcode drives the standard iterator protocol over the produced value — throwing a TypeError on a non-iterable source and propagating any throw raised while producing or iterating it — so the source span, built from already-admitted VM opcodes, needs no new VM handler. STAYS OUT of the resumable allowlist: TryFindUnsupportedResumableOpcode and ExecuteResumable are untouched. UnifiedBytecodeProductionSpreadNonSimpleSourceTests: identifier-call, generator-call, named-property-of-call, deep-named-property-of-call, Set-from-call, mixed-normal-and-spread, iterate-once-left-to-right, throw-on-non-iterable, and throw-in-chain (all assert correctness plus the unified-bytecode-production-fast-path func=build route-hit log so an interpreter fallback fails the test); three representative shapes ([...g()], [...g().items], [a, ...g(), c]) also added to ProductionRouteCoverageRatchetTests. Full internal suite 5642 passed / 0 failed / 2 skipped.
2026-06-04 A30 OptionalChainDependency — optional-computed-START member calls (TryIsFirstBoundaryOptionalComputedStartPlainCallCandidate / TryAppendOptionalComputedStartPlainCallTarget and TryIsFirstBoundaryOptionalChainComputedReceiverOptionalCallCandidate / TryAppendOptionalChainComputedReceiverOptionalCallTarget, sync route only) Two optional-computed-START member-call shapes now route through synchronous production unified bytecode: o?.[k]() (leading optional hop on a COMPUTED receiver, plain non-optional computed call — the computed-key twin of the already-admitted Case 6 a?.b[k]()) and the double-optional a?.b?.[k]() (optional named start + optional computed continuation, plain call — the computed-key twin of the already-admitted Case 5 a?.b?.c()). Before this slice both declined UnsupportedPlanShape ("Unsupported computed property key op") at the compiler's generic computed-member-call key-span walk: the leading JumpIfNullish (for o?.[k]()) / the GetNamedProperty(opt) + JumpIfShortCircuited prefix (for a?.b?.[k]()) sit between the receiver base and the key span, which the generic FindComputedCallKeyStart walk (plain-named-reads only) cannot skip. The two new candidate predicates fully validate the rigid op layout (activation-resolved base; the leading JumpIfNullish(ReplaceWithUndefined) targeting the program END, or the optional named hop + JumpIfShortCircuited + second JumpIfNullish both targeting END; a simple computed key; a non-optional LoadComputedCallTarget; simple call arguments) BEFORE any operand is emitted, and the two new compiler handlers lower base → JumpIfNullishReplaceUndefined(end) [→ GetNamedProperty → second JumpIfNullishReplaceUndefined(end)] → key-load → PrepareComputedCallTarget → args, every nullish jump backpatched to the same chain end. A nullish receiver at ANY hop short-circuits the WHOLE call to undefined — the call is never made and the computed key is never evaluated past the short-circuit; this is the receiver on the present path; throws from the invoked method propagate. STAYS OUT of the resumable allowlist: the widening is gated by allowSyncOnlyOptionalComputedStartCalls on TryFindExpressionDecline (set only on the sync TryFindPlanDecline walk), so the resumable route still declines these shapes as OptionalChainDependency at the plan walk (EvaluateResumable_OptionalComputedHopCall_StillDeclinesAtPlanWalk stays green) and TryFindUnsupportedResumableOpcode is untouched; all emitted opcodes already have sync VM handlers. Remaining: the callee-optional o?.[k]?.() and spread-onto-optional (a?.b?.(...args)) still decline. UnifiedBytecodeProductionInvocationTests: OptionalComputedStartCall_ShortCircuitsToUndefinedWhenBaseNullish, OptionalComputedStartCall_InvokesMethodAndPreservesThisWhenBaseNonNull, OptionalComputedStartCall_DoesNotEvaluateKeyOrInvokeWhenBaseNullish, OptionalComputedStartCall_PropagatesThrowFromInvokedMethod, OptionalComputedStartCall_WithLiteralKeyAndArguments, DoubleOptionalNamedThenComputedCall_ShortCircuitsWhenFirstHopNullish, DoubleOptionalNamedThenComputedCall_ShortCircuitsWhenSecondHopNullish, DoubleOptionalNamedThenComputedCall_InvokesMethodAndPreservesThisWhenPresent, DoubleOptionalNamedThenComputedCall_DoesNotEvaluateKeyWhenShortCircuited, DoubleOptionalNamedThenComputedCall_PropagatesThrowFromInvokedMethod (all assert correctness, short-circuit-at-each-hop with no key/method side effect, throw-in-chain, and the unified-bytecode-production-fast-path func=invoke route-hit log so an interpreter fallback fails the test); the two short-circuit + two present shapes also added to ProductionRouteCoverageRatchetTests. Full internal suite 5630 passed / 0 failed / 2 skipped (+10 invocation tests, +4 ratchet rows).
2026-06-04 R1/R5 resumable VM typeof of a free/dynamic identifier (B25: TryFindUnsupportedResumableOpcode + one ExecuteResumable handler) The resumable VM (ExecuteResumable) already admitted free/dynamic identifier READS (LoadDynamicIdentifier) and free CALL / OPTIONAL-CALL targets (PrepareDynamicIdentifierCallTarget/PrepareDynamicIdentifierOptionalCallTarget, #3111/B15) resolved against the live UnifiedBytecodeResumeState.CallingEnvironment (#3108), but typeof freeVar of a free/dynamic identifier (opcode TypeOfDynamicIdentifier) still declined back to the interpreter — it was missing from the resumable allowlist and the ExecuteResumable switch. This slice admits it: TypeOfDynamicIdentifier is added to TryFindUnsupportedResumableOpcode, and the ExecuteResumable switch gets one handler that is the LITERAL TWIN of the sync Execute path — it resolves the name against RequireDynamicEnvironment(state.CallingEnvironment) (the SAME threaded env the admitted reads/calls use, captured at construction and stable across yield/await) and reuses the static TypeOfDynamicIdentifier helper. The foundation was already complete (the calling environment is threaded; the compiler already lowers free typeof to TypeOfDynamicIdentifier under allowsOrdinaryDynamicIdentifiers: true; the expression-decline walk already admits free TypeOfIdentifier operands when allowsDynamicIdentifiers), so the opcode allowlist was the only gate. The defining invariant holds: typeof NEVER throws ReferenceError — the helper swallows the unbound-binding throw and returns "undefined", so an unbound free name yields "undefined" (no throw) while a bound one yields its runtime type, and because resolution is live each resumed step observes the CURRENT binding (a retyped/late-bound global flips type across the resume). The ShouldStopEvaluation guard is the defensive non-ReferenceError-throw path only. At that checkpoint, dynamic writes/updates and deletes still stayed omitted, so those shapes declined. UnifiedBytecodeResumableTypeOfDynamicTests: eligibility EvaluateResumable_TypeOfFreeIdentifierBetweenYields_AdmitsTypeOfDynamicOpcode (admits function* g(){ yield typeof defined; yield typeof undeclaredFree; } and asserts the program carries TypeOfDynamicIdentifier); runtime (all assert the resumable fast-path route log so an interpreter fallback fails the test) GeneratorTypeOfDefinedAndUndeclaredFree_RoutesResumableAndProducesTypes (func=g argc=0, `number
2026-06-04 A29 OptionalChainDependency — multi-hop optional COMPUTED read chain (TryIsFirstBoundaryOptionalComputedPropertyReadChainCandidate / TryAppendFirstBoundaryOptionalComputedPropertyReadChain, sync) Multi-hop optional COMPUTED reads a?.[k]?.[j] (and deeper a?.[k]?.[j]?.[m], named-prefixed a.x?.[k]?.[j], and trailing-named-tail a?.[k]?.[j].c) now route through synchronous production unified bytecode. Before this slice the computed candidate/emitter only admitted a SINGLE optional computed hop (one JumpIfNullishReplaceUndefined + key span + GetComputedProperty, optionally followed by short-circuiting NAMED reads); a second ?.[ ] hop declined OptionalChainDependency at the second hop's short-circuiting GetComputedProperty (and at its boundary JumpIfNullish). The candidate/emitter were extended to walk one-or-more optional computed hops forward: after the activation-resolved base and any plain named prefix run, each hop is [JumpIfNullish(ReplaceWithUndefined:true), key-span…, GetComputedProperty] where the FIRST hop's read is the chain's first boundary (!ShortCircuitOnNullishTarget) and every subsequent hop's read short-circuits (ShortCircuitOnNullishTarget:true). Key spans never contain GetComputedProperty/JumpIfNullish, so the next GetComputedProperty delimits each hop; each lowered boundary jump targets the op immediately after its own GetComputedProperty (Target == computedIndex + 1), and short-circuit cascades hop-to-hop. The emitter chains ONE JumpIfNullishReplaceUndefined per hop, all backpatched to the SAME chain end (mirroring the A28 named-chain emitter), so a nullish at any hop skips every later key evaluation straight to undefined. A trailing run of short-circuiting NAMED reads (a?.[k]?.[j].c) is still peeled into the chain tail. The short-circuiting-GetComputedProperty eligibility case was wired to call the same candidate. A nullish value at ANY hop short-circuits the whole remaining chain to undefined WITHOUT evaluating later keys; a real-undefined intermediate followed by a NON-optional read (a?.[k]?.[j].c) still throws TypeError. STAYS OUT of the resumable allowlist (TryFindUnsupportedResumableOpcode untouched) — synchronous admission only; the opcodes (JumpIfNullishReplaceUndefined, GetComputedProperty, GetNamedProperty) already have sync VM handlers. DeepChainedOptionalComputedChain_ShortCircuitsAtEveryHop, DeepChainedOptionalComputedChain_ThreeHops_ShortCircuitsAtEveryHop, DeepChainedOptionalComputedChain_AfterNamedPrefix_ShortCircuitsAtEveryHop, DeepChainedOptionalComputedChain_TrailingNamedRead_ShortCircuitsBeforeKey, DeepChainedOptionalComputedChain_RealUndefinedIntermediateBeforeNonOptionalThrows, DeepChainedOptionalComputedChain_DoesNotEvaluateLaterKeysAfterShortCircuit in UnifiedBytecodeProductionInvocationTests assert per-hop short-circuit + correctness + side-effecting-key-not-evaluated-after-short-circuit + the unified-bytecode-production-fast-path func=readChain route-hit log (interpreter fallback fails the test). Full internal suite 5610 passed / 0 failed / 2 skipped (+6 new).
2026-06-04 A28 OptionalChainDependency — multi-hop optional named read chain (TryIsFirstBoundaryOptionalNamedChainCandidate / TryAppendFirstBoundaryOptionalNamedPropertyReadChain, sync) Verified and locked in: pure-named multi-hop optional reads a?.b?.c, a?.b?.c?.d, deeper (6-hop a?.b?.c?.d?.e?.g), and non-optional-prefixed tails (a.x?.b?.c, a.b.c?.d?.e) already route through synchronous production unified bytecode. The eligibility candidate validates the WHOLE program (activation-resolved base, an optional ?. first hop after an optional run of plain named prefix reads, then one-or-more short-circuiting named hops), and the emitter chains ONE JumpIfNullishReplaceUndefined boundary jump per optional hop, every jump backpatched to the same chain end. A nullish value introduced at ANY hop short-circuits the whole remaining chain to undefined; a real-undefined intermediate followed by a NON-optional read (a?.b?.c.d) still throws TypeError. No production-code change was required this slice — the candidate/emitter already chained multiple hops (admitted in #2972); this slice adds dedicated 3+ hop, prefixed, and real-undefined-adversarial regression coverage so the multi-hop contract cannot silently regress. Stays OUT of the resumable allowlist. DeepChainedOptionalNamedChain_ShortCircuitsAtEveryHop, DeepChainedOptionalNamedChain_AfterNonOptionalPrefix_ShortCircuitsAtEveryHop, DeepChainedOptionalNamedChain_RealUndefinedIntermediateBeforeNonOptionalHopThrows in UnifiedBytecodeProductionInvocationTests assert per-hop short-circuit + correctness + the unified-bytecode-production-fast-path func=readChain route-hit log (interpreter fallback fails the test).
2026-06-04 A19 PropertyWriteDependency — literal-base PURE named write chains (TryIsFirstBoundaryLiteralBasePropertyWriteChainCandidate, sync) Deep PURE property-WRITE chains whose BASE is an object/array literal and whose TERMINAL store is named now route through synchronous production unified bytecode, mirroring the A17/A18 read-past-boundary widening (#3154): ({ a: { b: 0 } }).a.b = v, ({ a: { b: {} } }).a.b.c = v, and the array-literal / computed-prefix analog [box][0].a = v. Prior to this slice every literal-base write declined PropertyWriteDependency: the existing write candidates (TryIsFirstBoundaryPropertyWriteCandidate, TryIsFirstBoundaryNestedNamedPropertyWriteCandidate, …ComputedPrefixNamedPropertyWriteCandidate) all require op 0 to be an activation-resolved (or plain dynamic-identifier) base, so a CreateObject/CreateArray base bailed even though the activation-base analog box.a.b.c = v was already admitted. This slice adds one self-contained selector TryIsFirstBoundaryLiteralBasePropertyWriteChainCandidate that validates the WHOLE program with a single stack-discipline walk (the WRITE twin of the read walker): op 0 must be CreateObject/CreateArray, the literal's own construction ops (Define{Computed}ObjectProperty, ArrayPush/ArrayPushHole/ArraySpread/ObjectSpread, plus key/value sub-expressions) balance the stack back to a single base value, the receiver prefix is plain named/computed reads (key…, RequireObjectCoercible(Depth: 1), ResolvePropertyKey, GetComputedProperty), the assigned value is a simple operand sub-expression, and the program ends on EXACTLY ONE non-private non-name-inferred SetNamedProperty (a non-terminal Set* — i.e. a chained assignment a.b = o.c = v — falls to default reject). Anything outside that vocabulary declines by default reject — a call anywhere in the chain or value, a compound/logical write (DuplicateTop), an optional/short-circuit read, a private name, a method/accessor, or a name-inferred define — so any setter in the chain runs exactly once (matching the interpreter) and the base stays pure. BOUNDARY: the SetComputedProperty terminal off a literal base (({a:{}}).a['b'] = v) is deliberately NOT admitted — the compiler's computed-write lowering only recognizes an activation-resolved/named-prefix receiver and bails on a literal base with Unsupported computed property key span; admitting it is compiler foundation work, so it stays declined rather than half-correct. The selector is wired into the GetNamedProperty, GetComputedProperty, and SetNamedProperty per-op cases after the existing write candidates, so it only fires for shapes those already reject. STAYS OUT of the resumable allowlist (TryFindUnsupportedResumableOpcode untouched) — synchronous-route admission only; the opcodes involved already have sync VM handlers. Eligibility UnifiedBytecodeLiteralBasePropertyWriteTestsEvaluate_ObjectLiteralBaseNamedWrite_AcceptsOwnedPropertyOpcodes (1× GetNamedProperty + SetNamedProperty), Evaluate_ObjectLiteralBaseDeepNamedWrite_AcceptsOwnedPropertyOpcodes (2× GetNamedProperty + 1× SetNamedProperty), Evaluate_ArrayLiteralBaseComputedPrefixNamedWrite_AcceptsOwnedPropertyOpcodes (GetComputedProperty + SetNamedProperty), Evaluate_ObjectLiteralBaseNamedWriteWithIdentifierValue_Accepts; adversarial declines Evaluate_ComputedTerminalWriteOffLiteralBase_Declines, Evaluate_ChainedAssignmentOffLiteralBase_Declines (PropertyWriteDependency), Evaluate_CallInValueOffLiteralBase_Declines, Evaluate_CompoundWriteOffLiteralBase_Declines, Evaluate_AccessorInLiteralBaseWrite_Declines. Runtime + ROUTING (all assert the unified-bytecode-production-fast-path log so an interpreter fallback fails the test): Execute_ObjectLiteralBaseNamedWrite_RoutesAndReturnsValue (42), Execute_ObjectLiteralBaseDeepNamedWrite_… (9), Execute_ArrayLiteralBaseComputedPrefixNamedWrite_… (5), Execute_LiteralBaseNamedWrite_MutatesTheOwnSlotOfTheLiteral (1 — write lands on the right receiver), Execute_GetterInReceiverPrefixInvokedExactlyOnce_MatchesInterpreter (7,1,7 — prefix getter runs once and mutation lands on its return), Execute_NullishReceiverPrefixThrowsTypeError_LikeInterpreter. (The A17/A18 read test's stale Evaluate_WriteAtEndOfLiteralBaseChain_Declines adversarial assertion — which A19 now correctly admits — is repointed to the still-declined computed-terminal write.) Full internal suite 5601 passed / 0 failed / 2 skipped (+15 new).
2026-06-04 R1/R5 resumable VM OPTIONAL CALL dispatch (B15: TryFindUnsupportedResumableOpcode + two ExecuteResumable handlers) The resumable VM (ExecuteResumable) already admitted slot-identifier (f?.()) and named (o?.m(), o.m?.()) optional calls; it declined the computed-member optional call o[k]?.() (opcode PrepareComputedOptionalCallTarget) and the free/dynamic-identifier optional call freeFn?.() (opcode PrepareDynamicIdentifierOptionalCallTarget). Both opcodes are now on the resumable allowlist with ExecuteResumable handlers that are literal twins of the sync VM's — o[k]?.() reuses GetComputedCallTargetValue, freeFn?.() reuses PrepareDynamicIdentifierCallTarget against the UnifiedBytecodeResumeState.CallingEnvironment (#3108) — and the short-circuit is realized by the chain-end jump (replaced undefined is the final call result), which survives yield/await because the program counter / operand stack restore from the resume state. The OPTIONAL-COMPUTED call o?.[k]() (leading optional hop) is a different shape declined earlier by the shared production-plan walk (OptionalChainDependency), so it never reaches the opcode path — admitting the opcode does not change that. UnifiedBytecodeResumableOptionalCallTests (gate admits PrepareComputedOptionalCallTarget + PrepareDynamicIdentifierOptionalCallTarget; end-to-end generator + async fast-path routing; nullish short-circuit across a yield, live-binding reassignment across a yield, a throwing callee surfacing on the resumed step; and a pinned o?.[k]() plan-walk decline).
2026-06-03 A25/A26 DeleteDependency — deep property delete chains past a computed hop (TryIsFirstBoundaryDeepPropertyDeleteChainCandidate, sync) Synchronous property delete chains with a plain COMPUTED read hop anywhere before the terminal delete now route through production unified bytecode: delete box[k1][k2] (A26, computed-then-computed), delete box.a[k1][k2] (named-then-computed-then-computed), and delete box[k1].b (computed-then-named). Before this slice all three declined DeleteDependency: TryIsFirstBoundaryComputedPropertyDeleteCandidate only walks a strictly-NAMED hop prefix before a single computed key span, so any intermediate GetComputedProperty broke the prefix loop, and TryIsFirstBoundaryNamedPropertyDeleteCandidate requires every intermediate hop be a plain named read with a terminal DeleteNamedProperty, rejecting a computed hop or a DeleteComputedProperty terminal. (The pure-named deep chain delete box.a.b.c (A25) was already admitted by the named-delete candidate; this slice adds a regression for it.) The new self-contained selector TryIsFirstBoundaryDeepPropertyDeleteChainCandidate validates the WHOLE program with one stack-discipline walk — op 0 is an activation-resolved (or admitted plain dynamic-identifier) base, intermediate ops are any mix of plain named reads (GetNamedProperty, non-optional/non-private) and plain computed reads (key…, RequireObjectCoercible(Depth: 1), ResolvePropertyKey, GetComputedProperty, plus unary/binary key sub-expressions), and the LAST op is a non-optional non-private DeleteNamedProperty or DeleteComputedProperty; the terminal boolean must be the sole stack residue and at least one computed read hop is required (pure-named chains stay on the named candidate). Any optional/short-circuit hop, private name, or non-read/non-delete op declines by default reject, so optional delete chains and private-member deletes keep their dedicated candidates / IR runner. The walker is wired into the GetNamedProperty, GetComputedProperty, DeleteNamedProperty, and DeleteComputedProperty per-op cases after the existing delete candidates, so it fires only for shapes those reject. The VM's descriptor-aware delete helper owns strict/sloppy semantics: strict-mode delete of a non-configurable property throws TypeError, sloppy returns false, and only the intended slot is removed. STAYS OUT of the resumable allowlist (TryFindUnsupportedResumableOpcode untouched) — synchronous admission only; all opcodes already have sync VM handlers. Eligibility (opcode shape): Evaluate_DeepComputedThenComputedDeleteCandidate_AcceptsOwnedPropertyOpcodes, Evaluate_NamedThenComputedThenComputedDeleteCandidate_AcceptsOwnedPropertyOpcodes, Evaluate_ComputedThenNamedDeleteCandidate_AcceptsOwnedPropertyOpcodes; adversarial declines Evaluate_DeepDeleteChainWithPrivateNamedHop_Declines, Evaluate_DeepOptionalComputedDeleteChain_DeclinesAsOptionalChain (OptionalChainDependency). Runtime + ROUTING (all assert unified-bytecode-production-fast-path func=remove argc=N so an interpreter fallback fails the test): DeepNamedPropertyDelete_UsesProductionFastPath_AndDeletesOnlyTarget (true,false,2), DeepComputedPropertyDelete_... (A26), NamedThenComputedThenComputedDelete_..., ComputedThenNamedDelete_..., plus strict/sloppy non-configurable edges DeepComputedDelete_NonConfigurableTarget_SloppyReturnsFalse_... (false,7) and DeepComputedDelete_NonConfigurableTarget_StrictThrowsTypeError_... (TypeError,7). UnifiedBytecodeProduction pack 1114 green single-threaded; full internal suite 5553 passed / 0 failed / 2 skipped (+11 new).
2026-06-03 A17/A18 PropertyReadBoundaryOutOfScope — literal-base PURE read chains (TryIsFirstBoundaryLiteralBasePropertyReadChainCandidate, sync) Deep PURE property-read chains whose BASE is an object/array literal now route through synchronous production unified bytecode, for example ({a:{b:{c:1}}}).a.b.c, ({a:1})['a']['b'], [box][0].a.b, ({a:{x:1}})[left+right].x, and mixed named/computed off a literal base. Prior to this slice, every literal-base computed read (even single-hop ({a:1})['a']) declined PropertyReadBoundaryOutOfScope: the existing TryIsFirstBoundaryComputedPropertyReadChainCandidate/named candidate required op 0 to be an activation-resolved value (LoadIdentifier/LoadThis/etc.), so a CreateObject/CreateArray base bailed; the named-only literal-base case ({}.a.b) was admitted by TryIsFirstBoundaryObjectLiteralNamedPropertyReadCandidate but had no computed counterpart, and the shared object/array literal SPAN measurers mis-parse when the read tail begins with a computed-hop key load immediately after the literal (the trailing key LoadLiteral looks like the start of another property/element with no following Define/Push). This slice adds one self-contained selector TryIsFirstBoundaryLiteralBasePropertyReadChainCandidate that validates the WHOLE program with a single stack-discipline walk: op 0 must be CreateObject/CreateArray, the literal's own construction ops (Define{Computed}ObjectProperty, ArrayPush/ArrayPushHole/ArraySpread/ObjectSpread, plus key/value sub-expressions) balance the stack back to a single base value, and the trailing hops are plain named reads and computed reads (key…, RequireObjectCoercible(Depth: 1), ResolvePropertyKey, GetComputedProperty). The walk avoids the span-measurer ambiguity entirely (no separate base measurement). It declines anything outside the read/construction vocabulary by default reject — calls, writes, optional/short-circuit reads, private names, methods, accessors, and name-inferred defines all fall out — so a getter in the chain is invoked exactly once per hop (matching the interpreter) and the base stays pure (a call op anywhere, including a computed key, declines). The selector is wired into both the GetNamedProperty and GetComputedProperty per-op cases after the existing activation-resolved candidates, so it only fires for shapes those already reject. STAYS OUT of the resumable allowlist (TryFindUnsupportedResumableOpcode untouched) — this is a synchronous-route admission only; the opcodes involved already have sync VM handlers. Eligibility UnifiedBytecodeLiteralBasePropertyReadTestsEvaluate_ObjectLiteralBaseNamedReadDeep_AcceptsOwnedPropertyOpcodes (3× GetNamedProperty, no GetComputedProperty), Evaluate_ObjectLiteralBaseComputedReadDeep_AcceptsOwnedPropertyOpcodes (3× GetComputedProperty + RequireObjectCoercible(1) + ResolvePropertyKey), Evaluate_ObjectLiteralBaseMixedReadDeep_..., Evaluate_ArrayLiteralBaseComputedThenNamedRead_..., Evaluate_ObjectLiteralBaseComputedReadWithRichKey_Accepts (binary key); adversarial declines Evaluate_CallMidChainOffLiteralBase_Declines, Evaluate_WriteAtEndOfLiteralBaseChain_Declines (PropertyWriteDependency), Evaluate_OptionalReadInLiteralBaseChain_Declines, Evaluate_AccessorInLiteralBase_Declines, Evaluate_MethodInLiteralBase_Declines. Runtime + ROUTING (all assert the unified-bytecode-production-fast-path log so an interpreter fallback fails the test): Execute_ObjectLiteralBaseNamedReadDeep_RoutesAndReturnsValue (42), Execute_ObjectLiteralBaseComputedReadDeep_... (7), Execute_ArrayLiteralBaseComputedThenNamedRead_... (99), Execute_ObjectLiteralBaseMixedReadWithParamKey_... (5), Execute_GetterInvokedExactlyOncePerHop_MatchesInterpreter (11,1 — getter runs once), Execute_NullishHopThrowsTypeError_LikeInterpreter. Full internal suite 5542 passed / 0 failed / 2 skipped (+16 new); UnifiedBytecodeProduction pack 1103 green single-threaded.
2026-06-03 R1/R5 resumable VM #field in obj (B18: TryFindUnsupportedResumableOpcode + an ExecuteResumable PrivateFieldIn handler + private-name-scope threading on UnifiedBytecodeResumeState) The resumable VM (ExecuteResumable) declined any generator/async whose body evaluated a private-field-in test (#x in obj) between suspension points, because TryFindUnsupportedResumableOpcode omitted PrivateFieldIn from its allowlist (decline UnsupportedPlanShape, reason opcode 'PrivateFieldIn' is not supported by resumable production routing), so every #x in obj fell back to the interpreter even though the sync VM already admitted the opcode. This slice (a) adds PrivateFieldIn to the allowlist and ports the check into the ExecuteResumable switch as the literal twin of the sync VM's handler — it reads the object operand off the top of the stack, and if it is not a JsValueKind.Object throws the same TypeError ("Cannot use 'in' operator to search for a private field in a non-object") surfaced as the resumable Throw step (state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);); otherwise it replaces the top with JsValue.True/JsValue.False from the shared HasPrivateField helper; and (b) threads the body's lexically-active private-name scopes (the class brand scope plus enclosing captured scopes) onto UnifiedBytecodeResumeState.PrivateNameScopes and re-enters them on the per-step context at the top of ExecuteResumable. Step (b) was REQUIRED for correctness: the sync VM gets the scopes for free because the regular function-invocation path enters them around the body, but each resumable step runs on a fresh per-step context, so without re-entry context.ResolvePrivateNameKey("#value") returned null and HasPrivateField wrongly reported the field absent (#value in holder came back false). All three resumable invokers (sync generator, async function, async generator) now populate the scopes via the shared UnifiedBytecodeResumeState.CombinePrivateNameScopes (enclosing scopes first, own class scope innermost, matching SyncFunctionInvoker), so the opcode is correct for every resumable kind, not just sync generators. PrivateFieldIn is a pure boolean op: it carries no AwaitedProgram, cannot itself yield/await, and pushes exactly one value, so it always runs to completion inside a single resumable step. The object operand can come from a suspending sub-expression (#x in (yield o)); it sits on UnifiedBytecodeResumeState.OperandStack (the stable backing store) and is restored on resume, exactly like every other admitted unary. BOUNDARY: the private NAME read/write/update opcodes (receiver.#value, receiver.#value = v, receiver.#value++) are a separate slice and stay on their existing route; this slice admits only the in-test opcode. Eligibility Evaluate_PrivateFieldIn_AcceptsAndVmChecksPrivateBrand (asserts the admitted program carries PrivateFieldIn); runtime PrivateFieldIn_AcrossYieldInGeneratorMethod_UsesResumableUnifiedBytecodeFastPath (route log unified-bytecode-resumable-generator-fast-path func=<anonymous> argc=1, ready crosses the yield, true:false after resume — #value in holder true via brand, #value in {} false), the adversarial PrivateFieldIn_NonObjectAcrossYieldInGeneratorMethod_ThrowsViaResumableFastPath (same resumable-generator route, resuming with a primitive 5 throws a catchable TypeError, outer-caught threw:true), and PrivateFieldIn_AcrossAwaitInAsyncMethod_UsesResumableUnifiedBytecodeFastPath (route log unified-bytecode-resumable-async-fast-path func=<anonymous> argc=1, true:false after the await — pins the async-path scope threading). UnifiedBytecodeProduction+resumable pack 1103 green single-threaded; private/resumable/generator/drift pack 619 green; full internal suite 5526 passed / 0 failed / 2 skipped (+3 new).
2026-06-03 R1/R5 resumable VM OBJECT + ARRAY literals (B16/B17: TryFindUnsupportedResumableOpcode + 12 ExecuteResumable handlers) The resumable VM (ExecuteResumable) declined any generator/async whose body materialized an OBJECT literal ({a, b: v, [k]: v, ...spread}) or ARRAY literal ([a, , b, ...spread]) between suspension points, because TryFindUnsupportedResumableOpcode omitted the whole literal opcode family — CreateObject/DefineObjectProperty/DefineComputedObjectProperty/DefineObjectMethod/DefineComputedObjectMethod/DefineObjectAccessor/DefineComputedObjectAccessor/ObjectSpread and CreateArray/ArrayPush/ArrayPushHole/ArraySpread — so every literal fell back to the interpreter (decline UnsupportedPlanShape, reason e.g. opcode 'CreateObject' is not supported by resumable production routing). This slice admits all 12 opcodes: it adds them to the allowlist and ports the sync handlers into the ExecuteResumable switch, re-expressed against its stack/stackPointer/programCounter/state/context/program locals via the flag-aware PushResumableValue helper (clears the new receiver's short-circuit-flag column slot) and throwing via state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);. Each literal is built bottom-up on the operand stack: a single Create{Object,Array} pushes a FRESH receiver (a new JsObject wired to context.RealmState.ObjectPrototype, or new JsArray(context.RealmState)), then the Define*/ArrayPush*/*Spread opcodes mutate it in place, popping their argument(s) while leaving the receiver on the stack. A sub-expression can suspend ({a: yield 1}, yield [yield 1]); the partially-built receiver plus any already-evaluated keys/values below the suspension sit on UnifiedBytecodeResumeState.OperandStack (the stable backing store) and are restored on resume, the same mechanism the admitted property writes rely on. The handlers reuse the sync VM's DefineObjectLiteralProperty/DefineComputedObjectLiteralProperty/DefineObjectLiteralMethod/DefineObjectLiteralAccessor/ApplyObjectLiteralSpread and TypedAstEvaluator.EnumerateSpread verbatim, so computed-key ToPropertyKey coercion, name inference, own-enumerable spread copy with getter order, and array-hole semantics are identical; the opcodes that can throw (computed-key coercion, a spread getter, an iterator step) surface the throw as the resumable Throw step. ECMAScript requires a fresh object/array per evaluation, so Create* allocates anew on every step (including each loop turn across yields) rather than caching. BOUNDARY (allowlisted with handlers but not yet reachable): object METHODS ({ m(){} }) and GET/SET accessors ({ get x(){} }) still decline because the method/accessor VALUE is a function literal that lowers to LoadFunctionLiteral, which has no resumable handler and stays off the allowlist — admitting nested function literals into the resumable VM is a separate foundation; the Define{Computed}ObjectMethod/Accessor opcodes are added now (1:1 with ExecuteResumable) so those shapes flip to eligible without further VM work once LoadFunctionLiteral is admitted. Also unrelated: a var x = <literal> whose literal contains no suspension declines at the resumable var-declaration lowering boundary (SimpleVariableDeclarationInstruction / template-literal span), independent of this opcode work. Eligibility EvaluateResumable_ObjectLiteralAcrossYield_AdmitsCreateObjectAndDefineProperty, EvaluateResumable_ComputedKeyObjectLiteral_AdmitsDefineComputed, EvaluateResumable_ObjectSpread_AdmitsObjectSpread, EvaluateResumable_ArrayLiteral_AdmitsArrayOpcodes (admit each shape and assert the program carries the matching opcodes), plus the NEGATIVE boundary EvaluateResumable_ObjectMethodAndAccessor_StaysDeclined (LoadFunctionLiteral); runtime GeneratorObjectLiteralAcrossYield_RoutesResumableAndBuildsObject (route log func=g argc=0, `10
2026-06-03 R1/R5 resumable VM new.target meta-property (B19: TryFindUnsupportedResumableOpcode + an ExecuteResumable LoadNewTarget handler) The resumable VM (ExecuteResumable) declined any generator/async whose body read new.target between suspension points, because TryFindUnsupportedResumableOpcode omitted LoadNewTarget from its allowlist (decline UnsupportedPlanShape, reason opcode 'LoadNewTarget' is not supported by resumable production routing), so every new.target read fell back to the interpreter even though the sync VM already admitted the opcode. This slice admits the opcode: it adds LoadNewTarget to the allowlist and ports the read into the ExecuteResumable switch as the literal twin of the sync VM's handler and the tier-2 IR runner — a single chain lookup of Symbol.NewTarget against UnifiedBytecodeResumeState.CallingEnvironment (the closure captured at construction and stable across yield/await), falling back to JsValue.Undefined. A generator or async function is never a constructor (new g() throws), so its own function environment binds new.target to undefined; the chain lookup returns exactly that. LoadNewTarget is a pure meta-property read: it carries no AwaitedProgram, cannot itself yield/await, and pushes exactly one value, so it always runs to completion inside a single resumable step and needs no resume-state restoration — the cleanest class of resumable admission (no operand-stack-across-suspension concern). Because CallingEnvironment is stable across suspension, the value observed after a resume matches the value at body entry. BOUNDARY (deliberately NOT admitted, and why this is a bounded slice): async ARROWS that lexically inherit this/new.target decline at the activation gate (ArrowLexicalThisDependency) — that is independent of this opcode and out of scope; their new.target semantics keep their existing interpreter route and are pinned correct by a negative proof. Eligibility EvaluateResumable_GeneratorNewTargetAcrossYield_AdmitsLoadNewTarget (generator) and EvaluateResumable_AsyncNewTargetAfterAwait_AdmitsLoadNewTarget (async; both assert the admitted program carries LoadNewTarget), plus the boundary gate EvaluateResumable_AsyncArrowLexicalNewTarget_DeclinesArrowLexicalThis (asserts ArrowLexicalThisDependency); runtime GeneratorNewTargetAcrossYield_RoutesResumableAndIsUndefined (route log func=g argc=0, `1
2026-06-03 R1/R5 resumable VM regex LITERAL (B22: TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) declined any generator/async whose body evaluated a regex LITERAL (/pat/flags) between suspension points, because TryFindUnsupportedResumableOpcode omitted LoadRegexLiteral from its allowlist (decline UnsupportedPlanShape, reason opcode 'LoadRegexLiteral' is not supported by resumable production routing), so every regex literal fell back to the interpreter. This slice admits the opcode: it adds LoadRegexLiteral to the allowlist and ports the sync handler into the ExecuteResumable switch as a literal twin — read the interned pattern string (program.StringConstants[DecodeRegexLiteralPatternOperand(operand)]) and encoded flags byte (DecodeRegexLiteralFlagsOperand(operand)) from the program and build a FRESH RegExp via RegExpHelper.CreateRegExpLiteral(..., context.RealmState), pushing it with JsValue.FromObjectUnsafe. LoadRegexLiteral is a pure constant materialization: it carries no AwaitedProgram, cannot itself yield/await, and pushes exactly one freshly created object, so it always runs to completion inside a single resumable step and needs no resume-state restoration — the cleanest class of resumable admission (no operand-stack-across-suspension concern at all). ECMAScript requires a distinct RegExp object per evaluation, so the object is constructed anew on every step (including each loop turn across yields) rather than cached, exactly as the sync VM does; per-evaluation lastIndex independence is therefore preserved. Deliberately NOT admitted (the opcode allowlist remains the gate): nothing adjacent — this is a self-contained single-opcode slice; regex object methods (.test()/.exec()) inside a resumable body remain subject to the existing call-boundary admission rules independent of this opcode. Eligibility EvaluateResumable_RegexLiteral_AdmitsLoadRegexLiteral (generator), EvaluateResumable_AsyncRegexLiteral_AdmitsLoadRegexLiteral (async; both assert the admitted program carries LoadRegexLiteral); runtime GeneratorRegexLiteral_RoutesResumableAndMatches (route log func=g argc=0, `1
2026-06-03 PropertyWriteDependency/PropertyUpdateDependency/DeleteDependency control-expression computed keys (IsSupportedComputedPropertyKeySpan + TryAppendComputedPropertyKeySpan, both the eligibility selector and the compiler) Computed property accesses whose KEY is a control expression — a ternary obj[cond ? a : b], a logical-and obj[a && b], or a nullish-coalesce obj[a ?? b] — now route through production unified bytecode for writes (obj[cond ? a : b] = v), updates (++obj[cond ? a : b]), and deletes (delete obj[cond ? a : b]), including the nested-named-receiver forms (box.child[cond ? a : b] = v). Previously these declined: the shared computed-key-span validator IsSupportedComputedPropertyKeySpan (mirrored in the eligibility selector and the compiler) is a stack-machine walker over Load*/unary/binary/CreateObject ops and hit its default reject on the JumpIfConditionalFalse/Jump/Pop control flow a ternary/logical key lowers to, so the compiler returned UnsupportedPlanShape (reason Unsupported computed property key span). This slice admits a key span that is EXACTLY ONE whole already-admitted control-expression operand span by delegating to the existing, battle-tested TryAppendSimpleControlExpressionOperandSpan emitter (which emits the branch opcodes with patched targets and composes nested control expressions). The compiler's TryAppendComputedPropertyKeySpan tries the control-expression emission first and rolls the builder back to a clean state on a non-whole-span match before falling through to the stack-machine path; the validator runs the same emitter against throwaway builders (TryProbeControlExpressionComputedKeySpan) so it never emits-then-bails on the live stream. Branches that would need a slot layout or call-target table (e.g. a member-call inside a branch) are passed null for those and cleanly decline, so the worst case is a clean fallback, never incorrect routing. Because the key span is shared across reads, writes, updates, and deletes, all of those widen at once. Deliberately NOT admitted: control-expression keys whose branches require slot-layout/call-target threading (member-call branches). Eligibility Evaluate_NestedNamedComputedPropertyWriteWithTernaryKey_AcceptsControlExpressionKeySpan (was a decline-assert, now asserts None + SetComputedProperty); runtime UnifiedBytecodeProductionConditionalComputedKeyTests (8 tests, all asserting the unified-bytecode-production-fast-path func=… argc=… route log so an interpreter fallback fails): nested ternary write (argc=3, both branches exercised, 49), direct ternary write (argc=3), ternary update (++…, argc=2, 42), ternary delete (argc=2, exactly one slot removed), logical-and key write (argc=4), nullish-coalesce key write (argc=4), nested-ternary key selecting the correct single slot (argc=4, 0,3,0), and strict-mode non-writable-target TypeError preserved on the fast path (argc=2). Full internal suite 5466 passed / 0 failed / 2 skipped (+9 net new; the 1 remaining red — UnifiedBytecodeResumableEligibility_AllowsEveryResumableVmOpcode, unexpected TdzHeadInit — is a stale allow-list assertion that also fails on clean main, independent of this slice); UnifiedBytecodeProduction pack 1096 green single-threaded.
2026-06-03 R1/R5 resumable VM property UPDATES + DELETES (B6/B7/B9/B10: TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) declined any generator/async whose body UPDATED (o.x++, o[k]--, prefix or postfix) or DELETED (delete o.x, delete o[k]) a property between suspension points, because TryFindUnsupportedResumableOpcode omitted UpdateNamedProperty/UpdateComputedProperty/DeleteNamedProperty/DeleteComputedProperty from its allowlist (decline UnsupportedPlanShape, reason opcode 'UpdateNamedProperty' is not supported by resumable production routing), so every property update/delete fell back to the interpreter. This slice — the natural follow-on to the property-WRITE slice (#3114) — admits the four opcodes: it adds them to the allowlist and ports the sync handlers into the ExecuteResumable switch, re-expressed against its stack/stackPointer/programCounter/state/context/program locals via the resumable ReplaceResumableTop helper, throwing via state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);. The update/delete opcodes operate purely on the operand stack — the base (and, for the computed form, the key) sit on UnifiedBytecodeResumeState.OperandStack (the stable backing store) across any suspension in a sibling sub-expression and are restored on resume, the same mechanism the already-admitted property READS and WRITES rely on. The opcodes themselves cannot suspend (no AwaitedProgram), so they always run to completion inside a single resumable step and never need resume-state restoration of their own operands. The handlers reuse the sync VM's UpdatePropertyValue/DeleteNamedProperty/DeleteComputedProperty helpers, threading the body's own strictness via state.IsStrict (the body-strictness scope frame the property-WRITE slice introduced already makes context.CurrentScope.IsStrict reflect the body), so a strict update of a read-only property and a strict delete of a non-configurable property both throw and translate to the resumable Throw step, while the sloppy forms are no-ops. The computed update preserves the sync VM's null/undefined-base TypeError guard before any read. The negative pin in the property-write proof pack (o.x++ previously declined) is repointed to a still-omitted shape (UpdateDynamicIdentifier, a free-variable update freeGlobal++). Historical note (superseded by later rows): at this checkpoint, super-neighbor update/delete rows and free dynamic updates/deletes (UpdateDynamicIdentifier, DeleteDynamicIdentifier) still declined because those resumable handlers were not yet admitted. B13/B14 later closed the super-property read/write/update boundary; B27/B28 later closed free dynamic update/delete; super-property deletes remain the super-neighbor residue. Eligibility EvaluateResumable_NamedPropertyUpdate_AdmitsUpdateNamedProperty, EvaluateResumable_ComputedPropertyUpdate_AdmitsUpdateComputedProperty, EvaluateResumable_NamedPropertyDelete_AdmitsDeleteNamedProperty, EvaluateResumable_ComputedPropertyDelete_AdmitsDeleteComputedProperty (admit the four shapes across a yield and assert the program carries the matching opcode), plus the repointed NEGATIVE pin EvaluateResumable_DynamicFreeVariableUpdate_StaysDeclined (freeGlobal++ still declines); runtime GeneratorPostfixNamedUpdate_RoutesResumableAndUsesOldValue (route log func=g argc=1, `1
2026-06-03 R1/R5 resumable VM SLOT UPDATES (B8 initial var/parameter slice; lexical targets superseded by B8a) The resumable VM (ExecuteResumable) declined any generator/async whose body INCREMENTED or DECREMENTED a slot between suspension points — x++, x--, ++x, --x — because the instruction allowlist (IsSupportedResumableInstruction) omitted IncrementSlotInstruction (decline UnsupportedPlanShape, reason Instruction 'IncrementSlotInstruction' is not eligible for resumable unified bytecode routing) and the opcode allowlist (TryFindUnsupportedResumableOpcode) omitted UpdateSlot, so every slot update fell back to the interpreter. This slice admits the update on PARAMETER and var slots only: it adds IncrementSlotInstruction to the instruction allowlist and UpdateSlot to the opcode allowlist, and ports the UpdateSlot handler into the ExecuteResumable switch (TDZ ReferenceError on an uninitialized slot, GetUpdatedNumericValue ToNumeric ++/-- which surfaces a non-coercible operand as the resumable Throw step, store back, push prefix-new/postfix-old). The update never touches the operand stack across a suspension (an update expression cannot itself yield/await), so no resume-state restoration is involved. BOUNDARY (the const gap): const-ness is a runtime environment property the lowered plan does not preserve, and UnifiedBytecodeResumeState carries no const-slot metadata, so the resumable VM cannot reproduce the TypeError: Assignment to constant variable the sync VM raises for a const update. A new instruction-level guard (IsLexicalSlotUpdateTarget, comparing the update target against ActivationSlotShape.LexicalSlotIndices) therefore declines every update whose target is a lexical (let/const) slot — the only statically provable non-const slots are parameters and var bindings — keeping the const-unsafe shapes on the interpreter. NOTE: the already-shipped resumable StoreSlot admission has the same latent const gap for plain assignment (const x; x = 2 silently succeeds on the resumable path); this slice does not widen it and stays strictly on the safe side. At B8 time, deliberately NOT admitted: lexical-slot updates (let i; i++) (superseded by B8a on 2026-06-05), property updates (o.x++), and compound/logical slot assignment instructions (x += v, x &&= v) — those keep their interpreter route. Eligibility EvaluateResumable_VarIncrementAcrossYield_AdmitsUpdateSlot, EvaluateResumable_ParameterIncrementAcrossYield_AdmitsUpdateSlot (admit var/parameter x++ across a yield and assert the program carries UpdateSlot), and the NEGATIVE pin EvaluateResumable_LetIncrement_StaysDeclined (let i; i++ still declines); runtime GeneratorVarPostfixIncrementAcrossYield_RoutesResumableAndIsCorrect (`10
2026-06-03 R5 resumable VM for-in drivers (ForInInit / ForInMoveNext) The resumable VM now admits for-in driver state across suspension. Generator bodies can suspend from inside a lowered for-in loop, and async bodies can evaluate for (k in await p) by compiling the awaited source to AwaitValue, leaving the resolved object on the operand stack for the existing ForInInit driver opcode. The slice also admits loop-style BreakableEnter/BreakableExit wrappers in resumable eligibility because the compiler already lowers them as control-flow metadata for this path. This slice did not admit const/let per-iteration lexical environments across suspension or async iterator drivers; for-of awaited sources were admitted later by the A47/B30 for-of driver slice. Eligibility EvaluateResumable_ForInDriverAcrossYield_AdmitsForInDriver, EvaluateResumable_AwaitedForInSource_AdmitsAwaitValueAndForInDriver, and IsSupportedForInInit_AwaitedSource_Accepts; runtime GeneratorForInDriverAcrossYield_RoutesResumableAndYieldsKey and AsyncForInAwaitedSource_RoutesResumableAndEnumeratesKey. Focused pack: `rtk dotnet test tests/Asynkron.JsEngine.Tests/Asynkron.JsEngine.Tests.csproj --filter "FullyQualifiedName~UnifiedBytecodeProductionEligibilityTests.IsSupportedForInInit
2026-06-03 R1/R5 resumable VM property WRITES (TryFindUnsupportedResumableOpcode + a body-strictness scope frame) The resumable VM (ExecuteResumable) declined any generator/async whose body ASSIGNED to a property between suspension points — o.x = v, o[k] = v, this.x = v — because TryFindUnsupportedResumableOpcode omitted SetNamedProperty/SetComputedProperty from its allowlist, so every property write fell back to the interpreter (decline UnsupportedPlanShape, reason opcode 'SetNamedProperty' is not supported by resumable production routing). This slice admits the two property-write opcodes: it adds them to the allowlist and ports SetNamedProperty/SetComputedProperty into the ExecuteResumable switch, re-expressed against its stack/stackPointer/programCounter/state/context/program locals via the resumable ReplaceResumableTop helper, throwing via state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);. The assignment value can itself suspend (o.x = yield 1); the base — and, for the computed form, the key — sit on UnifiedBytecodeResumeState.OperandStack (the stable backing store) across the suspension and are restored on resume, the same mechanism the already-admitted property READS rely on. CORRECTNESS FIX uncovered by the sloppy/strict adversarial pair: strict-only behavior (a write to a non-writable property throwing a TypeError) is decided deep inside JsOps/PropertyHandle by reading context.CurrentScope.IsStrict — but a resumable step runs under whatever scope the resume call (it.next() / promise continuation) supplies, NOT the body's scope, so a sloppy generator's write was incorrectly throwing. The sync VM avoids this because its function invoker's scope already reflects the body. The fix threads the body's own strictness onto a new UnifiedBytecodeResumeState.IsStrict (set in SyncGeneratorInvoker/AsyncFunctionInvoker from `function.Body.IsStrict
2026-06-03 R1/R5 resumable VM free/dynamic identifier resolution (TryFindResumablePlanDecline + TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) declined any generator/async whose body referenced ANYTHING outside its own parameters/locals: a free variable READ (yield outerVar) declined with DynamicLookupDependency and a free function CALL target (yield helper(x), where helper is module/script-level or a captured outer binding) declined with CapturedOrDynamicActivation/DynamicLookupDependency, so the single biggest remaining coverage gap fell back to the interpreter. This slice admits free/dynamic identifier READS and free function CALL targets. EvaluateResumable now (a) treats allowsDynamicIdentifiers = true in TryFindResumablePlanDecline so the expression-level decline no longer fires for ScopeId<0 free identifiers, (b) compiles with allowsOrdinaryDynamicIdentifiers: true so the compiler lowers a free read to LoadDynamicIdentifier and a free callee to PrepareDynamicIdentifierCallTarget, and (c) adds exactly those two opcodes to the TryFindUnsupportedResumableOpcode allowlist. The new ExecuteResumable handlers resolve by NAME against the LIVE closure environment threaded onto UnifiedBytecodeResumeState.CallingEnvironment (#3108), captured at construction and stable across suspension — reusing the same GetDynamicIdentifierValue/PrepareDynamicIdentifierCallTarget helpers as the sync Execute path. Because the environment is a live reference (not a value snapshot), a resumed step reads the CURRENT binding: a binding a sibling closure mutates while the generator is suspended, a global reassigned/rebound between yields, and a free callee rebound between yields are all observed correctly; an uninitialized free binding still throws ReferenceError. At that checkpoint, free writes/updates, typeof, delete, and eval/with still declined. HISTORICAL BOUNDARY (removed by B38 on 2026-06-05): a yield* <iterable> whose iterable resolves through a free/dynamic identifier (yield* spyIterable, yield* makeIterator()) kept its prior IR-runner routing because the resumable yield* delegation protocol was only validated against slot-resolved iterables; admitting it would regress delegation semantics (proven by 8 Generator_YieldStar* tests that regressed and were then re-greened by the guard). A captured binding from an enclosing function scope (resolves to that activation's slot, ScopeId>=0) is a distinct tier this slice does NOT admit. Eligibility EvaluateResumable_FreeReadAndFreeCallBetweenYields_AdmitsDynamicOpcodes (admits function* g(p){ yield base; yield helper(p); } and asserts the program carries LoadDynamicIdentifier/PrepareDynamicIdentifierCallTarget/CallInvocationBoundary); runtime GeneratorFreeReadAndCallBetweenYields_RoutesResumableAndProducesValues (route log func=g argc=1, values 5, 30), GeneratorReadsFreeBindingMutatedByClosureSibling_ReadsLiveValue (sibling bump() mutates the free n while suspended; live read `0
2026-06-03 R1/R5 resumable VM optional chains + optional calls (TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) declined any generator/async whose body used an OPTIONAL CHAIN (o?.a, o?.[k]) or OPTIONAL CALL (o?.m(), f?.()) between suspension points. The two prior resumable slices (value-tier reads, synchronous call dispatch) deferred these with the SAME reason: the resumable state had no equivalent of the sync VM's stack-parallel stackShortCircuitFlags array, so a short-circuit flag set before a suspension could not survive the resume. This slice adds UnifiedBytecodeResumeState.OperandStackShortCircuitFlags — a ulong[] flag column index-aligned with OperandStack, allocated only when program.RequiresShortCircuitStackFlags (matching the sync Execute allocation condition). Because both OperandStack and the flag column are stable backing arrays referenced by the static ExecuteResumable loop, and a yield/await suspend only saves/restores StackPointer, the live flag window stays aligned with the live operand window across suspend AND resume with no per-suspension copy. The opcodes GetNamedPropertyOptional, JumpIfNullishReplaceUndefined, JumpIfShortCircuited, PrepareIdentifierOptionalCallTarget, and PrepareNamedOptionalCallTarget are ported into the ExecuteResumable switch (re-expressed against its stack/stackPointer/programCounter/slots/state/context/program locals via local GetResumableShortCircuitFlag/SetResumableShortCircuitFlag/PushResumableValue*/ReplaceResumableTop* helpers mirroring the sync push/replace flag discipline) and removed from TryFindUnsupportedResumableOpcode. The resumable GetNamedProperty/GetComputedProperty/named+computed call-target prepares now honor the flag exactly as the sync VM does, and CallInvocationBoundary clears it on the call-result slot. Most admitted optional shapes short-circuit purely via the JumpIfNullishReplaceUndefined jump (their programs do not set RequiresShortCircuitStackFlags); the flag column is the correctness backstop for flag-using shapes. Deliberately NOT admitted (left in the unsupported set): computed optional calls o?.[k]() and PrepareComputedOptionalCallTarget (the resumable compiler declines that shape at compile time, so the opcode never reaches the path), super/construct optional boundaries, direct eval, and TypeOfDynamicIdentifier/DeleteDynamicIdentifier. Eligibility EvaluateResumable_OptionalChainAndCallBetweenYields_AdmitsOptionalOpcodes (admits function* g(o){ yield o?.a; yield o?.m(); } and asserts the program carries GetNamedPropertyOptional/PrepareNamedOptionalCallTarget/CallInvocationBoundary); runtime GeneratorOptionalChainAndCall_NonNullish_RoutesResumableAndProducesValues (route log func=g argc=1, values 7, 42), GeneratorOptionalChain_NullishHeadAcrossYield_ShortCircuitsToUndefined (nullish head short-circuit straddling each yield, `1
2026-06-03 R1/R5 resumable VM synchronous call dispatch (TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) declined any generator/async whose body CALLED a function between suspension points, falling back to the interpreter, because it did not thread the dynamic calling environment the call path needs. This slice admits NON-OPTIONAL synchronous call dispatch — plain f(), o.m(), o[k]() — by porting PrepareIdentifierCallTarget, PrepareNamedCallTarget, PrepareComputedCallTarget, and CallInvocationBoundary into the ExecuteResumable switch (re-expressed against its stack/stackPointer/programCounter/slots/state/context/program locals, throwing via state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);) and removing them from TryFindUnsupportedResumableOpcode. Dispatch calls the SAME ExecutePreparedCall helper as the sync route. The enclosing lexical environment (the generator/async closure) is threaded once onto a new UnifiedBytecodeResumeState.CallingEnvironment field at construction (set in SyncGeneratorInvoker/AsyncFunctionInvoker) so it survives suspension and feeds caller-context-sensitive callees; slotEnvironments is passed null because resumable-eligible programs decline captured/dynamic activation and have no environment-backed slots. A callee that itself suspends/throws/recurses is handled from this frame as a synchronous call (the callee's own suspension is its own separate resumable frame); a throwing callee surfaces as a thrown step; a generator driving another generator's .next() keeps both frames independent. Deliberately NOT admitted (left in the unsupported set): optional calls o?.m() and any short-circuit-flag-setting opcode (the resumable state has no stackShortCircuitFlags persistence), direct eval, ConstructInvocationBoundary/super, and TypeOfDynamicIdentifier/DeleteDynamicIdentifier. Eligibility EvaluateResumable_CallBetweenYields_AdmitsCallOpcodes (admits function* g(o, helper){ yield helper(o.a); yield o.compute(2); } and asserts the program carries PrepareIdentifierCallTarget/PrepareNamedCallTarget/CallInvocationBoundary); runtime GeneratorCallBetweenYields_RoutesResumableAndProducesValues (route log func=g argc=2, values 11, 6), GeneratorCalleeThrows_SurfacesThrowOnResumedStep (callee throws on the resumed step, value `1
2026-06-03 R1/R5 resumable VM value-computation tier (TryFindUnsupportedResumableOpcode) The resumable VM (ExecuteResumable) used by generator/async function bodies previously handled only the slot/literal/binary/control-flow/suspension opcodes, so any suspendable function whose body read a property, resolved a computed key, applied typeof, or applied a unary operator between suspension points was declined by EvaluateResumable and fell back to the interpreter. This slice ports the NON-SUSPENDING value-computation tier into the ExecuteResumable switch, re-expressed against its local state machine (stack/stackPointer/programCounter/slots/state/context/program, throwing via state.IsCompleted = true; return UnifiedBytecodeStepResult.Throw(context.FlowValue);): GetNamedProperty (via the static GetNamedPropertyValue helper), GetComputedProperty (with its required RequireObjectCoercible + ResolvePropertyKey prelude, since every o[k] read lowers to that triple), TypeOf, TypeOfIdentifier (uninitialized-slot ReferenceError preserved; the inactive-catch-binding branch is unreachable because the resumable opcode set still excludes try/catch), and the unary operators UnaryPlus, UnaryMinus, UnaryLogicalNot, UnaryBitwiseNot, UnaryVoid. Each newly-handled opcode is removed from the TryFindUnsupportedResumableOpcode unsupported set so generator/async bodies using them are admitted by EvaluateResumable. Deliberately NOT admitted (left in the unsupported set, noted as follow-ups): the optional/short-circuit read variants (GetNamedPropertyOptional, GetComputedPropertyOptional) — the resumable state has no stackShortCircuitFlags array to persist short-circuit flags across a suspension; TypeOfDynamicIdentifier/DeleteDynamicIdentifier and named property WRITE/UPDATE/DELETE/CALL opcodes — they need a dynamic calling environment / receiver bookkeeping the resumable VM does not yet thread. Eligibility EvaluateResumable_PropertyAndUnaryBetweenYields_AdmitsValueTierOpcodes (admits function* g(o){ yield o.a; yield -o.b; yield typeof o.c; } and asserts the program carries GetNamedProperty/UnaryMinus/TypeOf); runtime GeneratorPropertyAndUnaryBetweenYields_RoutesResumableAndProducesValues (asserts the unified-bytecode-resumable-generator-fast-path func=g argc=1 route log AND the value sequence 10, -7, "string") and GeneratorComputedAndUnaryVariety_RoutesResumableAndProducesValues (computed o[k] + +/!/~/void between yields, func=g argc=2, value sequence 5, true, -1, undefined). Full internal suite 5386 passed / 0 failed (+3 new); UnifiedBytecodeProduction pack 1076 green single-threaded.
2026-06-03 R7 top-level var simple destructuring (DestructuringDependency / dynamic step-wise targets) Top-level (script-scope) simple var destructuring declarations started routing through production unified bytecode instead of declining into ExecutionPlanRunner.RunScript. Shapes admitted in that slice: var {a, b} = o;, var [x, y] = arr;, object rest var {a, ...rest} = o;, array rest var [head, ...tail] = arr;, and array holes var [, second] = arr;. Root cause of the prior decline was twofold: (1) the step-wise destructuring driver state symbols (__objDestr_src / __arrDestr_iter) are not part of the script activation slot map, so TryResolveDriverSlot failed before the targets were even reached; and (2) the destructuring targets (a/b/x/y) are script-global var bindings with no flat slot. AddSyntheticDestructuringStateSlots allocated scratch activation slots for the driver state (mirroring AddSyntheticResumeSlots for generator state), and TryResolveDestructuringTarget emitted a dynamic store (StoreDynamicIdentifierValue against the materialized script environment, via UnifiedBytecodeDriverDescriptor.TargetNameConstantIndex) for var-kind targets that don't resolve to a slot. The targets are already var-hoisted into the script environment before the VM runs (HoistVarDeclarations), so no declare op is needed. This row was later widened on 2026-06-06 to include script-scope let / const simple destructuring through TargetVariableKind and dynamic lexical initialization. Parameter, nested, default, computed-key, and disposal-aware destructuring remain separate boundaries. Note: the tools/profile-scripts/destructuring.js workload is still blocked by the orthogonal "non-iterating lexical block environments with flat slot mappings" gate (its const destructuring lives inside a for-loop block, which declines independently of top-level destructuring), so its route-hit count is unchanged by this original slice. Eligibility EvaluateScript_TopLevelObjectVarDestructuring_AcceptsWithDynamicTargets, EvaluateScript_TopLevelArrayVarDestructuring_AcceptsWithDynamicTargets, EvaluateScript_TopLevelArrayVarRestDestructuring_AcceptsWithDynamicTargets; runtime TopLevelObjectVarDestructuring_UsesUnifiedBytecodeProductionFastPath (=3), TopLevelArrayVarDestructuring_... (=60), TopLevelArrayVarRestDestructuring_...WithCorrectBindings (=4), TopLevelObjectVarRestDestructuring_...WithCorrectBindings (=60), TopLevelArrayVarDestructuringHole_BindsUndefinedForElidedElement (=2), TopLevelObjectVarDestructuringNullSource_ThrowsTypeError. Full internal suite 5383 passed / 0 failed; UnifiedBytecodeProduction pack 1076 green; FirstBoundaryStackDepthGuard + ExpressionProgram coverage-map drift unchanged.
2026-06-02 PropertyUpdateDependency nested named prefix + computed update (and PropertyWriteDependency rich computed-key write) Activation-resolved nested named receiver chains ending in a computed update now route through production unified bytecode, for example box.child[key]++, ++box.child[key], box.child[key]--, --box.child[key], the deep box.child.branch[key]++, and the rich-key box.child[key + 1]++. The eligibility selector (TryIsFirstBoundaryNestedNamedComputedPropertyUpdateCandidate) walks the named receiver-prefix chain (>=1 plain GetNamedProperty hop) then validates the computed key span (IsSupportedComputedPropertyKeySpan) and a trailing UpdateComputedProperty; it is wired into both the UpdateComputedProperty per-op case and the GetNamedProperty prefix per-op case. A dedicated compiler emitter (TryAppendFirstBoundaryNestedNamedComputedPropertyUpdate, dispatched before the simple computed-update emitter, which otherwise intercepts the trailing UpdateComputedProperty and rejects the named prefix as an unsupported key span) emits the base load, prefix GetNamedProperty reads, computed key span, and UpdateComputedProperty. The shape is validated in full before any staging is committed, so a false path cannot leave a partially emitted, stack-overflowing program. The collapsed receiver resolves the computed key once per update and preserves postfix-old / prefix-new semantics. Computed receiver-prefix updates are covered by the later A23 row. Companion verification on the WRITE side confirmed the rich binary computed key (box.child[key + 1] = value) was already admitted by TryIsFirstBoundaryNestedNamedComputedPropertyWriteCandidate via IsSupportedComputedPropertyKeySpan and is now locked by test; the ternary computed key (box.child[cond ? a : b] = value) is covered by the later control-expression computed-key row. Eligibility Evaluate_NestedNamedComputedPropertyUpdate_AcceptsOwnedPropertyOpcodes (theory over ++/--, prefix/postfix), Evaluate_DeepNestedNamedComputedPropertyUpdate_AcceptsOwnedPropertyOpcodes, Evaluate_NestedNamedComputedPropertyUpdateWithBinaryKey_AcceptsOwnedPropertyOpcodes, Evaluate_NestedNamedComputedPropertyWriteWithBinaryKey_AcceptsOwnedPropertyOpcodes; runtime NestedNamedComputedPropertyUpdate_PostfixAndPrefix_UsesUnifiedBytecodeProductionFastPath (func=post/func=pre argc=2, key resolved once through a getter/setter), NestedNamedComputedPropertyUpdate_DecrementAndDeepPrefix_UsesUnifiedBytecodeProductionFastPath (func=dec/func=deep argc=2), and NestedNamedComputedPropertyWriteWithRichKey_UsesUnifiedBytecodeProductionFastPath (argc=3, binary key resolved once).
2026-06-02 CallDependency optional-named-then-plain-computed read chain call argument Identifier and named-member calls now keep production unified bytecode when a logical argument is an optional named hop followed by plain named continuations and a plain computed read, for example fn(box?.prop[key]), fn(box?.prop[a + b]), and fn(box?.a.b[key]). The call-argument span walker (TryMeasureSimpleOptionalNamedThenComputedReadOperandSpan wired into HasSimpleCallArguments ahead of the plainer optional measurers, plus TryIsOptionalNamedThenComputedReadCallArgumentOperation for the GetComputedProperty(SC=True) op) and compiler emitter (TryAppendSimpleOptionalNamedThenComputedReadOperandSpan in TryAppendCallArguments) recognize [base, GetNamedProperty(IsOptional,!SC), GetNamedProperty(!IsOptional,SC)*, keySpan, GetComputedProperty(!IsOptional,SC)] and emit the JumpIfNullishReplaceUndefined(end) head jump at the optional hop, the named hop/continuation reads, the computed key span, GetComputedProperty, and trailing plain named reads, so a nullish head short-circuits the whole chain to undefined. A second optional hop (fn(box?.prop?.[key])) is now handled by the A31 computed second-hop call-argument row. Eligibility Evaluate_IdentifierCallWithOptionalNamedThenComputedReadArgument_AcceptsGetComputedProperty, ...BinaryKeyArgument_AcceptsGetComputedProperty, Evaluate_IdentifierCallWithDeepOptionalNamedThenComputedReadArgument_Accepts, Evaluate_IdentifierCallWithOptionalNamedThenOptionalComputedReadArgument_AcceptsComputedContinuation; runtime IdentifierCallWithOptionalNamedThenComputedReadArgument_UsesUnifiedBytecodeProductionFastPath (argc=3), ...BinaryKeyArgument... (argc=4), and IdentifierCallWithDeepOptionalNamedThenComputedReadArgument... (argc=3) for present-value and nullish-head short-circuit paths.
2026-06-02 CallDependency unary and typeof-identifier call arguments Identifier and named-member calls now keep production unified bytecode when a logical argument is a simple unary operation (fn(-x), fn(+x), fn(!x), fn(~x), fn(void x)) or typeof of an activation-resolved identifier (fn(typeof x)). The existing TryMeasureSimpleUnaryOperandSpan / TryMeasureSimpleTypeOfOperandSpan measurers and TryAppendSimpleUnaryOperandSpan / TryAppendSimpleTypeOfOperandSpan emitters are now wired into the top-level call-argument walkers (HasSimpleCallArguments and TryAppendCallArguments). typeof of a property read (fn(typeof box.p)) remains a follow-up (the value-operand typeof emitter does not yet lower property-read operands, so it declines safely). Eligibility Evaluate_IdentifierCallWithUnaryOperandArgument_AcceptsUnaryOpcode (theory over -/+/!/~/void) and Evaluate_IdentifierCallWithTypeOfIdentifierArgument_AcceptsTypeOfIdentifier; runtime IdentifierCallWithUnaryAndTypeOfArguments_UsesUnifiedBytecodeProductionFastPath (func=unary/func=kind argc=2).
2026-06-02 R7 top-level typeof of block-scoped lexical binding declines (correctness) Top-level scripts that resolve a typeof <identifier> to a block-scoped lexical binding now decline the production route. On the flat-slot script path a for (let i ...) counter (or any block let/const) keeps its flat slot after its block exits, so a TypeOfIdentifier slot read would leak the binding's stale value instead of "undefined". EvaluateScript now declines via TryFindBlockScopedTypeOfIdentifierLeak, and the companion script-root-slot fast path in ExecutionPlanBuilder declines any out-of-scope reference to a block-scoped lexical binding via ScriptFastPathBlockBindingLeakDetector, routing these scripts back to the scope-chain-aware IR runner. Fixes FlatSlotOptimizationTests.ForLoopCounterNotVisibleOutside. FlatSlotOptimizationTests.ForLoopCounterNotVisibleOutside; UnifiedBytecodeProduction pack stays green; ExpressionProgram coverage-map drift test unchanged.
2026-06-02 PropertyWriteDependency computed-read prefix + named write Activation-resolved receivers reached through a computed property read now route a trailing named property write through production unified bytecode, for example box[key].child = value. The eligibility selector (TryIsFirstBoundaryComputedPrefixNamedPropertyWriteCandidate, reusing the simple computed-read measurer) admits [base, box[key] read, value, SetNamedProperty], and the general expression loop emits it. A latent rollback bug in TryAppendFirstBoundaryNamedPropertySet (it loaded the base before rejecting a multi-op receiver, leaving a stray load for the general loop to double and overflow the stack) was fixed by validating the RHS shape before emitting. A double computed prefix (box[k1][k2].child = v) still declines PropertyWriteDependency. Eligibility Evaluate_ComputedPrefixNamedPropertyWrite_AcceptsOwnedPropertyOpcodes, Evaluate_DoubleComputedPrefixNamedPropertyWrite_DeclinesWithPropertyWriteDependency; runtime ComputedPrefixNamedPropertyWrite_UsesUnifiedBytecodeProductionFastPath (argc=3).
2026-06-02 CallDependency optional-computed-then-named read chain call argument Identifier and named-member calls now keep production unified bytecode when a logical argument is an optional computed read followed by plain named continuation reads, for example fn(box?.[key].value) and fn(box?.[key].a.b). The call-argument span walker (TryMeasureSimpleOptionalComputedPropertyReadOperandSpan extended with a continuation walk plus TryIsEmbeddedOptionalComputedReadChainCallArgumentContinuation) and compiler emitter (TryAppendSimpleOptionalComputedPropertyReadOperandSpan) recognize [base, JumpIfNullish(RWU), keySpan, GetComputedProperty, GetNamedProperty(SC)+] and emit the JumpIfNullishReplaceUndefined(end) head jump plus plain GetNamedProperty continuation reads, so a nullish base short-circuits the whole chain to undefined. An optional continuation hop (fn(box?.[key]?.value)) is now handled by the A31 computed second-hop call-argument row. Eligibility Evaluate_IdentifierCallWithOptionalComputedThenNamedReadChainArgument_AcceptsGetComputedAndNamedReads, ...DeepNamedReadChainArgument_Accepts, ...OptionalNamedReadArgument_AcceptsNamedContinuation; runtime IdentifierCallWithOptionalComputedThenNamedReadChainArgument_UsesUnifiedBytecodeProductionFastPath (argc=3).
2026-06-02 PropertyWriteDependency nested named prefix + computed compound/logical write Activation-resolved nested named receiver chains ending in a computed compound (box.child[key] += value, and other production binary operators) or logical (box.child[key] &&= value, ||=, ??=) property write now route through production unified bytecode. The eligibility selectors (TryIsFirstBoundaryComputedCompoundPropertyWriteCandidate, TryIsFirstBoundaryComputedLogicalPropertyWriteCandidate) walk the named receiver-prefix chain so the computed key span starts after the prefix; the compiler emitters (TryAppendFirstBoundaryComputedCompoundPropertySet, TryAppendFirstBoundaryComputedLogicalPropertySet) emit the base load, prefix GetNamedProperty reads, computed key span, then the proven compound/short-circuit suffix. The collapsed receiver keeps RequireObjectCoercible(Depth=1), so the compound key is resolved once and the logical write short-circuits exactly like the prefix-free baseline. Computed receiver-prefix compound/logical writes are now covered by the later A51j row. Eligibility Evaluate_NestedNamedComputedCompoundPropertyWrite_AcceptsOwnedPropertyOpcodes, Evaluate_DeepNestedNamedComputedCompoundPropertyWrite_AcceptsOwnedPropertyOpcodes, and Evaluate_NestedNamedComputedLogicalPropertyWrite_AcceptsOwnedPropertyOpcodes (&&=/||=/??=); runtime NestedNamedComputedCompoundPropertyWrite_UsesUnifiedBytecodeProductionFastPath (argc=3, key resolved once through a getter/setter) and NestedNamedComputedLogicalPropertyWrite_ShortCircuits_UsesUnifiedBytecodeProductionFastPath (argc=3).
2026-06-02 PropertyWriteDependency nested named prefix + computed write Activation-resolved nested named receiver chains ending in a computed property write now route through production unified bytecode, for example box.child[key] = value and box.child[key + suffix] = value. The eligibility selector (TryIsFirstBoundaryNestedNamedComputedPropertyWriteCandidate) walks the named receiver-prefix chain then validates the computed key span and simple RHS, and the compiler emitter (TryAppendFirstBoundaryNestedNamedComputedPropertySet) emits the base load, prefix GetNamedProperty reads, computed key span, value, and SetComputedProperty. Computed receiver-prefix computed writes are now covered by the later A51j row. Eligibility Evaluate_NestedNamedComputedPropertyWrite_AcceptsOwnedPropertyOpcodes and ...WithBinaryKey_...; runtime NestedNamedComputedPropertyWrite_UsesUnifiedBytecodeProductionFastPath (argc=3) and ...BinaryKey...ResolvesKeyOnce (argc=4).
2026-06-02 CallDependency baseline optional computed property-read call argument Identifier and named-member calls now keep production unified bytecode when a logical argument is a baseline optional computed property read, for example fn(box?.[key]) and fn(box?.[a + b]). The call-argument span walker (HasSimpleCallArguments plus TryIsOptionalComputedReadCallArgumentOperation) and compiler emitter (TryAppendSimpleOptionalComputedPropertyReadOperandSpan) recognize [base, JumpIfNullish(ReplaceWithUndefined), keySpan, GetComputedProperty] and emit the proven JumpIfNullishReplaceUndefined(end) guard + key span + GetComputedProperty, so a nullish base short-circuits the read to undefined. A chained optional computed hop (fn(box?.[key]?.[key])) is now handled by the A31 computed second-hop call-argument row. Eligibility Evaluate_IdentifierCallWithOptionalComputedPropertyReadArgument_AcceptsGetComputedProperty, Evaluate_IdentifierCallWithOptionalComputedBinaryKeyArgument_AcceptsGetComputedProperty, Evaluate_IdentifierCallWithChainedOptionalComputedReadArgument_AcceptsComputedReadChain; runtime IdentifierCallWithOptionalComputedPropertyReadArgument_UsesUnifiedBytecodeProductionFastPath (argc=3) and ...BinaryKey... (argc=4) for present-value and nullish-base short-circuit paths.
2026-06-02 CallDependency optional-start named read chain call argument Identifier and named-member calls keep production unified bytecode when a logical argument is an optional-start named read chain, for example fn(box?.child.value), sink.add(box?.child.nested.deep), and the later A31 named second-hop forms fn(box?.child?.value) / fn(box?.value?.nested). The call-argument span walker (HasSimpleCallArguments plus TryIsEmbeddedOptionalNamedReadChainCallArgumentContinuation) and compiler emitter (TryAppendSimpleOptionalNamedReadChainOperandSpan) recognize [base, GetNamedProperty(IsOptional,!SC), GetNamedProperty(SC)+] and emit one JumpIfNullishReplaceUndefined(end) per optional hop plus owned GetNamedProperty continuation reads, so a nullish value at any optional named hop short-circuits the whole chain to undefined with exact parity to the standalone optional-named-chain route. Computed optional continuations are now covered by the A31 computed second-hop call-argument row. Eligibility Evaluate_IdentifierCallWithOptionalNamedReadChainArgument_AcceptsGetNamedPropertyChain, Evaluate_NamedMemberCallWithOptionalNamedReadChainArgument_AcceptsGetNamedPropertyChain, Evaluate_IdentifierCallWithOptionalThenOptionalNamedReadChainArgument_AcceptsGetNamedPropertyChain; runtime IdentifierCallWithOptionalNamedReadChainArgument_UsesUnifiedBytecodeProductionFastPath, ...AmongOtherArguments_..., and IdentifierCallWithChainedOptionalNamedReadArgument_* assert unified-bytecode-production-fast-path func=invoke argc=2/4 for present-value and nullish-head/second-hop short-circuit paths.
2026-06-02 CallDependency baseline optional named property-read call argument Identifier and named-member calls keep production unified bytecode when a logical argument is a baseline single-hop optional named property read, for example fn(box?.value) and sink.add(box?.value). The call-argument span walker (eligibility HasSimpleCallArguments) and compiler emitter (TryAppendCallArguments) recognize and emit the [base, GetNamedPropertyOptional] operand span, so a nullish base yields undefined for that argument without leaving the production VM. Named chained optional reads such as fn(box?.value?.nested) are now covered by the A31 optional-start named-chain span; computed chained optional call arguments are now covered by the A31 computed second-hop call-argument span. Focused Evaluate_IdentifierCallWithOptionalNamedPropertyReadArgument_AcceptsGetNamedPropertyAndCallBoundary, Evaluate_NamedMemberCallWithOptionalNamedPropertyReadArgument_AcceptsGetNamedPropertyAndCallBoundary, and Evaluate_IdentifierCallWithChainedOptionalNamedPropertyReadArgument_AcceptsGetNamedPropertyChain eligibility tests; runtime route-hit proofs IdentifierCallWithOptionalNamedPropertyReadArgument_UsesUnifiedBytecodeProductionFastPath and NamedMemberCallWithOptionalNamedPropertyReadArgument_UsesUnifiedBytecodeProductionFastPath assert unified-bytecode-production-fast-path func=invoke argc=2 for both the present-value and nullish short-circuit paths.
2026-06-02 R7 top-level slotless lexicals plus R2/R3 dynamic global member calls Top-level scripts can now compile slotless let / const declarations through DeclareDynamicLexical and InitializeDynamicLexical, and supported arithmetic stack expressions can include embedded named member calls from dynamic global identifier bases such as Math.sqrt(...) and Math.pow(...). This admits the simplearithmetic profile into the production VM instead of the old script runner. Focused EvaluateScript_TopLevelSimpleArithmeticBuiltins_AcceptsDynamicGlobalMemberCalls and TopLevelSimpleArithmeticBuiltins_UsesUnifiedBytecodeProductionFastPath tests; rtk ./tools/profile simplearithmetic --route-hits now reports unified-bytecode-production-fast-path=10000.
2026-06-02 R7 top-level script route and script completion Top-level scripts can now attempt the production unified-bytecode VM before ExecutionPlanRunner.RunScript when the script plan is otherwise admitted. The compiler models script completion with a dedicated completion slot, EvaluateAndDiscard stores completion values without leaving stack residue, and return from a script program returns the stored completion. This admits the propertyaccess profile's top-level object/property loop. Focused EvaluateScript_TopLevelPropertyAccessLoop_AcceptsWithScriptCompletionSlot and TopLevelPropertyAccessLoop_UsesUnifiedBytecodeProductionFastPath tests; rtk ./tools/profile propertyaccess --route-hits now reports unified-bytecode-production-fast-path=20.
2026-06-02 Ordinary sync simple-return / simple-binary route priority Simple literal returns, simple parameter returns, parameter binary returns, and parameter binary-chain returns now defer their old caller-level and simple-IR shortcuts when the cached plan is production-bytecode eligible. The production VM is now attempted before simple-ir-parameter-*, simple-ir-return-*, SyncIrCallTrampoline, and generic ExecutionPlanRunner for admitted ordinary sync functions. Activation proof pack now asserts production unified-bytecode route logs for simple literal, parameter, binary, and binary-chain functions; source gate locks production VM before simple IR fallbacks; route-hit probes moved activation-noargs-lite and functioncalls-lite out of the zero-hit bucket.
2026-06-02 PropertyReadBoundaryOutOfScope inside CallInvocationBoundary Identifier and named-member calls now keep production unified bytecode when argument values are simple named or computed property-read spans, for example fn(box.value), fn(box["value"]), and sink.add(box.value). The call argument span walker and compiler now count and emit those reads as one logical argument instead of declining the property read before the call boundary. Focused eligibility proof for GetNamedProperty / GetComputedProperty plus CallInvocationBoundary; runtime route-hit proof for identifier and named-member calls with property-read arguments.
2026-06-02 PropertyReadBoundaryOutOfScope inside SuperConstructInvocationBoundary Derived constructors now keep production unified bytecode when an admitted constructor parameter is read through a simple named or computed property inside super(...), for example constructor(values) { super(values.length); }, constructor(prefix, ...items) { super(items.length); }, and super(items["length"]). The property-read op is now recognized as owned by the super-construct argument boundary instead of forcing the constructor back to the existing route. Focused eligibility proof for GetNamedProperty / GetComputedProperty plus SuperConstructInvocationBoundary; runtime route-hit proof for Derived with super(values.length), super(items.length), and super(items["length"]).
2026-06-02 pre-gate:IsClassConstructor plus derived-constructor parameter gates Explicit derived class constructors now enter production unified bytecode with simple literal-default parameters and final-rest identifier parameters when the body is otherwise on the admitted super(...) route. Runtime-dependent derived-constructor defaults and destructured constructor parameters remain separately owned. Focused derived-constructor route-hit and no-route tests; constructor proof pack; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:IsClassConstructor plus parameter-shape gates Base class constructors now enter production unified bytecode with simple literal-default parameters and final-rest identifier parameters, reusing the existing constructor VM path and slot initialization instead of falling back solely because the parameter list is non-simple. Runtime-dependent constructor defaults and destructured constructor parameters remain separately owned. Focused base-constructor route-hit tests; constructor proof pack; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:hasParameterExpressions Ordinary sync functions with simple identifier parameters and literal defaults now initialize default values directly into VM parameter slots, including materialized activation environments used by nested closures. Defaults folded to literals before invocation, such as value = 40 + 2, share this route; runtime-dependent defaults still use the existing parameter environment route. Focused default-literal and folded-default route-hit tests; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:hasParameterExpressions / pre-gate:IsArrowFunction Arrow functions with the same simple literal-default parameter shape now share the production slot-initialization path, including defaults folded to literals before invocation. Runtime-dependent arrow defaults still decline. Focused arrow default-literal and folded-default route-hit tests; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:hasOnlySimpleIdentifierParameters / pre-gate:IsArrowFunction Arrow functions with plain leading identifier parameters and a final rest identifier parameter now share the production slot-initialization path used by ordinary final-rest functions. Focused arrow final-rest route-hit tests; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:hasOnlySimpleIdentifierParameters plus bounded implicit-arguments dependency Ordinary sync functions with plain leading identifier parameters and a final rest identifier parameter now enter production unified bytecode when bounded implicit arguments use owns the body, including typeof arguments, arguments.length, arguments[0], bounded identifier update (arguments++), assignment (arguments = ...), delete (delete arguments), and call-target (arguments()) shapes. Focused final-rest-plus-implicit-arguments route-hit tests; direct eligibility opcode assertions; UnifiedBytecodeProduction pack.
2026-06-02 pre-gate:hasParameterExpressions plus bounded implicit-arguments dependency Ordinary sync functions with simple literal defaults now enter production unified bytecode when the existing implicit-arguments predicate owns the body, including typeof arguments, arguments.length, arguments[0], bounded identifier update (arguments++), assignment (arguments = ...), delete (delete arguments), and call-target (arguments()) shapes in simple expression spans. Runtime-dependent default expressions and destructured parameter lists remain separately owned. Focused default-plus-implicit-arguments route-hit tests; direct eligibility opcode assertions; UnifiedBytecodeProduction pack.

Better Progress Meter

Do not use Production Decline Families alone as the progress meter. The family list is a coarse taxonomy and can stay present while many concrete shapes inside that family have already been admitted.

Use this meter instead:

  1. Route-hit evidence for representative workloads: rtk ./tools/profile <profile> --route-hits
  2. The concrete remaining gate view in docs/unified-bytecode-expansion-contract.md.
  3. Source gates proving accepted routes do not call back into ExpressionProgram, ExecutionPlanRunner, or AST evaluators.
  4. Live fallback usage: which real workloads still report zero unified-bytecode-production-fast-path hits.

Current reproducible snapshot from local route-hit probes:

Baseline: origin/main at c42166d7c on 2026-06-08. Command shape:

profiles=(simplearithmetic fib forloop whileloop ir-arithmetic activation-noargs-lite activation-params-lite activation-arguments-lite activation-closures-lite activation-evalscope-lite objectcreation arrayops stringops propertyaccess classdef destructuring spread mapset json regex promise closures-lite recursion-lite forofiteration functioncalls functioncalls-lite)
for p in "${profiles[@]}"; do
  rtk ./tools/profile "$p" --route-hits
done
Workload Route hits Signal
simplearithmetic 10,000 Active top-level script arithmetic route.
fib 10 Active production route on the wrapper/entry shape; recursion still limits the measured workload.
forloop 40 Active ordinary sync loop/arithmetic route.
whileloop 20 Active ordinary sync loop route.
ir-arithmetic 20 Active var-binding arithmetic route.
activation-noargs-lite 600,002 Active simple literal-return activation route plus wrapper/entry shapes.
activation-params-lite 500,002 Active parameterized activation route plus wrapper/entry shapes.
activation-arguments-lite 1 Minimal-hit: wrapper/entry shape routes; the arguments-object workload itself remains a blocker.
activation-closures-lite 120,300 Partial-hit: admitted captured-closure shapes route; dynamic activation residue and retained live-with closure chains remain blockers for broader closure shapes.
activation-evalscope-lite 64 Partial-hit: entry/wrapper shapes route; eval-sensitive dynamic scope remains a blocker.
objectcreation 20 Minimal-hit: wrapper/entry shape routes; broad object-construction workload remains outside the production route.
arrayops 400,000 Active array operation wrapper/iteration route.
stringops 20 Minimal-hit: wrapper/entry shape routes; string builtin workload remains outside the production route.
propertyaccess 20 Active narrow top-level property-access script route.
classdef 160,000 Active class-definition workload route.
destructuring 0 Zero-hit: measured destructuring profile remains blocked by non-admitted script/block shapes.
spread 0 Zero-hit: measured spread workload does not enter the production route.
mapset 20 Minimal-hit: wrapper/entry shape routes; Map/Set builtin workload remains outside the production route.
json 0 Zero-hit: JSON builtin workload does not enter the production route.
regex 0 Zero-hit: RegExp builtin workload does not enter the production route.
promise 60 Active promise wrapper/eligible route; async/microtask semantics remain separate.
closures-lite 8,400 Active closure workload route for eligible shapes.
recursion-lite 2 Minimal-hit: wrapper/entry shape routes; recursive workload remains outside the production route.
forofiteration 4,000 Active admitted sync iterator-driver route.
functioncalls 8,000,010 Active ordinary function-call route plus wrapper/entry shapes.
functioncalls-lite 1,600,002 Active ordinary function-call route plus wrapper/entry shapes.

Zero route hits do not necessarily mean the syntax family has no bytecode support. They mean the measured workload shape did not enter the production unified-bytecode fast path. That is why route-hit evidence must be read together with the source shape and eligibility boundary.

Final proof rerun on 2026-06-08 confirmed the representative production route subset used by the expansion contract: forloop 40 hits, propertyaccess 20, functioncalls-lite 1,600,002, activation-noargs-lite 600,002, and forofiteration 4,000. The same run reported forloop --memory total allocation at 968.36 MB. The previous 2026-06-06 Test262 regression script selected 1,910 generated cases from the 523-entry full pack; 1,906 passed and 4 failed in the strict/non-strict Intl DateTimeFormat temporal resolved-time-zone rows (formatRangeToParts and formatToParts). Those residuals are Intl semantics evidence, not a retained discard-specific production bytecode gate.

Practical Reading

The current state is best described as:

  • Production unified bytecode is the target hot route for admitted shapes.
  • Expression bytecode and statement IR are still active execution tiers.
  • Legacy AST/dynamic paths are retained for correctness boundaries, not as the desired normal path.
  • Full bytecode execution requires both widening admitted semantics and retiring the remaining fallback tiers for non-dynamic code.