guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. release_1-9-8-95-gf11


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-8-95-gf11871d
Date: Sun, 14 Mar 2010 22:27:33 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=f11871d6c557e706b80e7fa6c0c1f1da854fe1c4

The branch, master has been updated
       via  f11871d6c557e706b80e7fa6c0c1f1da854fe1c4 (commit)
       via  7e08f8a6c16ef88ecca8895e81219b040593c212 (commit)
       via  42ee0d00ba61e51a5b4a9f2d59e6f95b52e49dbf (commit)
       via  42cb9b03111ccddb4abcf25004c4bd8bd069390f (commit)
      from  5c43d9c78388a3545bbd841f6ab37f6c3adfb4a7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f11871d6c557e706b80e7fa6c0c1f1da854fe1c4
Author: Andy Wingo <address@hidden>
Date:   Sun Mar 14 23:28:26 2010 +0100

    small vm.texi updates
    
    * doc/ref/vm.texi (A Virtual Machine for Guile):
      (VM Concepts, Variables and the VM, Branch Instructions): Small
      updates.

commit 7e08f8a6c16ef88ecca8895e81219b040593c212
Author: Andy Wingo <address@hidden>
Date:   Sun Mar 14 23:09:56 2010 +0100

    add some vm hook docs
    
    * doc/ref/api-evaluation.texi (VM Behaviour): Add docs for
      vm-trace-level and set-vm-trace-level!.

commit 42ee0d00ba61e51a5b4a9f2d59e6f95b52e49dbf
Author: Andy Wingo <address@hidden>
Date:   Sun Mar 14 23:06:58 2010 +0100

    (debug) at the repl invokes the vm debugger
    
    * module/ice-9/boot-9.scm (top-repl): Map (debug) at the repl to (system
      vm debug).
    
    * module/system/vm/debug.scm (run-debugger, debugger-repl): Don't take
      the index as an arg, for now anyway.
      (debug): New wrapper.

commit 42cb9b03111ccddb4abcf25004c4bd8bd069390f
Author: Andy Wingo <address@hidden>
Date:   Sun Mar 14 23:05:42 2010 +0100

    Update api-debug.texi; there is a ways to go.
    
    * doc/ref/api-debug.texi: Update a bit.

-----------------------------------------------------------------------

Summary of changes:
 doc/ref/api-debug.texi      |  302 +++++++++++++-----------------------------
 doc/ref/api-evaluation.texi |    9 ++
 doc/ref/vm.texi             |   79 ++++++------
 module/ice-9/boot-9.scm     |    2 +-
 module/system/vm/debug.scm  |   23 ++-
 5 files changed, 159 insertions(+), 256 deletions(-)

diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
index 3c9ec11..747ac45 100644
--- a/doc/ref/api-debug.texi
+++ b/doc/ref/api-debug.texi
@@ -10,9 +10,9 @@
 
 @cindex Debugging
 In order to understand Guile's debugging facilities, you first need to
-understand a little about how the evaluator works and what the Scheme
-stack is.  With that in place we explain the low level trap calls that
-the evaluator can be configured to make, and the trap and breakpoint
+understand a little about how Guile represent the Scheme control stack.
+With that in place we explain the low level trap calls that the
+evaluator can be configured to make, and the trap and breakpoint
 infrastructure that builds on top of those calls.
 
 @menu
@@ -25,41 +25,31 @@ infrastructure that builds on top of those calls.
 @node Evaluation Model
 @subsection Evaluation and the Scheme Stack
 
