The FSF has a new address.
[bpt/guile.git] / ice-9 / debugger / trap-hooks.scm
dissimilarity index 100%
index 77abc0d..e69de29 100644 (file)
@@ -1,320 +0,0 @@
-;;;; (ice-9 debugger trap-hooks) -- abstraction of libguile's traps interface
-
-;;; Copyright (C) 2002 Free Software Foundation, Inc.
-;;;
-;; This library is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU Lesser General Public
-;; License as published by the Free Software Foundation; either
-;; version 2.1 of the License, or (at your option) any later version.
-;; 
-;; This library is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; Lesser General Public License for more details.
-;; 
-;; You should have received a copy of the GNU Lesser General Public
-;; License along with this library; if not, write to the Free Software
-;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-;;; This module provides an abstraction around Guile's low level trap
-;;; handler interface; its aim is to make the low level trap mechanism
-;;; shareable between the debugger and other applications, and to
-;;; insulate the rest of the debugger code a bit from changes that may
-;;; occur in the low level trap interface in future.
-
-(define-module (ice-9 debugger trap-hooks)
-  #:use-module (ice-9 debugger trc)
-  #:export (add-trapped-stack-id!
-           remove-trapped-stack-id!
-           before-apply-frame-hook
-           before-enter-frame-hook
-           before-exit-frame-hook
-           after-apply-frame-hook
-           after-enter-frame-hook
-           after-exit-frame-hook
-           add-apply-frame-hook!
-           add-breakpoint-hook!
-           add-enter-frame-hook!
-           add-exit-frame-hook!
-           add-trace-hook!
-           remove-apply-frame-hook!
-           remove-breakpoint-hook!
-           remove-enter-frame-hook!
-           remove-exit-frame-hook!
-           remove-trace-hook!
-           debug-hook-membership))
-
-;;; The current low level traps interface is as follows.
-;;;
-;;; All trap handlers are subject to SCM_TRAPS_P, which is controlled
-;;; by the `traps' setting of `(evaluator-traps-interface)' but also
-;;; (and more relevant in most cases) by the `with-traps' procedure.
-;;; Basically, `with-traps' sets SCM_TRAPS_P to 1 during execution of
-;;; its thunk parameter.
-;;;
-;;; Note that all trap handlers are called with SCM_TRAPS_P set to 0
-;;; for the duration of the call, to avoid nasty recursive trapping
-;;; loops.  If a trap handler knows what it is doing, it can override
-;;; this by `(trap-enable traps)'.
-;;;
-;;; The apply-frame handler is called when Guile is about to perform
-;;; an application if EITHER the `apply-frame' evaluator trap option
-;;; is set, OR the `trace' debug option is set and the procedure to
-;;; apply has its `trace' procedure property set.  The arguments
-;;; passed are:
-;;;
-;;; - the symbol 'apply-frame
-;;;
-;;; - a continuation or debug object describing the current stack
-;;;
-;;; - a boolean indicating whether the application is tail-recursive.
-;;;
-;;; The enter-frame handler is called when the evaluator begins a new
-;;; evaluation frame if EITHER the `enter-frame' evaluator trap option
-;;; is set, OR the `breakpoints' debug option is set and the code to
-;;; be evaluated has its `breakpoint' source property set.  The
-;;; arguments passed are:
-;;;
-;;; - the symbol 'enter-frame
-;;;
-;;; - a continuation or debug object describing the current stack
-;;;
-;;; - a boolean indicating whether the application is tail-recursive.
-;;;
-;;; - an unmemoized copy of the expression to be evaluated.
-;;;
-;;; If the `enter-frame' evaluator trap option is set, the enter-frame
-;;; handler is also called when about to perform an application in
-;;; SCM_APPLY, immediately before possible calling the apply-frame
-;;; handler.  (I don't totally understand this.)  In this case, the
-;;; arguments passed are:
-;;;
-;;; - the symbol 'enter-frame
-;;;
-;;; - a continuation or debug object describing the current stack.
-;;;
-;;; The exit-frame handler is called when Guile exits an evaluation
-;;; frame (in SCM_CEVAL) or an application frame (in SCM_APPLY), if
-;;; EITHER the `exit-frame' evaluator trap option is set, OR the
-;;; `trace' debug option is set and the frame is marked as having been
-;;; traced.  The frame will be marked as having been traced if the
-;;; apply-frame handler was called for this frame.  (This is trickier
-;;; than it sounds because of tail recursion: the same debug frame
-;;; could have been used for multiple applications, only some of which
-;;; were traced - I think.)  The arguments passed are:
-;;;
-;;; - the symbol 'exit-frame
-;;;
-;;; - a continuation or debug object describing the current stack
-;;;
-;;; - the result of the evaluation or application.
-
-;;; {Stack IDs}
-;;;
-;;; Mechanism for limiting trapping to contexts whose stack ID matches
-;;; one of a registered set.  The default set up is to limit trapping
-;;; to events in the contexts of the Guile REPL and of file loading.
-
-(define trapped-stack-ids (list 'repl-stack 'load-stack))
-(define all-stack-ids-trapped? #f)
-
-(define (add-trapped-stack-id! id)
-  "Add ID to the set of stack ids for which traps are active.
-If `#t' is in this set, traps are active regardless of stack context.
-To remove ID again, use `remove-trapped-stack-id!'.  If you add the
-same ID twice using `add-trapped-stack-id!', you will need to remove
-it twice."
-  (set! trapped-stack-ids (cons id trapped-stack-ids))
-  (set! all-stack-ids-trapped? (memq #t trapped-stack-ids)))
-
-(define (remove-trapped-stack-id! id)
-  "Remove ID from the set of stack ids for which traps are active."
-  (set! trapped-stack-ids (delq1! id trapped-stack-ids))
-  (set! all-stack-ids-trapped? (memq #t trapped-stack-ids)))
-
-(define (trap-here? cont)
-  ;; Return true if the stack id of the specified continuation (or
-  ;; debug object) is in the set that we should trap for; otherwise
-  ;; false.
-  (or all-stack-ids-trapped?
-      (memq (stack-id cont) trapped-stack-ids)))
-
-;;; {Global State}
-;;;
-;;; Variables tracking registered handlers, relevant procedures, and
-;;; what's turned on as regards the evaluator's debugging options.
-
-(define before-enter-frame-hook (make-hook 3))
-(define enter-frame-hook (make-hook))
-(define breakpoint-hook (make-hook))
-(define after-enter-frame-hook (make-hook))
-
-(define before-exit-frame-hook (make-hook 2))
-(define exit-frame-hook (make-hook))
-(define after-exit-frame-hook (make-hook))
-
-(define before-apply-frame-hook (make-hook 2))
-(define apply-frame-hook (make-hook))
-(define trace-hook (make-hook))
-(define after-apply-frame-hook (make-hook))
-
-(define (hook-not-empty? hook)
-  (not (hook-empty? hook)))
-
-(define set-debug-and-trap-options
-  (let ((dopts (debug-options))
-       (topts (evaluator-traps-interface))
-       (setting (lambda (key opts)
-                  (let ((l (memq key opts)))
-                    (and l
-                         (not (null? (cdr l)))
-                         (cadr l)))))
-       (debug-set-boolean! (lambda (key value)
-                             ((if value debug-enable debug-disable) key)))
-       (trap-set-boolean! (lambda (key value)
-                            ((if value trap-enable trap-disable) key))))
-    (let ((save-debug (memq 'debug dopts))
-         (save-trace (memq 'trace dopts))
-         (save-breakpoints (memq 'breakpoints dopts))
-         (save-enter-frame (memq 'enter-frame topts))
-         (save-apply-frame (memq 'apply-frame topts))
-         (save-exit-frame (memq 'exit-frame topts))
-         (save-enter-frame-handler (setting 'enter-frame-handler topts))
-         (save-apply-frame-handler (setting 'apply-frame-handler topts))
-         (save-exit-frame-handler (setting 'exit-frame-handler topts)))
-      (lambda ()
-       (let ((need-trace (hook-not-empty? trace-hook))
-             (need-breakpoints (hook-not-empty? breakpoint-hook))
-             (need-enter-frame (hook-not-empty? enter-frame-hook))
-             (need-apply-frame (hook-not-empty? apply-frame-hook))
-             (need-exit-frame (hook-not-empty? exit-frame-hook)))
-         (debug-set-boolean! 'debug
-                             (or need-trace
-                                 need-breakpoints
-                                 need-enter-frame
-                                 need-apply-frame
-                                 need-exit-frame
-                                 save-debug))
-         (debug-set-boolean! 'trace
-                             (or need-trace
-                                 save-trace))
-         (debug-set-boolean! 'breakpoints
-                             (or need-breakpoints
-                                 save-breakpoints))
-         (trap-set-boolean! 'enter-frame
-                            (or need-enter-frame
-                                save-enter-frame))
-         (trap-set-boolean! 'apply-frame
-                            (or need-apply-frame
-                                save-apply-frame))
-         (trap-set-boolean! 'exit-frame
-                            (or need-exit-frame
-                                save-exit-frame))
-         (trap-set! enter-frame-handler
-                    (cond ((or need-breakpoints
-                               need-enter-frame)
-                           enter-frame-handler)
-                          (else save-enter-frame-handler)))
-         (trap-set! apply-frame-handler
-                    (cond ((or need-trace
-                               need-apply-frame)
-                           apply-frame-handler)
-                          (else save-apply-frame-handler)))
-         (trap-set! exit-frame-handler
-                    (cond ((or need-exit-frame)
-                           exit-frame-handler)
-                          (else save-exit-frame-handler))))
-       ;;(write (evaluator-traps-interface))
-       *unspecified*))))
-
-(define (enter-frame-handler key cont . args)
-  ;; For a non-application entry, ARGS is (TAIL? EXP), where EXP is an
-  ;; unmemoized copy of the source expression.  For an application
-  ;; entry, ARGS is empty.
-  (if (trap-here? cont)
-      (let ((application-entry? (null? args)))
-       (trc 'enter-frame-handler)
-       (if application-entry?
-           (run-hook before-enter-frame-hook cont #f #f)
-           (run-hook before-enter-frame-hook cont (car args) (cadr args)))
-       (run-hook enter-frame-hook)
-       (or application-entry?
-           (run-hook breakpoint-hook))
-       (run-hook after-enter-frame-hook))))
-
-(define (exit-frame-handler key cont retval)
-  (if (trap-here? cont)
-      (begin
-       (trc 'exit-frame-handler retval (stack-length (make-stack cont)))
-       (run-hook before-exit-frame-hook cont retval)
-       (run-hook exit-frame-hook)
-       (run-hook after-exit-frame-hook))))
-
-(define (apply-frame-handler key cont tail?)
-  (if (trap-here? cont)
-      (begin
-       (trc 'apply-frame-handler tail?)
-       (run-hook before-apply-frame-hook cont tail?)
-       (run-hook apply-frame-hook)
-       (run-hook trace-hook)
-       (run-hook after-apply-frame-hook))))
-
-(define-public (add-enter-frame-hook! proc)
-  (add-hook! enter-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (add-breakpoint-hook! proc)
-  (add-hook! breakpoint-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (add-exit-frame-hook! proc)
-  (add-hook! exit-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (add-apply-frame-hook! proc)
-  (add-hook! apply-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (add-trace-hook! proc)
-  (add-hook! trace-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (remove-enter-frame-hook! proc)
-  (remove-hook! enter-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (remove-breakpoint-hook! proc)
-  (remove-hook! breakpoint-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (remove-exit-frame-hook! proc)
-  (remove-hook! exit-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (remove-apply-frame-hook! proc)
-  (remove-hook! apply-frame-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (remove-trace-hook! proc)
-  (remove-hook! trace-hook proc)
-  (set-debug-and-trap-options))
-
-(define-public (debug-hook-membership)
-  (for-each (lambda (name+hook)
-             (format #t "~A:\n" (car name+hook))
-             (for-each (lambda (proc)
-                         (format #t "  ~S\n" proc))
-                       (hook->list (cdr name+hook))))
-           `((before-enter-frame-hook . ,before-enter-frame-hook)
-             (enter-frame-hook        . ,enter-frame-hook       )
-             (breakpoint-hook         . ,breakpoint-hook        )
-             (after-enter-frame-hook  . ,after-enter-frame-hook )
-             (before-exit-frame-hook  . ,before-exit-frame-hook )
-             (exit-frame-hook         . ,exit-frame-hook        )
-             (after-exit-frame-hook   . ,after-exit-frame-hook  )
-             (before-apply-frame-hook . ,before-apply-frame-hook)
-             (apply-frame-hook        . ,apply-frame-hook       )
-             (trace-hook              . ,trace-hook             )
-             (after-apply-frame-hook  . ,after-apply-frame-hook ))))
-
-;;; (ice-9 debugger trap-hooks) ends here.