separate.scm 4.3 KB

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