-The idea of the Scheme stack is central to a lot of debugging.  It
-always exists implicitly, as a result of the way that the Guile
-evaluator works, and can be summoned into concrete existence as a
-first-class Scheme value by the @code{make-stack} call, so that an
-introspective Scheme program -- such as a debugger -- can present it in
-some way and allow the user to query its details.  The first thing to
-understand, therefore, is how the workings of the evaluator build up the
-stack.
-
address@hidden Evaluations
address@hidden Applications
-Broadly speaking, the evaluator performs @dfn{evaluations} and
address@hidden  An evaluation means that it is looking at a source
-code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
-whether the top level of the expression is a procedure call, macro,
-builtin syntax, or whatever, and doing some appropriate processing in
-each case.  (In the examples here, @code{(+ x 5)} would normally be a
-procedure call, and @code{(if msg (loop))} builtin syntax.)  For a
-procedure call, ``appropriate processing'' includes evaluating the
-procedure's arguments, as that must happen before the procedure itself
-can be called.  An application means calling a procedure once its
-arguments have been calculated.
-
address@hidden Stack
address@hidden Frames
address@hidden Stack frames
-Typically evaluations and applications alternate with each other, and
-together they form a @dfn{stack} of operations pending completion.  This
-is because, on the one hand, evaluation of an expression like @code{(+ x
-5)} requires --- once its arguments have been calculated --- an
-application (in this case, of the procedure @code{+}) before it can
-complete and return a result, and, on the other hand, the application of
-a procedure written in Scheme involves evaluating the sequence of
-expressions that constitute that procedure's code.  Each level on this
-stack is called a @dfn{frame}.
+The idea of the Scheme stack is central to a lot of debugging.  The
+Scheme stack is a reified representation of the pending function returns
+in an expression's continuation. As Guile implements function calls
+using a stack, this reification takes the form of a number of nested
+stack frames, each of which has the procedure and its arguments, along
+with local variables and temporary values.
+
+A Scheme stack always exists implicitly, and can be summoned into
+concrete existence as a first-class Scheme value by the
address@hidden call, so that an introspective Scheme program -- such
+as a debugger -- can present it in some way and allow the user to query
+its details. The first thing to understand, therefore, is how Guile's
+function call convention creates the stack.
+
+Broadly speaking, Guile represents all control flow on a stack. Calling
+a function involves pushing an empty frame on the stack, then evaluating
+the procedure and its arguments, then fixing up the new frame so that it
+points to the old one. Frames on the stack are thus linked together. A
+tail call is the same, except it reuses the existing frame instead of
+pushing on a new one.
+
+In this way, the only frames that are on the stack are ``active''
+frames, frames which need to do some work before the computation is
+complete. On the other hand, a function that has tail-called another
+function will not be on the stack, as it has no work left to do.
 
 Therefore, when an error occurs in a running program, or the program
 hits a breakpoint, or in fact at any point that the programmer chooses,
@@ -74,7 +64,6 @@ stack and its frames.
 * Examining the Stack::
 * Examining Stack Frames::
 * Source Properties::           Remembering the source of an expression.
-* Decoding Memoized Source Expressions::
 * Starting a New Stack::
 @end menu
 
@@ -96,10 +85,10 @@ describes the Scheme stack at that point.
 Create a new stack. If @var{obj} is @code{#t}, the current
 evaluation stack is used for creating the stack frames,
 otherwise the frames are taken from @var{obj} (which must be
-either a debug object or a continuation).
+a continuation or a frame object).
 
 @var{args} should be a list containing any combination of
-integer, procedure and @code{#t} values.
+integer, procedure, prompt tag and @code{#t} values.
 
 These values specify various ways of cutting away uninteresting
 stack frames from the top and bottom of the stack that
@@ -107,28 +96,26 @@ stack frames from the top and bottom of the stack that
 @code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
 @var{outer_cut_2} @dots{})}.
 
