struct.scm 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ; This is file struct.scm.
  4. ; This file defines a level of abstraction for storage somewhat higher
  5. ; than that of d-vectors and b-vectors: pairs, symbols, and other datatypes.
  6. (define (stob-maker type maker)
  7. (lambda (length key)
  8. (maker type length key)))
  9. (define (stob-predicate type)
  10. (lambda (obj) (stob-of-type? obj type)))
  11. ; data for these comes from STOB-DATA in arch.scm
  12. (define-shared-primitive-data-type pair #t)
  13. (define-shared-primitive-data-type symbol #t #f
  14. make-symbol ; hidden from RTS
  15. ()
  16. (symbol-next set-symbol-next!)) ; hidden from RTS
  17. (define-shared-primitive-data-type closure #f #t)
  18. (define-shared-primitive-data-type location)
  19. (define-shared-primitive-data-type cell)
  20. (define-shared-primitive-data-type weak-pointer)
  21. (define-shared-primitive-data-type shared-binding #f #f
  22. #f
  23. ()
  24. (shared-binding-next set-shared-binding-next!)) ; hidden from RTS
  25. (define-shared-primitive-data-type port)
  26. (define-shared-primitive-data-type channel #f #f
  27. make-channel ; hidden from RTS
  28. (;; these setters are hidden from the RTS
  29. (channel-status set-channel-status!)
  30. (channel-id set-channel-id!)
  31. (channel-os-index set-channel-os-index!)
  32. (channel-close-silently? set-channel-close-silently?!))
  33. ;; none of these are visible to the RTS
  34. (channel-next set-channel-next!)
  35. ;; this is
  36. ;; false - if there's nothing going on
  37. ;; true - if there's an operation pending
  38. ;; the number of bytes transferred - if error? (below) is false
  39. ;; the error code - if error? (below) is true
  40. (channel-os-status set-channel-os-status!)
  41. (channel-error? set-channel-error?!))
  42. ; Vectors and so on
  43. (define-vector-data-type vector #t)
  44. (define-vector-data-type record)
  45. (define-vector-data-type extended-number)
  46. (define make-bignum (stob-maker (enum stob byte-vector) make-b-vector))
  47. (define bignum? (stob-predicate (enum stob bignum)))
  48. (define bignum-length b-vector-length)
  49. (define bignum-ref b-vector-ref)
  50. (define bignum-set! b-vector-set!)
  51. (define (bignum-size len)
  52. (+ stob-overhead (bytes->cells len)))
  53. (define-vector-data-type continuation)
  54. (define-vector-data-type template)
  55. (define (vm-make-vector+gc len)
  56. (let ((vector (maybe-make-d-vector+gc (enum stob vector)
  57. len)))
  58. (if (false? vector)
  59. (error "Out of space, unable to allocate"))
  60. vector))
  61. (define (vm-vector-fill! v val)
  62. (do ((i 0 (+ i 1)))
  63. ((= i (vm-vector-length v)) v)
  64. (vm-vector-set! v i val)))
  65. ; We use D-VECTOR-INIT! because continuations in the heap are only initialized,
  66. ; never modified.
  67. (define-syntax define-cont-field
  68. (syntax-rules ()
  69. ((define-cont-field ref set offset)
  70. (begin
  71. (define (ref c) (continuation-ref c offset))
  72. (define (set c val) (d-vector-init! c offset val))))))
  73. (define-cont-field continuation-cont set-continuation-cont!
  74. continuation-cont-index)
  75. (define-cont-field continuation-pc set-continuation-pc!
  76. continuation-pc-index)
  77. (define-cont-field continuation-code set-continuation-code!
  78. continuation-code-index)
  79. (define (template-code tem) (template-ref tem 0))
  80. (define (template-byte-code tem) (template-ref tem 1))
  81. (define (template-name tem) (template-ref tem 2))
  82. ; Code vectors
  83. (define make-code-vector (stob-maker (enum stob byte-vector) make-b-vector))
  84. (define code-vector? (stob-predicate (enum stob byte-vector)))
  85. (define code-vector-length b-vector-length)
  86. (define code-vector-ref b-vector-ref)
  87. (define code-vector-set! b-vector-set!)
  88. (define (code-vector-size len)
  89. (+ stob-overhead (bytes->cells len)))
  90. ; for small strings only
  91. (define (vm-make-string length key)
  92. (make-b-vector (enum stob string)
  93. (scalar-value-units->bytes length)
  94. key))
  95. (define (vm-make-string+gc length)
  96. (let ((string (maybe-make-b-vector+gc (enum stob string)
  97. (scalar-value-units->bytes length))))
  98. (if (false? string)
  99. (error "Out of space, unable to allocate"))
  100. string))
  101. (define vm-string? (stob-predicate (enum stob string)))
  102. (define (vm-string-length x)
  103. (bytes->scalar-value-units (b-vector-length x)))
  104. ; deals in code points, not PreScheme characters
  105. ; #### This should be rewritten as a loop the PreScheme compiler can unroll
  106. (define (vm-string-ref s i)
  107. (let ((base (scalar-value-units->bytes i)))
  108. (do ((bits 0 (+ bits bits-per-byte))
  109. (j 0 (+ 1 j))
  110. (scalar-value 0
  111. (adjoin-bits (b-vector-ref s (+ base j))
  112. scalar-value
  113. bits)))
  114. ((>= j bytes-per-scalar-value-unit)
  115. scalar-value))))
  116. ;; #### ditto
  117. (define (vm-string-set! s i c)
  118. (let ((base (scalar-value-units->bytes i)))
  119. (do ((bits 0 (+ bits bits-per-byte))
  120. (j 0 (+ 1 j))
  121. (shifted c (unsigned-high-bits shifted bits-per-byte)))
  122. ((>= j bytes-per-scalar-value-unit))
  123. (b-vector-set! s (+ base j)
  124. (low-bits shifted bits-per-byte)))
  125. (unspecific))) ; avoid type problem
  126. (define (vm-string-size length)
  127. (+ stob-overhead (bytes->cells (scalar-value-units->bytes length))))
  128. ; Converting external (C, Latin-1) strings to S48 strings.
  129. ; for small strings only
  130. (define (enter-string string key)
  131. (let* ((len (string-length string))
  132. (v (vm-make-string len key)))
  133. (copy-string-to-vm-string/latin-1! string len v)
  134. v))
  135. (define (enter-string+gc-n string len)
  136. (let ((v (vm-make-string+gc len)))
  137. (copy-string-to-vm-string/latin-1! string len v)
  138. v))
  139. (define (enter-string+gc string)
  140. (enter-string+gc-n string (string-length string)))
  141. (define (copy-string-to-vm-string/latin-1! string len v)
  142. (do ((i 0 (+ i 1)))
  143. ((>= i len))
  144. (vm-string-set! v i (char->ascii (string-ref string i))))
  145. (unspecific))
  146. (define (copy-vm-string-to-string/latin-1! vm-string start count string)
  147. (do ((i 0 (+ 1 i)))
  148. ((>= i count))
  149. (let ((c (vm-string-ref vm-string i)))
  150. (string-set! string (+ i start)
  151. (if (<= c 255)
  152. (ascii->char c)
  153. #\?))))
  154. (unspecific))
  155. (define (copy-vm-string-chars! from from-index to to-index count)
  156. (copy-memory! (address+ (address-after-header from)
  157. (* from-index bytes-per-scalar-value-unit))
  158. (address+ (address-after-header to)
  159. (* to-index bytes-per-scalar-value-unit))
  160. (* count bytes-per-scalar-value-unit)))
  161. ; This depends on our having 0 bytes at the end of strings.
  162. ; We should really be doing the NUL termination here, but
  163. ; DEFINE-CONSING-PRIMITIVE doesn't let us do it easily.
  164. (define (extract-low-string code-vector) ; used by OPEN
  165. (assert (code-vector? code-vector))
  166. (fetch-nul-terminated-string (address-after-header code-vector)))
  167. (define (vm-string=? s1 s2)
  168. (assert (and (vm-string? s1) (vm-string? s2)))
  169. (let ((len (b-vector-length s1)))
  170. (and (= len (b-vector-length s2))
  171. (memory-equal? (address-after-header s1)
  172. (address-after-header s2)
  173. len))))
  174. ;; This is only a very crude approximation for debugging purposes.
  175. (define (write-vm-string vm-string out)
  176. (do ((size (vm-string-length vm-string))
  177. (i 0 (+ 1 i)))
  178. ((>= i size) 0) ; make type checker happy
  179. (write-char (ascii->char (vm-string-ref vm-string i)) out)))
  180. ; Number predicates
  181. ;(define bignum? (stob-predicate (enum stob bignum)))
  182. (define ratnum? (stob-predicate (enum stob ratnum)))
  183. (define double? (stob-predicate (enum stob double)))
  184. ; Doubles
  185. (define (extract-double double)
  186. (fetch-flonum (address-after-header double)))
  187. (define double-bytes 8)
  188. (define double-size
  189. (+ stob-overhead (bytes->cells double-bytes)))
  190. (define (enter-double value key)
  191. (let ((double (make-b-vector (enum stob double) double-bytes key)))
  192. (store-flonum! (address-after-header double) value)
  193. double))
  194. ; Hashing
  195. ; The hash function used here is taken from srfi-13.
  196. (define (vm-string-hash s)
  197. (let* ((bound 4194304)
  198. (end (vm-string-length s))
  199. (mask (let lp ((i #x10000))
  200. (if (>= i bound)
  201. (- i 1)
  202. (lp (+ i i))))))
  203. (let lp ((i 0) (ans 0))
  204. (if (>= i end)
  205. (remainder ans bound)
  206. (lp (+ i 1)
  207. (bitwise-and mask (+ (* 37 ans) (vm-string-ref s i))))))))