reify-primitives.scm 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. ;;; Continuation-passing style (CPS) intermediate language (IL)
  2. ;; Copyright (C) 2013, 2014, 2015 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Commentary:
  17. ;;;
  18. ;;; A pass to reify lone $prim's that were never folded into a
  19. ;;; $primcall, and $primcall's to primitives that don't have a
  20. ;;; corresponding VM op.
  21. ;;;
  22. ;;; Code:
  23. (define-module (language cps reify-primitives)
  24. #:use-module (ice-9 match)
  25. #:use-module (language cps)
  26. #:use-module (language cps utils)
  27. #:use-module (language cps with-cps)
  28. #:use-module (language cps primitives)
  29. #:use-module (language cps intmap)
  30. #:use-module (language bytecode)
  31. #:export (reify-primitives))
  32. (define (module-box cps src module name public? bound? val-proc)
  33. (with-cps cps
  34. (letv box)
  35. (let$ body (val-proc box))
  36. (letk kbox ($kargs ('box) (box) ,body))
  37. ($ (with-cps-constants ((module module)
  38. (name name)
  39. (public? public?)
  40. (bound? bound?))
  41. (build-term ($continue kbox src
  42. ($primcall 'cached-module-box
  43. (module name public? bound?))))))))
  44. (define (primitive-module name)
  45. (case name
  46. ((bytevector?
  47. bytevector-length
  48. bytevector-u8-ref bytevector-u8-set!
  49. bytevector-s8-ref bytevector-s8-set!
  50. bytevector-u16-ref bytevector-u16-set!
  51. bytevector-u16-native-ref bytevector-u16-native-set!
  52. bytevector-s16-ref bytevector-s16-set!
  53. bytevector-s16-native-ref bytevector-s16-native-set!
  54. bytevector-u32-ref bytevector-u32-set!
  55. bytevector-u32-native-ref bytevector-u32-native-set!
  56. bytevector-s32-ref bytevector-s32-set!
  57. bytevector-s32-native-ref bytevector-s32-native-set!
  58. bytevector-u64-ref bytevector-u64-set!
  59. bytevector-u64-native-ref bytevector-u64-native-set!
  60. bytevector-s64-ref bytevector-s64-set!
  61. bytevector-s64-native-ref bytevector-s64-native-set!
  62. bytevector-ieee-single-ref bytevector-ieee-single-set!
  63. bytevector-ieee-single-native-ref bytevector-ieee-single-native-set!
  64. bytevector-ieee-double-ref bytevector-ieee-double-set!
  65. bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!)
  66. '(rnrs bytevectors))
  67. ((atomic-box?
  68. make-atomic-box atomic-box-ref atomic-box-set!
  69. atomic-box-swap! atomic-box-compare-and-swap!)
  70. '(ice-9 atomic))
  71. ((current-thread) '(ice-9 threads))
  72. ((class-of) '(oop goops))
  73. ((u8vector-ref
  74. u8vector-set! s8vector-ref s8vector-set!
  75. u16vector-ref u16vector-set! s16vector-ref s16vector-set!
  76. u32vector-ref u32vector-set! s32vector-ref s32vector-set!
  77. u64vector-ref u64vector-set! s64vector-ref s64vector-set!
  78. f32vector-ref f32vector-set! f64vector-ref f64vector-set!)
  79. '(srfi srfi-4))
  80. (else '(guile))))
  81. (define (primitive-ref cps name k src)
  82. (module-box cps src (primitive-module name) name #f #t
  83. (lambda (cps box)
  84. (with-cps cps
  85. (build-term
  86. ($continue k src ($primcall 'box-ref (box))))))))
  87. (define (builtin-ref cps idx k src)
  88. (with-cps cps
  89. ($ (with-cps-constants ((idx idx))
  90. (build-term
  91. ($continue k src ($primcall 'builtin-ref (idx))))))))
  92. (define (reify-clause cps ktail)
  93. (with-cps cps
  94. (letv throw)
  95. (let$ throw-body
  96. (with-cps-constants ((wna 'wrong-number-of-args)
  97. (false #f)
  98. (str "Wrong number of arguments")
  99. (eol '()))
  100. (build-term
  101. ($continue ktail #f
  102. ($call throw (wna false str eol false))))))
  103. (letk kthrow ($kargs ('throw) (throw) ,throw-body))
  104. (let$ body (primitive-ref 'throw kthrow #f))
  105. (letk kbody ($kargs () () ,body))
  106. (letk kclause ($kclause ('() '() #f '() #f) kbody #f))
  107. kclause))
  108. ;; A $kreceive continuation should have only one predecessor.
  109. (define (uniquify-receive cps k)
  110. (match (intmap-ref cps k)
  111. (($ $kreceive ($ $arity req () rest () #f) kargs)
  112. (with-cps cps
  113. (letk k ($kreceive req rest kargs))
  114. k))
  115. (_
  116. (with-cps cps k))))
  117. (define (reify-primitives cps)
  118. (define (visit-cont label cont cps)
  119. (define (resolve-prim cps name k src)
  120. (cond
  121. ((builtin-name->index name)
  122. => (lambda (idx) (builtin-ref cps idx k src)))
  123. (else
  124. (primitive-ref cps name k src))))
  125. (match cont
  126. (($ $kfun src meta self tail #f)
  127. (with-cps cps
  128. (let$ clause (reify-clause tail))
  129. (setk label ($kfun src meta self tail clause))))
  130. (($ $kargs names vars ($ $continue k src ($ $prim name)))
  131. (with-cps cps
  132. (let$ k (uniquify-receive k))
  133. (let$ body (resolve-prim name k src))
  134. (setk label ($kargs names vars ,body))))
  135. (($ $kargs names vars
  136. ($ $continue k src ($ $primcall 'call-thunk/no-inline (proc))))
  137. (with-cps cps
  138. (setk label ($kargs names vars ($continue k src ($call proc ()))))))
  139. (($ $kargs names vars ($ $continue k src ($ $primcall name args)))
  140. (if (or (prim-instruction name) (branching-primitive? name))
  141. ;; Assume arities are correct.
  142. cps
  143. (with-cps cps
  144. (letv proc)
  145. (let$ k (uniquify-receive k))
  146. (letk kproc ($kargs ('proc) (proc)
  147. ($continue k src ($call proc args))))
  148. (let$ body (resolve-prim name kproc src))
  149. (setk label ($kargs names vars ,body)))))
  150. (($ $kargs names vars ($ $continue k src ($ $call proc args)))
  151. (with-cps cps
  152. (let$ k (uniquify-receive k))
  153. (setk label ($kargs names vars
  154. ($continue k src ($call proc args))))))
  155. (($ $kargs names vars ($ $continue k src ($ $callk k* proc args)))
  156. (with-cps cps
  157. (let$ k (uniquify-receive k))
  158. (setk label ($kargs names vars
  159. ($continue k src ($callk k* proc args))))))
  160. (_ cps)))
  161. (with-fresh-name-state cps
  162. (persistent-intmap (intmap-fold visit-cont cps cps))))