env.scm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. (define *env*)
  3. (define (current-env) *env*)
  4. (define (set-current-env! env) (set! *env* env))
  5. ; Access to environment slots
  6. (define env-ref vm-vector-ref)
  7. (define env-set! vm-vector-set!)
  8. (define (env-parent env) (env-ref env 0))
  9. (define (set-env-parent! env x) (env-set! env 0 x))
  10. (define (env-back env back) ;Resembles NTHCDR
  11. (do ((env env (env-parent env))
  12. (i back (- i 1)))
  13. ((= i 0) env)))
  14. ; Making new environments
  15. (define (pop-args-into-env count)
  16. (push *env*)
  17. (push (make-header (enum stob vector) (cells->bytes (+ count 1))))
  18. (add-env-stats count)
  19. (set! *env* (address->stob-descriptor (address1+ *stack*))))
  20. (define (stack-loc s)
  21. (- (address->integer *stack-end*) s))
  22. ; Alternative method for making environments - put the values into the heap.
  23. (define (heap-env-space count)
  24. (+ stob-overhead (+ count 1))) ; includes superior environment
  25. (define (pop-args-into-heap-env count key)
  26. (let ((stob (make-d-vector (enum stob vector) (+ count 1) key)))
  27. (copy-memory! *stack*
  28. (address+ (address-after-header stob)
  29. (cells->a-units 1))
  30. (cells->bytes count))
  31. (add-cells-to-stack! (- count))
  32. (vm-vector-set! stob 0 *env*)
  33. (set! *env* stob)))
  34. ; Migrate the current environment to the heap. Used when creating a closure.
  35. ; CURRENT-ENV-SIZE size is conservative.
  36. (define (current-env-size)
  37. (if (within-stack? *env*)
  38. (stack-size)
  39. 0))
  40. ; This is what the interpreter calls when it needs to put the current
  41. ; environment in a closure.
  42. (define (preserve-current-env key)
  43. (preserve-current-env-with-reason key (enum copy closure)))
  44. (define (preserve-current-env-with-reason key reason)
  45. (if (within-stack? *env*)
  46. (set! *env* (save-env-in-heap *env* *cont* key reason)))
  47. *env*)
  48. ; 1) Copy ENV and its ancestors into heap, adding forwarding pointers
  49. ; 2) Go down the continuation chain updating the env pointers
  50. ;
  51. ; This code depends on continuation-cont pointers not crossing environment
  52. ; parent pointers on the stack.
  53. (define (save-env-in-heap env cont key reason)
  54. (let ((top (copy-env env key reason)))
  55. (let loop ((env top))
  56. (cond ((within-stack? (env-parent env))
  57. (let ((new (copy-env (env-parent env) key reason)))
  58. (set-env-parent! env new)
  59. (loop new)))))
  60. (let loop ((cont cont))
  61. (let ((env (stack-cont-env cont)))
  62. (cond ((and (stob? env)
  63. (stob? (stob-header env)))
  64. (set-stack-cont-env! cont (stob-header env))
  65. (loop (integer->address (stack-cont-cont cont)))))))
  66. top))
  67. ; ARGUMENTS-ON-STACK needs to walk down the stack and find the end of the
  68. ; current arguments. It looks for headers, which we clobber with forwarding
  69. ; pointers, so we put a marker in the first slot of the environment and
  70. ; ARGUMENTS-ON-STACK knows to back up one if it finds the marker.
  71. ; (Putting the forwarding pointer in the first slot doesn't work, because
  72. ; we can't distinguish between it and a normal first slot.)
  73. (define (copy-env env key reason)
  74. (let ((new (header+contents->stob (stob-header env)
  75. (address-after-header env)
  76. key)))
  77. (add-copy-env-stats env reason)
  78. (vm-vector-set! env 0 argument-limit-marker)
  79. (stob-header-set! env new)
  80. new))