vm-exception.scm 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; More precise conditions for VM exceptions.
  3. ; GLOBAL and SET-GLOBAL! are in shadow.scm.
  4. (let ((handler (lambda (opcode reason proc . rest)
  5. (signal-vm-exception
  6. opcode reason
  7. (map value->expression (cons proc rest))))))
  8. (define-vm-exception-handler (enum op call) handler)
  9. (define-vm-exception-handler (enum op tail-call) handler)
  10. (define-vm-exception-handler (enum op big-call) handler))
  11. (define-vm-exception-handler (enum op with-continuation)
  12. (lambda (opcode reason val)
  13. (signal-vm-exception opcode reason (value->expression val))))
  14. (let ((handler (lambda (opcode reason . args)
  15. (signal-vm-exception
  16. opcode reason
  17. (cons 'apply (map value->expression args))))))
  18. (define-vm-exception-handler (enum op apply) handler)
  19. (define-vm-exception-handler (enum op closed-apply) handler))
  20. (let ((handler (lambda (opcode reason proc args)
  21. (signal-condition
  22. (condition
  23. (construct-vm-exception opcode reason)
  24. (make-assertion-violation)
  25. (cond (proc
  26. (condition
  27. (make-message-condition "returning wrong number of values")
  28. (make-irritants-condition (list (cons proc args)))))
  29. ((null? args)
  30. (condition
  31. (make-message-condition
  32. "returning zero values when one is expected")
  33. (make-who-condition 'values)
  34. (make-irritants-condition (list '(values)))))
  35. (else
  36. (condition
  37. (make-message-condition "returning wrong number of values")
  38. (make-who-condition 'values)
  39. (make-irritants-condition
  40. (list (error-form 'values args)))))))))))
  41. (define-vm-exception-handler (enum op return) handler)
  42. (define-vm-exception-handler (enum op values) handler)
  43. (define-vm-exception-handler (enum op closed-values) handler))
  44. (let ((handler
  45. (lambda (opcode reason thing type-byte offset . rest)
  46. (let* ((data (assq (enumerand->name type-byte stob)
  47. stob-data))
  48. (who
  49. ((if (= opcode
  50. (enum op stored-object-ref))
  51. car
  52. cadr)
  53. (list-ref data (+ offset 3)))))
  54. (signal-condition
  55. (condition
  56. (construct-vm-exception opcode reason)
  57. (make-assertion-violation)
  58. (make-message-condition (vm-exception-reason->message reason))
  59. (make-who-condition who)
  60. (make-irritants-condition
  61. (list
  62. (error-form who (cons thing rest))))))))))
  63. (define-vm-exception-handler (enum op stored-object-ref) handler)
  64. (define-vm-exception-handler (enum op stored-object-set!) handler))
  65. (define-vm-exception-handler (enum op make-vector-object)
  66. (lambda (opcode reason type . rest)
  67. (let* ((type-name (enumerand->name type stob))
  68. (maker
  69. (string->symbol
  70. ;; Don't simplify this to "make-" --JAR
  71. (string-append (symbol->string 'make-)
  72. (symbol->string type-name)))))
  73. (signal-condition
  74. (condition
  75. (construct-vm-exception opcode reason)
  76. (make-assertion-violation)
  77. (make-who-condition maker)
  78. (make-message-condition (vm-exception-reason->message reason))
  79. (make-irritants-condition
  80. (list
  81. (error-form maker rest))))))))
  82. (define (vector-vm-exception-handler suffix)
  83. (lambda (opcode reason thing type . rest)
  84. (let* ((type-name (enumerand->name type stob))
  85. (maker
  86. (string->symbol
  87. (string-append (symbol->string type-name)
  88. "-"
  89. (symbol->string suffix)))))
  90. (signal-condition
  91. (condition
  92. (construct-vm-exception opcode reason)
  93. (make-assertion-violation)
  94. (make-who-condition maker)
  95. (make-message-condition (vm-exception-reason->message reason))
  96. (make-irritants-condition
  97. (list (error-form maker (cons thing rest)))))))))
  98. (define-vm-exception-handler (enum op stored-object-length)
  99. (vector-vm-exception-handler 'length))
  100. (define-vm-exception-handler (enum op stored-object-indexed-ref)
  101. (vector-vm-exception-handler 'ref))
  102. (define-vm-exception-handler (enum op stored-object-indexed-set!)
  103. (vector-vm-exception-handler 'set!))
  104. (define-vm-exception-handler (enum op scalar-value->char)
  105. (lambda (opcode reason value)
  106. (signal-vm-exception opcode reason
  107. `(scalar-value->char ,(value->expression value)))))
  108. (define-vm-exception-handler (enum op close-channel)
  109. (lambda (opcode reason channel status . rest)
  110. (apply signal-i/o-error opcode reason channel status rest)))
  111. (define-vm-exception-handler (enum op channel-ready?)
  112. (lambda (opcode reason channel status . rest)
  113. (apply signal-i/o-error opcode reason channel status rest)))
  114. (define (signal-i/o-error opcode reason channel status . rest)
  115. (enum-case exception reason
  116. ((os-error)
  117. (signal-condition
  118. (condition
  119. (construct-vm-exception opcode reason)
  120. (make-os-error status)
  121. (make-i/o-error)
  122. (make-who-condition (enumerand->name opcode op))
  123. (make-message-condition
  124. (os-string->string (byte-vector->os-string (os-error-message status))))
  125. (make-irritants-condition (cons channel rest)))))
  126. (else
  127. (apply signal-vm-exception opcode reason channel status rest))))
  128. (define-vm-exception-handler (enum op write-image-low)
  129. (lambda (opcode reason status filename . rest)
  130. (enum-case exception reason
  131. ((os-error)
  132. (signal-condition
  133. (condition
  134. (construct-vm-exception opcode reason)
  135. (make-os-error status)
  136. (make-i/o-error)
  137. (make-who-condition 'write-image)
  138. (make-message-condition
  139. (os-string->string (byte-vector->os-string (os-error-message status))))
  140. (make-irritants-condition
  141. (cons (byte-vector->os-string filename)
  142. rest)))))
  143. (else
  144. (apply signal-vm-exception opcode reason status rest)))))
  145. ; REST has who, status or message last
  146. (define (signal-call-external-error opcode reason . rest)
  147. (enum-case exception reason
  148. ((external-error external-assertion-violation)
  149. (let* ((rev-rest (reverse rest))
  150. (who (cadr rev-rest))
  151. (message
  152. (os-string->string
  153. (byte-vector->os-string (car rev-rest)))))
  154. (signal-condition
  155. (condition
  156. (if (= reason (enum exception external-assertion-violation))
  157. (make-assertion-violation)
  158. (make-error))
  159. (construct-vm-exception opcode reason)
  160. (make-who-condition who)
  161. (make-message-condition message)
  162. (make-irritants-condition (reverse (cddr rev-rest)))))))
  163. ((external-os-error)
  164. (let* ((rev-rest (reverse rest))
  165. (who (cadr rev-rest))
  166. (status (car rev-rest))
  167. (message
  168. (os-string->string
  169. (byte-vector->os-string
  170. (os-error-message status)))))
  171. (signal-condition
  172. (condition
  173. (if (= reason (enum exception external-assertion-violation))
  174. (make-assertion-violation)
  175. (make-error))
  176. (construct-vm-exception opcode reason)
  177. (make-os-error status)
  178. (make-who-condition who)
  179. (make-message-condition message)
  180. (make-irritants-condition (reverse (cddr rev-rest)))))))
  181. (else
  182. (apply signal-vm-exception opcode reason rest))))
  183. (define-vm-exception-handler (enum op call-external-value)
  184. signal-call-external-error)
  185. (define-vm-exception-handler (enum op call-external-value-2)
  186. signal-call-external-error)
  187. ; Utilities
  188. (define (construct-vm-exception opcode reason)
  189. (make-vm-exception opcode
  190. (if reason
  191. (enumerand->name reason exception)
  192. #f)))