disclosers.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; --------------------
  3. ; DISCLOSE methods
  4. (define-method &disclose ((obj :closure))
  5. (let ((id (template-id (closure-template obj)))
  6. (name (template-print-name (closure-template obj))))
  7. (if name
  8. (list 'procedure
  9. id
  10. ;; A heuristic that sometimes loses.
  11. ; (if (and (pair? name)
  12. ; (eq? (car name) '#t) ;Curried
  13. ; (vector? (closure-env obj)))
  14. ; (error-form
  15. ; (if (null? (cdddr name))
  16. ; (caddr name)
  17. ; (cdddr name))
  18. ; (reverse (cdr (vector->list (closure-env obj)))))
  19. ; name)
  20. name)
  21. (list 'procedure id))))
  22. (define-method &disclose ((obj :template))
  23. (let ((id (template-id obj))
  24. (name (template-print-name obj)))
  25. (if name
  26. (list 'template id name)
  27. (list 'template id))))
  28. (define-method &disclose ((obj :location))
  29. (cons 'location
  30. (cons (location-id obj)
  31. (let ((name (location-name obj)))
  32. (if (and name (not (eq? name (location-id obj))))
  33. (list name (location-package-name obj))
  34. '())))))
  35. (define-method &disclose ((obj :cell))
  36. (if (cell-unassigned? obj)
  37. (list 'uninitialized-cell)
  38. (list 'cell)))
  39. ;; this overwrites the method defined in rts/continuation.scm
  40. (define-method &disclose ((obj :continuation))
  41. (list (if (vm-exception-continuation? obj)
  42. 'vm-exception-continuation
  43. 'continuation)
  44. (list 'pc (continuation-pc obj))
  45. (let ((tem (continuation-template obj)))
  46. (if tem
  47. (or (template-print-name tem) ; <-- the original method doesn't have this
  48. (template-id tem))
  49. '?))))
  50. (define-method &disclose ((obj :code-vector))
  51. (list 'byte-vector (code-vector-length obj))
  52. ; (cons 'code-vector
  53. ; (let ((z (code-vector-length obj)))
  54. ; (do ((i (- z 1) (- i 1))
  55. ; (l '() (cons (code-vector-ref obj i) l)))
  56. ; ((< i 0) l))))
  57. )
  58. (define-method &disclose ((obj :channel))
  59. (let ((status (channel-status obj)))
  60. (list (cond ((= status (enum channel-status-option closed))
  61. 'closed-channel)
  62. ((or (= status (enum channel-status-option input))
  63. (= status (enum channel-status-option special-input)))
  64. 'input-channel)
  65. ((or (= status (enum channel-status-option output))
  66. (= status (enum channel-status-option special-output)))
  67. 'output-channel)
  68. (else ; shouldn't happen unless we get out of sync
  69. 'unknown-channel))
  70. (channel-id obj))))
  71. (define-method &disclose ((obj :port))
  72. (disclose-port obj))
  73. (define (template-print-name tem)
  74. (make-print-name (template-names tem)))
  75. (define (make-print-name names)
  76. (if (null? names)
  77. #f
  78. (let ((name (car names))
  79. (parent-name (make-print-name (cdr names))))
  80. (cond (parent-name
  81. `(,(if name name 'unnamed)
  82. in
  83. ,@(if (pair? parent-name) parent-name (list parent-name))))
  84. ((string? name) #f) ;File name
  85. (else name)))))
  86. (define (template-file-name tem)
  87. (let loop ((names (template-names tem)))
  88. (if (null? names)
  89. #f
  90. (if (string? (car names))
  91. (car names)
  92. (loop (cdr names))))))
  93. ; --------------------
  94. ; Location names
  95. (define (location-info loc)
  96. (let ((id (location-id loc)))
  97. (if (integer? id)
  98. (table-ref location-info-table id)
  99. #f)))
  100. (define (location-name loc)
  101. (let ((probe (location-info loc)))
  102. (if probe
  103. (car probe)
  104. #f)))
  105. (define (location-package-name loc)
  106. (let ((probe (location-info loc)))
  107. (if probe
  108. (table-ref package-name-table (cdr probe))
  109. #f)))
  110. ; --------------------
  111. ; Condition disclosers
  112. (define *condition-disclosers* '())
  113. (define (define-condition-discloser pred proc)
  114. (set! *condition-disclosers*
  115. (cons (cons pred proc) *condition-disclosers*)))
  116. ; Simple conditions
  117. (define-method &disclose-condition ((c :pair))
  118. (let loop ((l *condition-disclosers*))
  119. (if (null? l)
  120. (cons (cond ((error? c) 'error)
  121. ((warning? c) 'warning)
  122. (else (car c)))
  123. (condition-stuff c))
  124. (if ((caar l) c)
  125. ((cdar l) c)
  126. (loop (cdr l))))))
  127. (define-condition-discloser interrupt?
  128. (lambda (c)
  129. (list 'interrupt (enumerand->name (cadr c) interrupt))))
  130. ; Make prettier error messages for VM exceptions
  131. (define-condition-discloser vm-exception?
  132. (lambda (c)
  133. (disclose-vm-condition (vm-exception-opcode c)
  134. (vm-exception-reason c)
  135. (vm-exception-arguments c))))
  136. (define vm-exception-disclosers
  137. (make-vector op-count
  138. (lambda (opcode reason args)
  139. (list 'error
  140. "vm-exception"
  141. reason
  142. (let ((name (enumerand->name opcode op)))
  143. (if (>= opcode (enum op eq?))
  144. (error-form name args)
  145. (cons name args)))))))
  146. (define (define-vm-exception-discloser opcode discloser)
  147. (vector-set! vm-exception-disclosers opcode discloser))
  148. (define (disclose-vm-condition opcode reason args)
  149. ((vector-ref vm-exception-disclosers opcode)
  150. opcode
  151. reason
  152. args))
  153. (let ((disc (lambda (opcode reason args)
  154. (let ((loc (car args)))
  155. (cons 'error
  156. (cons (if (location-defined? loc)
  157. "unassigned variable"
  158. "undefined variable")
  159. (cons (or (location-name loc) loc)
  160. (let ((pack
  161. (location-package-name loc)))
  162. (if pack
  163. (list (list 'package pack))
  164. '())))))))))
  165. (define-vm-exception-discloser (enum op global) disc)
  166. (define-vm-exception-discloser (enum op set-global!) disc))
  167. (define-vm-exception-discloser (enum op unassigned-check)
  168. (lambda (opcode reason args)
  169. (list 'error
  170. "LETREC variable used before its value has been produced")))
  171. (let ((disc (lambda (opcode reason args)
  172. (list 'error
  173. (case reason
  174. ((bad-procedure)
  175. "attempt to call a non-procedure")
  176. ((wrong-number-of-arguments)
  177. "wrong number of arguments")
  178. ((wrong-type-argument)
  179. "wrong type argument")
  180. (else
  181. (symbol->string reason)))
  182. (map value->expression (cons (car args) (cadr args)))))))
  183. (define-vm-exception-discloser (enum op call) disc)
  184. (define-vm-exception-discloser (enum op tail-call) disc)
  185. (define-vm-exception-discloser (enum op big-call) disc))
  186. (let ((disc (lambda (opcode reason args)
  187. (list 'error
  188. (case reason
  189. ((bad-procedure)
  190. "with-continuation passed a non-procedure")
  191. ((wrong-number-of-arguments)
  192. "with-continuation passed a non-nullary procedure")
  193. (else
  194. (string-append "with-continuation: "
  195. (symbol->string reason))))
  196. (value->expression (car args))))))
  197. (define-vm-exception-discloser (enum op with-continuation) disc))
  198. (let ((disc (lambda (opcode reason args)
  199. (list 'error
  200. (symbol->string reason)
  201. (cons 'apply (map value->expression args))))))
  202. (define-vm-exception-discloser (enum op apply) disc)
  203. (define-vm-exception-discloser (enum op closed-apply) disc))
  204. (let ((disc (lambda (opcode reason args)
  205. (let ((proc (car args))
  206. (args (cadr args)))
  207. (cond (proc
  208. (list 'error
  209. "returning wrong number of values"
  210. (cons proc args)))
  211. ((null? args)
  212. (list 'error
  213. "returning zero values when one is expected"
  214. '(values)))
  215. (else
  216. (list 'error
  217. "returning wrong number of values"
  218. (error-form 'values args))))))))
  219. (define-vm-exception-discloser (enum op return) disc)
  220. (define-vm-exception-discloser (enum op values) disc)
  221. (define-vm-exception-discloser (enum op closed-values) disc))
  222. (let ((disc (lambda (opcode reason args)
  223. (let ((thing (car args))
  224. (type-byte (cadr args))
  225. (offset (caddr args))
  226. (rest (cdddr args)))
  227. (let ((data (assq (enumerand->name type-byte stob)
  228. stob-data)))
  229. (list 'error
  230. "vm-exception"
  231. (error-form ((if (= opcode
  232. (enum op stored-object-ref))
  233. car
  234. cadr)
  235. (list-ref data (+ offset 3)))
  236. (cons thing rest))))))))
  237. (define-vm-exception-discloser (enum op stored-object-ref) disc)
  238. (define-vm-exception-discloser (enum op stored-object-set!) disc))
  239. (let ((disc (lambda (opcode reason args)
  240. (let ((type (enumerand->name (car args) stob)))
  241. (list 'error
  242. "vm-exception"
  243. (error-form (string->symbol
  244. ;; Don't simplify this to "make-" --JAR
  245. (string-append (symbol->string 'make-)
  246. (symbol->string type)))
  247. (cdr args)))))))
  248. (define-vm-exception-discloser (enum op make-vector-object) disc))
  249. (define (vector-vm-exception-discloser suffix)
  250. (lambda (opcode reason args)
  251. (let ((type (enumerand->name (cadr args) stob)))
  252. (list 'error
  253. "vm-exception"
  254. (error-form (string->symbol
  255. (string-append (symbol->string type)
  256. "-"
  257. (symbol->string suffix)))
  258. (cons (car args) (cddr args)))))))
  259. (define-vm-exception-discloser (enum op stored-object-length)
  260. (vector-vm-exception-discloser 'length))
  261. (define-vm-exception-discloser (enum op stored-object-indexed-ref)
  262. (vector-vm-exception-discloser 'ref))
  263. (define-vm-exception-discloser (enum op stored-object-indexed-set!)
  264. (vector-vm-exception-discloser 'set!))
  265. ;(define-vm-exception-discloser (enum op get-cont-from-heap)
  266. ; (lambda (opcode reason args)
  267. ; (let ((value (car args))
  268. ; (continuation (cadr args)))
  269. ; (if (not continuation)
  270. ; (list 'error
  271. ; "exit status is not a small integer"
  272. ; (value->expression value))
  273. ; (list 'error
  274. ; "returning to a non-continuation"
  275. ; (value->expression continuation))))))
  276. (define-vm-exception-discloser (enum op scalar-value->char)
  277. (lambda (opcode reason args)
  278. (let ((value (car args)))
  279. `(error
  280. "vm-exception"
  281. "wrong-type-argument"
  282. (scalar-value->char ,(value->expression value))))))
  283. ; Call-errors should print as (proc 'arg1 'arg2 ...)
  284. (define-condition-discloser call-error?
  285. (lambda (c)
  286. (list 'error (cadr c) (error-form (caddr c) (cdddr c)))))
  287. ; --------------------
  288. ; Associating names with templates
  289. (define (template-debug-data tem)
  290. (get-debug-data (template-info tem)))
  291. (define (template-id tem)
  292. (let ((info (template-info tem)))
  293. (if (debug-data? info)
  294. (debug-data-uid info)
  295. info)))
  296. (define (template-name tem)
  297. (let ((probe (template-debug-data tem)))
  298. (if probe
  299. (debug-data-name probe)
  300. '?)))
  301. (define (template-names tem)
  302. (debug-data-names (template-info tem)))
  303. ; We can follow parent links to get a full description of procedure
  304. ; nesting: "foo in bar in unnamed in baz"
  305. (define (debug-data-names info)
  306. (let ((dd (get-debug-data info)))
  307. (if (debug-data? dd) ;paranoid
  308. (cons (debug-data-name dd)
  309. (debug-data-names (debug-data-parent dd)))
  310. '())))
  311. ; --------------------
  312. ; Utilities
  313. (define (error-form proc args)
  314. (cons proc (map value->expression args)))
  315. (define (value->expression obj)
  316. (if (or (number? obj) (char? obj) (string? obj) (boolean? obj))
  317. obj
  318. `',obj))