disasm.scm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Disassembler that uses the VM's data structures.
  3. ;(define (disassemble stuff . no-subtemplates)
  4. ; (let ((template (cond ((template? stuff) stuff)
  5. ; ((closure? stuff) (closure-template stuff))
  6. ; ((and (location? stuff)
  7. ; (closure? (contents stuff)))
  8. ; (closure-template (contents stuff)))
  9. ; (else
  10. ; (error "cannot coerce to template" stuff)))))
  11. ; (really-disassemble template
  12. ; 0
  13. ; (if (null? no-subtemplates)
  14. ; #f
  15. ; (car no-subtemplates)))
  16. ; (newline)))
  17. (define (disassemble code-pointer)
  18. (really-disassemble code-pointer 0 #f))
  19. (define (really-disassemble code level write-templates?)
  20. (let loop ((pc 0))
  21. (if (< pc (code-vector-length code))
  22. (loop (write-instruction code pc level write-templates?)))))
  23. (define (newline-indent n)
  24. (newline)
  25. (do ((i n (- i 1)))
  26. ((= i 0))
  27. (display #\space)))
  28. (define (write-pc pc)
  29. (if (< pc 100) (display " "))
  30. (if (< pc 10) (display " "))
  31. (write pc))
  32. (define (write-instruction code pc level write-sub-templates?)
  33. (let ((opcode (code-vector-ref code pc)))
  34. (newline-indent (* level 3))
  35. (write-pc pc)
  36. (display " (")
  37. (write (enumerand->name opcode op))
  38. (let ((pc (cond ((= opcode (enum op computed-goto))
  39. (display-computed-goto pc code))
  40. ((or (= opcode (enum op make-flat-env))
  41. (= opcode (enum op make-big-flat-env)))
  42. (display-flat-env pc code))
  43. ((= opcode (enum op protocol))
  44. (display-protocol pc code))
  45. ((= opcode (enum op cont-data))
  46. (+ pc (get-offset (+ pc 1) code)))
  47. (else
  48. (print-opcode-args opcode (+ pc 1) code
  49. level write-sub-templates?)))))
  50. (display #\))
  51. pc)))
  52. (define (display-computed-goto start-pc code)
  53. (display #\space)
  54. (let ((count (code-vector-ref code (+ start-pc 1))))
  55. (write count)
  56. (do ((pc (+ start-pc 2) (+ pc 2))
  57. (count count (- count 1)))
  58. ((= count 0) pc)
  59. (display #\space)
  60. (write `(=> ,(+ start-pc (get-offset pc code)))))))
  61. (define (display-flat-env pc code)
  62. (let ((total-count (code-vector-ref code (+ pc 1))))
  63. (display #\space) (write total-count) (display "...")))
  64. ; (let loop ((pc (+ pc 2)) (count 0) (old-back 0))
  65. ; (if (= count total-count)
  66. ; pc
  67. ; (let ((back (+ (code-vector-ref code pc)
  68. ; old-back))
  69. ; (limit (+ pc 2 (code-vector-ref code (+ pc 1)))))
  70. ; (do ((pc (+ pc 2) (+ pc 1))
  71. ; (count count (+ count 1))
  72. ; (offsets '() (cons (code-vector-ref code pc) offsets)))
  73. ; ((= pc limit)
  74. ; (display #\space)
  75. ; (write `(,back ,(reverse offsets)))
  76. ; (loop pc count back))))))))
  77. (define (display-protocol pc code)
  78. (let ((protocol (code-vector-ref code (+ pc 1))))
  79. (display #\space)
  80. (+ pc (cond ((<= protocol maximum-stack-args)
  81. (display protocol)
  82. (if (= pc 0) 3 2))
  83. ((= protocol two-byte-nargs-protocol)
  84. (display (get-offset (+ pc 2) code))
  85. (if (= pc 0) 5 4))
  86. ((= protocol two-byte-nargs+list-protocol)
  87. (display (get-offset (+ pc 2) code))
  88. (display "+")
  89. (if (= pc 0) 5 4))
  90. ((= protocol args+nargs-protocol)
  91. (display "args+nargs")
  92. 3)
  93. ((= protocol ignore-values-protocol)
  94. (display "discard all values")
  95. 2)
  96. ((= protocol call-with-values-protocol)
  97. (display "call-with-values ")
  98. (write `(=> ,(+ pc (get-offset (+ pc 2) code))))
  99. 4)
  100. ((= protocol nary-dispatch-protocol)
  101. (display "nary-dispatch")
  102. (do ((i 0 (+ i 1)))
  103. ((= i 4))
  104. (let ((offset (code-vector-ref code (+ pc 2 i))))
  105. (if (not (= offset 0))
  106. (begin
  107. (display #\space)
  108. (display (list (if (= i 3) "3+" i)
  109. '=>
  110. (+ pc offset)))))))
  111. 6)
  112. (else
  113. (error "unknown protocol" protocol))))))
  114. (define (print-opcode-args op pc code level write-templates?)
  115. (let ((specs (vector-ref opcode-arg-specs op)))
  116. (let loop ((specs specs) (pc pc))
  117. (cond ((or (null? specs)
  118. (= 0 (arg-spec-size (car specs))))
  119. pc)
  120. (else
  121. (display #\space)
  122. (print-opcode-arg specs pc code level write-templates?)
  123. (loop (cdr specs) (+ pc (arg-spec-size (car specs)))))))))
  124. (define (arg-spec-size spec)
  125. (case spec
  126. ((nargs byte stob literal) 1)
  127. ((offset small-index index two-bytes) 2)
  128. (else 0)))
  129. (define (print-opcode-arg specs pc code level write-templates?)
  130. (case (car specs)
  131. ((nargs byte)
  132. (write (code-vector-ref code pc)))
  133. ((literal)
  134. (write (- (code-vector-ref code pc) 128)))
  135. ((two-bytes)
  136. (write (get-offset pc code)))
  137. ((index)
  138. (write (get-offset pc code)))
  139. ; (let ((thing (template-ref template (get-offset pc code))))
  140. ; (write-literal-thing thing level write-templates?))
  141. ((small-index)
  142. (write (code-vector-ref pc code)))
  143. ; (let ((thing (template-ref template (code-vector-ref code pc))))
  144. ; (write-literal-thing thing level write-templates?))
  145. ((offset)
  146. (write `(=> ,(+ pc -1 (get-offset pc code))))) ; -1 to back up over opcode
  147. ((stob)
  148. (write (enumerand->name (code-vector-ref code pc) stob)))))
  149. (define (get-offset pc code)
  150. (+ (* (code-vector-ref code pc)
  151. byte-limit)
  152. (code-vector-ref code (+ pc 1))))
  153. (define (write-literal-thing thing level write-templates?)
  154. (cond ((location? thing)
  155. (write `(location ,thing ,(location-id thing))))
  156. ((not (template? thing))
  157. (display #\')
  158. (write thing))
  159. (write-templates?
  160. (really-disassemble thing (+ level 1) #t))
  161. (else
  162. (display "..."))))