vm-external.scm 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. (define (s48-disable-interrupts!)
  3. (disable-interrupts!))
  4. (define (s48-enable-interrupts!)
  5. (enable-interrupts!))
  6. ; used for raising exceptions in external code
  7. (define (s48-push x)
  8. (push x))
  9. (define (s48-stack-ref i)
  10. (stack-ref i))
  11. (define (s48-stack-set! x v)
  12. (stack-set! x v))
  13. (define (s48-enter-integer x)
  14. (enter-integer x (ensure-space long-as-integer-size)))
  15. (define (s48-enter-unsigned-integer x)
  16. (enter-unsigned-integer x (ensure-space long-as-integer-size)))
  17. ; arguments must either both be intergers or both floanums
  18. (define (s48-integer-or-floanum-add x y)
  19. (if (double? x)
  20. (flonum-add x y)
  21. (integer-add x y)))
  22. (define (s48-integer-or-floanum-sub x y)
  23. (if (double? x)
  24. (flonum-subtract x y)
  25. (integer-subtract x y)))
  26. (define (s48-integer-or-floanum-mul x y)
  27. (if (double? x)
  28. (flonum-multiply x y)
  29. (integer-multiply x y)))
  30. (define (s48-integer-remainder x y)
  31. (integer-remainder x y))
  32. (define (s48-integer-quotient x y)
  33. (integer-quotient x y))
  34. (define (s48-integer-divide x y)
  35. (integer-divide x y))
  36. (define-syntax define-integer-or-floanum-comparison
  37. (syntax-rules ()
  38. ((define-integer-or-floanum-comparison
  39. s48-integer-or-floanum-proc integer-op flonum-op)
  40. (define (s48-integer-or-floanum-proc x y)
  41. (enter-boolean
  42. (if (double? x)
  43. (flonum-op x y)
  44. (integer-op x y)))))))
  45. (define-integer-or-floanum-comparison s48-integer-or-floanum-= integer= flonum=)
  46. (define-integer-or-floanum-comparison s48-integer-or-floanum-< integer< flonum<)
  47. (define-integer-or-floanum-comparison s48-integer-or-floanum-> integer> flonum>)
  48. (define-integer-or-floanum-comparison s48-integer-or-floanum-<= integer<= flonum<=)
  49. (define-integer-or-floanum-comparison s48-integer-or-floanum->= integer>= flonum>=)
  50. (define (s48-integer-bitwise-not x)
  51. (integer-bitwise-not x))
  52. (define (s48-integer-bit-count x)
  53. (integer-bit-count x))
  54. (define (s48-integer-bitwise-and x y)
  55. (integer-bitwise-and x y))
  56. (define (s48-integer-bitwise-ior x y)
  57. (integer-bitwise-ior x y))
  58. (define (s48-integer-bitwise-xor x y)
  59. (integer-bitwise-xor x y))
  60. ;; Strings
  61. (define (ensure-string s)
  62. (if (not (vm-string? s))
  63. (raise-argument-type-error s)))
  64. (define (ensure-index-range i min max)
  65. (if (or (< i min)
  66. (> i max))
  67. (raise-range-error (enter-fixnum i)
  68. (enter-fixnum min) (enter-fixnum max))))
  69. (define (ensure-string-index s i)
  70. (ensure-index-range i 0 (- (vm-string-length s) 1)))
  71. (define (s48-string-set s i c)
  72. (ensure-string s)
  73. (ensure-string-index s i)
  74. (vm-string-set! s i c))
  75. (define (s48-string-ref s i)
  76. (ensure-string s)
  77. (ensure-string-index s i)
  78. (vm-string-ref s i))
  79. (define (s48-string-length s)
  80. (ensure-string s)
  81. (vm-string-length s))
  82. (define (s48-allocate-string len)
  83. (vm-make-string+gc len))
  84. (define (s48-enter-string-latin-1 s)
  85. (enter-string+gc s))
  86. (define (s48-enter-string-latin-1-n s count)
  87. (enter-string+gc-n s count))
  88. (define (s48-copy-latin-1-to-string-n string len vm-string)
  89. (ensure-string vm-string)
  90. (ensure-index-range len 0 (vm-string-length vm-string))
  91. (copy-string-to-vm-string/latin-1! string len vm-string))
  92. (define (s48-copy-latin-1-to-string string vm-string)
  93. (ensure-string vm-string)
  94. (let ((len (string-length string)))
  95. (ensure-index-range len 0 (vm-string-length vm-string))
  96. (copy-string-to-vm-string/latin-1! string (string-length string) vm-string)))
  97. (define (s48-copy-string-to-latin-1 vm-string string)
  98. (ensure-string vm-string)
  99. (copy-vm-string-to-string/latin-1! vm-string 0 (vm-string-length vm-string) string))
  100. (define (s48-copy-string-to-latin-1-n vm-string start count string)
  101. (ensure-string vm-string)
  102. (ensure-string-index vm-string start)
  103. (ensure-index-range count 0 (- (vm-string-length vm-string) start))
  104. (copy-vm-string-to-string/latin-1! vm-string start count string))
  105. (define (s48-enter-string-utf-8 p)
  106. (call-with-values
  107. (lambda ()
  108. (utf-8-length p (string-length (fetch-nul-terminated-string p))))
  109. (lambda (consumed decoded)
  110. (let ((vm (vm-make-string+gc decoded)))
  111. (decode-utf-8! p vm consumed)
  112. vm))))
  113. (define (s48-enter-string-utf-8-n p size)
  114. (call-with-values
  115. (lambda ()
  116. (utf-8-length p size))
  117. (lambda (consumed decoded)
  118. (let ((vm (vm-make-string+gc decoded)))
  119. (decode-utf-8! p vm consumed)
  120. vm))))
  121. (define (s48-string-utf-8-length vm-string)
  122. (ensure-string vm-string)
  123. (string-encoding-length/utf-8 vm-string 0 (vm-string-length vm-string)))
  124. (define (s48-string-utf-8-length-n vm-string start-index count)
  125. (ensure-string vm-string)
  126. (ensure-string-index vm-string start-index)
  127. (ensure-index-range count 0 (- (vm-string-length vm-string) start-index))
  128. (string-encoding-length/utf-8 vm-string start-index count))
  129. (define (s48-copy-string-to-utf-8 vm-string string)
  130. (ensure-string vm-string)
  131. (copy-vm-string-to-string/utf-8! vm-string 0 (vm-string-length vm-string) string))
  132. (define (s48-copy-string-to-utf-8-n vm-string start count string)
  133. (ensure-string vm-string)
  134. (ensure-string-index vm-string start)
  135. (ensure-index-range count 0 (- (vm-string-length vm-string) start))
  136. (copy-vm-string-to-string/utf-8! vm-string start count string))
  137. ;; returns # bytes consumed, # characters decoded
  138. (define (utf-8-length p size)
  139. (let loop ((index 0)
  140. (target-index 0))
  141. (if (>= index size)
  142. (values index target-index)
  143. (call-with-values
  144. (lambda ()
  145. (decode-scalar-value
  146. (enum text-encoding-option utf-8)
  147. (address+ p index)
  148. (- size index)))
  149. (lambda (encoding-ok? ok? incomplete? value count)
  150. (cond
  151. ((not encoding-ok?)
  152. (loop (+ 1 index) (+ target-index 1)))
  153. (incomplete?
  154. (values index target-index))
  155. (else
  156. (loop (+ index count) (+ target-index 1)))))))))
  157. (define (decode-utf-8! p s size)
  158. (let loop ((index 0)
  159. (target-index 0))
  160. (if (>= index size)
  161. (unspecific)
  162. (call-with-values
  163. (lambda ()
  164. (decode-scalar-value
  165. (enum text-encoding-option utf-8)
  166. (address+ p index)
  167. (- size index)))
  168. (lambda (encoding-ok? ok? incomplete? value count)
  169. (cond
  170. ((not encoding-ok?)
  171. (vm-string-set! s target-index (char->ascii #\?))
  172. (loop (+ 1 index) (+ target-index 1)))
  173. (incomplete?
  174. (vm-string-set! s target-index (char->ascii #\?))
  175. (unspecific))
  176. (else
  177. (vm-string-set! s target-index value)
  178. (loop (+ index count) (+ target-index 1)))))))))
  179. (define (string-encoding-length/utf-8 s start-index count)
  180. (let loop ((utf-8-length 0)
  181. (char-index 0))
  182. (if (>= char-index count)
  183. utf-8-length
  184. (loop (+ utf-8-length
  185. (scalar-value-encoding-length/utf-8
  186. (vm-string-ref s (+ start-index char-index))))
  187. (+ 1 char-index)))))
  188. (define (scalar-value-encoding-length/utf-8 sv)
  189. (call-with-values
  190. (lambda ()
  191. (encode-scalar-value (enum text-encoding-option utf-8)
  192. sv (integer->address 0) 0))
  193. (lambda (encoding-ok? ok? out-of-space? count)
  194. ;; we know the encoding is OK
  195. count)))
  196. (define (copy-vm-string-to-string/utf-8! vm-string start count string)
  197. (let loop ((source-index 0)
  198. (target-index 0))
  199. (if (>= source-index count)
  200. (unspecific)
  201. (let ((sv (vm-string-ref vm-string (+ start source-index))))
  202. (call-with-values
  203. (lambda ()
  204. (encode-scalar-value (enum text-encoding-option utf-8)
  205. sv (address+ string target-index) 4))
  206. (lambda (encoding-ok? ok? out-of-space? count)
  207. (loop (+ source-index 1) (+ target-index count))))))))