This file is indexed.

/usr/share/scheme48-1.9/env/disasm.scm is in scheme48 1.9-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
; Part of Scheme 48 1.9.  See file COPYING for notices and license.

; Authors: Richard Kelsey, Jonathan Rees, Martin Gasbichler, Mike Sperber

;;;; Disassembler

; This will need to track the template's offset.  Drat.

; This defines a command processor command
;      dis <expression>
; that evaluates <expression> to obtain a procedure or lambda-expression,
; which is then disassembled.

; The assembly language is designed to be rereadable.  See env/assem.scm.

(define-command-syntax 'dis "[<exp>]" "disassemble procedure"
  '(&opt expression))

; The command.  The thing to be disassembled defaults to the focus object (##).

(define (dis . maybe-exp)
  (disassemble (if (null? maybe-exp)
		   (focus-object)
		   (eval (car maybe-exp) (environment-for-commands)))))

(define (disassemble obj)
  (really-disassemble (coerce-to-template-or-code obj) 0)
  (newline))

(define (really-disassemble template-or-code level)
    (let* ((template (if (template? template-or-code)
                         template-or-code
                         #f))
           (code (if template
                     (template-code template)
                     template-or-code)))
      (parse-template-code template code level disasm-attribution)))

(define (disasm-init-template level template p-args push-template? push-env? push-closure?)
  (if (template-name template)
      (write (template-name template)))
  (print-opcode (enum op protocol) 0 level)
  (show-protocol p-args 0)
  (if (or push-template? push-env? push-closure?)
      (begin
        (display " (push")
	(if push-closure?
	    (display " closure"))
        (if push-env?
            (display " env"))
        (if push-template?
            (display " template"))
        (display #\))))
  (display #\))
  level)

(define (disasm-attribute-literal literal index level)
  level)

(define (disasm-make-label target-pc)
  target-pc)

(define (disasm-at-label label level)
  level)

(define disasm-table (make-opcode-table
                               (lambda (opcode template level pc len . args)
                                 (print-opcode opcode pc level)
                                 (print-opcode-args args)
                                 (display #\))
                                 level)))

(define disasm-attribution
  (make-attribution disasm-init-template disasm-attribute-literal 
                    disasm-table disasm-make-label disasm-at-label))

(define-syntax define-disasm
  (syntax-rules ()
    ((define-disasm inst disasm)
     (opcode-table-set! disasm-table (enum op inst) disasm))))

;------------------------------
(define-disasm protocol
  (lambda (opcode template level pc len p-args)
    (print-opcode opcode pc level)
    (show-protocol (cdr p-args) pc)
    (display #\))
    level))

(define (show-protocol p-args pc)
  (let ((protocol (car p-args)))
    (display #\space)
    (cond ((<= protocol maximum-stack-args)
           (display protocol))
          ((= protocol two-byte-nargs-protocol)
           (display (cadr p-args)))
          ((= protocol two-byte-nargs+list-protocol)
           (display (cadr p-args))
           (display " +"))
          ((= protocol ignore-values-protocol)
           (display "discard all values"))
          ((= protocol call-with-values-protocol)
           (display "call-with-values")
           (let ((target-pc (cadr p-args)))
             (if (not (= pc target-pc))
                 (begin
                   (display #\space)
                   (write `(=> ,(cadr p-args)))))))
          ((= protocol args+nargs-protocol)
           (display "args+nargs ")
           (display (cadr p-args))
           (display "+"))
          ((= protocol nary-dispatch-protocol)
           (display "nary-dispatch")
           (for-each display-dispatch (cdr p-args) (list 0 1 2 "3+")))
          ((= protocol big-stack-protocol)
           (apply
            (lambda (real-attribution stack-size)
              (display "big-stack")
              (show-protocol real-attribution pc)
              (display #\space)
              (display stack-size))
            (cdr p-args)))
          (else
           (assertion-violation 'show-protocol "unknown protocol" protocol)))))

(define (display-dispatch target-pc tag)
  (if target-pc
      (begin
        (display #\space)
        (display (list tag '=> target-pc)))))

;------------------------------
(define-disasm global
  (lambda (opcode template level pc len index-to-template index-within-template)
    (print-opcode opcode pc level)
    (print-opcode-args (list index-to-template index-within-template))
    (display #\space)
    (display-global-reference template (cdr index-within-template))
    (display #\))
    level))

(define-disasm set-global!
  (lambda (opcode template level pc len index-to-template index-within-template)
    (print-opcode opcode pc level)
    (print-opcode-args (list index-to-template index-within-template))
    (display #\space)
    (display-global-reference template (cdr index-within-template))
    (display #\))
    level))    

(define (display-global-reference template index)
  (let ((loc (if template
		 (template-ref template index)
		 #f)))
    (cond ((location? loc)
	   (write (or (location-name loc)
		      `(location ,(location-id loc)))))
	  (else
	   (display #\')
	   (write loc)))))


;------------------------------
(define (disasm-make-flat-env opcode template level pc len env-data-arg)
  (let ((env-data (cdr env-data-arg)))
    (print-opcode opcode pc level)
    (display #\space)
    (write (env-data-total-count env-data))
    (display #\space)
    
    (let ((closure-offsets (env-data-closure-offsets env-data)))
      (if (not (null? closure-offsets))
          (begin
            (write (length closure-offsets))
            (display-flat-env-closures env-data))
          (write 0)))

    (display #\space)
    (display (env-data-frame-offsets env-data))

    (for-each (lambda (env-offset)
                (display #\space)
                (display #\()
                (display (car env-offset))
                (display " => ")
                (display (cdr env-offset))
                (display #\)))
              (env-data-env-offsets env-data))
    (display #\))
    level))

(define (display-flat-env-closures env-data)
  (display " (closures from ")
  (display (env-data-maybe-template-index env-data))
  (display #\:)
  (for-each (lambda (offset)
              (display #\space)
              (display offset))
            (env-data-closure-offsets env-data))
  (display #\)))

(define-disasm make-flat-env disasm-make-flat-env)
(define-disasm make-big-flat-env disasm-make-flat-env)

;------------------------------

(define (display-cont-data cont-data)
  (write-char #\space)
  (display (list '=> (cont-data-pc cont-data)))
  (write-char #\space)
  (display (list 'depth (cont-data-depth cont-data)))
  (write-char #\space)
  (display (list 'template (cont-data-template cont-data)))
  (write-char #\space)
  (cond
   ((cont-data-live-offsets cont-data)
    => (lambda (offsets)
	 (display (cons 'live offsets))))
   (else
    (display "all-live"))))

(define-disasm cont-data
  (lambda (opcode template level pc len cont-data-arg)
    (print-opcode opcode pc level)
    (display-cont-data (cdr cont-data-arg))
    (display #\))
    level))
;------------------------------
(define (display-shuffle opcode template level pc len moves-data)
  (print-opcode opcode pc level)
  (write-char #\space)
  (let ((moves (cdr moves-data)))
    (display (length moves))
    (for-each (lambda (move)
                (write-char #\space)
                (display (list (car move) (cdr move))))
              moves)
    (write-char #\))
    level))    

(define-disasm stack-shuffle! display-shuffle)
(define-disasm big-stack-shuffle! display-shuffle)

(define (write-instruction code template pc level write-sub-templates?)
  ;; As in the previous version, WRITE-SUB-TEMPLATES? is ignored and
  ;; sub templates are never written.
  (call-with-values 
   (lambda ()
     (parse-instruction template code pc level disasm-attribution))
   (lambda (len level)
     (+ pc len))))

;------------------------------
(define (print-opcode opcode pc level)    
  (newline-indent (* level 3))
  (write-pc pc)
  (display " (")
  (write (enumerand->name opcode op)))

; Generic opcode argument printer.

(define (print-opcode-args args)
  (for-each (lambda (arg)
              (display #\space)
              (print-opcode-arg arg))
            args))

; Print out the particular type of argument.  

; This works only for the generic argument types, the special types
; are handled by the instruction disassemblers themselves

(define (print-opcode-arg spec.arg)
  (let ((spec (car spec.arg))
        (arg (cdr spec.arg)))
    (case spec
      ((byte two-bytes nargs two-byte-nargs literal index two-byte-index
             stack-index two-byte-stack-index)
       (write arg))
      ((offset)
       (write `(=> ,arg)))
      ((offset-)
       (write `(=> ,arg)))
      ((stob)
       (write (enumerand->name arg stob)))
      ((instr)
       (write arg))
      (else
       (assertion-violation 'print-opcode-arg "unknown arg spec" spec)))))

;----------------
; Utilities.

; Turn OBJ into a template, if possible.

(define (coerce-to-template-or-code obj)
  (cond ((template? obj)
	 obj)
	((closure? obj)
	 (closure-template obj))
	((continuation? obj)
	 (or (continuation-template obj)
	     (continuation-code obj)))
	(else
	 (assertion-violation 'coerce-to-template-or-code
			      "expected a procedure or continuation" obj))))

; Indenting and aligning the program counter.

(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))