Lua.Compiler.GotoResolution (Lua v1.0.0-rc.3)

View Source

Resolves goto / ::label:: ahead of interpreter execution.

The list interpreter walks an instruction tree and, by the time it reaches a :goto, has already consumed the head of the current block — so it can neither scan backward nor reach an enclosing block at run time. This pass resolves every goto up front, rewriting {:goto, name} to {:goto, id} and recording in proto.goto_targets an entry id => {depth, level, target_tail}:

  • depth — the number of cont entries the interpreter drops to leave the blocks between the goto and its target. A :test branch pushes one cont entry, each loop body pushes two (a CPS marker plus a :loop_exit); depth is the sum across the boundaries crossed, so after dropping it the remaining cont is exactly what was active when the destination block was first entered.

  • level — the target label's scope register level (recorded by codegen on the {:label, name, level} instruction). The goto closes any open upvalue cell at or above this register, so locals in the blocks it leaves or re-enters get fresh cells (Lua 5.3 §3.3.4 block-exit).

  • target_tail — the instruction sublist immediately after the matching {:label, name, level} in its owning block.

Label scope (Lua 5.3 §3.3.4): a goto targets a label in its own block or an enclosing one, never inside a nested block or a sibling block. do blocks are flattened by codegen into the parent's instruction list, so several blocks' labels can share one flat list. Each {:label, name, level, path} and {:goto, name, path} carries the lexical block path recorded by scope resolution (innermost-last, unique per do block). A label is visible to a goto only when the label's path is a prefix of the goto's path — i.e. the label sits in the goto's own block or one enclosing it. Among visible candidates the nearest after the goto (else the nearest before) is chosen, matching the forward continue / break idioms and the backward-jump loop.

Gotos never cross a function boundary, so each prototype is resolved independently against its own instruction tree.

Summary

Functions

Resolve gotos in proto and every nested prototype, returning the proto with rewritten instructions and a populated goto_targets map.

Functions

resolve(proto)

Resolve gotos in proto and every nested prototype, returning the proto with rewritten instructions and a populated goto_targets map.