frame.scm 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Martin Gasbichler, Mike Sperber
  3. ; A frame contains information about a procedure's current stack frame. It
  4. ; also has a list of the literals that will go in the procedure's template
  5. ; and the debugging data for the template.
  6. ;
  7. ; template-index - the location of this procedure's template in the frame
  8. ; (#f if the template is not needed)
  9. ; env-index - the location of this procedure's environment in the frame
  10. ; (#f if the procedure does not use its environment)
  11. ; closure-index - the location of this procedure's closure in the frame
  12. ; (#f if the closure is not needed)
  13. ; size - largest size reached by the frame, in descriptors
  14. ; literals - list of literals and bindings referenced
  15. ; count - length of LITERALS
  16. ; debug-data - debug information (see ddata.scm)
  17. (define-record-type frame :frame
  18. (really-make-frame literals count debug-data template-index env-index closure-index size)
  19. frame?
  20. (template-index frame-template-index)
  21. (env-index frame-env-index)
  22. (closure-index frame-closure-index)
  23. (size frame-size set-frame-size!)
  24. (literals frame-literals set-frame-literals!)
  25. (count frame-count set-frame-count!)
  26. (debug-data frame-debug-data))
  27. ; SIZE is the number of values on the stack when the procedure is
  28. ; entered (typically the number of arguments). ENV? is true if the
  29. ; environment was pushed on after the arguments, TEMPLATE? is true if
  30. ; the template was pushed as well. CLOSURE? is true if the closure
  31. ; was pushed as well.
  32. (define (make-frame parent name size template? env? closure?)
  33. (let* ((ddata (new-debug-data (adjust-procedure-name name)
  34. (if parent
  35. (frame-debug-data parent)
  36. #f))))
  37. (define (allocate-index really?)
  38. (and really?
  39. (let ((index size))
  40. (set! size (+ 1 size))
  41. index)))
  42. (let* ((closure-index (allocate-index closure?))
  43. (env-index (allocate-index env?))
  44. (template-index (allocate-index template?)))
  45. (really-make-frame '()
  46. 0
  47. ddata
  48. template-index env-index closure-index
  49. size))))
  50. (define (adjust-procedure-name name)
  51. (cond ((string? name) ; only files have strings for names
  52. (if (keep-file-names?)
  53. name
  54. #f))
  55. ((and (keep-procedure-names?)
  56. (name? name))
  57. (name->symbol name))
  58. (else
  59. #f)))
  60. ; Convert an index, which is relative to the base of the frame, to an offset
  61. ; from the current stack pointer.
  62. (define (index->offset index depth)
  63. (- depth (+ index 1)))
  64. ; Offsets for the template and environment.
  65. (define (template-offset frame depth)
  66. (if (frame-template-index frame)
  67. (index->offset (frame-template-index frame)
  68. depth)
  69. #f))
  70. (define (environment-offset frame depth)
  71. (index->offset (frame-env-index frame)
  72. depth))
  73. ; Note that FRAME reaches a size of DEPTH.
  74. (define (depth-check! frame depth)
  75. (if (< (frame-size frame)
  76. depth)
  77. (set-frame-size! frame depth)))
  78. ; These two procedures look up bindings and literals in the list of values
  79. ; to go in the template. They're added if not already present. The returned
  80. ; index is that of template, not the frame's list.
  81. (define (binding->index frame binding name assigned?)
  82. (let loop ((i 0) (l (frame-literals frame)))
  83. (cond ((null? l)
  84. (really-literal->index frame
  85. (make-thingie binding name assigned?)
  86. #f))
  87. ((and (thingie? (car l))
  88. (eq? binding (thingie-binding (car l)))
  89. (eq? name (thingie-name (car l))))
  90. (if assigned?
  91. (set-thingie-assigned?! (car l) #t))
  92. (really-literal->index frame #f i))
  93. (else
  94. (loop (+ i 1) (cdr l))))))
  95. (define (literal->index frame thing)
  96. (really-literal->index frame thing
  97. (position thing (frame-literals frame))))
  98. (define (really-literal->index frame thing probe)
  99. (let ((count (frame-count frame)))
  100. (if probe
  101. ;; +++ Eliminate duplicate entries.
  102. ;; Not necessary, just a modest space saver [how much?].
  103. ;; Measurably slows down compilation.
  104. ;; when 1 thing, lits = (x), count = 1, probe = 0, want 2
  105. (+ (- count probe)
  106. (- template-overhead 1))
  107. (begin
  108. (if (>= count two-byte-limit)
  109. (assertion-violation 'literal->index
  110. "compiler bug: too many literals"
  111. thing))
  112. (set-frame-literals! frame
  113. (cons thing
  114. (frame-literals frame)))
  115. (set-frame-count! frame (+ count 1))
  116. ;; when 1st thing, count = 0, want 2
  117. (+ count template-overhead)))))
  118. (define (position elt list)
  119. (let loop ((i 0) (l list))
  120. (cond ((null? l)
  121. #f)
  122. ((equal? elt (car l))
  123. i)
  124. (else
  125. (loop (+ i 1) (cdr l))))))