low.scm 6.2 KB

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