annotate lisp/disass.el @ 5075:868a9ffcc37b

Normally return a compiled function if one argument, #'constantly. 2010-02-24 Aidan Kehoe <kehoea@parhasard.net> * cl-extra.el (constantly): Normally return a compiled function from #'constantly if we are handed a single argument. Shouldn't actually matter, the overhead for returning a single constant in a lambda form vs. in a compiled function is minuscule, but using compiled functions as much as possible is good style in XEmacs, our interpreter is not stellar (nor indeed should it need to be).
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 24 Feb 2010 17:17:13 +0000
parents e29fcfd8df5f
children 308d34e9f07d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; disass.el --- disassembler for compiled Emacs Lisp code
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;;; Copyright (C) 1986, 1991-1994 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Author: Doug Cutting <doug@csli.stanford.edu>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Jamie Zawinski <jwz@jwz.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Maintainer: XEmacs Development Team
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; Keywords: internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; along with XEmacs; see the file COPYING. If not, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 ;;; Synched up with: FSF 19.28.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 ;; The single entry point, `disassemble', disassembles a code object generated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; by the Emacs Lisp byte-compiler. This doesn't invert the compilation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;; operation, not by a long shot, but it's useful for debugging.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; Original version by Doug Cutting (doug@csli.stanford.edu)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; Substantially modified by Jamie Zawinski for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; the new lapcode-based byte compiler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 (require 'byte-optimize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 (defvar disassemble-column-1-indent 8 "*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 (defvar disassemble-column-2-indent 10 "*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 (defvar disassemble-recursive-indent 3 "*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 ;;;###autoload
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 (defun disassemble (object &optional buffer indent interactive-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 "Print disassembled code for OBJECT in (optional) BUFFER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 OBJECT can be a symbol defined as a function, or a function itself
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 \(a lambda expression or a compiled-function object).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 If OBJECT is not already compiled, we compile it, but do not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 redefine OBJECT if it is a symbol."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 (interactive (list (intern (completing-read "Disassemble function: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 obarray 'fboundp t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 nil 0 t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 (if (eq (car-safe object) 'byte-code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 (setq object (list 'lambda () object)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 (or indent (setq indent 0)) ;Default indent to zero
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 (if (or interactive-p (null buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 (with-output-to-temp-buffer "*Disassemble*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 (set-buffer "*Disassemble*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 (disassemble-internal object indent (not interactive-p)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 (set-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 (disassemble-internal object indent nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 (defun disassemble-internal (obj indent interactive-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 (let ((macro nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (name nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (while (symbolp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 (setq name obj
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 obj (symbol-function obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 (if (subrp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 (error "Can't disassemble #<subr %s>" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 (if (eq (car-safe obj) 'autoload)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 (load (elt obj 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 (setq obj (symbol-function name))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 (if (eq (car-safe obj) 'macro) ;handle macros
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 (setq macro t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 obj (cdr obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 (if (and (listp obj) (eq (car obj) 'byte-code))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 (setq obj (list 'lambda nil obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 (if (and (listp obj) (not (eq (car obj) 'lambda)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 (error "not a function"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 (if (consp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 (if (assq 'byte-code obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 (if interactive-p (message (if name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 "Compiling %s's definition..."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 "Compiling definition...")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 (setq obj (byte-compile obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 (if interactive-p (message "Done compiling. Disassembling..."))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 (cond ((consp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 (setq obj (cdr obj)) ;throw lambda away
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 (setq args (car obj)) ;save arg list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 (setq obj (cdr obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 (setq args (compiled-function-arglist obj))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (if (zerop indent) ; not a nested function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 (indent-to indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 (insert (format "byte code%s%s%s:\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 (if (or macro name) " for" "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 (if macro " macro" "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 (if name (format " %s" name) "")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 (let ((doc (if (consp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 (and (stringp (car obj)) (car obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 (condition-case error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 (documentation obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 (error (format "%S" error))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 (if (and doc (stringp doc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (progn (and (consp obj) (setq obj (cdr obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (indent-to indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 (princ " doc: " (current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 (let ((frobbed nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 (if (string-match "\n" doc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 (setq doc (substring doc 0 (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 frobbed t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 (if (> (length doc) 70)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 (setq doc (substring doc 0 65) frobbed t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 (if frobbed (setq doc (concat doc " ..."))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 (insert doc "\n"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 (indent-to indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 (insert " args: ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 (prin1 args (current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 (insert "\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 (if (condition-case ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 (commandp obj) ; ie interactivep
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 (error nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 (let ((interactive (if (consp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 (elt (assq 'interactive obj) 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 (elt (compiled-function-interactive obj) 1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 (if (eq (car-safe (car-safe obj)) 'interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 (setq obj (cdr obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (indent-to indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 (insert " interactive: ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 (if (eq (car-safe interactive) 'byte-code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 (insert "\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 (disassemble-1 interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 (+ indent disassemble-recursive-indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 (let ((print-escape-newlines t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (prin1 interactive (current-buffer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 (insert "\n")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 (cond ((and (consp obj) (assq 'byte-code obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (disassemble-1 (assq 'byte-code obj) indent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ((compiled-function-p obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 (disassemble-1 obj indent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (insert "Uncompiled body: ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (let ((print-escape-newlines t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (prin1 (if (cdr obj) (cons 'progn obj) (car obj))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (current-buffer))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (if interactive-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (message nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 (defun disassemble-1 (obj indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 "Print the byte-code call OBJ in the current buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 OBJ should be a compiled-function object generated by the byte compiler."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (let (bytes constvec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 (if (consp obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 (setq bytes (car (cdr obj)) ; the byte code
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 constvec (car (cdr (cdr obj)))) ; constant vector
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 (setq bytes (compiled-function-instructions obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 constvec (compiled-function-constants obj)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (let ((lap (byte-decompile-bytecode bytes constvec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 op arg opname pc-value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (let ((tagno 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 tmp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 (lap lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 (while (setq tmp (assq 'TAG lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 (setcar (cdr tmp) (setq tagno (1+ tagno)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 (setq lap (cdr (memq tmp lap)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 (while lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 ;; Take off the pc value of the next thing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 ;; and put it in pc-value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (setq pc-value nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (if (numberp (car lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (setq pc-value (car lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 lap (cdr lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 ;; Fetch the next op and its arg.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (setq op (car (car lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 arg (cdr (car lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (setq lap (cdr lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (indent-to indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 (if (eq 'TAG op)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 ;; We have a label. Display it, but first its pc value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (if pc-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 (insert (format "%d:" pc-value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 (insert (int-to-string (car arg))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 ;; We have an instruction. Display its pc value first.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 (if pc-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 (insert (format "%d" pc-value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (indent-to (+ indent disassemble-column-1-indent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 (if (and op
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 (string-match "^byte-" (setq opname (symbol-name op))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (setq opname (substring opname 5))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 (setq opname "<not-an-opcode>"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (if (eq op 'byte-constant2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (insert " #### shouldn't have seen constant2 here!\n "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 (insert opname)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (indent-to (+ indent disassemble-column-1-indent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 disassemble-column-2-indent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 -1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (insert " ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (cond ((memq op byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 (insert (int-to-string (nth 1 arg))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 ((memq op '(byte-call byte-unbind
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 byte-listN byte-concatN byte-insertN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 (insert (int-to-string arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 ((memq op '(byte-varref byte-varset byte-varbind))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 (prin1 (car arg) (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 ((memq op '(byte-constant byte-constant2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 ;; it's a constant
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 (setq arg (car arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 ;; but if the value of the constant is compiled code, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 ;; recursively disassemble it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 (cond ((or (compiled-function-p arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 (and (eq (car-safe arg) 'lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 (assq 'byte-code arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 (and (eq (car-safe arg) 'macro)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 (or (compiled-function-p (cdr arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 (and (eq (car-safe (cdr arg)) 'lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 (assq 'byte-code (cdr arg))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 (cond ((compiled-function-p arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 (insert "<compiled-function>\n"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 ((eq (car-safe arg) 'lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 (insert "<compiled lambda>"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 (t (insert "<compiled macro>\n")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (disassemble-internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 arg
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (+ indent disassemble-recursive-indent 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 ((eq (car-safe arg) 'byte-code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 (insert "<byte code>\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (disassemble-1 ;recurse on byte-code object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 arg
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (+ indent disassemble-recursive-indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 ((eq (car-safe (car-safe arg)) 'byte-code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 (insert "(<byte code>...)\n")
4783
e29fcfd8df5f Eliminate most core code byte-compile warnings.
Aidan Kehoe <kehoea@parhasard.net>
parents: 428
diff changeset
250 (mapc ;recurse on list of byte-code objects
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 #'(lambda (obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 (disassemble-1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 obj
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (+ indent disassemble-recursive-indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 ;; really just a constant
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (let ((print-escape-newlines t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 (prin1 arg (current-buffer))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 (insert "\n")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (provide 'disass)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 ;;; disass.el ends here