-
Notifications
You must be signed in to change notification settings - Fork 3
/
stream-inspector.lisp
42 lines (34 loc) · 1.39 KB
/
stream-inspector.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(defpackage :stream-inspector
(:use :cl)
(:export
#:get-lisp-obj-by-address
#:get-lisp-obj-by-persistent-pointer
#:*persistent-pointers*))
(in-package :stream-inspector)
(defvar *printed-counter* 0)
(defvar *printed-objects*
#-ccl(make-hash-table :weakness :value)
#+ccl(make-hash-table :weak :value))
(defvar *persistent-pointers* nil)
;; When *PERSISTENT-POINTERS* is enabled, CLOS objects are printed with a persistent pointer at the beggining.
;; That pointer can be later used to find the object by its printed representation.
;; Unlike the get-lisp-obj-by-address approach, this is portable and also immune to garbage collection moves.
(defmethod print-object :around ((obj standard-object) stream)
(when *persistent-pointers*
(let ((printed-id (incf *printed-counter*)))
(setf (gethash printed-id *printed-objects*) obj)
(format stream "#~a" printed-id)))
(call-next-method))
(defmethod print-object :around ((obj condition) stream)
(when *persistent-pointers*
(let ((printed-id (incf *printed-counter*)))
(setf (gethash printed-id *printed-objects*) obj)
(format stream "#~a" printed-id)))
(call-next-method))
(defun get-lisp-obj-by-persistent-pointer (pointer)
(when *persistent-pointers*
(gethash pointer *printed-objects*)))
#+sbcl
(defun get-lisp-obj-by-address (address)
(sb-kernel:make-lisp-obj address))
(provide :stream-inspector)