-/*
- A register file is a stack of register frames. We represent a register
- frame by its offset from "base", the logical first entry in the register
- file. The bottom-most register frame's offset from base is 0.
-
- In a program where function "a" calls function "b" (global code -> a -> b),
- the register file might look like this:
-
- | global frame | call frame | call frame | spare capacity |
- -----------------------------------------------------------------------------------------------------
- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | <-- index in buffer
- -----------------------------------------------------------------------------------------------------
- | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | | | | | | <-- index relative to base
- -----------------------------------------------------------------------------------------------------
- | <-globals | temps-> | <-vars | temps-> | <-vars |
- ^ ^ ^ ^
- | | | |
- buffer base (frame 0) frame 1 frame 2
-
- Since all variables, including globals, are accessed by negative offsets
- from their register frame pointers, to keep old global offsets correct, new
- globals must appear at the beginning of the register file, shifting base
- to the right.
-
- If we added one global variable to the register file depicted above, it
- would look like this:
-
- | global frame |< >
- -------------------------------> <
- | 0 | 1 | 2 | 3 | 4 | 5 |< >snip< > <-- index in buffer
- -------------------------------> <
- | -4 | -3 | -2 | -1 | 0 | 1 |< > <-- index relative to base
- -------------------------------> <
- | <-globals | temps-> |
- ^ ^
- | |
- buffer base (frame 0)
-
- As you can see, global offsets relative to base have stayed constant,
- but base itself has moved. To keep up with possible changes to base,
- clients keep an indirect pointer, so their calculations update
- automatically when base changes.