Skip to content

Renumber capture guard: extend the free-spelling skip to composite images #310

Description

@Unisay

Problem

The emission-time renumbering pass (Language.PureScript.Backend.Lua.Renumber, #306) guards against capturing free (global) references by skipping, during index allocation, any index whose direct prefix_S_index spelling occurs free in the chunk. That guard covers the terminal-run shapes — for a binder x_S_5 next to a free global x_S_0, allocation skips 0 and renumbers to x_S_1:

-- before                        -- after
local x_S_5 = 1                  local x_S_1 = 1
return x_S_5 + x_S_0             return x_S_1 + x_S_0

It does not cover composite images: a derived name embeds its run mid-name (a dispatcher b_S_5_S_loop renumbering in step with member b_S_5), and the guard only checks the member spelling b_S_0, not the composite b_S_0_S_loop. A hand-written FFI file that reads a global literally named b_S_0_S_loop would be captured by the renamed dispatcher local.

The class is close to unreachable in practice: it needs an FFI global whose name both embeds a supply-shaped digit segment mid-name and lands exactly on a renumbered composite spelling. No real FFI code does this; the direct-spelling guard already covers every name the compiler mints today whose image equals its full spelling.

Approach

Extend the guard to post-check the full rebuilt image of every renamed binder against the chunk's free-name set, and on a hit re-allocate deterministically (bump the run's index until the composite clears). Idempotence and stability must be preserved — the skip has to be a pure function of chunk structure, mirroring how the existing counter-level skip re-derives on a second pass. Note [Supply-drawn digit runs] in the module documents the current guard's scope.

Prerequisites / Relations

Independent; hardens the pass merged in #306. No open issue depends on it.

Verification / Measurement

A unit fixture in the pass's spec: a chunk binding b_S_5 and its dispatcher b_S_5_S_loop alongside a free global read of b_S_0_S_loop must renumber the pair away from the collision (today the dispatcher lands exactly on the free spelling). The existing idempotence property (chunks generated over supply-minted name pools) and the golden corpus must stay green and byte-identical — no real artifact exercises the class.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: codegenLua code generation / printingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions