mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-10 14:00:21 +02:00
Verify pass works on first-order CPS
* module/language/cps2/verify.scm: Work with first-order CPS.
This commit is contained in:
parent
e0ef087ceb
commit
bf5c7954ff
1 changed files with 73 additions and 38 deletions
|
@ -128,75 +128,110 @@ definitions that are available at LABEL."
|
|||
|
||||
(define (check-valid-var-uses conts kfun)
|
||||
(define (adjoin-def var defs) (intset-add defs var))
|
||||
(let visit-fun ((kfun kfun) (free empty-intset))
|
||||
(define (visit-exp exp bound)
|
||||
(let visit-fun ((kfun kfun) (free empty-intset) (first-order empty-intset))
|
||||
(define (visit-exp exp bound first-order)
|
||||
(define (check-use var)
|
||||
(unless (intset-ref bound var)
|
||||
(error "unbound var" var)))
|
||||
(define (visit-first-order kfun)
|
||||
(if (intset-ref first-order kfun)
|
||||
first-order
|
||||
(visit-fun kfun empty-intset (intset-add first-order kfun))))
|
||||
(match exp
|
||||
((or ($ $const) ($ $prim)) #t)
|
||||
((or ($ $const) ($ $prim)) first-order)
|
||||
;; todo: $closure
|
||||
(($ $fun kfun)
|
||||
(visit-fun kfun bound))
|
||||
(visit-fun kfun bound first-order))
|
||||
(($ $closure kfun)
|
||||
(visit-first-order kfun))
|
||||
(($ $rec names vars (($ $fun kfuns) ...))
|
||||
(let ((bound (fold1 adjoin-def vars bound)))
|
||||
(for-each (lambda (kfun) (visit-fun kfun bound)) kfuns)))
|
||||
(fold1 (lambda (kfun first-order)
|
||||
(visit-fun kfun bound first-order))
|
||||
kfuns first-order)))
|
||||
(($ $values args)
|
||||
(for-each check-use args))
|
||||
(for-each check-use args)
|
||||
first-order)
|
||||
(($ $call proc args)
|
||||
(check-use proc)
|
||||
(for-each check-use args))
|
||||
(($ $callk k proc args)
|
||||
(for-each check-use args)
|
||||
first-order)
|
||||
(($ $callk kfun proc args)
|
||||
(check-use proc)
|
||||
(for-each check-use args))
|
||||
(for-each check-use args)
|
||||
(visit-first-order kfun))
|
||||
(($ $branch kt ($ $values (arg)))
|
||||
(check-use arg))
|
||||
(check-use arg)
|
||||
first-order)
|
||||
(($ $branch kt ($ $primcall name args))
|
||||
(for-each check-use args))
|
||||
(for-each check-use args)
|
||||
first-order)
|
||||
(($ $primcall name args)
|
||||
(for-each check-use args))
|
||||
(for-each check-use args)
|
||||
first-order)
|
||||
(($ $prompt escape? tag handler)
|
||||
(check-use tag))))
|
||||
(intmap-for-each
|
||||
(lambda (label bound)
|
||||
(check-use tag)
|
||||
first-order)))
|
||||
(intmap-fold
|
||||
(lambda (label bound first-order)
|
||||
(let ((bound (intset-union free bound)))
|
||||
(match (intmap-ref conts label)
|
||||
(($ $kargs names vars ($ $continue k src exp))
|
||||
(visit-exp exp (fold1 adjoin-def vars bound)))
|
||||
(_ #t))))
|
||||
(compute-available-definitions conts kfun))))
|
||||
(visit-exp exp (fold1 adjoin-def vars bound) first-order))
|
||||
(_ first-order))))
|
||||
(compute-available-definitions conts kfun)
|
||||
first-order)))
|
||||
|
||||
(define (fold-nested-funs f conts kfun seed)
|
||||
(intset-fold
|
||||
(lambda (label seed)
|
||||
(match (intmap-ref conts label)
|
||||
(($ $kargs _ _ ($ $continue _ _ ($ $fun label)))
|
||||
(f label seed))
|
||||
(($ $kargs _ _ ($ $continue _ _ ($ $rec _ _ (($ $fun label) ...))))
|
||||
(fold1 f label seed))
|
||||
(_ seed)))
|
||||
(compute-function-body conts kfun)
|
||||
seed))
|
||||
(define (reachable-functions conts kfun)
|
||||
(worklist-fold*
|
||||
(lambda (kfun kfuns)
|
||||
;(pk 'verify kfun kfuns)
|
||||
(let ((kfuns (intset-add kfuns kfun)))
|
||||
(values (intset-fold
|
||||
(lambda (label nested)
|
||||
(define (return kfun*)
|
||||
;(pk 'return label kfuns kfun* nested)
|
||||
(append (filter (lambda (kfun)
|
||||
(not (intset-ref kfuns kfun)))
|
||||
kfun*)
|
||||
nested))
|
||||
(define (return1 kfun) (return (list kfun)))
|
||||
(define (return0) (return '()))
|
||||
(match (intmap-ref conts label)
|
||||
(($ $kargs _ _ ($ $continue _ _ exp))
|
||||
(match exp
|
||||
(($ $fun label) (return1 label))
|
||||
(($ $rec _ _ (($ $fun labels) ...)) (return labels))
|
||||
(($ $closure label nfree) (return1 label))
|
||||
(($ $callk label) (return1 label))
|
||||
(_ (return0))))
|
||||
(_ (return0))))
|
||||
(compute-function-body conts kfun)
|
||||
'())
|
||||
kfuns)))
|
||||
(intset kfun)
|
||||
empty-intset))
|
||||
|
||||
(define (check-label-partition conts kfun)
|
||||
;; A continuation can only belong to one function.
|
||||
(let visit-fun ((kfun kfun) (seen empty-intmap))
|
||||
(fold-nested-funs
|
||||
visit-fun
|
||||
conts
|
||||
kfun
|
||||
(intset-fold
|
||||
(lambda (kfun seen)
|
||||
(intset-fold
|
||||
(lambda (label seen)
|
||||
(intmap-add seen label kfun
|
||||
(lambda (old new)
|
||||
(error "label used by two functions" label old new))))
|
||||
(compute-function-body conts kfun)
|
||||
seen))))
|
||||
seen))
|
||||
(reachable-functions conts kfun)
|
||||
empty-intmap))
|
||||
|
||||
(define (compute-reachable-labels conts kfun)
|
||||
(let visit-fun ((kfun kfun) (seen empty-intset))
|
||||
(fold-nested-funs visit-fun conts kfun
|
||||
(intset-union seen (compute-function-body conts kfun)))))
|
||||
(intset-fold
|
||||
(lambda (kfun seen)
|
||||
(intset-union seen (compute-function-body conts kfun)))
|
||||
(reachable-functions conts kfun)
|
||||
empty-intset))
|
||||
|
||||
(define (check-arities conts kfun)
|
||||
(define (check-arity exp cont)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue