~ chicken-core (chicken-5) 4180f098b6109fcbf5d5ddef611017b997befa99


commit 4180f098b6109fcbf5d5ddef611017b997befa99
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Jul 16 08:25:32 2010 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Fri Jul 16 08:25:32 2010 +0200

    frameinfo handling and commands

diff --git a/csi.scm b/csi.scm
index 5f2122b7..8c03b5ca 100644
--- a/csi.scm
+++ b/csi.scm
@@ -54,6 +54,7 @@ EOF
     ##sys#windows-platform)
   (hide parse-option-string bytevector-data member* canonicalize-args 
 	describer-table dirseparator? circular-list? improper-pairs?
+	show-frameinfo selected-frame select-frame copy-from-frame
 	findall command-table default-editor) )
 
 
@@ -66,6 +67,7 @@ EOF
 (set! ##sys#notices-enabled #t)
 
 (define editor-command (make-parameter #f))
+(define selected-frame #f)
 
 (define default-editor 
   (or (get-environment-variable "EDITOR")
@@ -333,6 +335,14 @@ EOF
 				    " " (read-line)))))
 			   (if (not (zero? r))
 			       (printf "Editor returned with non-zero exit status ~a" r))))
+			((f)
+			 (show-frameinfo selected-frame)
+			 (##sys#void))
+			((nf)
+			 (select-frame (read))
+			 (##sys#void))
+			((cf)
+			 (copy-from-frame (read)))
 			((s)
 			 (let* ((str (read-line))
 				(r (system str)) )
@@ -354,6 +364,9 @@ EOF
  ,e FILENAME       Run external editor
  ,s TEXT ...       Execute shell-command
  ,exn              Describe last exception
+ ,f                Show frame information
+ ,nf N             Select frame N
+ ,cf NAME          Get variable NAME from current frame
  ,t EXP            Evaluate form and print elapsed time
  ,x EXP            Pretty print expanded expression EXP\n")
 			 (##sys#hash-table-for-each
@@ -710,7 +723,109 @@ EOF
 	    (if (and (fx>= c 32) (fx< c 128))
 		(write-char (integer->char c) out)
 		(write-char #\. out) ) ) ) 
-	(##sys#write-char-0 #\newline out) ) ) ) )
+	(write-char #\newline out) ) ) ) )
+
+
+;;; Frame-info operations:
+
+(define show-frameinfo
+  (let ((write-char write-char)
+	(newline newline)
+	(display display))
+    (lambda (fn)
+      (define (prin1 x)
+	(##sys#with-print-length-limit
+	 100
+	 (lambda ()
+	   (##sys#print x #t ##sys#standard-output))))
+      (let* ((ct (or ##sys#repl-recent-call-chain '()))
+	     (len (length ct)))
+	(set! selected-frame 
+	  (or (and (memq fn ct) fn)
+	      (and (fx> len 0)
+		   (list-ref ct (fx- len 1)))))
+	(do ((ct ct (cdr ct))
+	     (i (fx- len 1) (fx- i 1)))
+	    ((null? ct))
+	  (let* ((info (car ct))
+		 (here (eq? selected-frame info))
+		 (form (##sys#slot info 1)) ; cooked1 (expr/form)
+		 (data (##sys#slot info 2)) ; cooked2 (cntr/frameinfo)
+		 (finfo (##sys#structure? data 'frameinfo))
+		 (cntr (if finfo (##sys#slot data 1) data))) ; cntr
+	    (printf "~a~a:~a\t~a\t  " 
+	      (if here #\* #\space)
+	      i
+	      (if (and finfo (pair? (##sys#slot data 2))) #\. #\space) ; e
+	      (##sys#slot info 0))	; raw
+	    (when cntr (printf "[~a] " cntr))
+	    (prin1 form)
+	    (newline)
+	    (if (and here finfo)
+		(for-each
+		 (lambda (e v)
+		   (do ((i 0 (fx+ i 1))
+			(be e (cdr be)))
+		       ((null? be))
+		     (printf "  ~s:\t  " (car be))
+		     (prin1 (##sys#slot v i))
+		     (newline)))
+		 (##sys#slot data 2)	   ; e
+		 (##sys#slot data 3)))))))))	   ; v
+	  
+(define select-frame
+  (let ((display display))
+    (lambda (n)
+      (cond ((or (not (number? n))
+		 (not ##sys#repl-recent-call-chain)
+		 (fx< n 0)
+		 (fx>= n (length ##sys#repl-recent-call-chain)))
+	     (display "no such frame\n"))
+	    (else
+	     (set! selected-frame
+	       (list-ref 
+		##sys#repl-recent-call-chain
+		(fx- (length ##sys#repl-recent-call-chain) (fx+ n 1))))
+	     (show-frameinfo selected-frame))))))
+
+(define copy-from-frame
+  (let ((display display)
+	(call/cc call/cc))
+    (lambda (name)
+      (let* ((ct (or ##sys#repl-recent-call-chain '()))
+	     (len (length ct))
+	     (name 
+	      (cond ((symbol? name) (##sys#slot name 1)) ; name
+		    ((string? name) name)
+		    (else 
+		     (display "string or symbol required for `,cf'\n")
+		     #f))))
+	(if name
+	    (call/cc
+	     (lambda (return)
+	       (define (fail msg)
+		 (display msg)
+		 (return (##sys#void)))
+	       (do ((ct ct (cdr ct))
+		    (i (fx- len 1) (fx- i 1)))
+		   ((null? ct) (fail "no environment in frame\n")) 
+		 (let* ((info (car ct))
+			(here (eq? selected-frame info))
+			(data (##sys#slot info 2)) ; cooked2 (cntr/frameinfo)
+			(finfo (##sys#structure? data 'frameinfo))
+			(cntr (if finfo (##sys#slot data 1) data))) ; cntr
+		   (when (and here finfo)
+		     (for-each
+		      (lambda (e v)
+			(do ((i 0 (fx+ i 1))
+			     (be e (cdr be)))
+			    ((null? be) (fail "no such variable\n"))
+			  (when (string=? name (##sys#slot (car be) 1)) ; name
+			    (history-add (list (##sys#slot v i)))
+			    (return (##sys#slot v i)))))
+		      (##sys#slot data 2)	; e
+		      (##sys#slot data 3))))))) ; v
+	    (##sys#void))))))
 
 
 ;;; Start interpreting:
diff --git a/eval.scm b/eval.scm
index 93068b88..ff35cfaf 100644
--- a/eval.scm
+++ b/eval.scm
@@ -1474,6 +1474,7 @@
 (define ##sys#repl-eval-hook #f)
 (define ##sys#repl-print-length-limit #f)
 (define ##sys#repl-read-hook #f)
+(define ##sys#repl-recent-call-chain #f)
 
 (define (##sys#repl-print-hook x port)
   (##sys#with-print-length-limit ##sys#repl-print-length-limit (cut ##sys#print x #t port))
@@ -1548,7 +1549,8 @@
 		  (begin
 		    (##sys#write-char-0 #\newline ##sys#standard-error)
 		    (write-err args) ) )
-	      (print-call-chain ##sys#standard-error)
+	      (set! ##sys#repl-recent-call-chain
+		(print-call-chain ##sys#standard-error))
 	      (flush-output ##sys#standard-error) ) ) )
 	 (lambda ()
 	   (let loop ()
diff --git a/library.scm b/library.scm
index c0560ce7..a2a36c0c 100644
--- a/library.scm
+++ b/library.scm
@@ -3383,16 +3383,17 @@ EOF
     (##sys#print header #f port)
     (for-each
      (lambda (info) 
-       (let ((more1 (##sys#slot info 1)) ; cooked1 (expr/form)
-	     (more2 (##sys#slot info 2)) ) ; cooked2 (frameinfo)
+       (let* ((more1 (##sys#slot info 1)) ; cooked1 (expr/form)
+	      (more2 (##sys#slot info 2)) ; cooked2 (cntr/frameinfo)
+	      (fi (##sys#structure? more2 'frameinfo)))
 	 (##sys#print "\n\t" #f port)
 	 (##sys#print (##sys#slot info 0) #f port) ; raw (mode)
-	 (##sys#print "\t\t" #f port)
+	 (##sys#print "\t  " #f port)
 	 (when more2
 	   (##sys#write-char-0 #\[ port)
 	   (##sys#print 
-	    (if (##sys#structure? more2 'frameinfo)
-		(##sys#slot more2 0)
+	    (if fi
+		(##sys#slot more2 1)	; cntr
 		more2)
 	    #f port)
 	   (##sys#print "] " #f port) )
@@ -3410,7 +3411,9 @@ EOF
   (##sys#check-port port 'print-call-chain)
   (##sys#check-exact start 'print-call-chain)
   (##sys#check-string header 'print-call-chain)
-  (##sys#really-print-call-chain port (##sys#get-call-chain start thread) header) )
+  (let ((ct (##sys#get-call-chain start thread)))
+    (##sys#really-print-call-chain port ct header)
+    ct))
 
 (define get-call-chain ##sys#get-call-chain)
 
diff --git a/manual/Using the interpreter b/manual/Using the interpreter
index a71f3643..ccc516ca 100644
--- a/manual/Using the interpreter	
+++ b/manual/Using the interpreter	
@@ -143,6 +143,12 @@ The toplevel loop understands a number of special commands:
 
 ; ,exn : Describes the last exception that occurred and adds it to the result history (it can be accessed using the {{#}} notation).
 
+; ,f : Show call-trace items of the most recent error
+
+; ,nf N : Select call-trace item with the given number, where the number {{0}} indicates the last item in the trace
+
+; cf NAME : Returns the value of the local variable with the given name (which may be a symbol or string)
+
 ; ,q : Quit the interpreter.
 
 ; ,r : Show system information.
diff --git a/runtime.c b/runtime.c
index cd17c989..c60190f7 100644
--- a/runtime.c
+++ b/runtime.c
@@ -149,7 +149,7 @@ extern void _C_do_apply_hack(void *proc, C_word *args, int count) C_noret;
 #define DEFAULT_FORWARDING_TABLE_SIZE  32
 #define DEFAULT_LOCATIVE_TABLE_SIZE    32
 #define DEFAULT_COLLECTIBLES_SIZE      1024
-#define DEFAULT_TRACE_BUFFER_SIZE      8
+#define DEFAULT_TRACE_BUFFER_SIZE      10
 
 #define MAX_HASH_PREFIX                64
 
diff --git a/tests/test-finalizers.scm b/tests/test-finalizers.scm
index b9eda52d..512b0991 100644
--- a/tests/test-finalizers.scm
+++ b/tests/test-finalizers.scm
@@ -1,5 +1,7 @@
 ;;;; test-finalizers.scm
 
+(##sys#eval-debug-level 0)		; disable keeping trace-buffer with frameinfo
+
 (define x (list 1 2 3))
 (define y (list 4 5 6))
 (define x-f #f)
Trap