-
Notifications
You must be signed in to change notification settings - Fork 32
JumpOnSassy
Okay. On Petit, we statically know where all the labels are, so we can compile direct jumps to those locations.
It doesn't work that way on native Larceny.
In particular, the JUMP instruction really does need to know what the actual offset into the target code vector is.
This is "easy" on Sparc, because we wrote the assembler ourselves. It isn't clear what the best way to do it on Sassy is.
However... there is one nice invariant about the common assembler component that leads one to a particular strategy: we assemble outer lambdas before inner lambdas that they contain (in terms of the static MacScheme instructions); this way, we actually know what all of the offsets are when we need to compile a JUMP instruction in an inner lambda.
The same principle can be applied to Sassy, it seems.
My original plan for Sassy, before I discovered this problem, was a final postpass after all of the segments have been converted into input compatible with sassy. This postpass would take the pasted segment and traverse it, passing each codevector to the sassy
procedure, and then that output to some other coercions to generate an appropriate bytevector object.
But it turns out that the SassyOutput object you get from sassy
has offset information in a symbol table that it carries along with it. In particular:
;; sassy-symbol-table : SassyOutput -> [Hashtable Symbol SassySym]
;; sassy-reloc-list : SassyOutput -> [Listof SassyReloc]
;; sassy-symbol-name : SassySym -> Symbol
;; sassy-symbol-offset : SassySym -> [Maybe Integer]
Therefore, if we interleave the sassy
postpass with the actual generation of sassy code sequences, then we can make the offsets we need available to us as we assemble a particular JUMP instruction. Part of the problem with this is that the SassyOutput object needs to be made available to the assembler processing the nested lambda; there might be a way to adapt the existing code slot in the assembly structure to handle this, but for now PnkFelix has just decided to make a new slot in the user-data for the assembly structure.
At first, PnkFelix adopted the following approach: when we assemble a JUMP, in addition to using the levels
argument to JUMP to figure out which closure we need to put into StackSlotZero, we also use the levels
argument to traverse the as-parent
field until we find the assembler structure for the code we're jumping into, and then pull the corresponding SassyOutput object.
However, the aforementioned approach doesn't always work, because it assumes that you can statically determine the target codevector of a JUMP from the levels
argument. This perhaps should be true, but its more difficult than you might think, because of the lexes
instruction. In particular, the target of a JUMP might even be the current codevector that we're trying to assemble, which means that we don't know the offset yet and can't plug it in. Will suggested back-patching, but PnkFelix doesn't want to learn how to do that. So instead he's separating out the two cases; either we know the offset, and plug it in, or we don't, in which case we assume that the label must be in the current codevector, and so we put a jmp
to a local label into the sassy input and let sassy deal with the offsets. See changeset:3051.
Update: see also Ticket #130 and changeset:3229.
Here is a program that ended up turning into something with a JUMP instruction in its MacScheme output, and thus a way to check whether an implementation of the JUMP instruction is working. (With the bogus implementation of JUMP that I came up with in my first draft, the label referred to by the JUMP is unknown to Sassy, and so it just compiled it into a branch to the next instruction; eek! This led to the program below producing ((6 3))
, instead of the expected (2)
(let ((p (lambda (x) (list 6 x) x))
(app (lambda (f) (f))))
(app (lambda () (p 3) (list (p 2)))))
(One might also wonder why this program isn't optimized more than it currently is, in terms of the MacScheme we do end up generating. But that's more a question for Will at this point...)