low.scm 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
  3. ; Low-level things that rely on the fact that we're running under the
  4. ; Scheme 48 VM.
  5. ; Historical kludge; ASCII is a misnomer (as it covers only [0, 127])---
  6. ; we really mean Latin-1.
  7. (define (char->ascii c)
  8. (let ((scalar-value (char->scalar-value c)))
  9. (if (>= scalar-value ascii-limit)
  10. (assertion-violation 'char->ascii
  11. "not an ASCII character"
  12. c))
  13. scalar-value))
  14. (define (ascii->char x)
  15. (if (or (>= x ascii-limit) (< x 0))
  16. (assertion-violation 'ascii->char
  17. "not an ASCII code"
  18. x))
  19. (scalar-value->char x))
  20. (define (char->integer c) (char->scalar-value c))
  21. (define (integer->char n) (scalar-value->char n))
  22. (define ascii-limit 128)
  23. ; space, horizontal tab, line feed (= newline), vertical tab, form feed, and
  24. ; carriage return
  25. (define ascii-whitespaces '(32 9 10 11 12 13))
  26. ; Procedures and closures are two different abstractions. Procedures
  27. ; are created by LAMBDA and invoked with procedure call; those are
  28. ; their only defined operations. Closures are made with MAKE-CLOSURE,
  29. ; accessed using CLOSURE-TEMPLATE and CLOSURE-ENV, and invoked by
  30. ; INVOKE-CLOSURE, which starts the virtual machine going.
  31. ; In a running Scheme 48 system, the two happen to be implemented
  32. ; using the same data type. The following is the only part of the
  33. ; system that should know this fact.
  34. (define procedure? closure?)
  35. (define (invoke-closure closure . args)
  36. (apply (loophole :procedure closure)
  37. args))
  38. ; Similarly, there are escapes and there are VM continuations.
  39. ; Escapes are obtained with PRIMITIVE-CWCC and invoked with
  40. ; WITH-CONTINUATION. VM continuations are obtained with
  41. ; PRIMITIVE-CATCH and inspected using CONTINUATION-REF and friends.
  42. ; (This is not such a hot naming strategy; it would perhaps be better
  43. ; to use the terms "continuation" and "frame".)
  44. ; In a running Scheme 48 system, the two happen to be implemented
  45. ; using the same data type. The following is the only part of the
  46. ; system that should know this fact.
  47. (define (primitive-cwcc p)
  48. (primitive-catch (lambda (cont)
  49. (p (loophole :escape cont))))) ;?
  50. ; (define (invoke-continuation cont thunk)
  51. ; (with-continuation (loophole :escape cont) thunk))
  52. ; These two procedures are part of the location abstraction.
  53. ; We don't let UNASSIGNED escape because use of the value it returns can
  54. ; be confusing. Here we just test it against other values.
  55. (define (make-undefined-location id)
  56. (let ((loc (make-location id #f)))
  57. (set-location-defined?! loc #f)
  58. loc))
  59. (define (location-assigned? loc)
  60. (and (location-defined? loc)
  61. (if (eq? (contents loc)
  62. (unassigned))
  63. #f
  64. #t)))
  65. ; Used by the cell discloser
  66. (define (cell-unassigned? cell)
  67. (eq? (cell-ref cell) (unassigned)))
  68. ; Used by the inspector.
  69. (define (vector-unassigned? v i)
  70. (eq? (vector-ref v i) (unassigned)))
  71. ; STRING-COPY is here because it's needed by STRING->SYMBOL.
  72. (define (string-copy s)
  73. (let* ((z (string-length s))
  74. (copy (make-string z)))
  75. (copy-string-chars! s 0 copy 0 z)
  76. copy))
  77. ; The symbol table
  78. (define (string->symbol string)
  79. (intern (if (immutable? string)
  80. string ;+++
  81. (make-immutable! (string-copy string)))))
  82. ; The following magic bitmasks are derived from PORT-STATUS-OPTIONS in arch.scm.
  83. (define (input-port? port)
  84. (and (port? port)
  85. (= 1 (bitwise-and 1 (port-status port)))))
  86. (define (output-port? port)
  87. (and (port? port)
  88. (= 2 (bitwise-and 2 (port-status port)))))
  89. ; Every record has a record type (another record) in the first slot.
  90. (define (record-type r)
  91. (record-ref r 0))
  92. ; code-vectors == byte-vectors
  93. ; These are functions so that they will be inlined.
  94. (define (make-code-vector length init) (make-byte-vector length init))
  95. (define (code-vector? x) (byte-vector? x))
  96. (define (code-vector-length bv) (byte-vector-length bv))
  97. (define (code-vector-ref bv i) (byte-vector-ref bv i))
  98. (define (code-vector-set! bv i x) (byte-vector-set! bv i x))
  99. ; Shared bindings - six procedures from two primitives. The lookup and
  100. ; undefine primitives take a flag which is true for imports and false for
  101. ; exports.
  102. (define (lookup-imported-binding name)
  103. (lookup-shared-binding name #t))
  104. (define (lookup-exported-binding name)
  105. (lookup-shared-binding name #f))
  106. (define (define-imported-binding name value)
  107. (shared-binding-set! (lookup-shared-binding name #t)
  108. value))
  109. (define (define-exported-binding name value)
  110. (shared-binding-set! (lookup-shared-binding name #f)
  111. value))
  112. (define (undefine-imported-binding name)
  113. (undefine-shared-binding name #t))
  114. (define (undefine-exported-binding name)
  115. (undefine-shared-binding name #f))
  116. ; These really shouldn't be here, but we don't know where else to put them.
  117. (define (byte-vector=? b1 b2)
  118. (let ((size-1 (byte-vector-length b1))
  119. (size-2 (byte-vector-length b2)))
  120. (and (= size-1 size-2)
  121. (let loop ((i 0))
  122. (cond
  123. ((>= i size-1) #t)
  124. ((= (byte-vector-ref b1 i) (byte-vector-ref b2 i))
  125. (loop (+ 1 i)))
  126. (else #f))))))
  127. (define (byte-vector . l)
  128. (let ((v (make-byte-vector (secret-length l 0) 0)))
  129. (do ((i 0 (+ i 1))
  130. (l l (cdr l)))
  131. ((eq? l '()) v)
  132. (byte-vector-set! v i (car l)))))
  133. (define (secret-length list length)
  134. (if (eq? list '())
  135. length
  136. (secret-length (cdr list) (+ length 1))))
  137. ; Writing debugging messages.
  138. (define (debug-message . stuff)
  139. (message stuff))
  140. ; Checking for undumpable objects when writing images.
  141. ; Also convert file-name to VM format
  142. (define (write-image file-name start-procedure message)
  143. (let ((undumpable (make-vector 1000 #f)))
  144. (write-image-low file-name
  145. start-procedure
  146. message
  147. undumpable)
  148. (if (vector-ref undumpable 0)
  149. (assertion-violation 'write-image
  150. "undumpable records written in image"
  151. (vector-prefix->list undumpable)))))
  152. ; Return a list containing the non-#F values at the beginning of VECTOR.
  153. (define (vector-prefix->list vector)
  154. (do ((i 0 (+ i 1))
  155. (losers '() (cons (vector-ref vector i) losers)))
  156. ((or (= i (vector-length vector))
  157. (if (vector-ref vector i) #f #t))
  158. losers)))
  159. ; Proposals are just vectors.
  160. (define empty-log '#(#f))
  161. (define (make-proposal)
  162. (vector #f empty-log empty-log #f))