123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
- ; Disassembler that uses the VM's data structures.
- ;(define (disassemble stuff . no-subtemplates)
- ; (let ((template (cond ((template? stuff) stuff)
- ; ((closure? stuff) (closure-template stuff))
- ; ((and (location? stuff)
- ; (closure? (contents stuff)))
- ; (closure-template (contents stuff)))
- ; (else
- ; (error "cannot coerce to template" stuff)))))
- ; (really-disassemble template
- ; 0
- ; (if (null? no-subtemplates)
- ; #f
- ; (car no-subtemplates)))
- ; (newline)))
- (define (disassemble code-pointer)
- (really-disassemble code-pointer 0 #f))
- (define (really-disassemble code level write-templates?)
- (let loop ((pc 0))
- (if (< pc (code-vector-length code))
- (loop (write-instruction code pc level write-templates?)))))
- (define (newline-indent n)
- (newline)
- (do ((i n (- i 1)))
- ((= i 0))
- (display #\space)))
- (define (write-pc pc)
- (if (< pc 100) (display " "))
- (if (< pc 10) (display " "))
- (write pc))
- (define (write-instruction code pc level write-sub-templates?)
- (let ((opcode (code-vector-ref code pc)))
- (newline-indent (* level 3))
- (write-pc pc)
- (display " (")
- (write (enumerand->name opcode op))
- (let ((pc (cond ((= opcode (enum op computed-goto))
- (display-computed-goto pc code))
- ((or (= opcode (enum op make-flat-env))
- (= opcode (enum op make-big-flat-env)))
- (display-flat-env pc code))
- ((= opcode (enum op protocol))
- (display-protocol pc code))
- ((= opcode (enum op cont-data))
- (+ pc (get-offset (+ pc 1) code)))
- (else
- (print-opcode-args opcode (+ pc 1) code
- level write-sub-templates?)))))
- (display #\))
- pc)))
- (define (display-computed-goto start-pc code)
- (display #\space)
- (let ((count (code-vector-ref code (+ start-pc 1))))
- (write count)
- (do ((pc (+ start-pc 2) (+ pc 2))
- (count count (- count 1)))
- ((= count 0) pc)
- (display #\space)
- (write `(=> ,(+ start-pc (get-offset pc code)))))))
- (define (display-flat-env pc code)
- (let ((total-count (code-vector-ref code (+ pc 1))))
- (display #\space) (write total-count) (display "...")))
- ; (let loop ((pc (+ pc 2)) (count 0) (old-back 0))
- ; (if (= count total-count)
- ; pc
- ; (let ((back (+ (code-vector-ref code pc)
- ; old-back))
- ; (limit (+ pc 2 (code-vector-ref code (+ pc 1)))))
- ; (do ((pc (+ pc 2) (+ pc 1))
- ; (count count (+ count 1))
- ; (offsets '() (cons (code-vector-ref code pc) offsets)))
- ; ((= pc limit)
- ; (display #\space)
- ; (write `(,back ,(reverse offsets)))
- ; (loop pc count back))))))))
- (define (display-protocol pc code)
- (let ((protocol (code-vector-ref code (+ pc 1))))
- (display #\space)
- (+ pc (cond ((<= protocol maximum-stack-args)
- (display protocol)
- (if (= pc 0) 3 2))
- ((= protocol two-byte-nargs-protocol)
- (display (get-offset (+ pc 2) code))
- (if (= pc 0) 5 4))
- ((= protocol two-byte-nargs+list-protocol)
- (display (get-offset (+ pc 2) code))
- (display "+")
- (if (= pc 0) 5 4))
- ((= protocol args+nargs-protocol)
- (display "args+nargs")
- 3)
- ((= protocol ignore-values-protocol)
- (display "discard all values")
- 2)
- ((= protocol call-with-values-protocol)
- (display "call-with-values ")
- (write `(=> ,(+ pc (get-offset (+ pc 2) code))))
- 4)
- ((= protocol nary-dispatch-protocol)
- (display "nary-dispatch")
- (do ((i 0 (+ i 1)))
- ((= i 4))
- (let ((offset (code-vector-ref code (+ pc 2 i))))
- (if (not (= offset 0))
- (begin
- (display #\space)
- (display (list (if (= i 3) "3+" i)
- '=>
- (+ pc offset)))))))
- 6)
- (else
- (error "unknown protocol" protocol))))))
- (define (print-opcode-args op pc code level write-templates?)
- (let ((specs (vector-ref opcode-arg-specs op)))
- (let loop ((specs specs) (pc pc))
- (cond ((or (null? specs)
- (= 0 (arg-spec-size (car specs))))
- pc)
- (else
- (display #\space)
- (print-opcode-arg specs pc code level write-templates?)
- (loop (cdr specs) (+ pc (arg-spec-size (car specs)))))))))
- (define (arg-spec-size spec)
- (case spec
- ((nargs byte stob literal) 1)
- ((offset small-index index two-bytes) 2)
- (else 0)))
- (define (print-opcode-arg specs pc code level write-templates?)
- (case (car specs)
- ((nargs byte)
- (write (code-vector-ref code pc)))
- ((literal)
- (write (- (code-vector-ref code pc) 128)))
- ((two-bytes)
- (write (get-offset pc code)))
- ((index)
- (write (get-offset pc code)))
- ; (let ((thing (template-ref template (get-offset pc code))))
- ; (write-literal-thing thing level write-templates?))
- ((small-index)
- (write (code-vector-ref pc code)))
- ; (let ((thing (template-ref template (code-vector-ref code pc))))
- ; (write-literal-thing thing level write-templates?))
- ((offset)
- (write `(=> ,(+ pc -1 (get-offset pc code))))) ; -1 to back up over opcode
- ((stob)
- (write (enumerand->name (code-vector-ref code pc) stob)))))
- (define (get-offset pc code)
- (+ (* (code-vector-ref code pc)
- byte-limit)
- (code-vector-ref code (+ pc 1))))
- (define (write-literal-thing thing level write-templates?)
- (cond ((location? thing)
- (write `(location ,thing ,(location-id thing))))
- ((not (template? thing))
- (display #\')
- (write thing))
- (write-templates?
- (really-disassemble thing (+ level 1) #t))
- (else
- (display "..."))))
|