BLOCK
and RETURN-FROM
TAGBODY
and GO
CATCH
and THROW
UNWIND-PROTECT
HANDLER-BIND
mnemonic | description | semantics |
---|---|---|
( | Load NIL into values . | value1 := NIL , mv_count := 1 |
(PUSH-NIL | Push n NIL s into the STACK . | n times do: *--STACK := NIL ,
Invalidate values . |
( | Load T into values . | value1 := T , mv_count := 1 |
(CONST | Load the function's n th constant into values . | value1 := consts [n ],
mv_count := 1 |
mnemonic | description | semantics |
---|---|---|
(LOAD | Load a directly accessible local variable into values . | value1 := *(STACK +n ),
mv_count := 1 |
(LOADI | Load an indirectly accessible local variable into values . | k := k1 + jmpbufsize * k2 ,
value1 := *(*(SP +k )+ n ),
mv_count := 1 |
(LOADC | Load a closed-up variable, defined in the same function and
directly accessible, into values . | value1 := SVREF (*(STACK +n ),1+m ),
mv_count := 1 |
(LOADV | Load a closed-up variable, defined in an outer function,
into values . | v := venv-const ,
m times do: v := SVREF (v ,0),
value1 := SVREF (v ,m ),
mv_count := 1 |
(LOADIC | Load a closed-up variable, defined in the same function and
indirectly accessible, into values . | k := k1 + jmpbufsize * k2 ,
value1 := SVREF (*(*(SP +k )+n ),1+m ),
mv_count := 1 |
(STORE | Store values into a directly accessible local variable. | *(STACK +n ) := value1 ,
mv_count := 1 |
(STOREI | Store values into an indirectly accessible local variable. | k := k1 + jmpbufsize * k2 ,
*(*(SP +k )+ n ) := value1 ,
mv_count := 1 |
(STOREC | Store values into a closed-up variable, defined in the same function and directly accessible. | SVREF (*(STACK +n ),1+m) := value1 ,
mv_count := 1 |
(STOREV | Store values into a closed-up variable, defined in an outer function. | v := venv-const ,
m times do: v := SVREF (v ,0),
SVREF (v ,m ) := value1 ,
mv_count := 1 |
(STOREIC | Store values into a closed-up variable, defined in the same function and indirectly accessible. | k := k1 + jmpbufsize * k2 ,
SVREF (*(*(SP +k )+n ),1+m ) := value1 ,
mv_count := 1 |
mnemonic | description | semantics |
---|---|---|
(GETVALUE | Load a symbol's value into values . | value1 := symbol-value(consts [n ]),
mv_count := 1 |
(SETVALUE | Store values into a symbol's value. | symbol-value(consts [n ]) := value1 ,
mv_count := 1 |
(BIND | Bind a symbol dynamically. | Bind the value of the symbol
consts [n ] to value1 ,
implicitly STACK -= 3,
Invalidate values . |
(UNBIND1) | Dissolve one binding frame. | Unbind the binding frame STACK is pointing to,
implicitly STACK += 3 |
(UNBIND | Dissolve n binding frames. | n times do:
Unbind the binding frame STACK is pointing to, thereby
incrementing STACK
Thus, STACK += 1+2*n |
(PROGV) | Bind a set of symbols dynamically to a set of values. | symbols := *STACK ++,
*--SP := STACK ,
build a single binding frame binding the symbols in
symbols to the values in value1 ,
Invalidate values . |
mnemonic | description | semantics |
---|---|---|
(PUSH) | Push one object onto the STACK . | *--STACK := value1 ,
Invalidate values . |
(POP) | Pop one object from the STACK , into values . | value1 := *STACK ++, mv_count := 1 |
(SKIP | Restore a previous STACK pointer.
Remove n objects from the STACK . | STACK := STACK + n |
(SKIPI | Restore a previous STACK pointer. Remove an unknown
number of objects from the STACK . | k := k1 + jmpbufsize * k2 ,
STACK := *(SP +k ),
SP := SP +k +1,
STACK := STACK + n |
(SKIPSP | Restore a previous SP pointer. | k := k1 + jmpbufsize * k2 ,
SP := SP +k |
mnemonic | description | semantics |
---|---|---|
(SKIP&RET | Clean up the STACK , and return from the function. | STACK := STACK +n ,
return from the function, returning values. |
(SKIP&RETGF | Clean up the STACK , and return from the generic
function. | If bit 3 is set in the function's flags ,
then STACK := STACK +n , mv_count := 1,
and return from the function.
Otherwise: if the current function has no &REST argument,
then STACK := STACK +n -numreq ,
apply value1 to the numreq arguments
still on the STACK , and
return from the function.
Else STACK := STACK +n -numreq -1,
apply value1 to the numreq arguments and the
&REST argument, all still on the STACK , and
return from the function. |
(JMP | Jump to label . | PC := label . |
(JMPIF | Jump to label , if value1 is true. | If value1 is not NIL , PC := label . |
(JMPIFNOT | Jump to label , if value1 is false. | If value1 is NIL , PC := label . |
(JMPIF1 | Jump to label and forget secondary values,
if value1 is true. | If value1 is not NIL ,
mv_count := 1, PC := label . |
(JMPIFNOT1 | Jump to label and forget secondary values,
if value1 is false. | If value1 is NIL ,
mv_count := 1, PC := label . |
(JMPIFATOM | Jump to label , if value1 is not a cons. | If value1 is not a cons, PC := label .
Invalidate values . |
(JMPIFCONSP | Jump to label , if value1 is a cons. | If value1 is a cons, PC := label .
Invalidate values . |
(JMPIFEQ | Jump to label , if value1 is EQ to the top-of-stack. | If eq(value1 ,*STACK ++), PC := label .
Invalidate values . |
(JMPIFNOTEQ | Jump to label , if value1 is not EQ
to the top-of-stack. | If not eq(value1 ,*STACK ++), PC := label .
Invalidate values . |
(JMPIFEQTO | Jump to label ,
if the top-of-stack is EQ to a constant. | If eq(*STACK ++,consts [n ]), PC := label .
Invalidate values . |
(JMPIFNOTEQTO | Jump to label , if the top-of-stack is not EQ
to a constant. | If not eq(*STACK ++,consts [n ]), PC := label .
Invalidate values . |
(JMPHASH | Table-driven jump, depending on value1 . | Lookup value1 in the hash table consts [n ].
(The hash table's test is either EQ or EQL .)
If found, the hash table value is a signed FIXNUM ,
jump to it: PC := PC + value. Else jump to label .
Invalidate values . |
(JMPHASHV | Table-driven jump, depending on value1 ,
inside a generic function. | Lookup value1 in the hash table SVREF (consts [0],n ).
(The hash table's test is either EQ or EQL .)
If found, the hash table value is a signed FIXNUM ,
jump to it: PC := PC + value. Else jump to label .
Invalidate values . |
(JSR | Subroutine call. | *--STACK := function. Then start interpreting the
bytecode at label , with values undefined.
When a (RET) is encountered,
program execution is resumed at the instruction after
(JSR . |
(JMPTAIL | Tail subroutine call. | n >= m .
The STACK frame of size n is reduced to size m :
{*(STACK +n -m ), ..., *(STACK +n -1)} :=
{*STACK , ..., *(STACK +m -1)}.
STACK += n-m.
*--STACK := function.
Then jump to label , with values undefined. |
mnemonic | description | semantics |
---|---|---|
(VENV) | Load the venv-const into values . | value1 := consts [0], mv_count := 1. |
(MAKE-VECTOR1&PUSH | Create a SIMPLE-VECTOR used for closed-up variables. | v := new SIMPLE-VECTOR of size n +1.
SVREF (v ,0) := value1 .
*--STACK := v . Invalidate values . |
(COPY-CLOSURE | Create a closure by copying the prototype and filling in the lexical environment. | f := copy-function(consts [m ]).
For i =0,..,n -1:
f _consts [i] := *(STACK +n -1-i ).
STACK += n .
value1 := f , mv_count := 1 |
mnemonic | description | semantics |
---|---|---|
(CALL | Calls a constant function with k arguments. | The function consts [n ] is called
with the arguments *(STACK +k -1), ..., *(STACK +0).
STACK += k . The returned values go into values . |
(CALL0 | Calls a constant function with 0 arguments. | The function consts [n ] is called with 0 arguments.
The returned values go into values . |
(CALL1 | Calls a constant function with 1 argument. | The function consts [n ] is called with one argument *STACK .
STACK += 1. The returned values go into values . |
(CALL2 | Calls a constant function with 2 arguments. | The function consts [n ] is called
with two arguments *(STACK +1) and *(STACK +0).
STACK += 2. The returned values go into values . |
(CALLS1 | Calls a system function with no &REST . | Calls the system function FUNTAB [b ].
The right number of arguments is already on the STACK
(including #<UNBOUND> s in place of absent &OPTIONAL or
&KEY parameters).
The arguments are removed from the STACK . The returned values go into values . |
(CALLS2 | Calls a system function with no &REST . | Calls the system function FUNTAB [256+b ].
The right number of arguments is already on the STACK
(including #<UNBOUND> s in place of absent &OPTIONAL or
&KEY parameters).
The arguments are removed from the STACK . The returned values go into values . |
(CALLSR | Calls a system function with &REST . | Calls the system function FUNTAB R[b ].
The minimum number of arguments is already on the STACK ,
and m additional arguments as well.
The arguments are removed from the STACK . The returned values go into values . |
(CALLC) | Calls a computed compiled function with no &KEY s. | Calls the compiled function value1 .
The right number of arguments is already on the STACK
(including #<UNBOUND> s in place of absent &OPTIONAL
parameters).
The arguments are removed from the STACK . The returned values go into values . |
(CALLCKEY) | Calls a computed compiled function with &KEY s. | Calls the compiled function value1 .
The right number of arguments is already on the STACK
(including #<UNBOUND> s in place of absent &OPTIONAL
or &KEY parameters).
The arguments are removed from the STACK . The returned values go into values . |
(FUNCALL | Calls a computed function. | Calls the function *(STACK +n )
with the arguments *(STACK +n -1), ..., *(STACK +0).
STACK += n +1. The returned values go into values . |
(APPLY | Calls a computed function with an unknown number of arguments. | Calls the function *(STACK +n )
with the arguments *(STACK +n -1), ..., *(STACK +0)
and a list of additional arguments value1 .
STACK += n +1. The returned values go into values . |
mnemonic | description | semantics |
---|---|---|
(PUSH-UNBOUND | Push n #<UNBOUND> s into the STACK . | n times do: *--STACK := #<UNBOUND> .
Invalidate values . |
(UNLIST | Destructure a proper LIST . | 0 ≤ m ≤ n .
n times do: *--STACK := CAR (value1 ),
value1 := CDR (value1 ).
During the last m iterations, the list value1
may already have reached its end;
in this case, *--STACK := #<UNBOUND> .
At the end, value1 must be NIL .
Invalidate values . |
(UNLIST* | Destructure a proper or dotted LIST . | 0 ≤ m ≤ n , n > 0.
n times do: *--STACK := CAR (value1 ),
value1 := CDR (value1 ).
During the last m iterations, the list value1
may already have reached its end;
in this case, *--STACK := #<UNBOUND> .
At the end, after n CDR s, *--STACK := value1 .
Invalidate values . |
(JMPIFBOUNDP | Jump to label , if a local variable is not unbound. | If *(STACK +n ) is not #<UNBOUND> ,
value1 := *(STACK +n ), mv_count := 1, PC := label .
Else: Invalidate values .. |
(BOUNDP | Load T or NIL into values , depending on whether a local
variable is bound. | If *(STACK +n ) is not #<UNBOUND> ,
value1 := T , mv_count := 1.
Else: value1 := NIL , mv_count := 1. |
(UNBOUND->NIL | If a local variable is unbound, assign a default value
NIL to it. | If *(STACK +n ) is #<UNBOUND> ,
*(STACK +n ) := NIL . |
mnemonic | description | semantics |
---|---|---|
(VALUES0) | Load no values into values . | value1 := NIL , mv_count := 0 |
(VALUES1) | Forget secondary values. | mv_count := 1 |
( | Pop the first n objects from STACK into values . | Load values(*(STACK +n -1),...,*(STACK +0)) into
values. STACK += n . |
(MV-TO- | Save values on STACK . | Push the mv_count values onto the STACK
(in order: value1 comes first).
STACK -= mv_count . Invalidate values . |
(NV-TO- | Save n values on STACK . | Push the first n values onto the STACK
(in order: value1 comes first).
STACK -= n . Invalidate values . |
(MV-TO-LIST) | Convert multiple values into a list. | value1 := list of values, mv_count := 1 |
(LIST-TO-MV) | Convert a LIST into multiple values. | Call the function VALUES-LIST with value1 as argument.
The returned values go into values . |
(MVCALLP) | Start a MULTIPLE-VALUE-CALL invocation. | *--SP := STACK . *--STACK := value1 . |
(MVCALL) | Finish a MULTIPLE-VALUE-CALL invocation. | newSTACK := *SP ++.
Call the function *(newSTACK-1), passing it
*(newSTACK-2), ..., *(STACK +0) as arguments.
STACK := newSTACK. The returned values go into values . |
BLOCK
and RETURN-FROM
mnemonic | description | semantics |
---|---|---|
(BLOCK-OPEN | Create a BLOCK frame. | Create a BLOCK frame, STACK -= 3, SP -= 2+jmpbufsize .
The topmost (third) object in the block frame is
CONS (consts [n ],frame-pointer) (its block-cons ).
Upon a RETURN-FROM to this frame, execution will continue at label .
Invalidate values .. |
(BLOCK-CLOSE) | Dissolve a BLOCK frame. | Dissolve the BLOCK frame at STACK , STACK += 3,
SP += 2+jmpbufsize . Mark the block-cons as invalid. |
(RETURN-FROM | Leave a BLOCK whose block-cons is given. | block-cons := consts [n ].
If CDR (block-cons ) = #<DISABLED> , an ERROR is SIGNAL ed.
Else CDR (block-cons ) is a frame-pointer.
Unwind the stack up to this frame, pass it values. |
(RETURN-FROM-I | Leave a BLOCK whose block-cons is indirectly accessible. | k := k1 + jmpbufsize * k2 ,
block-cons := *(*(SP +k )+n ).
If CDR (block-cons ) = #<DISABLED> , an ERROR is SIGNAL ed.
Else CDR (block-cons ) is a frame-pointer.
Unwind the stack up to this frame, pass it values. |
mnemonic | description | semantics |
---|---|---|
(TAGBODY-OPEN | Create a TAGBODY frame. | Fetch consts [m ], this is a SIMPLE-VECTOR with
n elements, then decode n label operands.
Create a TAGBODY frame, STACK -= 3+n , SP -= 1+jmpbufsize .
The third object in the TAGBODY frame is
CONS (consts [m ],frame-pointer) (the tagbody-cons )
Upon a GO to tag label of this frame, execution
will continue at labell .
Invalidate values . |
(TAGBODY-CLOSE-NIL) | Dissolve a TAGBODY frame, and load NIL into values . | Dissolve the TAGBODY frame at STACK ,
STACK += 3+m , SP += 1+jmpbufsize .
Mark the tagbody-cons as invalid.
value1 := NIL , mv_count := 1. |
(TAGBODY-CLOSE) | Dissolve a TAGBODY frame. | Dissolve the TAGBODY frame at STACK ,
STACK += 3+m , SP += 1+jmpbufsize .
Mark the tagbody-cons as invalid. |
(GO | Jump into a TAGBODY whose tagbody-cons is given. | tagbody-cons := consts [n ].
If CDR (tagbody-cons ) = #<DISABLED> , an ERROR is SIGNAL ed.
Else CDR (tagbody-cons ) is a frame-pointer. Unwind the stack up
to this frame, pass it the number label . |
(GO-I | Jump into a TAGBODY whose tagbody-cons is indirectly
accessible. | k := k1 + jmpbufsize * k2 ,
tagbody-cons := *(*(SP +k )+n ).
If CDR (tagbody-cons ) = #<DISABLED> , an ERROR is SIGNAL ed.
Else CDR (tagbody-cons ) is a frame-pointer. Unwind the stack up
to this frame, pass it the number label . |
mnemonic | description | semantics |
---|---|---|
(CATCH-OPEN | Create a CATCH frame. | Create a CATCH frame, with value1 as tag.
STACK -= 3, SP -= 2+jmpbufsize .
Upon a THROW to this tag execution continues at
label . |
(CATCH-CLOSE) | Dissolve a CATCH frame. | Dissolve the CATCH frame at STACK .
STACK += 3, SP += 2+jmpbufsize . |
(THROW) | Non-local exit to a CATCH frame. | tag := *STACK ++.
Search the innermost CATCH frame with tag
tag on the STACK , unwind the
stack up to it, pass it values. |
UNWIND-PROTECT
mnemonic | description | semantics |
---|---|---|
(UNWIND-PROTECT-OPEN
| Create an UNWIND-PROTECT frame. | Create an UNWIND-PROTECT frame.
STACK -= 2, SP -= 2+jmpbufsize .
When the stack will be unwound by a non-local exit,
values will be saved on STACK , and execution will be
transferred to label . |
(UNWIND-PROTECT-NORMAL-EXIT) | Dissolve an UNWIND-PROTECT frame, and start the cleanup
code. | Dissolve the UNWIND-PROTECT frame at STACK .
STACK += 2, SP += 2+jmpbufsize .
*--SP := 0, *--SP := 0, *--SP := STACK .
Save the values on the STACK ,
STACK -= mv_count . |
(UNWIND-PROTECT-CLOSE) | Terminate the cleanup code. | newSTACK := *SP ++. Load
values(*(newSTACK-1), ..., *(STACK +0)) into values .
STACK := newSTACK. SPword1 := *SP ++, SPword2 := *SP ++.
Continue depending on SPword1 and SPword2.
If both are 0, simply continue execution.
If SPword2 is 0 but SPword1 is nonzero, interpret it as a
label and jump to it. |
(UNWIND-PROTECT-CLEANUP) | Dissolve an UNWIND-PROTECT frame, and execute the cleanup
code like a subroutine call. | Dissolve the UNWIND-PROTECT frame at STACK ,
get label out of the frame.
STACK += 2, SP += 2+jmpbufsize .
*--SP := 0, *--SP := PC, *--SP := STACK .
Save the values on the STACK , STACK -= mv_count .
PC := label . |
HANDLER-BIND
mnemonic | description | semantics |
---|---|---|
(HANDLER-OPEN | Create a handler frame. | Create a handler frame, using consts [n ] which
contains the CONDITION types, the corresponding labels and
the current SP depth (= function entry SP - current SP ).
|
(HANDLER-BEGIN&PUSH) | Start a handler. | Restore the same SP state as after the HANDLER-OPEN.
value1 := the CONDITION that was passed to the handler,
mv_count := 1.
*--STACK := value1 . |
mnemonic | description | semantics |
---|---|---|
(NOT) | Inlined call to NOT . | value1 := not(value1 ), mv_count := 1. |
(EQ) | Inlined call to EQ . | value1 := eq(*STACK ++,value1 ),
mv_count := 1. |
(CAR) | Inlined call to CAR . | value1 := CAR (value1 ), mv_count := 1. |
(CDR) | Inlined call to CDR . | value1 := CDR (value1 ), mv_count := 1. |
(CONS) | Inlined call to CONS . | value1 := cons(*STACK ++,value1 ),
mv_count := 1. |
(SYMBOL-FUNCTION) | Inlined call to SYMBOL-FUNCTION . | value1 := SYMBOL-FUNCTION (value1 ),
mv_count := 1. |
(SVREF) | Inlined call to SVREF . | value1 := SVREF (*STACK ++,value1 ),
mv_count := 1. |
(SVSET) | Inlined call to ( . | arg1 := *(STACK +1),
arg2 := *(STACK +0), STACK += 2.
SVREF (arg2 ,value1 ) :=
arg1 .
value1 := arg1 ,
mv_count := 1. |
(LIST | Inlined call to LIST . | value1 := LIST (*(STACK +n -1),...,*(STACK +0)),
mv_count := 1, STACK += n . |
(LIST* | Inlined call to LIST* . | value1 := LIST* (*(STACK +n -1),...,
*(STACK +0),value1 ),
mv_count := 1, STACK += n . |
The most frequent short sequences of instructions have an
equivalent combined instruction. They are only present for space and
speed optimization. The only exception is
FUNCALL&SKIP&RETGF
, which is needed for
generic functions.
mnemonic | equivalent |
---|---|
(NIL&PUSH) | (NIL) (PUSH) |
(T&PUSH) | (T) (PUSH) |
(CONST&PUSH | (CONST |
(LOAD&PUSH | (LOAD |
(LOADI&PUSH | (LOADI |
(LOADC&PUSH | (LOADC |
(LOADV&PUSH | (LOADV |
(POP&STORE | (POP) (STORE |
(GETVALUE&PUSH | (GETVALUE |
(JSR&PUSH | (JSR |
(COPY-CLOSURE&PUSH | (COPY-CLOSURE |
(CALL&PUSH | (CALL |
(CALL1&PUSH | (CALL1 |
(CALL2&PUSH | (CALL2 |
(CALLS1&PUSH | (CALLS1 |
(CALLS2&PUSH | (CALLS2 |
(CALLSR&PUSH | (CALLSR |
(CALLC&PUSH) | (CALLC) (PUSH) |
(CALLCKEY&PUSH) | (CALLCKEY) (PUSH) |
(FUNCALL&PUSH | (FUNCALL |
(APPLY&PUSH | (APPLY |
(CAR&PUSH) | (CAR) (PUSH) |
(CDR&PUSH) | (CDR) (PUSH) |
(CONS&PUSH) | (CONS) (PUSH) |
(LIST&PUSH | (LIST |
(LIST*&PUSH | (LIST* |
(NIL&STORE | (NIL) (STORE |
(T&STORE | (T) (STORE |
(LOAD&STOREC | (LOAD |
(CALLS1&STORE | (CALLS1 |
(CALLS2&STORE | (CALLS2 |
(CALLSR&STORE | (CALLSR |
(LOAD&CDR&STORE | (LOAD |
(LOAD&CONS&STORE | (LOAD |
(LOAD&INC&STORE | (LOAD |
(LOAD&DEC&STORE | (LOAD |
(LOAD&CAR&STORE | (LOAD |
(CALL1&JMPIF | (CALL1 |
(CALL1&JMPIFNOT | (CALL1 |
(CALL2&JMPIF | (CALL2 |
(CALL2&JMPIFNOT | (CALL2 |
(CALLS1&JMPIF | (CALLS1 |
(CALLS1&JMPIFNOT | (CALLS1 |
(CALLS2&JMPIF | (CALLS2 |
(CALLS2&JMPIFNOT | (CALLS2 |
(CALLSR&JMPIF | (CALLSR |
(CALLSR&JMPIFNOT | (CALLSR |
(LOAD&JMPIF | (LOAD |
(LOAD&JMPIFNOT | (LOAD |
(LOAD&CAR&PUSH | (LOAD |
(LOAD&CDR&PUSH | (LOAD |
(LOAD&INC&PUSH | (LOAD |
(LOAD&DEC&PUSH | (LOAD |
(CONST&SYMBOL-FUNCTION | (CONST |
(CONST&SYMBOL-FUNCTION&PUSH | (CONST |
(CONST&SYMBOL-FUNCTION&STORE | (CONST |
(APPLY&SKIP&RET | (APPLY |
(FUNCALL&SKIP&RETGF | (FUNCALL |
These notes document CLISP version 2.49.93+ | Last modified: 2018-02-19 |