mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Add "custom primcall converter" facility to tree-il->cps lowering
* module/language/tree-il/compile-cps.scm (define-custom-primcall-converter): New exported macro, handling primcalls that need special logic. Fold "throw" and "values" into this macro. The goal is to allow the Hoot compiler to specially convert an "inline assembly" primcall.
This commit is contained in:
parent
c7632b8f97
commit
55364184d7
1 changed files with 80 additions and 67 deletions
|
@ -62,7 +62,7 @@
|
||||||
#:use-module (language tree-il cps-primitives)
|
#:use-module (language tree-il cps-primitives)
|
||||||
#:use-module (language tree-il)
|
#:use-module (language tree-il)
|
||||||
#:use-module (language cps intmap)
|
#:use-module (language cps intmap)
|
||||||
#:export (compile-cps))
|
#:export (compile-cps define-custom-primcall-converter))
|
||||||
|
|
||||||
(define (convert-primcall/default cps k src op param . args)
|
(define (convert-primcall/default cps k src op param . args)
|
||||||
(with-cps cps
|
(with-cps cps
|
||||||
|
@ -1438,6 +1438,82 @@ use as the proc slot."
|
||||||
($continue kvalues src ($prim 'values))))
|
($continue kvalues src ($prim 'values))))
|
||||||
kval))))))))
|
kval))))))))
|
||||||
|
|
||||||
|
(define *custom-primcall-converters* (make-hash-table))
|
||||||
|
(define-syntax-rule
|
||||||
|
(define-custom-primcall-converter (name cps src args convert-args k)
|
||||||
|
. body)
|
||||||
|
(let ((convert (lambda (cps src args convert-args k) . body)))
|
||||||
|
(hashq-set! *custom-primcall-converters* 'name convert)))
|
||||||
|
(define (custom-primcall-converter name)
|
||||||
|
(hashq-ref *custom-primcall-converters* name))
|
||||||
|
|
||||||
|
(define-custom-primcall-converter (throw cps src args convert-args k)
|
||||||
|
(define (fallback)
|
||||||
|
(convert-args cps args
|
||||||
|
(lambda (cps args)
|
||||||
|
(match args
|
||||||
|
((key . args)
|
||||||
|
(with-cps cps
|
||||||
|
(letv arglist)
|
||||||
|
(letk kargs ($kargs ('arglist) (arglist)
|
||||||
|
($throw src 'throw #f (key arglist))))
|
||||||
|
($ (build-list kargs src args))))))))
|
||||||
|
(define (specialize op param . args)
|
||||||
|
(convert-args cps args
|
||||||
|
(lambda (cps args)
|
||||||
|
(with-cps cps
|
||||||
|
(build-term
|
||||||
|
($throw src op param args))))))
|
||||||
|
(match args
|
||||||
|
((($ <const> _ key) ($ <const> _ subr) ($ <const> _ msg) args data)
|
||||||
|
;; Specialize `throw' invocations corresponding to common
|
||||||
|
;; "error" invocations.
|
||||||
|
(let ()
|
||||||
|
(match (vector args data)
|
||||||
|
(#(($ <primcall> _ 'cons (x ($ <const> _ ())))
|
||||||
|
($ <primcall> _ 'cons (x ($ <const> _ ()))))
|
||||||
|
(specialize 'throw/value+data `#(,key ,subr ,msg) x))
|
||||||
|
(#(($ <primcall> _ 'cons (x ($ <const> _ ()))) ($ <const> _ #f))
|
||||||
|
(specialize 'throw/value `#(,key ,subr ,msg) x))
|
||||||
|
(_ (fallback)))))
|
||||||
|
(_ (fallback))))
|
||||||
|
|
||||||
|
(define-custom-primcall-converter (values cps src args convert-args k)
|
||||||
|
(convert-args cps args
|
||||||
|
(lambda (cps args)
|
||||||
|
(match (intmap-ref cps k)
|
||||||
|
(($ $ktail)
|
||||||
|
(with-cps cps
|
||||||
|
(build-term
|
||||||
|
($continue k src ($values args)))))
|
||||||
|
(($ $kargs names)
|
||||||
|
;; Can happen if continuation already saw we produced the
|
||||||
|
;; right number of values.
|
||||||
|
(with-cps cps
|
||||||
|
(build-term
|
||||||
|
($continue k src ($values args)))))
|
||||||
|
(($ $kreceive ($ $arity req () rest () #f) kargs)
|
||||||
|
(cond
|
||||||
|
((and (not rest) (= (length args) (length req)))
|
||||||
|
(with-cps cps
|
||||||
|
(build-term
|
||||||
|
($continue kargs src ($values args)))))
|
||||||
|
((and rest (>= (length args) (length req)))
|
||||||
|
(with-cps cps
|
||||||
|
(letv rest)
|
||||||
|
(letk krest ($kargs ('rest) (rest)
|
||||||
|
($continue kargs src
|
||||||
|
($values ,(append (list-head args (length req))
|
||||||
|
(list rest))))))
|
||||||
|
($ (build-list krest src (list-tail args (length req))))))
|
||||||
|
(else
|
||||||
|
;; Number of values mismatch; reify a values call.
|
||||||
|
(with-cps cps
|
||||||
|
(letv val values)
|
||||||
|
(letk kvalues ($kargs ('values) (values)
|
||||||
|
($continue k src ($call values args))))
|
||||||
|
(build-term ($continue kvalues src ($prim 'values)))))))))))
|
||||||
|
|
||||||
;; cps exp k-name alist -> cps term
|
;; cps exp k-name alist -> cps term
|
||||||
(define (convert cps exp k subst)
|
(define (convert cps exp k subst)
|
||||||
(define (zero-valued? exp)
|
(define (zero-valued? exp)
|
||||||
|
@ -1696,72 +1772,9 @@ use as the proc slot."
|
||||||
|
|
||||||
(($ <primcall> src name args)
|
(($ <primcall> src name args)
|
||||||
(cond
|
(cond
|
||||||
((eq? name 'throw)
|
((custom-primcall-converter name)
|
||||||
(let ()
|
=> (lambda (convert-primcall)
|
||||||
(define (fallback)
|
(convert-primcall cps src args convert-args k)))
|
||||||
(convert-args cps args
|
|
||||||
(lambda (cps args)
|
|
||||||
(match args
|
|
||||||
((key . args)
|
|
||||||
(with-cps cps
|
|
||||||
(letv arglist)
|
|
||||||
(letk kargs ($kargs ('arglist) (arglist)
|
|
||||||
($throw src 'throw #f (key arglist))))
|
|
||||||
($ (build-list kargs src args))))))))
|
|
||||||
(define (specialize op param . args)
|
|
||||||
(convert-args cps args
|
|
||||||
(lambda (cps args)
|
|
||||||
(with-cps cps
|
|
||||||
(build-term
|
|
||||||
($throw src op param args))))))
|
|
||||||
(match args
|
|
||||||
((($ <const> _ key) ($ <const> _ subr) ($ <const> _ msg) args data)
|
|
||||||
;; Specialize `throw' invocations corresponding to common
|
|
||||||
;; "error" invocations.
|
|
||||||
(let ()
|
|
||||||
(match (vector args data)
|
|
||||||
(#(($ <primcall> _ 'cons (x ($ <const> _ ())))
|
|
||||||
($ <primcall> _ 'cons (x ($ <const> _ ()))))
|
|
||||||
(specialize 'throw/value+data `#(,key ,subr ,msg) x))
|
|
||||||
(#(($ <primcall> _ 'cons (x ($ <const> _ ()))) ($ <const> _ #f))
|
|
||||||
(specialize 'throw/value `#(,key ,subr ,msg) x))
|
|
||||||
(_ (fallback)))))
|
|
||||||
(_ (fallback)))))
|
|
||||||
((eq? name 'values)
|
|
||||||
(convert-args cps args
|
|
||||||
(lambda (cps args)
|
|
||||||
(match (intmap-ref cps k)
|
|
||||||
(($ $ktail)
|
|
||||||
(with-cps cps
|
|
||||||
(build-term
|
|
||||||
($continue k src ($values args)))))
|
|
||||||
(($ $kargs names)
|
|
||||||
;; Can happen if continuation already saw we produced the
|
|
||||||
;; right number of values.
|
|
||||||
(with-cps cps
|
|
||||||
(build-term
|
|
||||||
($continue k src ($values args)))))
|
|
||||||
(($ $kreceive ($ $arity req () rest () #f) kargs)
|
|
||||||
(cond
|
|
||||||
((and (not rest) (= (length args) (length req)))
|
|
||||||
(with-cps cps
|
|
||||||
(build-term
|
|
||||||
($continue kargs src ($values args)))))
|
|
||||||
((and rest (>= (length args) (length req)))
|
|
||||||
(with-cps cps
|
|
||||||
(letv rest)
|
|
||||||
(letk krest ($kargs ('rest) (rest)
|
|
||||||
($continue kargs src
|
|
||||||
($values ,(append (list-head args (length req))
|
|
||||||
(list rest))))))
|
|
||||||
($ (build-list krest src (list-tail args (length req))))))
|
|
||||||
(else
|
|
||||||
;; Number of values mismatch; reify a values call.
|
|
||||||
(with-cps cps
|
|
||||||
(letv val values)
|
|
||||||
(letk kvalues ($kargs ('values) (values)
|
|
||||||
($continue k src ($call values args))))
|
|
||||||
(build-term ($continue kvalues src ($prim 'values)))))))))))
|
|
||||||
((tree-il-primitive->cps-primitive+nargs+nvalues name)
|
((tree-il-primitive->cps-primitive+nargs+nvalues name)
|
||||||
=>
|
=>
|
||||||
(match-lambda
|
(match-lambda
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue