fix `lazy-require' in phase levels other than 0

The `lazy-require' form expands to `define-runtime-module-path-index',
whch doesn't work right at phase levels other than 0. Work around the
problem by generating a submodule to hold the
`define-runtime-module-path-index' form.

This repair fixes `raco exe' on certain uses of `match', which in turn
uses `lazy-require' at compile time.

Also, use `register-external-module' to generate appropriate
dependencies on lazily loaded modules.

original commit: 6b16679b39
This commit is contained in:
Matthew Flatt 2012-11-11 07:22:51 -07:00
commit 03c5a46331
16 changed files with 181 additions and 45 deletions

View File

@ -78,7 +78,20 @@
(let-values ([(n b) (module-path-index-split modidx)]) (let-values ([(n b) (module-path-index-split modidx)])
(and (not n) (not b)))) (and (not n) (not b))))
(string->symbol (format "_~a" sym)) (string->symbol (format "_~a" sym))
(string->symbol (format "_~s@~s~a" sym (mpi->string modidx) (string->symbol (format "_~s~a@~s~a"
sym
(match constantness
['constant ":c"]
['fixed ":f"]
[(function-shape a pm?)
(if pm? ":P" ":p")]
[(struct-type-shape c) ":t"]
[(constructor-shape a) ":mk"]
[(predicate-shape) ":?"]
[(accessor-shape c) ":ref"]
[(mutator-shape c) ":set!"]
[else ""])
(mpi->string modidx)
(if (zero? phase) (if (zero? phase)
"" ""
(format "/~a" phase)))))] (format "/~a" phase)))))]

View File

