Function Prologue Instructions

A function call in Guile is very cheap: the VM simply hands control to the procedure. The procedure itself is responsible for asserting that it has been passed an appropriate number of arguments. This strategy allows arbitrarily complex argument parsing idioms to be developed, without harming the common case.

For example, only calls to keyword-argument procedures “pay” for the cost of parsing keyword arguments. (At the time of this writing, calling procedures with keyword arguments is typically two to four times as costly as calling procedures with a fixed set of arguments.)

Instruction: assert-nargs-ee c24:expected
Instruction: assert-nargs-ge c24:expected
Instruction: assert-nargs-le c24:expected

If the number of actual arguments is not ==, >=, or <= expected, respectively, signal an error.

The number of arguments is determined by subtracting the stack pointer from the frame pointer (fp - sp). See Stack Layout, for more details on stack frames. Note that expected includes the procedure itself.

Instruction: arguments<=? c24:expected

Set the LESS_THAN, EQUAL, or NONE comparison result values if the number of arguments is respectively less than, equal to, or greater than expected.

Instruction: positional-arguments<=? c24:nreq x8:_ c24:expected

Set the LESS_THAN, EQUAL, or NONE comparison result values if the number of positional arguments is respectively less than, equal to, or greater than expected. The first nreq arguments are positional arguments, as are the subsequent arguments that are not keywords.

The arguments<=? and positional-arguments<=? instructions are used to implement multiple arities, as in case-lambda. See Case-lambda, for more information. See Branch Instructions, for more on comparison results.

Instruction: bind-kwargs c24:nreq c8:flags c24:nreq-and-opt x8:_ c24:ntotal n32:kw-offset

flags is a bitfield, whose lowest bit is allow-other-keys, second bit is has-rest, and whose following six bits are unused.

Find the last positional argument, and shuffle all the rest above ntotal. Initialize the intervening locals to SCM_UNDEFINED. Then load the constant at kw-offset words from the current ip, and use it and the allow-other-keys flag to bind keyword arguments. If has-rest, collect all shuffled arguments into a list, and store it in nreq-and-opt. Finally, clear the arguments that we shuffled up.

The parsing is driven by a keyword arguments association list, looked up using kw-offset. The alist is a list of pairs of the form (kw . index), mapping keyword arguments to their local slot indices. Unless allow-other-keys is set, the parser will signal an error if an unknown key is found.

A macro-mega-instruction.

Instruction: bind-optionals f24:nlocals

Expand the current frame to have at least nlocals locals, filling in any fresh values with SCM_UNDEFINED. If the frame has more than nlocals locals, it is left as it is.

Instruction: bind-rest f24:dst

Collect any arguments at or above dst into a list, and store that list at dst.

Instruction: alloc-frame c24:nlocals

Ensure that there is space on the stack for nlocals local variables. The value of any new local is undefined.

Instruction: reset-frame c24:nlocals

Like alloc-frame, but doesn’t check that the stack is big enough, and doesn’t initialize values to SCM_UNDEFINED. Used to reset the frame size to something less than the size that was previously set via alloc-frame.

Instruction: assert-nargs-ee/locals c12:expected c12:nlocals

Equivalent to a sequence of assert-nargs-ee and allocate-frame. The number of locals reserved is expected + nlocals.