FAILURE MAP
← Case archive

FA-90076 / Bytecode virtual machines / Open access

Upvalues: each closure gets a private copy of a captured local · case 01

After the scope closes, writes through one closure are invisible to its sibling.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Closure creation never looks up the existing open upvalue for the slot.

VERIFIED REPAIR

Reuse the open upvalue already registered for that stack slot.

Unsuccessful approach: Deduplicating only within the closure being created still splits sharing between closures.

Case contract

A register/stack VM with open and closed upvalues. ["local", v] pushes a slot; ["set", s, v] and ["get", s] access slots; ["closure", id, [slots]] captures slots, reusing the existing open upvalue for a slot so closures share variables; ["uset"/"uget", id, k, (v)] access the k-th upvalue, going to the stack slot while open and to the upvalue's own cell once closed; ["close", level] closes every open upvalue whose slot >= level (copying the slot value) and truncates the stack to level. Accessing a vanished slot appends "dangling-slot" and stops.

Why this case matters

Closure capture and upvalue closing are subtle lifetime transitions in register-based VMs.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    stack = []
    open_uv = []
    closures = {}
    out = []
    try:
        for ev in events:
            op = ev[0]
            if op == 'local':
                stack.append(ev[1])
            elif op == 'set':
                stack[ev[1]] = ev[2]
            elif op == 'get':
                out.append(stack[ev[1]])
            elif op == 'closure':
                ups = []
                for s in ev[2]:
                    uv = None
                    if uv is None:
                        uv = {'slot': s, 'open': True, 'value': None}
                        open_uv.append(uv)
                    ups.append(uv)
                closures[ev[1]] = ups
            elif op == 'uset':
                uv = closures[ev[1]][ev[2]]
                if uv['open']:
                    stack[uv['slot']] = ev[3]
                else:
                    uv['value'] = ev[3]
            elif op == 'uget':
                uv = closures[ev[1]][ev[2]]
                out.append(stack[uv['slot']] if uv['open'] else uv['value'])
            elif op == 'close':
                level = ev[1]
                for uv in open_uv:
                    if uv['slot'] >= level:
                        uv['value'] = stack[uv['slot']]
                        uv['open'] = False
                open_uv = [u for u in open_uv if u['open']]
                del stack[level:]
    except IndexError:
        out.append('dangling-slot')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('two closures share one open upvalue',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1]],),
   [6, 6]),
  ('closing a scope keeps closures linked',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [6, 6, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [6, 6, 0, 78, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78]),
  ('slot reuse after closing everything',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]),
  ('closure over only the outer local',
   ([['local', 1], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [1, 2]),
  ('control: plain locals', ([['local', 1], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 1])],
 [('two closures share one open upvalue',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1]],),
   [7, 7]),
  ('closing a scope keeps closures linked',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [7, 7, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [7, 7, 0, 79, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79]),
  ('slot reuse after closing everything',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79, 109, 6, 109]),
  ('closure over only the outer local',
   ([['local', 2], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [2, 2]),
  ('control: plain locals', ([['local', 2], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 2])],
 [('two closures share one open upvalue',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1]],),
   [8, 8]),
  ('closing a scope keeps closures linked',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [8, 8, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [8, 8, 0, 80, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80]),
  ('slot reuse after closing everything',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80, 109, 9, 109]),
  ('closure over only the outer local',
   ([['local', 3], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [3, 2]),
  ('control: plain locals', ([['local', 3], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 3])],
 [('two closures share one open upvalue',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1]],),
   [9, 9]),
  ('closing a scope keeps closures linked',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [9, 9, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [9, 9, 0, 81, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81]),
  ('slot reuse after closing everything',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81, 109, 12, 109]),
  ('closure over only the outer local',
   ([['local', 4], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [4, 2]),
  ('control: plain locals', ([['local', 4], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 4])],
 [('two closures share one open upvalue',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1]],),
   [10, 10]),
  ('closing a scope keeps closures linked',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [10, 10, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [10, 10, 0, 82, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82]),
  ('slot reuse after closing everything',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82, 109, 15, 109]),
  ('closure over only the outer local',
   ([['local', 5], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [5, 2]),
  ('control: plain locals', ([['local', 5], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 5])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
two closures share one open upvalue[6, 6][6, 6]Passed
closing a scope keeps closures linked[6, 6, 6][6, 6, 0]Failed
regression: new local reusing a closed slot[6, 6, 6, 78, 6][6, 6, 0, 78, 0]Failed
open upvalue tracks later stack writes[6, 6, 6, 78, 6, 10, 3, 78][6, 6, 0, 78, 0, 10, 3, 78]Failed
slot reuse after closing everything[6, 6, 6, 78, 6, 10, 3, 78, 109, 3, 109][6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]Failed
closure over only the outer local[1, 2][1, 2]Passed
control: plain locals[4, 1][4, 1]Passed

SHA-256 / 09ae715b1030372b5604893b278c02ab6f17004d0954b854dc3ed42ff5b5ee5d

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    stack = []
    open_uv = []
    closures = {}
    out = []
    try:
        for ev in events:
            op = ev[0]
            if op == 'local':
                stack.append(ev[1])
            elif op == 'set':
                stack[ev[1]] = ev[2]
            elif op == 'get':
                out.append(stack[ev[1]])
            elif op == 'closure':
                ups = []
                for s in ev[2]:
                    uv = next((u for u in ups if u['slot'] == s), None)
                    if uv is None:
                        uv = {'slot': s, 'open': True, 'value': None}
                        open_uv.append(uv)
                    ups.append(uv)
                closures[ev[1]] = ups
            elif op == 'uset':
                uv = closures[ev[1]][ev[2]]
                if uv['open']:
                    stack[uv['slot']] = ev[3]
                else:
                    uv['value'] = ev[3]
            elif op == 'uget':
                uv = closures[ev[1]][ev[2]]
                out.append(stack[uv['slot']] if uv['open'] else uv['value'])
            elif op == 'close':
                level = ev[1]
                for uv in open_uv:
                    if uv['slot'] >= level:
                        uv['value'] = stack[uv['slot']]
                        uv['open'] = False
                open_uv = [u for u in open_uv if u['open']]
                del stack[level:]
    except IndexError:
        out.append('dangling-slot')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('two closures share one open upvalue',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1]],),
   [6, 6]),
  ('closing a scope keeps closures linked',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [6, 6, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [6, 6, 0, 78, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78]),
  ('slot reuse after closing everything',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]),
  ('closure over only the outer local',
   ([['local', 1], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [1, 2]),
  ('control: plain locals', ([['local', 1], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 1])],
 [('two closures share one open upvalue',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1]],),
   [7, 7]),
  ('closing a scope keeps closures linked',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [7, 7, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [7, 7, 0, 79, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79]),
  ('slot reuse after closing everything',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79, 109, 6, 109]),
  ('closure over only the outer local',
   ([['local', 2], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [2, 2]),
  ('control: plain locals', ([['local', 2], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 2])],
 [('two closures share one open upvalue',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1]],),
   [8, 8]),
  ('closing a scope keeps closures linked',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [8, 8, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [8, 8, 0, 80, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80]),
  ('slot reuse after closing everything',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80, 109, 9, 109]),
  ('closure over only the outer local',
   ([['local', 3], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [3, 2]),
  ('control: plain locals', ([['local', 3], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 3])],
 [('two closures share one open upvalue',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1]],),
   [9, 9]),
  ('closing a scope keeps closures linked',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [9, 9, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [9, 9, 0, 81, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81]),
  ('slot reuse after closing everything',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81, 109, 12, 109]),
  ('closure over only the outer local',
   ([['local', 4], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [4, 2]),
  ('control: plain locals', ([['local', 4], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 4])],
 [('two closures share one open upvalue',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1]],),
   [10, 10]),
  ('closing a scope keeps closures linked',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [10, 10, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [10, 10, 0, 82, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82]),
  ('slot reuse after closing everything',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82, 109, 15, 109]),
  ('closure over only the outer local',
   ([['local', 5], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [5, 2]),
  ('control: plain locals', ([['local', 5], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 5])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
two closures share one open upvalue[6, 6][6, 6]Passed
closing a scope keeps closures linked[6, 6, 6][6, 6, 0]Failed
regression: new local reusing a closed slot[6, 6, 6, 78, 6][6, 6, 0, 78, 0]Failed
open upvalue tracks later stack writes[6, 6, 6, 78, 6, 10, 3, 78][6, 6, 0, 78, 0, 10, 3, 78]Failed
slot reuse after closing everything[6, 6, 6, 78, 6, 10, 3, 78, 109, 3, 109][6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]Failed
closure over only the outer local[1, 2][1, 2]Passed
control: plain locals[4, 1][4, 1]Passed

SHA-256 / a2907520ec2252f957dd8596b105ce9c828f42ccad66d550ca084e095f88e530

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    stack = []
    open_uv = []
    closures = {}
    out = []
    try:
        for ev in events:
            op = ev[0]
            if op == 'local':
                stack.append(ev[1])
            elif op == 'set':
                stack[ev[1]] = ev[2]
            elif op == 'get':
                out.append(stack[ev[1]])
            elif op == 'closure':
                ups = []
                for s in ev[2]:
                    uv = next((u for u in open_uv if u['slot'] == s), None)
                    if uv is None:
                        uv = {'slot': s, 'open': True, 'value': None}
                        open_uv.append(uv)
                    ups.append(uv)
                closures[ev[1]] = ups
            elif op == 'uset':
                uv = closures[ev[1]][ev[2]]
                if uv['open']:
                    stack[uv['slot']] = ev[3]
                else:
                    uv['value'] = ev[3]
            elif op == 'uget':
                uv = closures[ev[1]][ev[2]]
                out.append(stack[uv['slot']] if uv['open'] else uv['value'])
            elif op == 'close':
                level = ev[1]
                for uv in open_uv:
                    if uv['slot'] >= level:
                        uv['value'] = stack[uv['slot']]
                        uv['open'] = False
                open_uv = [u for u in open_uv if u['open']]
                del stack[level:]
    except IndexError:
        out.append('dangling-slot')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('two closures share one open upvalue',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1]],),
   [6, 6]),
  ('closing a scope keeps closures linked',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [6, 6, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [6, 6, 0, 78, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78]),
  ('slot reuse after closing everything',
   ([['local', 10],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 6],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 78],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 3],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]),
  ('closure over only the outer local',
   ([['local', 1], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [1, 2]),
  ('control: plain locals', ([['local', 1], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 1])],
 [('two closures share one open upvalue',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1]],),
   [7, 7]),
  ('closing a scope keeps closures linked',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [7, 7, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [7, 7, 0, 79, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79]),
  ('slot reuse after closing everything',
   ([['local', 20],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 7],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 79],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 6],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [7, 7, 0, 79, 0, 20, 6, 79, 109, 6, 109]),
  ('closure over only the outer local',
   ([['local', 2], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [2, 2]),
  ('control: plain locals', ([['local', 2], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 2])],
 [('two closures share one open upvalue',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1]],),
   [8, 8]),
  ('closing a scope keeps closures linked',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [8, 8, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [8, 8, 0, 80, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80]),
  ('slot reuse after closing everything',
   ([['local', 30],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 8],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 80],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 9],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [8, 8, 0, 80, 0, 30, 9, 80, 109, 9, 109]),
  ('closure over only the outer local',
   ([['local', 3], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [3, 2]),
  ('control: plain locals', ([['local', 3], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 3])],
 [('two closures share one open upvalue',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1]],),
   [9, 9]),
  ('closing a scope keeps closures linked',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [9, 9, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [9, 9, 0, 81, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81]),
  ('slot reuse after closing everything',
   ([['local', 40],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 9],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 81],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 12],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [9, 9, 0, 81, 0, 40, 12, 81, 109, 12, 109]),
  ('closure over only the outer local',
   ([['local', 4], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [4, 2]),
  ('control: plain locals', ([['local', 4], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 4])],
 [('two closures share one open upvalue',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1]],),
   [10, 10]),
  ('closing a scope keeps closures linked',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1]],),
   [10, 10, 0]),
  ('regression: new local reusing a closed slot',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1]],),
   [10, 10, 0, 82, 0]),
  ('open upvalue tracks later stack writes',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82]),
  ('slot reuse after closing everything',
   ([['local', 50],
     ['local', 0],
     ['closure', 'f', [0, 1]],
     ['closure', 'g', [1]],
     ['uset', 'f', 1, 10],
     ['uget', 'g', 0],
     ['get', 1],
     ['close', 1],
     ['uset', 'g', 0, 0],
     ['uget', 'f', 1],
     ['local', 82],
     ['closure', 'h', [1]],
     ['uget', 'h', 0],
     ['uget', 'f', 1],
     ['uget', 'f', 0],
     ['set', 0, 15],
     ['uget', 'f', 0],
     ['close', 0],
     ['uget', 'h', 0],
     ['local', 109],
     ['closure', 'k', [0]],
     ['uget', 'k', 0],
     ['uget', 'f', 0],
     ['get', 0]],),
   [10, 10, 0, 82, 0, 50, 15, 82, 109, 15, 109]),
  ('closure over only the outer local',
   ([['local', 5], ['closure', 'c', [0]], ['close', 0], ['local', 2], ['uget', 'c', 0], ['get', 0]],),
   [5, 2]),
  ('control: plain locals', ([['local', 5], ['local', 2], ['set', 1, 4], ['get', 1], ['get', 0]],), [4, 5])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
two closures share one open upvalue[6, 6][6, 6]Passed
closing a scope keeps closures linked[6, 6, 0][6, 6, 0]Passed
regression: new local reusing a closed slot[6, 6, 0, 78, 0][6, 6, 0, 78, 0]Passed
open upvalue tracks later stack writes[6, 6, 0, 78, 0, 10, 3, 78][6, 6, 0, 78, 0, 10, 3, 78]Passed
slot reuse after closing everything[6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109][6, 6, 0, 78, 0, 10, 3, 78, 109, 3, 109]Passed
closure over only the outer local[1, 2][1, 2]Passed
control: plain locals[4, 1][4, 1]Passed

SHA-256 / b40f53a6d9e9da906a69be80b4a5a5cfe135df9463b5c13c1b0f134eeb6c0f3b

Verification & scope

A deterministic, bounded teaching model of one bytecode virtual machine mechanism with a stipulated instruction encoding; it is not a production VM and claims no conformance to any real specification. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:23.309270+00:00.

Case digest / a84367206e5dced02fac84e37d579c6c814cc32bd9a5a8e5222210761e0a84ac