separate.scm 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; packages packages-internal scan compiler table
  4. ; syntactic vm-exposure signals locations fluids template
  5. ; closures types inline dump/restore
  6. ; environments
  7. ; Separate compilation
  8. ; Setting the get-location method isn't sufficient because it won't
  9. ; intercept locations in already existing structures (e.g. scheme)...
  10. ;
  11. ; cf. compile-structures in link.scm
  12. ; Hacking the environment lookup mechanism to modify bindings on the
  13. ; way out won't work, because it might cause denotation comparison to
  14. ; fail during macro expansion...
  15. ; So I think the best we can do is to maintain a location -> reference map.
  16. ; There may be many routes to any particular location, but we'll only
  17. ; be able to remember one of them.
  18. ; (Actually, we _could_ remember all of them and then check at load time to
  19. ; make sure that they all agree.)
  20. ; The filtered environment also ought to be passed to the scanner,
  21. ; because it caches looked-up bindings in nodes. The effect of not
  22. ; doing this is to get warning at compile time, and unbound variables
  23. ; at load time.
  24. (define (compile-package-to-file p filename)
  25. (let* ((table (make-table location-id))
  26. (env (package->separate p table))
  27. (stuff (scan-package p env))
  28. (templates '()))
  29. (for-each (lambda (filename+nodes)
  30. (set! templates
  31. (cons (compile-scanned-forms
  32. (cdr filename+nodes)
  33. p
  34. (car filename+nodes)
  35. (current-output-port)
  36. env)
  37. templates)))
  38. stuff)
  39. (call-with-output-file filename
  40. (lambda (port)
  41. (fasdump (reverse templates) p table port)))))
  42. (define (package->separate p table)
  43. (let ((cenv (package->environment p)))
  44. (lambda (name)
  45. (let ((probe (cenv name)))
  46. (if (and (pair? probe)
  47. (location? (cdr probe))
  48. (not (table-ref table (cdr probe))))
  49. (table-set! table
  50. (cdr probe)
  51. (cons (name->qualified name)
  52. (let ((type (binding-type probe)))
  53. (if (equal? type usual-variable-type)
  54. #f
  55. type)))))
  56. probe))))
  57. (define *level* 0)
  58. (define (fasdump templates p table port)
  59. (let* ((write-char (lambda (c)
  60. (write-char c port)))
  61. (dump (lambda (thing)
  62. (dump thing write-char -1))))
  63. (dump *level*)
  64. (dump (map structure-name (package-opens p))) ;lose
  65. (dump (map car (package-accesses p)))
  66. (table-walk (lambda (loc qname+type)
  67. (dump (location-id loc))
  68. (dump qname+type))
  69. table)
  70. (dump '-)
  71. (let-fluid $dump-index (lambda (loc)
  72. (if (table-ref table loc)
  73. (location-id loc)
  74. (begin (warn "lose" loc) #f)))
  75. (lambda ()
  76. (dump templates)))))
  77. (define (fasload filename name->structure)
  78. (call-with-input-file filename
  79. (lambda (port)
  80. (let* ((read-char (lambda () (read-char port)))
  81. (restore (lambda () (restore read-char)))
  82. (table (make-table))
  83. (level (restore)))
  84. (if (not (equal? level *level*))
  85. (warn "format revision level disagreement - try recompiling"
  86. `(file: ,level current: ,*level*)))
  87. (let* ((open-names (restore))
  88. (access-names (restore))
  89. (p (make-package (lambda () (map name->structure open-names))
  90. (lambda ()
  91. (map (lambda (name)
  92. (cons name
  93. (name->structure name)))
  94. access-names))
  95. #f #f filename '()
  96. #f ;uid
  97. #f))) ;name
  98. (let loop ()
  99. (let ((uid (restore)))
  100. (if (not (eq? uid '-))
  101. (let ((qname+type (restore)))
  102. (table-set! table uid (reference->location qname+type p))
  103. (loop)))))
  104. (let-fluid $restore-index (lambda (id define?)
  105. (table-ref table id))
  106. (lambda ()
  107. (let ((templates (restore)))
  108. (for-each (lambda (template)
  109. (if (not (template? template))
  110. (assertion-violation 'fasload "lossage" template))
  111. (invoke-closure (make-closure template
  112. (package-uid p))))
  113. templates))))
  114. p)))))
  115. (define (reference->location qname+type p)
  116. (let* ((compile-time-type (or (cdr qname+type) usual-variable-type))
  117. (name (qualified->name (car qname+type) p))
  118. (binding (package-lookup p name)))
  119. (if (pair? binding)
  120. (let ((type (binding-type binding)))
  121. (if (not (equal? type compile-time-type))
  122. (warn "type inconsistency"
  123. `(compile time: ,compile-time-type)
  124. `(load time: ,type)))
  125. (cdr binding))
  126. (package-define! p name compile-time-type))))