Annotation of 43BSDReno/contrib/emacs-18.55/lisp/disass.el, revision 1.1

1.1     ! root        1: ;;; Disassembler for compiled Emacs Lisp code
        !             2: ;; Copyright (C) 1986 Free Software Foundation
        !             3: ;;; By Doug Cutting ([email protected])
        !             4: 
        !             5: ;; This file is part of GNU Emacs.
        !             6: 
        !             7: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             8: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             9: ;; accepts responsibility to anyone for the consequences of using it
        !            10: ;; or for whether it serves any particular purpose or works at all,
        !            11: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            12: ;; License for full details.
        !            13: 
        !            14: ;; Everyone is granted permission to copy, modify and redistribute
        !            15: ;; GNU Emacs, but only under the conditions described in the
        !            16: ;; GNU Emacs General Public License.   A copy of this license is
        !            17: ;; supposed to have been given to you along with GNU Emacs so you
        !            18: ;; can know your rights and responsibilities.  It should be in a
        !            19: ;; file named COPYING.  Among other things, the copyright notice
        !            20: ;; and this notice must be preserved on all copies.
        !            21: 
        !            22: 
        !            23: (require 'byte-compile "bytecomp")
        !            24: 
        !            25: (defvar disassemble-column-1-indent 4 "*")
        !            26: 
        !            27: (defvar disassemble-column-2-indent 9 "*")
        !            28: 
        !            29: (defvar disassemble-recursive-indent 3 "*")
        !            30: 
        !            31: ;(defun d (x)
        !            32: ;  (interactive "xDiss ")
        !            33: ;  (with-output-to-temp-buffer "*Disassemble*"
        !            34: ;    (disassemble-internal (list 'lambda '() x ''return-value)
        !            35: ;                        standard-output 0 t)))
        !            36: 
        !            37: (defun disassemble (object &optional stream indent interactive-p)
        !            38:   "Print disassembled code for OBJECT on (optional) STREAM.
        !            39: OBJECT can be a function name, lambda expression or any function object
        !            40: returned by SYMBOL-FUNCTION.  If OBJECT is not already compiled, we will
        !            41: compile it (but not redefine it)."
        !            42:   (interactive (list (intern (completing-read "Disassemble function: "
        !            43:                                              obarray 'fboundp t))
        !            44:                     nil 0 t))
        !            45:   (or indent (setq indent 0))          ;Default indent to zero
        !            46:   (if interactive-p
        !            47:       (with-output-to-temp-buffer "*Disassemble*"
        !            48:        (disassemble-internal object standard-output indent t))
        !            49:     (disassemble-internal object (or stream standard-output) indent nil))
        !            50:   nil)
        !            51: 
        !            52: (defun disassemble-internal (obj stream indent interactive-p)
        !            53:   (let ((macro 'nil)
        !            54:        (name 'nil)
        !            55:        (doc 'nil)
        !            56:        args)
        !            57:     (while (symbolp obj)
        !            58:       (setq name obj
        !            59:            obj (symbol-function obj)))
        !            60:     (if (subrp obj)
        !            61:        (error "Can't disassemble #<subr %s>" name))
        !            62:     (if (eq (car obj) 'macro)          ;handle macros
        !            63:        (setq macro t
        !            64:              obj (cdr obj)))
        !            65:     (if (not (eq (car obj) 'lambda))
        !            66:        (error "not a function"))
        !            67:     (if (assq 'byte-code obj)
        !            68:        nil
        !            69:       (if interactive-p (message (if name
        !            70:                                     "Compiling %s's definition..."
        !            71:                                     "Compiling definition...")
        !            72:                                 name))
        !            73:       (setq obj (byte-compile-lambda obj))
        !            74:       (if interactive-p (message "Done compiling.  Disassembling...")))
        !            75:     (setq obj (cdr obj))               ;throw lambda away
        !            76:     (setq args (car obj))              ;save arg list
        !            77:     (setq obj (cdr obj))
        !            78:     (write-spaces indent stream)
        !            79:     (princ (format "byte code%s%s%s:\n"
        !            80:                   (if (or macro name) " for" "")
        !            81:                   (if macro " macro" "")
        !            82:                   (if name (format " %s" name) ""))
        !            83:           stream)
        !            84:     (let ((doc (and (stringp (car obj)) (car obj))))
        !            85:       (if doc
        !            86:          (progn (setq obj (cdr obj))
        !            87:                 (write-spaces indent stream)
        !            88:                 (princ " doc: " stream)
        !            89:                 (princ doc stream)
        !            90:                 (terpri stream))))
        !            91:     (write-spaces indent stream)
        !            92:     (princ " args: " stream)
        !            93:     (prin1 args stream)
        !            94:     (terpri stream)
        !            95:     (let ((interactive (car (cdr (assq 'interactive obj)))))
        !            96:       (if interactive
        !            97:          (progn (write-spaces indent stream)
        !            98:                 (princ " interactive: " stream)
        !            99:                 (if (eq (car-safe interactive) 'byte-code)
        !           100:                     (disassemble-1 interactive stream
        !           101:                       (+ indent disassemble-recursive-indent))
        !           102:                   (prin1 interactive stream)
        !           103:                   (terpri stream)))))
        !           104:     (setq obj (assq 'byte-code obj))   ;obj is now call to byte-code
        !           105:     (disassemble-1 obj stream indent))
        !           106:   (if interactive-p
        !           107:       (message "")))
        !           108: 
        !           109: (defun disassemble-1 (obj &optional stream indent)
        !           110:   "Prints the byte-code call OBJ to (optional) STREAM.
        !           111: OBJ should be a call to BYTE-CODE generated by the byte compiler."
        !           112:   (or indent (setq indent 0))          ;default indent to 0
        !           113:   (or stream (setq stream standard-output))
        !           114:   (let ((bytes (car (cdr obj)))                ;the byte code
        !           115:        (ptr -1)                        ;where we are in it
        !           116:        (constants (car (cdr (cdr obj)))) ;constant vector
        !           117:        ;(next-indent indent)
        !           118:        offset tmp length)
        !           119:     (setq length (length bytes))
        !           120:     (terpri stream)
        !           121:     (while (< (setq ptr (1+ ptr)) length)
        !           122:       ;(setq indent next-indent)
        !           123:       (write-spaces indent stream)     ;indent to recursive indent
        !           124:       (princ (setq tmp (prin1-to-string ptr)) stream) ;print line #
        !           125:       (write-char ?\  stream)
        !           126:       (write-spaces (- disassemble-column-1-indent (length tmp) 1)
        !           127:                    stream)
        !           128:       (setq op (aref bytes ptr))       ;fetch opcode
        !           129:       ;; Note: as offsets are either encoded in opcodes or stored as
        !           130:       ;; bytes in the code, this function (disassemble-offset)
        !           131:       ;; can set OP and/or PTR.
        !           132:       (setq offset (disassemble-offset));fetch offset
        !           133:       (setq tmp (aref byte-code-vector op))
        !           134:       (if (consp tmp)
        !           135:          (setq ;next-indent (if (numberp (cdr tmp))
        !           136:                ;               (+ indent (cdr tmp))
        !           137:                ;             (+ indent (funcall (cdr tmp) offset)))
        !           138:                tmp (car tmp)))
        !           139:       (setq tmp (symbol-name tmp))
        !           140:       (princ tmp stream)               ;print op-name for opcode
        !           141:       (if (null offset)
        !           142:          nil
        !           143:        (write-char ?\  stream)
        !           144:        (write-spaces (- disassemble-column-2-indent (length tmp) 1)
        !           145:                      stream)           ;indent to col 2
        !           146:        (princ                          ;print offset
        !           147:         (cond ((or (eq op byte-varref)
        !           148:                    (eq op byte-varset)
        !           149:                    (eq op byte-varbind))
        !           150:                ;; it's a varname (atom)
        !           151:                (aref constants offset)) ;fetch it from constants
        !           152:               ((or (eq op byte-goto)
        !           153:                    (eq op byte-goto-if-nil)
        !           154:                    (eq op byte-goto-if-not-nil)
        !           155:                    (eq op byte-goto-if-nil-else-pop)
        !           156:                    (eq op byte-goto-if-not-nil-else-pop)
        !           157:                    (eq op byte-call)
        !           158:                    (eq op byte-unbind))
        !           159:                ;; it's a number
        !           160:                offset)                 ;return it
        !           161:               ((or (eq op byte-constant)
        !           162:                    (eq op byte-constant2))
        !           163:                ;; it's a constant
        !           164:                (setq tmp (aref constants offset))
        !           165:                ;; but is constant byte code?
        !           166:                (cond ((and (eq (car-safe tmp) 'lambda)
        !           167:                            (assq 'byte-code tmp))
        !           168:                       (princ "<compiled lambda>" stream)
        !           169:                       (terpri stream)
        !           170:                       (disassemble     ;recurse on compiled lambda
        !           171:                         tmp
        !           172:                         stream
        !           173:                         (+ indent disassemble-recursive-indent))
        !           174:                       "")
        !           175:                      ((eq (car-safe tmp) 'byte-code)
        !           176:                       (princ "<byte code>" stream)
        !           177:                       (terpri stream)
        !           178:                       (disassemble-1   ;recurse on byte-code object
        !           179:                         tmp
        !           180:                         stream
        !           181:                         (+ indent disassemble-recursive-indent))
        !           182:                       "")
        !           183:                      ((eq (car-safe (car-safe tmp)) 'byte-code)
        !           184:                       (princ "(<byte code>...)" stream)
        !           185:                       (terpri stream)
        !           186:                       (mapcar          ;recurse on list of byte-code objects
        !           187:                         (function (lambda (obj)
        !           188:                                     (disassemble-1
        !           189:                                       obj
        !           190:                                       stream
        !           191:                                       (+ indent disassemble-recursive-indent))))
        !           192:                         tmp)
        !           193:                       "")
        !           194:                      ((and (eq tmp 'byte-code) 
        !           195:                            (eq (aref bytes (+ ptr 4)) (+ byte-call 3)))
        !           196:                       ;; this won't catch cases where args are pushed w/
        !           197:                       ;; constant2.
        !           198:                       (setq ptr (+ ptr 4))
        !           199:                       "<compiled call to byte-code.  compiled code compiled?>")
        !           200:                      (t
        !           201:                       ;; really just a constant
        !           202:                       (let ((print-escape-newlines t))
        !           203:                         (prin1-to-string tmp)))))
        !           204:               (t "<error in disassembler>"))
        !           205:         stream))
        !           206:       (terpri stream)))
        !           207:   nil)
        !           208: 
        !           209: 
        !           210: (defun disassemble-offset ()
        !           211:   "Don't call this!"
        !           212:   ;; fetch and return the offset for the current opcode.
        !           213:   ;; return NIL if this opcode has no offset
        !           214:   ;; OP, PTR and BYTES are used and set dynamically
        !           215:   (let (tem)
        !           216:     (cond ((< op byte-nth)
        !           217:           (setq tem (logand op 7))
        !           218:           (setq op (logand op 248))
        !           219:           (cond ((eq tem 6)
        !           220:                  (setq ptr (1+ ptr))   ;offset in next byte
        !           221:                  (aref bytes ptr))
        !           222:                 ((eq tem 7)
        !           223:                  (setq ptr (1+ ptr))   ;offset in next 2 bytes
        !           224:                  (+ (aref bytes ptr)
        !           225:                     (progn (setq ptr (1+ ptr))
        !           226:                            (lsh (aref bytes ptr) 8))))
        !           227:                 (t tem)))      ;offset was in opcode
        !           228:          ((>= op byte-constant)
        !           229:           (setq tem (- op byte-constant)) ;offset in opcode
        !           230:           (setq op byte-constant)
        !           231:           tem)
        !           232:          ((or (= op byte-constant2)
        !           233:               (and (>= op byte-goto)
        !           234:                    (<= op byte-goto-if-not-nil-else-pop)))
        !           235:           (setq ptr (1+ ptr))          ;offset in next 2 bytes
        !           236:           (+ (aref bytes ptr)
        !           237:              (progn (setq ptr (1+ ptr))
        !           238:                     (lsh (aref bytes ptr) 8))))
        !           239:          (t nil))))                    ;no offset
        !           240: 
        !           241: 
        !           242: (defun write-spaces (n &optional stream)
        !           243:   "Print N spaces to (optional) STREAM."
        !           244:   (or stream (setq stream standard-output))
        !           245:   (if (< n 0) (setq n 0))
        !           246:   (if (eq stream (current-buffer))
        !           247:       (insert-char ?\  n)
        !           248:     (while (> n 0)
        !           249:       (write-char ?\  stream)
        !           250:       (setq n (1- n)))))
        !           251: 
        !           252: (defconst byte-code-vector
        !           253:  '[<not-an-opcode>
        !           254:    <not-an-opcode>
        !           255:    <not-an-opcode>
        !           256:    <not-an-opcode>
        !           257:    <not-an-opcode>
        !           258:    <not-an-opcode>
        !           259:    <not-an-opcode>
        !           260:    <not-an-opcode>
        !           261:    (varref . 1)
        !           262:    <not-an-opcode>
        !           263:    <not-an-opcode>
        !           264:    <not-an-opcode>
        !           265:    <not-an-opcode>
        !           266:    <not-an-opcode>
        !           267:    <not-an-opcode>
        !           268:    <not-an-opcode>
        !           269:    (varset . -1)
        !           270:    <not-an-opcode>
        !           271:    <not-an-opcode>
        !           272:    <not-an-opcode>
        !           273:    <not-an-opcode>
        !           274:    <not-an-opcode>
        !           275:    <not-an-opcode>
        !           276:    <not-an-opcode>
        !           277:    (varbind . 0);Pops a value, "pushes" a binding
        !           278:    <not-an-opcode>
        !           279:    <not-an-opcode>
        !           280:    <not-an-opcode>
        !           281:    <not-an-opcode>
        !           282:    <not-an-opcode>
        !           283:    <not-an-opcode>
        !           284:    <not-an-opcode>
        !           285:    (call . -); #'-, not -1!
        !           286:    <not-an-opcode>
        !           287:    <not-an-opcode>
        !           288:    <not-an-opcode>
        !           289:    <not-an-opcode>
        !           290:    <not-an-opcode>
        !           291:    <not-an-opcode>
        !           292:    <not-an-opcode>
        !           293:    (unbind . -);"pops" bindings
        !           294:    <not-an-opcode>
        !           295:    <not-an-opcode>
        !           296:    <not-an-opcode>
        !           297:    <not-an-opcode>
        !           298:    <not-an-opcode>
        !           299:    <not-an-opcode>
        !           300:    <not-an-opcode>
        !           301:    <not-an-opcode>
        !           302:    <not-an-opcode>
        !           303:    <not-an-opcode>
        !           304:    <not-an-opcode>
        !           305:    <not-an-opcode>
        !           306:    <not-an-opcode>
        !           307:    <not-an-opcode>
        !           308:    <not-an-opcode>
        !           309:    (nth . -1)
        !           310:    symbolp
        !           311:    consp
        !           312:    stringp
        !           313:    listp
        !           314:    (eq . -1)
        !           315:    (memq . -1)
        !           316:    not
        !           317:    car
        !           318:    cdr
        !           319:    (cons . -1)
        !           320:    list1
        !           321:    (list2 . -1)
        !           322:    (list3 . -2)
        !           323:    (list4 . -3)
        !           324:    length
        !           325:    (aref . -1)
        !           326:    (aset . -2)
        !           327:    symbol-value
        !           328:    symbol-function
        !           329:    (set . -1)
        !           330:    (fset . -1)
        !           331:    (get . -1)
        !           332:    (substring . -2)
        !           333:    (concat2 . -1)
        !           334:    (concat3 . -2)
        !           335:    (concat4 . -3)
        !           336:    sub1
        !           337:    add1
        !           338:    (eqlsign . -1) ;=
        !           339:    (gtr . -1)     ;>
        !           340:    (lss . -1)     ;<
        !           341:    (leq . -1)     ;<=
        !           342:    (geq . -1)     ;>=
        !           343:    (diff . -1)    ;-
        !           344:    negate         ;unary -
        !           345:    (plus . -1)    ;+
        !           346:    (max . -1)
        !           347:    (min . -1)
        !           348:    <not-an-opcode>
        !           349:    (point . 1)
        !           350:    (mark\(obsolete\) . 1)
        !           351:    goto-char 
        !           352:    insert
        !           353:    (point-max . 1)
        !           354:    (point-min . 1)
        !           355:    char-after
        !           356:    (following-char . 1)
        !           357:    (preceding-char . 1)
        !           358:    (current-column . 1)
        !           359:    (indent-to . 1)
        !           360:    (scan-buffer\(obsolete\) . -2)
        !           361:    (eolp . 1)
        !           362:    (eobp . 1)
        !           363:    (bolp . 1)
        !           364:    (bobp . 1)
        !           365:    (current-buffer . 1)
        !           366:    set-buffer
        !           367:    (read-char . 1)
        !           368:    set-mark\(obsolete\)
        !           369:    interactive-p
        !           370:    <not-an-opcode>
        !           371:    <not-an-opcode>
        !           372:    <not-an-opcode>
        !           373:    <not-an-opcode>
        !           374:    <not-an-opcode>
        !           375:    <not-an-opcode>
        !           376:    <not-an-opcode>
        !           377:    <not-an-opcode>
        !           378:    <not-an-opcode>
        !           379:    <not-an-opcode>
        !           380:    <not-an-opcode>
        !           381:    <not-an-opcode>
        !           382:    (constant2 . 1)
        !           383:    goto;>>>
        !           384:    goto-if-nil;>>
        !           385:    goto-if-not-nil;>>
        !           386:    (goto-if-nil-else-pop . -1)
        !           387:    (goto-if-not-nil-else-pop . -1)
        !           388:    return
        !           389:    (discard . -1)
        !           390:    (dup . 1)
        !           391:    (save-excursion . 1);Pushes a binding
        !           392:    (save-window-excursion . 1);Pushes a binding
        !           393:    (save-restriction . 1);Pushes a binding
        !           394:    (catch . -1);Takes one argument, returns a value
        !           395:    (unwind-protect . 1);Takes one argument, pushes a binding, returns a value
        !           396:    (condition-case . -2);Takes three arguments, returns a value
        !           397:    (temp-output-buffer-setup . -1)
        !           398:    temp-output-buffer-show
        !           399:    <not-an-opcode>
        !           400:    <not-an-opcode>
        !           401:    <not-an-opcode>
        !           402:    <not-an-opcode>
        !           403:    <not-an-opcode>
        !           404:    <not-an-opcode>
        !           405:    <not-an-opcode>
        !           406:    <not-an-opcode>
        !           407:    <not-an-opcode>
        !           408:    <not-an-opcode>
        !           409:    <not-an-opcode>
        !           410:    <not-an-opcode>
        !           411:    <not-an-opcode>
        !           412:    <not-an-opcode>
        !           413:    <not-an-opcode>
        !           414:    <not-an-opcode>
        !           415:    <not-an-opcode>
        !           416:    <not-an-opcode>
        !           417:    <not-an-opcode>
        !           418:    <not-an-opcode>
        !           419:    <not-an-opcode>
        !           420:    <not-an-opcode>
        !           421:    <not-an-opcode>
        !           422:    <not-an-opcode>
        !           423:    <not-an-opcode>
        !           424:    <not-an-opcode>
        !           425:    <not-an-opcode>
        !           426:    <not-an-opcode>
        !           427:    <not-an-opcode>
        !           428:    <not-an-opcode>
        !           429:    <not-an-opcode>
        !           430:    <not-an-opcode>
        !           431:    <not-an-opcode>
        !           432:    <not-an-opcode>
        !           433:    <not-an-opcode>
        !           434:    <not-an-opcode>
        !           435:    <not-an-opcode>
        !           436:    <not-an-opcode>
        !           437:    <not-an-opcode>
        !           438:    <not-an-opcode>
        !           439:    <not-an-opcode>
        !           440:    <not-an-opcode>
        !           441:    <not-an-opcode>
        !           442:    <not-an-opcode>
        !           443:    <not-an-opcode>
        !           444:    <not-an-opcode>
        !           445:    (constant . 1)
        !           446:    ])
        !           447: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.