-Each @var{inner_cut_N} can be @code{#t}, an integer, or a
-procedure.  @code{#t} means to cut away all frames up to but
-excluding the first user module frame.  An integer means to cut
-away exactly that number of frames.  A procedure means to cut
-away all frames up to but excluding the application frame whose
+Each @var{inner_cut_N} can be @code{#t}, an integer, a prompt
+tag, or a procedure.  @code{#t} means to cut away all frames up
+to but excluding the first user module frame.  An integer means
+to cut away exactly that number of frames.  A prompt tag means
+to cut away all frames that are inside a prompt with the given
+tag. A procedure means to cut away all frames up to but
+excluding the application frame whose procedure matches the
+specified one.
+
+Each @var{outer_cut_N} can be an integer, a prompt tag, or a
+procedure.  An integer means to cut away that number of frames.
+A prompt tag means to cut away all frames that are outside a
+prompt with the given tag. A procedure means to cut away
+frames down to but excluding the application frame whose
 procedure matches the specified one.
 
-Each @var{outer_cut_N} can be an integer or a procedure.  An
-integer means to cut away that number of frames.  A procedure
-means to cut away frames down to but excluding the application
-frame whose procedure matches the specified one.
-
 If the @var{outer_cut_N} of the last pair is missing, it is
 taken as 0.
 @end deffn
 
address@hidden {Scheme Procedure} last-stack-frame obj
address@hidden {C Function} scm_last_stack_frame (obj)
-Return the last (innermost) frame of @var{obj}, which must be
-either a debug object or a continuation.
address@hidden deffn
-
 
 @node Examining the Stack
 @subsubsection Examining the Stack
@@ -175,33 +162,12 @@ backtrace.
 Return @code{#t} if @var{obj} is a stack frame.
 @end deffn
 
address@hidden {Scheme Procedure} frame-number frame
address@hidden {C Function} scm_frame_number (frame)
-Return the frame number of @var{frame}.
address@hidden deffn
-
 @deffn {Scheme Procedure} frame-previous frame
 @deffnx {C Function} scm_frame_previous (frame)
 Return the previous frame of @var{frame}, or @code{#f} if
 @var{frame} is the first frame in its stack.
 @end deffn
 
address@hidden {Scheme Procedure} frame-next frame
address@hidden {C Function} scm_frame_next (frame)
-Return the next frame of @var{frame}, or @code{#f} if
address@hidden is the last frame in its stack.
address@hidden deffn
-
address@hidden {Scheme Procedure} frame-source frame
address@hidden {C Function} scm_frame_source (frame)
-Return the source of @var{frame}.
address@hidden deffn
-
address@hidden {Scheme Procedure} frame-procedure? frame
address@hidden {C Function} scm_frame_procedure_p (frame)
-Return @code{#t} if a procedure is associated with @var{frame}.
address@hidden deffn
-
 @deffn {Scheme Procedure} frame-procedure frame
 @deffnx {C Function} scm_frame_procedure (frame)
 Return the procedure for @var{frame}, or @code{#f} if no
@@ -213,21 +179,6 @@ procedure is associated with @var{frame}.
 Return the arguments of @var{frame}.
 @end deffn
 
address@hidden {Scheme Procedure} frame-evaluating-args? frame
address@hidden {C Function} scm_frame_evaluating_args_p (frame)
-Return @code{#t} if @var{frame} contains evaluated arguments.
address@hidden deffn
-
address@hidden {Scheme Procedure} frame-overflow? frame
address@hidden {C Function} scm_frame_overflow_p (frame)
-Return @code{#t} if @var{frame} is an overflow frame.
address@hidden deffn
-
address@hidden {Scheme Procedure} frame-real? frame
address@hidden {C Function} scm_frame_real_p (frame)
-Return @code{#t} if @var{frame} is a real frame.
address@hidden deffn
-
 @deffn {Scheme Procedure} display-application frame [port [indent]]
 @deffnx {C Function} scm_display_application (frame, port, indent)
 Display a procedure application @var{frame} to the output port
@@ -242,14 +193,12 @@ output.
 @cindex source properties
 As Guile reads in Scheme code from file or from standard input, it
 remembers the file name, line number and column number where each
-expression begins.  These pieces of information are known as the
address@hidden properties} of the expression.  If an expression undergoes
-transformation --- for example, if there is a syntax transformer in
-effect, or the expression is a macro call --- the source properties are
-copied from the untransformed to the transformed expression so that, if
-an error occurs when evaluating the transformed expression, Guile's
-debugger can point back to the file and location where the expression
-originated.
+expression begins. These pieces of information are known as the
address@hidden properties} of the expression. Syntax expanders and the
+compiler propagate these source properties to compiled procedures, so
+that, if an error occurs when evaluating the transformed expression,
+Guile's debugger can point back to the file and location where the
+expression originated.
 
 The way that source properties are stored means that Guile can only
 associate source properties with parenthesized expressions, and not, for
@@ -275,10 +224,7 @@ port>''.
 
 The recording of source properties is controlled by the read option
 named ``positions'' (@pxref{Reader options}).  This option is switched
address@hidden by default, together with the debug options ``debug'' and
-``backtrace'' (@pxref{Debugger options}), when Guile is run
-interactively; all these options are @emph{off} by default when Guile
-runs a script non-interactively.
address@hidden by default.
 
 The following procedures can be used to access and set the source
 properties of read expressions.
@@ -306,52 +252,9 @@ Return the property specified by @var{key} from 
@var{obj}'s source
 properties.
 @end deffn
 
-In practice there are only two ways that you should use the ability to
-set an expression's source properties.
-
address@hidden
address@hidden
-To set a breakpoint on an expression, use @code{(set-source-property!
address@hidden 'breakpoint #t)}.  If you do this, you should also set the
address@hidden and @code{enter-frame-handler} trap options
-(@pxref{Evaluator trap options}) and @code{breakpoints} debug option
-(@pxref{Debugger options}) appropriately, and the evaluator will then
-call your enter frame handler whenever it is about to evaluate that
-expression.
-
address@hidden
-To make a read or constructed expression appear to have come from a
-different source than what the expression's source properties already
-say, you can use @code{set-source-property!} to set the expression's
address@hidden, @code{line} and @code{column} properties.  The
-properties that you set will then show up later if that expression is
-involved in a backtrace or error report.
address@hidden itemize
-
-If you are looking for a way to attach arbitrary information to an
-expression other than these properties, you should use
address@hidden instead (@pxref{Object Properties}).  That
-will avoid bloating the source property hash table, which is really
-only intended for the debugging purposes just described.
-
-
address@hidden Decoding Memoized Source Expressions
address@hidden Decoding Memoized Source Expressions
-
address@hidden {Scheme Procedure} memoized? obj
address@hidden {C Function} scm_memoized_p (obj)
-Return @code{#t} if @var{obj} is memoized.
address@hidden deffn
-
address@hidden {Scheme Procedure} unmemoize m
address@hidden {C Function} scm_unmemoize (m)
-Unmemoize the memoized expression @var{m},
address@hidden deffn
-
address@hidden {Scheme Procedure} memoized-environment m
address@hidden {C Function} scm_memoized_environment (m)
-Return the environment of the memoized expression @var{m}.
address@hidden deffn
+If the @code{positions} reader option is enabled, each parenthesized
+expression will have values set for the @code{filename}, @code{line} and
address@hidden properties.
 
 
 @node Starting a New Stack
@@ -377,15 +280,15 @@ the error chose explicitly to provide.  This information 
originates with
 the @code{error} or @code{throw} call (or their C code equivalents, if
 the error is detected by C code) that signals the error, and is passed
 automatically to the handler procedure of the innermost applicable
address@hidden, @code{lazy-catch} or @code{with-throw-handler} expression.
address@hidden or @code{with-throw-handler} expression.
 
 @subsubsection Intercepting basic error information
 
 Therefore, to catch errors that occur within a chunk of Scheme code, and
 to intercept basic information about those errors, you need to execute
-that code inside the dynamic context of a @code{catch},
address@hidden or @code{with-throw-handler} expression, or the
-equivalent in C.  In Scheme, this means you need something like this:
+that code inside the dynamic context of a @code{catch} or
address@hidden expression, or the equivalent in C. In Scheme,
+this means you need something like this:
 
 @lisp
 (catch #t
@@ -436,9 +339,8 @@ SCM my_handler_proc (void *handler_data,
 
 @noindent
 Again, as with the Scheme version, @code{scm_c_catch} could be replaced
-by @code{scm_internal_lazy_catch} or @code{scm_c_with_throw_handler},
-and @code{SCM_BOOL_T} could instead be the symbol for a particular kind
-of error.
+by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead
+be the symbol for a particular kind of error.
 
 @subsubsection Capturing the full error stack
 
@@ -446,19 +348,10 @@ The other interesting information about an error is the 
full Scheme
 stack at the point where the error occurred; in other words what
 innermost expression was being evaluated, what was the expression that
 called that one, and so on.  If you want to write your code so that it
-captures and can display this information as well, there are three
+captures and can display this information as well, there are a couple
 important things to understand.
 
-Firstly, the code in question must be executed using the debugging
-version of the evaluator, because information about the Scheme stack is
-only available at all from the debugging evaluator.  Using the debugging
-evaluator means that the debugger option (@pxref{Debugger options})
-called @code{debug} must be enabled; this can be done by running
address@hidden(debug-enable 'debug)} or @code{(turn-on-debugging)} at the top
-level of your program; or by running guile with the @code{--debug}
-command line option, if your program begins life as a Scheme script.
-
-Secondly, the stack at the point of the error needs to be explicitly
+Firstly, the stack at the point of the error needs to be explicitly
 captured by a @code{make-stack} call (or the C equivalent
 @code{scm_make_stack}).  The Guile library does not do this
 ``automatically'' for you, so you will need to write code with a
@@ -472,16 +365,15 @@ running on top of the Guile library, and which uses 
@code{catch} and
 @code{make-stack} in the way we are about to describe to capture the
 stack when an error occurs.)
 
-Thirdly, in order to capture the stack effectively at the point where
-the error occurred, the @code{make-stack} call must be made before Guile
-unwinds the stack back to the location of the prevailing catch
-expression.  This means that the @code{make-stack} call must be made
-within the handler of a @code{lazy-catch} or @code{with-throw-handler}
-expression, or the optional "pre-unwind" handler of a @code{catch}.
-(For the full story of how these alternatives differ from each other,
-see @ref{Exceptions}.  The main difference is that @code{catch}
-terminates the error, whereas @code{lazy-catch} and
address@hidden only intercept it temporarily and then allow
+And secondly, in order to capture the stack effectively at the point
+where the error occurred, the @code{make-stack} call must be made before
+Guile unwinds the stack back to the location of the prevailing catch
+expression. This means that the @code{make-stack} call must be made
+within the handler of a @code{with-throw-handler} expression, or the
+optional "pre-unwind" handler of a @code{catch}. (For the full story of
+how these alternatives differ from each other, see @ref{Exceptions}. The
+main difference is that @code{catch} terminates the error, whereas
address@hidden only intercepts it temporarily and then allow
 it to continue propagating up to the next innermost handler.)
 
 So, here are some examples of how to do all this in Scheme and in C.
@@ -582,11 +474,11 @@ application frame -- that is, a frame that satisfies the
 
 @subsubsection What the Guile REPL does
 
-The Guile REPL code (in @file{ice-9/boot-9.scm}) uses a @code{catch}
-with a pre-unwind handler to capture the stack when an error occurs in
-an expression that was typed into the REPL, and saves the captured stack
-in a fluid (@pxref{Fluids and Dynamic States}) called
address@hidden  You can then use the @code{(backtrace)} command,
+The Guile REPL code (in @file{system/repl/repl.scm} and related files)
+uses a @code{catch} with a pre-unwind handler to capture the stack when
+an error occurs in an expression that was typed into the REPL, and saves
+the captured stack in a fluid (@pxref{Fluids and Dynamic States}) called
address@hidden You can then use the @code{(backtrace)} command,
 which is basically equivalent to @code{(display-backtrace (fluid-ref
 the-last-stack))}, to print out this stack at any time until it is
 overwritten by the next error that occurs.
@@ -619,17 +511,16 @@ Invoke the Guile debugger to explore the context of the 
last error.
 @cindex Tracing
 @cindex Code coverage
 @cindex Profiling
-The low level C code of Guile's evaluator can be configured to call
-out at key points to arbitrary user-specified procedures.  These
-procedures, and the circumstances under which the evaluator calls
-them, are configured by the ``evaluator trap options'' interface
-(@pxref{Evaluator trap options}), and by the @code{trace} and
address@hidden fields of the ``debug options'' interface
-(@pxref{Debugger options}).  In principle this allows Scheme code to
-implement any model it chooses for examining the evaluation stack as
-program execution proceeds, and for suspending execution to be resumed
-later.  Possible applications of this feature include breakpoints,
-runtime tracing, code coverage, and profiling.
+Guile's virtual machine can be configured to call out at key points to
+arbitrary user-specified procedures. For more information on these
+hooks, and the circumstances under which the VM calls them, see @ref{VM
+Behaviour}.
+
+In principle, these hooks allow Scheme code to implement any model it
+chooses for examining the evaluation stack as program execution
+proceeds, and for suspending execution to be resumed later. Possible
+applications of this feature include breakpoints, runtime tracing, code
+coverage, and profiling.
 
 @cindex Trap classes
 @cindex Trap objects
@@ -650,6 +541,14 @@ user wanting to use traps, and the developer interested in
 understanding how the interface hangs together.
 
 
address@hidden Actually, this section is bitrotten
+
+Dear reader: the following sections have some great ideas, and some code
+that just needs a few days of massaging to get it to work with the VM
+(as opposed to the old interpreter). Want to help? Yes? Yes!
address@hidden@@gnu.org}, that's where.
+
+
 @subsubsection A Quick Note on Terminology
 
 @cindex Trap terminology
@@ -1886,19 +1785,6 @@ hi!
 guile> 
 @end lisp
 
address@hidden
address@hidden Memoization
-(For anyone wondering why the first @code{(do-main 4)} call above
-generates lots more trace lines than the subsequent calls: these
-examples also demonstrate how the Guile evaluator ``memoizes'' code.
-When Guile evaluates a source code expression for the first time, it
-changes some parts of the expression so that they will be quicker to
-evaluate when that expression is evaluated again; this is called
-memoization.  The trace output from the first @code{(do-main 4)} call
-shows memoization steps, such as an internal define being transformed to
-a letrec.)
-
-
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End:
diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi
index 04540f7..ff91688 100644
--- a/doc/ref/api-evaluation.texi
+++ b/doc/ref/api-evaluation.texi
@@ -901,6 +901,15 @@ Accessors to a virtual machine's hooks. Usually you pass
 @code{(the-vm)} as the @var{vm}.
 @end deffn
 
address@hidden {Scheme Procedure} vm-trace-level vm
+Retrieve the ``trace level'' of the VM. If positive, the trace hooks associated
+with @var{vm} will be run. The initial trace level is 0.
address@hidden deffn
+
address@hidden {Scheme Procedure} set-vm-trace-level! vm level
+Set the ``trace level'' of the VM.
address@hidden deffn
+
 @xref{A Virtual Machine for Guile}, for more information on Guile's
 virtual machine.
 
diff --git a/doc/ref/vm.texi b/doc/ref/vm.texi
index ffcfbed..0e9ba7b 100644
--- a/doc/ref/vm.texi
+++ b/doc/ref/vm.texi
@@ -7,9 +7,9 @@
 @node A Virtual Machine for Guile
 @section A Virtual Machine for Guile
 
-Guile has both an interpreter and a compiler. To a user, the
-difference is largely transparent---interpreted and compiled
-procedures can call each other as they please.
+Guile has both an interpreter and a compiler. To a user, the difference
+is transparent---interpreted and compiled procedures can call each other
+as they please.
 
 The difference is that the compiler creates and interprets bytecode
 for a custom virtual machine, instead of interpreting the
@@ -33,21 +33,19 @@ machine.
 @subsection Why a VM?
 
 @cindex interpreter
address@hidden evaluator
-For a long time, Guile only had an interpreter, called the
address@hidden Guile's evaluator operates directly on the
-S-expression representation of Scheme source code.
+For a long time, Guile only had an interpreter. Guile's interpreter
+operated directly on the S-expression representation of Scheme source
+code.
 
-But while the evaluator is highly optimized and hand-tuned, and
-contains some extensive speed trickery (@pxref{Memoization}), it still
+But while the interpreter was highly optimized and hand-tuned, it still
 performs many needless computations during the course of evaluating an
 expression. For example, application of a function to arguments
-needlessly conses up the arguments in a list. Evaluation of an
-expression always has to figure out what the car of the expression is
--- a procedure, a memoized form, or something else. All values have to
-be allocated on the heap. Et cetera.
+needlessly consed up the arguments in a list. Evaluation of an
+expression always had to figure out what the car of the expression is --
+a procedure, a memoized form, or something else. All values have to be
+allocated on the heap. Et cetera.
 
-The solution to this problem is to compile the higher-level language,
+The solution to this problem was to compile the higher-level language,
 Scheme, into a lower-level language for which all of the checks and
 dispatching have already been done---the code is instead stripped to
 the bare minimum needed to ``do the job''.
@@ -71,7 +69,21 @@ for Guile (@code{cons}, @code{struct-ref}, etc.).
 So this is what Guile does. The rest of this section describes that VM
 that Guile implements, and the compiled procedures that run on it.
 
-Note that this decision to implement a bytecode compiler does not
+Before moving on, though, we should note that though we spoke of the
+interpreter in the past tense, Guile still has an interpreter. The
+difference is that before, it was Guile's main evaluator, and so was
+implemented in highly optimized C; now, it is actually implemented in
+Scheme, and compiled down to VM bytecode, just like any other program.
+(There is still a C interpreter around, used to bootstrap the compiler,
+but it is not normally used at runtime.)
+
+The upside of implementing the interpreter in Scheme is that we preserve
+tail calls and multiple-value handling between interpreted and compiled
+code. The downside is that the interpreter in Guile 2.0 is slower than
+the interpreter in 1.8. We hope the that the compiler's speed makes up
+for the loss!
+
+Also note that this decision to implement a bytecode compiler does not
 preclude native compilation. We can compile from bytecode to native
 code at runtime, or even do ahead of time compilation. More
 possibilities are discussed in @ref{Extending the Compiler}.
@@ -79,12 +91,9 @@ possibilities are discussed in @ref{Extending the Compiler}.
 @node VM Concepts
 @subsection VM Concepts
 
-A virtual machine (VM) is a Scheme object. Users may create virtual
-machines using the standard procedures described later in this manual,
-but that is usually unnecessary, as Guile ensures that there is one
-virtual machine per thread. When a VM-compiled procedure is run, Guile
-looks up the virtual machine for the current thread and executes the
-procedure using that VM.
+Compiled code is run by a virtual machine (VM). Each thread has its own
+VM. When a compiled procedure is run, Guile looks up the virtual machine
+for the current thread and executes the procedure using that VM.
 
 Guile's virtual machine is a stack machine---that is, it has few
 registers, and the instructions defined in the VM operate by pushing
@@ -113,12 +122,6 @@ the ``program counter'' (pc). This set of registers is 
pretty typical
 for stack machines; their exact meanings in the context of Guile's VM
 are described in the next section.
 
-A virtual machine executes by loading a compiled procedure, and
-executing the object code associated with that procedure. Of course,
-that procedure may call other procedures, tail-call others, ad
-infinitum---indeed, within a guile whose modules have all been
-compiled to object code, one might never leave the virtual machine.
-
 @c wingo: The following is true, but I don't know in what context to
 @c describe it. A documentation FIXME.
 
@@ -241,8 +244,8 @@ prove statements about functions. It is especially good at 
describing
 scope relations, and it is for that reason that we mention it here.
 
 Guile allocates all variables on the stack. When a lexically enclosed
-procedure with free variables---a @dfn{closure}---is created, it
-copies those variables its free variable vector. References to free
+procedure with free variables---a @dfn{closure}---is created, it copies
+those variables into its free variable vector. References to free
 variables are then redirected through the free variable vector.
 
 If a variable is ever @code{set!}, however, it will need to be
@@ -551,8 +554,8 @@ All the conditional branch instructions described below 
work in the
 same way:
 
 @itemize
address@hidden They pop off the Scheme object located on the stack and use it as
-the branch condition;
address@hidden They pop off Scheme object(s) located on the stack for use in the
+branch condition
 @item If the condition is true, then the instruction pointer is
 increased by the offset passed as an argument to the branch
 instruction;
@@ -560,22 +563,20 @@ instruction;
 the one to which the instruction pointer points).
 @end itemize
 
-Note that the offset passed to the instruction is encoded on two 8-bit
-integers which are then combined by the VM as one 16-bit integer. Note
-also that jump targets in Guile are aligned on 8-byte boundaries, and
-that the offset refers to the @var{n}th 8-byte boundary, effectively
-giving Guile a 19-bit relative address space.
+Note that the offset passed to the instruction is encoded as three 8-bit
+integers, in big-endian order, effectively giving Guile a 24-bit
+relative address space.
 
 @deffn Instruction br offset
-Jump to @var{offset}.
+Jump to @var{offset}. No values are popped.
 @end deffn
 
 @deffn Instruction br-if offset
-Jump to @var{offset} if the condition on the stack is not false.
+Jump to @var{offset} if the object on the stack is not false.
 @end deffn
 
 @deffn Instruction br-if-not offset
-Jump to @var{offset} if the condition on the stack is false.
+Jump to @var{offset} if the object on the stack is false.
 @end deffn
 
 @deffn Instruction br-if-eq offset
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index eca7163..2b50ff2 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -3644,7 +3644,7 @@ module '(ice-9 q) '(make-q q-length))}."
           '(((ice-9 threads)))
           '())))
     ;; load debugger on demand
-    (module-autoload! guile-user-module '(ice-9 debugger) '(debug))
+    (module-autoload! guile-user-module '(system vm debug) '(debug))
 
     ;; Note: SIGFPE, SIGSEGV and SIGBUS are actually "query-only" (see
     ;; scmsigs.c scm_sigaction_for_thread), so the handlers setup here have
diff --git a/module/system/vm/debug.scm b/module/system/vm/debug.scm
index 4c99469..51cdedf 100644
--- a/module/system/vm/debug.scm
+++ b/module/system/vm/debug.scm
@@ -28,7 +28,7 @@
   #:use-module (ice-9 format)
   #:use-module ((system vm inspect) #:select ((inspect . %inspect)))
   #:use-module (system vm program)
-  #:export (run-debugger debug-pre-unwind-handler))
+  #:export (debug run-debugger debug-pre-unwind-handler))
 
 
 (define (reverse-hashq h)
@@ -144,19 +144,20 @@
             (set! (prop vm) debugger)
             debugger)))))
 
-(define* (run-debugger stack frames i #:optional (vm (the-vm)))
+(define* (run-debugger stack frames #:optional (vm (the-vm)))
   (let* ((db (vm-debugger vm))
          (level (debugger-level db)))
     (dynamic-wind
       (lambda () (set! (debugger-level db) (1+ level)))
-      (lambda () (debugger-repl db stack frames i))
+      (lambda () (debugger-repl db stack frames))
       (lambda () (set! (debugger-level db) level)))))
 
-(define (debugger-repl db stack frames index)
-  (let ((top (vector-ref frames 0))
-        (cur (vector-ref frames index))
-        (level (debugger-level db))
-        (last #f))
+(define (debugger-repl db stack frames)
+  (let* ((index 0)
+         (top (vector-ref frames index))
+         (cur top)
+         (level (debugger-level db))
+         (last #f))
     (define (frame-at-index idx)
       (and (< idx (vector-length frames))
            (vector-ref frames idx)))
@@ -402,3 +403,9 @@ With an argument, select a frame by index, then show it."
                     0))))
   (save-stack debug-pre-unwind-handler)
   (apply throw key args))
+
+(define (debug)
+  (let ((stack (fluid-ref the-last-stack)))
+    (if stack
+       (run-debugger stack (stack->vector stack))
+       (display "Nothing to debug.\n"))))


hooks/post-receive
-- 
GNU Guile




reply via email to

[Prev in Thread] Current Thread [Next in Thread]