@ -1,5 +1,6 @@
#lang racket #lang racket/base
(require compiler/zo-parse)
(require racket/match racket/contract compiler/zo-parse)
(define (alpha-vary-ctop top) (define (alpha-vary-ctop top)
(match top (match top

View File

@ -1,4 +1,5 @@
#lang racket #lang racket/base
#| #|
Here's the idea: Here's the idea:
@ -40,6 +41,7 @@ Here's the idea:
(require racket/pretty (require racket/pretty
racket/system racket/system
racket/cmdline
"mpi.rkt" "mpi.rkt"
"util.rkt" "util.rkt"
"nodep.rkt" "nodep.rkt"

View File

@ -1,5 +1,10 @@
#lang racket #lang racket/base
(require compiler/zo-parse
(require racket/match
racket/list
racket/dict
racket/contract
compiler/zo-parse
"util.rkt") "util.rkt")
; XXX Use efficient set structure ; XXX Use efficient set structure
@ -150,21 +155,20 @@
(match (dict-ref g n) (match (dict-ref g n)
[(struct refs (n-tls n-stxs)) [(struct refs (n-tls n-stxs))
(hash-set! visited? n #t) (hash-set! visited? n #t)
(local (define-values (new-tls1 new-stxs1)
[(define-values (new-tls1 new-stxs1) (for/fold ([new-tls tls]
(for/fold ([new-tls tls] [new-stxs stxs])
[new-stxs stxs]) ([tl (in-list n-tls)])
([tl (in-list n-tls)]) (visit-tl tl new-tls new-stxs)))
(visit-tl tl new-tls new-stxs))) (define new-stxs2
(define new-stxs2 (for/fold ([new-stxs new-stxs1])
(for/fold ([new-stxs new-stxs1]) ([stx (in-list n-stxs)])
([stx (in-list n-stxs)]) (define this-stx (visit-stx stx))
(define this-stx (visit-stx stx)) (if this-stx
(if this-stx (list* this-stx new-stxs)
(list* this-stx new-stxs) new-stxs)))
new-stxs)))] (values (list* n new-tls1)
(values (list* n new-tls1) new-stxs2)])))
new-stxs2))])))
(define stx-visited? (make-hasheq)) (define stx-visited? (make-hasheq))
(define (visit-stx n) (define (visit-stx n)
(if (hash-has-key? stx-visited? n) (if (hash-has-key? stx-visited? n)

View File

@ -1,5 +1,9 @@
#lang racket #lang racket/base
(require compiler/zo-parse
(require racket/list
racket/match
racket/contract
compiler/zo-parse
"util.rkt" "util.rkt"
"mpi.rkt" "mpi.rkt"
"nodep.rkt" "nodep.rkt"
@ -156,12 +160,12 @@
(cond (cond
[(mod-lift-start . <= . n) [(mod-lift-start . <= . n)
; This is a lift ; This is a lift
(local [(define which-lift (- n mod-lift-start)) (define which-lift (- n mod-lift-start))
(define lift-tl (+ top-lift-start lift-offset which-lift))] (define lift-tl (+ top-lift-start lift-offset which-lift))
(when (lift-tl . >= . max-toplevel) (when (lift-tl . >= . max-toplevel)
(error 'merge-module "[~S] lift error: orig(~a) which(~a) max(~a) lifts(~a) now(~a)" (error 'merge-module "[~S] lift error: orig(~a) which(~a) max(~a) lifts(~a) now(~a)"
name n which-lift num-mod-toplevels mod-num-lifts lift-tl)) name n which-lift num-mod-toplevels mod-num-lifts lift-tl))
lift-tl)] lift-tl]
[else [else
(list-ref toplevel-remap n)])) (list-ref toplevel-remap n)]))
(lambda (n) (lambda (n)

View File

@ -1,5 +1,9 @@
#lang racket #lang racket/base
(require compiler/zo-parse
(require racket/list
racket/match
racket/contract
compiler/zo-parse
"util.rkt") "util.rkt")
(define (->module-path-index s) (define (->module-path-index s)

View File

@ -1,5 +1,7 @@
#lang racket #lang racket/base
(require syntax/modresolve)
(require racket/contract
syntax/modresolve)
(define current-module-path (make-parameter #f)) (define current-module-path (make-parameter #f))

View File

@ -1,5 +1,9 @@
#lang racket #lang racket/base
(require compiler/zo-parse
(require racket/list
racket/match
racket/contract
compiler/zo-parse
"util.rkt" "util.rkt"
"mpi.rkt" "mpi.rkt"
racket/set) racket/set)
@ -92,7 +96,8 @@
(define (nodep-form form phase) (define (nodep-form form phase)
(if (mod? form) (if (mod? form)
(local [(define-values (modvar-rewrite lang-info mods) (nodep-module form phase))] (let-values ([(modvar-rewrite lang-info mods)
(nodep-module form phase)])
(values modvar-rewrite lang-info (make-splice mods))) (values modvar-rewrite lang-info (make-splice mods)))
(error 'nodep-form "Doesn't support non mod forms"))) (error 'nodep-form "Doesn't support non mod forms")))

View File

@ -1,6 +1,10 @@
#lang racket #lang racket/base
(require unstable/struct
(require racket/match
racket/vector
unstable/struct
"util.rkt") "util.rkt")
(provide replace-modidx) (provide replace-modidx)
(define (replace-modidx expr self-modidx) (define (replace-modidx expr self-modidx)

View File

@ -1,5 +1,8 @@
#lang racket #lang racket/base
(require compiler/zo-structs
(require racket/match
racket/contract
compiler/zo-structs
"util.rkt") "util.rkt")
(define (update-toplevels toplevel-updater topsyntax-updater topsyntax-new-midpt) (define (update-toplevels toplevel-updater topsyntax-updater topsyntax-new-midpt)

View File

@ -1,5 +1,7 @@
#lang racket #lang racket/base
(require compiler/zo-parse)
(require racket/contract
compiler/zo-parse)
(define (prefix-syntax-start pre) (define (prefix-syntax-start pre)
(length (prefix-toplevels pre))) (length (prefix-toplevels pre)))

View File

@ -604,13 +604,51 @@
[(? void?) [(? void?)
(out-byte CPT_VOID out)] (out-byte CPT_VOID out)]
[(struct module-variable (modidx sym pos phase constantness)) [(struct module-variable (modidx sym pos phase constantness))
(define (to-sym n) (string->symbol (format "struct~a" n)))
(out-byte CPT_MODULE_VAR out) (out-byte CPT_MODULE_VAR out)
(out-anything modidx out) (out-anything modidx out)
(out-anything sym out) (out-anything sym out)
(out-anything (cond
[(function-shape? constantness)
(let ([a (function-shape-arity constantness)])
(cond
[(arity-at-least? a)
(bitwise-ior (arithmetic-shift (- (add1 (arity-at-least-value a))) 1)
(if (function-shape-preserves-marks? constantness) 1 0))]
[(list? a)
(string->symbol (apply
string-append
(add-between
(for/list ([a (in-list a)])
(define n (if (arity-at-least? a)
(- (add1 (arity-at-least-value a)))
a))
(number->string n))
":")))]
[else
(bitwise-ior (arithmetic-shift a 1)
(if (function-shape-preserves-marks? constantness) 1 0))]))]
[(struct-type-shape? constantness)
(to-sym (arithmetic-shift (struct-type-shape-field-count constantness)
4))]
[(constructor-shape? constantness)
(to-sym (bitwise-ior 1 (arithmetic-shift (constructor-shape-arity constantness)
4)))]
[(predicate-shape? constantness) (to-sym 2)]
[(accessor-shape? constantness)
(to-sym (bitwise-ior 3 (arithmetic-shift (accessor-shape-field-count constantness)
4)))]
[(mutator-shape? constantness)
(to-sym (bitwise-ior 4 (arithmetic-shift (mutator-shape-field-count constantness)
4)))]
[(struct-other-shape? constantness)
(to-sym 5)]
[else #f])
out)
(case constantness (case constantness
[(constant) (out-number -4 out)] [(#f) (void)]
[(fixed) (out-number -5 out)] [(fixed) (out-number -5 out)]
[else (void)]) [else (out-number -4 out)])
(unless (zero? phase) (unless (zero? phase)
(out-number -2 out) (out-number -2 out)
(out-number phase out)) (out-number phase out))

View File

@ -856,6 +856,7 @@
[(module-var) [(module-var)
(let ([mod (read-compact cp)] (let ([mod (read-compact cp)]
[var (read-compact cp)] [var (read-compact cp)]
[shape (read-compact cp)]
[pos (read-compact-number cp)]) [pos (read-compact-number cp)])
(let-values ([(flags mod-phase pos) (let-values ([(flags mod-phase pos)
(let loop ([pos pos]) (let loop ([pos pos])
@ -869,6 +870,33 @@
[else (values 0 0 pos)]))]) [else (values 0 0 pos)]))])
(make-module-variable mod var pos mod-phase (make-module-variable mod var pos mod-phase
(cond (cond
[shape
(cond
[(number? shape)
(define n (arithmetic-shift shape -1))
(make-function-shape (if (negative? n)
(make-arity-at-least (sub1 (- n)))
n)
(odd? shape))]
[(and (symbol? shape)
(regexp-match? #rx"^struct" (symbol->string shape)))
(define n (string->number (substring (symbol->string shape) 6)))
(case (bitwise-and n #x7)
[(0) (make-struct-type-shape (arithmetic-shift n -3))]
[(1) (make-constructor-shape (arithmetic-shift n -3))]
[(2) (make-predicate-shape)]
[(3) (make-accessor-shape (arithmetic-shift n -3))]
[(4) (make-mutator-shape (arithmetic-shift n -3))]
[else (make-struct-other-shape)])]
[else
;; parse symbol as ":"-separated sequence of arities
(make-function-shape
(for/list ([s (regexp-split #rx":" (symbol->string shape))])
(define i (string->number s))
(if (negative? i)
(make-arity-at-least (sub1 (- i)))
i))
#f)])]
[(not (zero? (bitwise-and #x1 flags))) 'constant] [(not (zero? (bitwise-and #x1 flags))) 'constant]
[(not (zero? (bitwise-and #x2 flags))) 'fixed] [(not (zero? (bitwise-and #x2 flags))) 'fixed]
[else #f]))))] [else #f]))))]

View File

@ -38,13 +38,26 @@
[(_ id . rest) [(_ id . rest)
(define-form-struct* id (id zo) . rest)])) (define-form-struct* id (id zo) . rest)]))
(define-form-struct function-shape ([arity procedure-arity?]
[preserves-marks? boolean?]))
(define-form-struct struct-shape ())
(define-form-struct (constructor-shape struct-shape) ([arity exact-nonnegative-integer?]))
(define-form-struct (predicate-shape struct-shape) ())
(define-form-struct (accessor-shape struct-shape) ([field-count exact-nonnegative-integer?]))
(define-form-struct (mutator-shape struct-shape) ([field-count exact-nonnegative-integer?]))
(define-form-struct (struct-type-shape struct-shape) ([field-count exact-nonnegative-integer?]))
(define-form-struct (struct-other-shape struct-shape) ())
;; In toplevels of resove prefix: ;; In toplevels of resove prefix:
(define-form-struct global-bucket ([name symbol?])) ; top-level binding (define-form-struct global-bucket ([name symbol?])) ; top-level binding
(define-form-struct module-variable ([modidx module-path-index?] (define-form-struct module-variable ([modidx module-path-index?]
[sym symbol?] [sym symbol?]
[pos exact-integer?] [pos exact-integer?]
[phase exact-nonnegative-integer?] [phase exact-nonnegative-integer?]
[constantness (or/c #f 'constant 'fixed)])) [constantness (or/c #f 'constant 'fixed
function-shape?
struct-shape?)]))
;; Syntax object ;; Syntax object
(define ((alist/c k? v?) l) (define ((alist/c k? v?) l)

View File

@ -0,0 +1,12 @@
#lang racket/base
(require racket/match)
;; check using `racket/match', particularly with a pattern
;; that eneds run-time support that may go through a
;; compile-time `lazy-require':
(match "x"
[(pregexp "x")
(with-output-to-file "stdout"
(lambda () (printf "This is 21.\n"))
#:exists 'append)])

View File

@ -227,6 +227,7 @@
(one-mz-test "embed-me17.rkt" "This is 17.\n" #f) (one-mz-test "embed-me17.rkt" "This is 17.\n" #f)
(one-mz-test "embed-me18.rkt" "This is 18.\n" #f) (one-mz-test "embed-me18.rkt" "This is 18.\n" #f)
(one-mz-test "embed-me19.rkt" "This is 19.\n" #f) (one-mz-test "embed-me19.rkt" "This is 19.\n" #f)
(one-mz-test "embed-me21.rkt" "This is 21.\n" #f)
;; Try unicode expr and cmdline: ;; Try unicode expr and cmdline:
(prepare dest "unicode") (prepare dest "unicode")