As described earlier (see Stack Layout), Guile’s calling convention is that arguments are passed and values returned on the stack.
For calls, both in tail position and in non-tail position, we require
that the procedure and the arguments already be shuffled into place
before the call instruction. “Into place” for a tail call means that
the procedure should be in slot 0, relative to the fp
, and the
arguments should follow. For a non-tail call, if the procedure is in
fp
-relative slot n, the arguments should follow from slot
n+1, and there should be three free slots between n-1 and
n-3 in which to save the mRA, vRA, and fp
.
Returning values is similar. Multiple-value returns should have values
already shuffled down to start from fp
-relative slot 0 before
emitting return-values
.
In both calls and returns, the sp
is used to indicate to the
callee or caller the number of arguments or return values, respectively.
After receiving return values, it is the caller’s responsibility to
restore the frame by resetting the sp
to its former value.
f24:proc x8:_ c24:nlocals
¶Call a procedure. proc is the local corresponding to a procedure. The three values below proc will be overwritten by the saved call frame data. The new frame will have space for nlocals locals: one for the procedure, and the rest for the arguments which should already have been pushed on.
When the call returns, execution proceeds with the next instruction.
There may be any number of values on the return stack; the precise
number can be had by subtracting the address of proc-1 from the
post-call sp
.
f24:proc x8:_ c24:nlocals l32:label
¶Call a procedure in the same compilation unit.
This instruction is just like call
, except that instead of
dereferencing proc to find the call target, the call target is
known to be at label, a signed 32-bit offset in 32-bit units from
the current ip
. Since proc is not dereferenced, it may be
some other representation of the closure.
x24:_
¶Tail-call a procedure. Requires that the procedure and all of the arguments have already been shuffled into position, and that the frame has already been reset to the number of arguments to the call.
x24:_ l32:label
¶Tail-call a known procedure. As call
is to call-label
,
tail-call
is to tail-call-label
.
x24:_
¶Return a number of values from a call frame. The return values should have already been shuffled down to a contiguous array starting at slot 0, and the frame already reset.
f12:dst f12:proc x8:_ c24:nlocals
¶Receive a single return value from a call whose procedure was in proc, asserting that the call actually returned at least one value. Afterwards, resets the frame to nlocals locals.
f24:proc b1:allow-extra? x7:_ c24:nvalues
¶Receive a return of multiple values from a call whose procedure was in
proc. If fewer than nvalues values were returned, signal an
error. Unless allow-extra? is true, require that the number of
return values equals nvalues exactly. After receive-values
has run, the values can be copied down via mov
, or used in place.