defeats the inlining optimization by making procedure bodies big in order to do lazy contract checking
svn: r2486
This commit is contained in:
parent
ab80f98943
commit
8617ca8fcd
|
@ -29,7 +29,7 @@ expands into procedures & structs like this:
|
|||
which are then called when the contract's fields are explored
|
||||
|
||||
|#
|
||||
|
||||
|
||||
(define (build-clauses name coerce-contract stx clauses)
|
||||
(let* ([field-names
|
||||
(map (λ (clause)
|
||||
|
@ -40,7 +40,15 @@ which are then called when the contract's fields are explored
|
|||
stx
|
||||
clause)]))
|
||||
(syntax->list clauses))]
|
||||
[all-ac-ids (generate-temporaries field-names)])
|
||||
[all-ac-ids (generate-temporaries field-names)]
|
||||
[defeat-inlining
|
||||
;; makes the procedure "big enough" so
|
||||
;; that inlining doesn't consider it.
|
||||
(λ (e)
|
||||
(let loop ([i 16])
|
||||
(cond
|
||||
[(zero? i) e]
|
||||
[else #`(values #,(loop (- i 1)))])))])
|
||||
(let loop ([clauses (syntax->list clauses)]
|
||||
[ac-ids all-ac-ids]
|
||||
[prior-ac-ids '()]
|
||||
|
@ -58,7 +66,8 @@ which are then called when the contract's fields are explored
|
|||
(let ([maker-arg #`(λ #,(match-up (reverse prior-ac-ids)
|
||||
(syntax (x ...))
|
||||
field-names)
|
||||
(#,coerce-contract #,name ctc-exp))])
|
||||
#,(defeat-inlining
|
||||
#`(#,coerce-contract #,name ctc-exp)))])
|
||||
(loop (cdr clauses)
|
||||
(cdr ac-ids)
|
||||
(cons (car ac-ids) prior-ac-ids)
|
||||
|
|
|
@ -48,6 +48,15 @@
|
|||
[wrap-name (string->symbol (format "~a/lazy-contract" (syntax-e (syntax name))))])
|
||||
#`
|
||||
(begin
|
||||
|
||||
;; `declare' future bindings for the top-level (so that everyone picks them up)
|
||||
#,@(if (eq? (syntax-local-context) 'top-level)
|
||||
(list
|
||||
(syntax
|
||||
(define-syntaxes (contract-type contract-maker contract-predicate contract-get contract-set)
|
||||
(values))))
|
||||
(list))
|
||||
|
||||
(define-values (wrap-type wrap-maker wrap-predicate wrap-get wrap-set)
|
||||
(make-struct-type 'wrap-name
|
||||
#f ;; super struct
|
||||
|
|
|
@ -3521,6 +3521,19 @@
|
|||
(couple-hd (contract c1 y 'pos 'neg))))
|
||||
1)
|
||||
|
||||
;; make sure that define-contract-struct contracts can go at the top level
|
||||
(test/spec-passed
|
||||
'd-c-s37
|
||||
'(parameterize ([current-namespace (make-namespace)])
|
||||
(eval '(require (lib "contract.ss")))
|
||||
(eval '(define-contract-struct couple (hd tl)))
|
||||
(eval '(contract-stronger?
|
||||
(couple/dc [hd any/c]
|
||||
[tl (hd) any/c])
|
||||
(couple/dc [hd any/c]
|
||||
[tl (hd) any/c])))))
|
||||
|
||||
|
||||
;; test the predicate
|
||||
(let ()
|
||||
(define-contract-struct couple (hd tl))
|
||||
|
@ -3926,6 +3939,10 @@
|
|||
(test #f contract-stronger? (couple/c (>=/c 2) (>=/c 3)) (couple/c (>=/c 4) (>=/c 5)))
|
||||
(test #t contract-stronger? (couple/c (>=/c 4) (>=/c 5)) (couple/c (>=/c 2) (>=/c 3)))
|
||||
(test #f contract-stronger? (couple/c (>=/c 1) (>=/c 5)) (couple/c (>=/c 5) (>=/c 1)))
|
||||
(let ([ctc (couple/dc [hd any/c] [tl (hd) any/c])])
|
||||
(test #t contract-stronger? ctc ctc))
|
||||
(let ([ctc (couple/dc [hd any/c] [tl (hd) (<=/c hd)])])
|
||||
(test #t contract-stronger? ctc ctc))
|
||||
(test #t contract-stronger? list-of-numbers list-of-numbers)
|
||||
(test #t contract-stronger? (short-list/less-than 4) (short-list/less-than 5))
|
||||
(test #f contract-stronger? (short-list/less-than 5) (short-list/less-than 4))
|
||||
|
|
Loading…
Reference in New Issue
Block a user