vm-exception.scm 7.2 KB

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