The bytecodes interpreter uses a stack of its own to save and restore values from intermediate calculations. This Forth-like data stack is also used in other parts of the C kernel for various purposes, such as saving compiled code, keeping arguments to FORMAT, etc.
However, one of the most important roles of the Interpreter Stack is to keep a log of the functions which are called during the execution of bytecodes. For each function invoked, the interpreter keeps three lisp objects on the stack:
+----------+------------------------------------------------+ | function | lexical environment | index to previous record | +----------+---------------------+--------------------------+
The first item is the object which is funcalled. It can be a bytecodes object, a compiled function or a generic function. In the last two cases the lexical environment is just NIL. In the first case, the second item on the stack is the lexical environment on which the code is executed. Each of these records are popped out of the stack after function invocation.
Let us see how these invocation records are used for debugging.
>(defun fact (x) ;;; Wrong definition of the (if (= x 0) ;;; factorial function. one ;;; one should be 1. (* x (fact (1- x))))) FACT >(fact 3) ;;; Tries 3! Error: The variable ONE is unbound. Error signalled by IF. Broken at IF. >>:b ;;; Backtrace. Backtrace: eval > fact > if > fact > if > fact > if > fact > IF ;;; Currently at the last IF. >>:h ;;; Help. Break commands: :q(uit) Return to some previous break level. :pop Pop to previous break level. :c(ontinue) Continue execution. :b(acktrace) Print backtrace. :f(unction) Show current function. :p(revious) Go to previous function. :n(ext) Go to next function. :g(o) Go to next function. :fs Search forward for function. :bs Search backward for function. :v(ariables) Show local variables, functions, blocks, and tags. :l(ocal) Return the nth local value on the stack. :hide Hide function. :unhide Unhide function. :hp Hide package. :unhp Unhide package. :unhide-all Unhide all variables and packages. :bds Show binding stack. :m(essage) Show error message. :hs Help stack. Top level commands: :cf Compile file. :exit or ^D Exit Lisp. :ld Load file. :step Single step form. :tr(ace) Trace function. :untr(ace) Untrace function. Help commands: :apropos Apropos. :doc(ument) Document. :h(elp) or ? Help. Type ":help help" for more information. >>:p ;;; Move to the last call of FACT. Broken at IF. >>:b Backtrace: eval > fact > if > fact > if > fact > if > FACT > if ;;; Now at the last FACT. >>:v ;;; The environment at the last call Local variables: ;;; to FACT is recovered. X: 0 ;;; X is the only bound variable. Block names: FACT. ;;; The block FACT is established. >>x 0 ;;; The value of x is 0. >>(return-from fact 1) ;;; Return from the last call of 6 ;;; FACT with the value of 0. ;;; The execution is resumed and > ;;; the value 6 is returned. ;;; Again at the top-level loop.