all necessary changes to check references to uninitialized letrec variables
includes a new pass, letrec_check, two new primitives, and changes to packages that grabbed the letrec undefined value
This commit is contained in:
parent
800641e11a
commit
72c958df62
|
@ -1,4 +1,5 @@
|
||||||
(module runtime mzscheme
|
(module runtime mzscheme
|
||||||
|
(require racket/undefined)
|
||||||
|
|
||||||
(provide (struct a60:array (vec dimens))
|
(provide (struct a60:array (vec dimens))
|
||||||
(struct a60:switch (choices))
|
(struct a60:switch (choices))
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
(define-struct a60:array (vec dimens))
|
(define-struct a60:array (vec dimens))
|
||||||
(define-struct a60:switch (choices))
|
(define-struct a60:switch (choices))
|
||||||
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
(define (check-boolean b) b)
|
(define (check-boolean b) b)
|
||||||
(define (goto f) (f))
|
(define (goto f) (f))
|
||||||
(define (get-value v) (v))
|
(define (get-value v) (v))
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
syntax/name
|
syntax/name
|
||||||
syntax/context
|
syntax/context
|
||||||
racket/syntax
|
racket/syntax
|
||||||
|
racket/undefined
|
||||||
(only racket/base filter)
|
(only racket/base filter)
|
||||||
"private/unitidmap.rkt")
|
"private/unitidmap.rkt")
|
||||||
|
|
||||||
;; ----------------------------------------------------------------------
|
;; ----------------------------------------------------------------------
|
||||||
;; Structures and helpers
|
;; Structures and helpers
|
||||||
|
|
||||||
(define undefined (letrec ([x x]) x)) ; initial value
|
|
||||||
|
|
||||||
(define insp (current-inspector)) ; for named structures
|
(define insp (current-inspector)) ; for named structures
|
||||||
|
|
||||||
(define-struct unit (num-imports exports go)) ; unit value
|
(define-struct unit (num-imports exports go)) ; unit value
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
mzlib/math
|
mzlib/math
|
||||||
mzlib/pconvert-prop
|
mzlib/pconvert-prop
|
||||||
scheme/match
|
scheme/match
|
||||||
|
racket/undefined
|
||||||
"set-result.rkt"
|
"set-result.rkt"
|
||||||
(only racket/base define-struct)
|
(only racket/base define-struct)
|
||||||
racket/struct-info
|
racket/struct-info
|
||||||
|
@ -87,15 +88,14 @@
|
||||||
(current-continuation-marks)))))
|
(current-continuation-marks)))))
|
||||||
|
|
||||||
;; Wrapped around uses of local-bound variables:
|
;; Wrapped around uses of local-bound variables:
|
||||||
(define (check-not-undefined name val)
|
(define (teach-check-not-undefined name val)
|
||||||
(if (eq? val undefined)
|
(if (undefined? val)
|
||||||
(raise
|
(raise
|
||||||
(make-exn:fail:contract:variable
|
(make-exn:fail:contract:variable
|
||||||
(format "local variable used before its definition: ~a" name)
|
(format "local variable used before its definition: ~a" name)
|
||||||
(current-continuation-marks)
|
(current-continuation-marks)
|
||||||
name))
|
name))
|
||||||
val))
|
val))
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
|
|
||||||
(define (identifier-is-bound? id)
|
(define (identifier-is-bound? id)
|
||||||
(or (identifier-binding id)
|
(or (identifier-binding id)
|
||||||
|
@ -1147,11 +1147,11 @@
|
||||||
;; For intermediate:
|
;; For intermediate:
|
||||||
|
|
||||||
;; This application form disallows rator expressions that aren't
|
;; This application form disallows rator expressions that aren't
|
||||||
;; top-level identifiers or of the form `(check-not-undefined ...)'.
|
;; top-level identifiers or of the form `(teach-check-not-undefined ...)'.
|
||||||
|
|
||||||
;; The latter is probably surprising. It turns out that every use of
|
;; The latter is probably surprising. It turns out that every use of
|
||||||
;; a `local'-bound identifier gets converted to an undefined check,
|
;; a `local'-bound identifier gets converted to an undefined check,
|
||||||
;; and the call to `check-not-undefined' can't be forged by the
|
;; and the call to `teach-check-not-undefined' can't be forged by the
|
||||||
;; programmer. So the pattern-match effectively recognizes uses of
|
;; programmer. So the pattern-match effectively recognizes uses of
|
||||||
;; `local'-bound identifiers, which are legal as rator
|
;; `local'-bound identifiers, which are legal as rator
|
||||||
;; expressions. (`let' and `letrec' get converted to `local'.)
|
;; expressions. (`let' and `letrec' get converted to `local'.)
|
||||||
|
@ -1163,8 +1163,8 @@
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ rator rand ...)
|
[(_ rator rand ...)
|
||||||
(let* ([fun (syntax rator)]
|
(let* ([fun (syntax rator)]
|
||||||
[undef-check? (syntax-case fun (check-not-undefined)
|
[undef-check? (syntax-case fun (teach-check-not-undefined)
|
||||||
[(check-not-undefined id)
|
[(teach-check-not-undefined id)
|
||||||
#t]
|
#t]
|
||||||
[_else #f])]
|
[_else #f])]
|
||||||
[binding (and (identifier? fun)
|
[binding (and (identifier? fun)
|
||||||
|
@ -1749,7 +1749,7 @@
|
||||||
((define-syntaxes (def-id/prop ...)
|
((define-syntaxes (def-id/prop ...)
|
||||||
(values
|
(values
|
||||||
(make-undefined-check
|
(make-undefined-check
|
||||||
(quote-syntax check-not-undefined)
|
(quote-syntax teach-check-not-undefined)
|
||||||
(quote-syntax tmp-id))
|
(quote-syntax tmp-id))
|
||||||
...))
|
...))
|
||||||
...)))])
|
...)))])
|
||||||
|
@ -1818,7 +1818,7 @@
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#%stratified-body
|
(#%stratified-body
|
||||||
(define-syntaxes (name) (make-undefined-check
|
(define-syntaxes (name) (make-undefined-check
|
||||||
(quote-syntax check-not-undefined)
|
(quote-syntax teach-check-not-undefined)
|
||||||
(quote-syntax tmp-id)))
|
(quote-syntax tmp-id)))
|
||||||
...
|
...
|
||||||
(define-values (tmp-id) rhs-expr)
|
(define-values (tmp-id) rhs-expr)
|
||||||
|
@ -1853,7 +1853,7 @@
|
||||||
(let-values ([(tmp-id) rhs-expr] ...)
|
(let-values ([(tmp-id) rhs-expr] ...)
|
||||||
#,(stepper-syntax-property
|
#,(stepper-syntax-property
|
||||||
#`(let-syntaxes ([(name) (make-undefined-check
|
#`(let-syntaxes ([(name) (make-undefined-check
|
||||||
(quote-syntax check-not-undefined)
|
(quote-syntax teach-check-not-undefined)
|
||||||
(quote-syntax tmp-id))]
|
(quote-syntax tmp-id))]
|
||||||
...)
|
...)
|
||||||
expr)
|
expr)
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
(require (only racket/base sort)
|
(require (only racket/base sort)
|
||||||
compatibility/mlist
|
compatibility/mlist
|
||||||
"pconvert-prop.rkt"
|
"pconvert-prop.rkt"
|
||||||
racket/class)
|
racket/class
|
||||||
|
racket/undefined)
|
||||||
|
|
||||||
(provide show-sharing
|
(provide show-sharing
|
||||||
constructor-style-printing
|
constructor-style-printing
|
||||||
|
@ -27,8 +28,6 @@
|
||||||
current-build-share-hook
|
current-build-share-hook
|
||||||
current-print-convert-hook)
|
current-print-convert-hook)
|
||||||
|
|
||||||
(define undefined-val (letrec ([x x]) x))
|
|
||||||
|
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; the value stored in the hash table. Contains the name
|
;; the value stored in the hash table. Contains the name
|
||||||
;; <which is a number unless we are in donkey and it already has a name>
|
;; <which is a number unless we are in donkey and it already has a name>
|
||||||
|
@ -123,7 +122,9 @@
|
||||||
(boolean? expr)
|
(boolean? expr)
|
||||||
(char? expr) (void? expr)
|
(char? expr) (void? expr)
|
||||||
(null? expr)
|
(null? expr)
|
||||||
(eq? expr undefined-val) ; #<undefined> test - yuck
|
;; #<undefined> test - yuck, and maybe not worth checking
|
||||||
|
;; anymore, since undefined generally shouldn't escape
|
||||||
|
(undefined? expr)
|
||||||
)
|
)
|
||||||
'atomic]
|
'atomic]
|
||||||
[(and (not (struct? expr)) ;; struct names are the wrong thing, here
|
[(and (not (struct? expr)) ;; struct names are the wrong thing, here
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
(require (for-syntax racket/base
|
(require (for-syntax racket/base
|
||||||
racket/list)
|
racket/list)
|
||||||
racket/list
|
racket/list
|
||||||
racket/contract)
|
racket/contract
|
||||||
|
racket/undefined)
|
||||||
|
|
||||||
(provide define-type type-case)
|
(provide define-type type-case)
|
||||||
|
|
||||||
|
@ -86,11 +87,6 @@
|
||||||
stx)]
|
stx)]
|
||||||
[_ (transfer-srcloc orig stx)]))))
|
[_ (transfer-srcloc orig stx)]))))
|
||||||
|
|
||||||
(define the-undefined
|
|
||||||
(letrec ([x x]) x))
|
|
||||||
(define (undefined? x)
|
|
||||||
(eq? the-undefined x))
|
|
||||||
|
|
||||||
(define-syntax (define-type stx)
|
(define-syntax (define-type stx)
|
||||||
(syntax-parse
|
(syntax-parse
|
||||||
stx
|
stx
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(module main scheme/base
|
(module main scheme/base
|
||||||
(require scheme/mpair
|
(require scheme/mpair
|
||||||
|
racket/undefined
|
||||||
(for-syntax scheme/base syntax/kerncase
|
(for-syntax scheme/base syntax/kerncase
|
||||||
"private/r5rs-trans.rkt")
|
"private/r5rs-trans.rkt")
|
||||||
(only-in mzscheme transcript-on transcript-off))
|
(only-in mzscheme transcript-on transcript-off))
|
||||||
|
@ -243,7 +244,6 @@
|
||||||
|
|
||||||
;; Copied from R5rS, but with an added `let' around body,
|
;; Copied from R5rS, but with an added `let' around body,
|
||||||
;; and with optimization for precedure letrecs
|
;; and with optimization for precedure letrecs
|
||||||
(define undefined (letrec ([u u]) u))
|
|
||||||
(define-for-syntax (immediate-value? stx)
|
(define-for-syntax (immediate-value? stx)
|
||||||
(let ([v (syntax-e stx)])
|
(let ([v (syntax-e stx)])
|
||||||
(or (number? v)
|
(or (number? v)
|
||||||
|
|
|
@ -174,15 +174,27 @@ The @|void-const| value is always @racket[eq?] to itself.
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "undefined"]{Undefined}
|
@section[#:tag "undefined"]{Undefined}
|
||||||
|
|
||||||
The constant @|undefined-const| is used as the initial value for
|
@note-lib[racket/undefined]
|
||||||
@racket[letrec] bindings and in other places where a placeholder value
|
|
||||||
is needed before a specific value can be assigned. Use
|
|
||||||
@racket[undefined] (which is bound to @|undefined-const|) as a last resort.
|
|
||||||
|
|
||||||
The @|undefined-const| value is always @racket[eq?] to itself.
|
The constant @racket[undefined] is conceptually used as a placeholder
|
||||||
|
value for a binding, so that a reference to a binding before its
|
||||||
|
definition can be detected. Such references are normally protected
|
||||||
|
implicitly via @racket[check-not-undefined], so that an expression does
|
||||||
|
not normally produce an @racket[undefined] value.
|
||||||
|
|
||||||
@note-lib-only[racket/undefined]
|
The @racket[undefined] value is always @racket[eq?] to itself.
|
||||||
|
|
||||||
@defthing[undefined any/c]{The @|undefined-const| constant.}
|
@defproc[(undefined? [v any/c]) boolean?]{Returns @racket[#t] if @racket[v] is the
|
||||||
|
constant @racket[undefined], @racket[#f] otherwise.}
|
||||||
|
|
||||||
@history[#:added "6.0.0.6"]
|
|
||||||
|
@defthing[undefined undefined?]{The ``undefined'' constant.}
|
||||||
|
|
||||||
|
@defproc[(check-not-undefined [v any/c] [sym symbol?]) (and/c any/c (not/c undefined?))]{
|
||||||
|
|
||||||
|
Checks whether @racket[v] is @racket[undefined], and raises
|
||||||
|
@racket[exn:fail:contract:variable] in that case with an error message
|
||||||
|
along the lines of ``@racket[sym]: variable used before its definition.''
|
||||||
|
If @racket[v] is not @racket[undefined], then it is returned.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -918,6 +918,9 @@
|
||||||
(test-comp '(let ([x 8][y 9]) (lambda () (+ x y)))
|
(test-comp '(let ([x 8][y 9]) (lambda () (+ x y)))
|
||||||
'(let ([x 8][y 9]) (lambda () (if #f y (+ x y)))))
|
'(let ([x 8][y 9]) (lambda () (if #f y (+ x y)))))
|
||||||
|
|
||||||
|
;; Don't optimize away use before definition:
|
||||||
|
(test-comp '(letrec ([x (begin x 5)]) x) '5 #f)
|
||||||
|
|
||||||
(test-comp '(let ([x 5]) (set! x 2)) '(let ([x 5]) (set! x x) (set! x 2)))
|
(test-comp '(let ([x 5]) (set! x 2)) '(let ([x 5]) (set! x x) (set! x 2)))
|
||||||
|
|
||||||
(test-comp '(let* () (f 5))
|
(test-comp '(let* () (f 5))
|
||||||
|
|
|
@ -87,8 +87,8 @@
|
||||||
(let ((x 4))
|
(let ((x 4))
|
||||||
(lambda (y) (+ x y))))
|
(lambda (y) (+ x y))))
|
||||||
(test 10 add4 6)
|
(test 10 add4 6)
|
||||||
(test (letrec([x x]) x) 'lambda (let ([x (lambda () (define d d) d)]) (x)))
|
(err/rt-test (let ([x (lambda () (define d d) d)]) (x)) exn:fail:contract:variable?)
|
||||||
(test (letrec([x x]) x) 'lambda ((lambda () (define d d) d)))
|
(err/rt-test ((lambda () (define d d) d)) exn:fail:contract:variable?)
|
||||||
(test '(3 4 5 6) (lambda x x) 3 4 5 6)
|
(test '(3 4 5 6) (lambda x x) 3 4 5 6)
|
||||||
(test '(5 6) (lambda (x y . z) z) 3 4 5 6)
|
(test '(5 6) (lambda (x y . z) z) 3 4 5 6)
|
||||||
(test 'second (lambda () (cons 'first 2) 'second))
|
(test 'second (lambda () (cons 'first 2) 'second))
|
||||||
|
@ -643,8 +643,8 @@
|
||||||
(test 'twox 'let*-values (let*-values ([() (values)][() (values)]) 'twox))
|
(test 'twox 'let*-values (let*-values ([() (values)][() (values)]) 'twox))
|
||||||
(test 'threex 'letrec-values (letrec-values ([() (values)][() (values)]) 'threex))
|
(test 'threex 'letrec-values (letrec-values ([() (values)][() (values)]) 'threex))
|
||||||
|
|
||||||
(letrec ([undef undef])
|
(err/rt-test (letrec-values ([(a b c) (values 1 a b)]) (list a b c))
|
||||||
(test (list 1 undef undef) 'no-split-letrec (letrec-values ([(a b c) (values 1 a b)]) (list a b c))))
|
exn:fail:contract:variable?)
|
||||||
|
|
||||||
(test '(10 11) 'letrec-values (letrec-values ([(names kps)
|
(test '(10 11) 'letrec-values (letrec-values ([(names kps)
|
||||||
(letrec ([oloop 10])
|
(letrec ([oloop 10])
|
||||||
|
@ -1642,13 +1642,15 @@
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; check that the compiler is not too agressive with `letrec' -> `let*'
|
;; check that the compiler is not too agressive with `letrec' -> `let*'
|
||||||
|
|
||||||
(test "#<undefined>\nready\n"
|
(test "<undefined>\nready\n"
|
||||||
get-output-string
|
get-output-string
|
||||||
(let ([p (open-output-string)])
|
(let ([p (open-output-string)])
|
||||||
(parameterize ([current-output-port p])
|
(parameterize ([current-output-port p])
|
||||||
(let ([restart void])
|
(let ([restart void])
|
||||||
(letrec ([dummy1 (let/cc k (set! restart k))]
|
(letrec ([dummy1 (let/cc k (set! restart k))]
|
||||||
[dummy2 (displayln maybe-ready)]
|
[dummy2 (displayln (with-handlers ([exn:fail:contract:variable?
|
||||||
|
(lambda (exn) '<undefined>)])
|
||||||
|
maybe-ready))]
|
||||||
[maybe-ready 'ready])
|
[maybe-ready 'ready])
|
||||||
(let ([rs restart])
|
(let ([rs restart])
|
||||||
(set! restart void)
|
(set! restart void)
|
||||||
|
|
|
@ -116,7 +116,8 @@
|
||||||
;;; OK, now let's get going. But, as usual, before we can do anything
|
;;; OK, now let's get going. But, as usual, before we can do anything
|
||||||
;;; interesting, we have to muck around for a bit first. First, we need to
|
;;; interesting, we have to muck around for a bit first. First, we need to
|
||||||
;;; load the support library. [-- replaced with a module.]
|
;;; load the support library. [-- replaced with a module.]
|
||||||
(require swindle/misc)
|
(require swindle/misc
|
||||||
|
racket/undefined)
|
||||||
|
|
||||||
;; This is a convenient function for raising exceptions
|
;; This is a convenient function for raising exceptions
|
||||||
(define (raise* exn-maker fmt . args)
|
(define (raise* exn-maker fmt . args)
|
||||||
|
@ -219,7 +220,7 @@
|
||||||
;;> This is Racket's `unspecified' value which is used as the default
|
;;> This is Racket's `unspecified' value which is used as the default
|
||||||
;;> value for unbound slots. It is provided so you can check if a slot is
|
;;> value for unbound slots. It is provided so you can check if a slot is
|
||||||
;;> unbound.
|
;;> unbound.
|
||||||
(define* ??? (letrec ([x x]) x)) ; this is Racket's #<undefined> value
|
(define* ??? undefined)
|
||||||
(define unspecified-initializer (lambda args ???))
|
(define unspecified-initializer (lambda args ???))
|
||||||
(define false-func (lambda args #f))
|
(define false-func (lambda args #f))
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
racket/list
|
racket/list
|
||||||
racket/match
|
racket/match
|
||||||
racket/function
|
racket/function
|
||||||
|
racket/undefined
|
||||||
unstable/function
|
unstable/function
|
||||||
|
|
||||||
(prefix-in c: (contract-req))
|
(prefix-in c: (contract-req))
|
||||||
|
@ -91,8 +92,8 @@
|
||||||
(define/decl -Boolean (Un -False -True))
|
(define/decl -Boolean (Un -False -True))
|
||||||
(define/decl -Undefined
|
(define/decl -Undefined
|
||||||
(make-Base 'Undefined
|
(make-Base 'Undefined
|
||||||
#'(lambda (x) (equal? (letrec ([y y]) y) x)) ; initial value of letrec bindings
|
#'undefined? ; initial value of letrec bindings
|
||||||
(lambda (x) (equal? (letrec ([y y]) y) x))))
|
undefined?))
|
||||||
(define/decl -Bytes (make-Base 'Bytes #'bytes? bytes?))
|
(define/decl -Bytes (make-Base 'Bytes #'bytes? bytes?))
|
||||||
(define/decl -Base-Regexp (make-Base 'Base-Regexp
|
(define/decl -Base-Regexp (make-Base 'Base-Regexp
|
||||||
#'(and/c regexp? (not/c pregexp?))
|
#'(and/c regexp? (not/c pregexp?))
|
||||||
|
|
|
@ -3,15 +3,14 @@
|
||||||
(require racket/match racket/contract/combinator
|
(require racket/match racket/contract/combinator
|
||||||
racket/fixnum racket/flonum
|
racket/fixnum racket/flonum
|
||||||
racket/set
|
racket/set
|
||||||
|
racket/undefined
|
||||||
(only-in (combine-in racket/private/promise)
|
(only-in (combine-in racket/private/promise)
|
||||||
promise?
|
promise?
|
||||||
prop:force promise-forcer))
|
prop:force promise-forcer))
|
||||||
|
|
||||||
(define undef (letrec ([x x]) x))
|
|
||||||
|
|
||||||
(define (base-val? e)
|
(define (base-val? e)
|
||||||
(or (number? e) (string? e) (char? e) (symbol? e)
|
(or (number? e) (string? e) (char? e) (symbol? e)
|
||||||
(null? e) (regexp? e) (eq? undef e) (path? e)
|
(null? e) (regexp? e) (undefined? e) (path? e)
|
||||||
(regexp? e) (keyword? e) (bytes? e) (boolean? e) (void? e)
|
(regexp? e) (keyword? e) (bytes? e) (boolean? e) (void? e)
|
||||||
;; Base values because you can only store flonums/fixnums in these
|
;; Base values because you can only store flonums/fixnums in these
|
||||||
;; and not any higher-order values. This isn't sound if we ever
|
;; and not any higher-order values. This isn't sound if we ever
|
||||||
|
|
|
@ -557,26 +557,23 @@
|
||||||
(apply or/c ss))
|
(apply or/c ss))
|
||||||
|
|
||||||
(define atomic-value?
|
(define atomic-value?
|
||||||
(let ([undefined (letrec ([x x]) x)])
|
(λ (x)
|
||||||
(λ (x)
|
(or (char? x) (symbol? x) (boolean? x)
|
||||||
(or (char? x) (symbol? x) (boolean? x)
|
(null? x) (keyword? x) (number? x)
|
||||||
(null? x) (keyword? x) (number? x)
|
(void? x))))
|
||||||
(void? x) (eq? x undefined)))))
|
|
||||||
|
|
||||||
(define/final-prop (one-of/c . elems)
|
(define/final-prop (one-of/c . elems)
|
||||||
(for ([arg (in-list elems)]
|
(for ([arg (in-list elems)]
|
||||||
[i (in-naturals)])
|
[i (in-naturals)])
|
||||||
(unless (atomic-value? arg)
|
(unless (atomic-value? arg)
|
||||||
(raise-argument-error 'one-of/c
|
(raise-argument-error 'one-of/c
|
||||||
"char, symbol, boolean, null, keyword, number, void, or undefined"
|
"char, symbol, boolean, null, keyword, number, or void"
|
||||||
i
|
i
|
||||||
elems)))
|
elems)))
|
||||||
(define (undefined? x) (eq? x (letrec ([x x]) x)))
|
|
||||||
(define or/c-args
|
(define or/c-args
|
||||||
(map (λ (x)
|
(map (λ (x)
|
||||||
(cond
|
(cond
|
||||||
[(void? x) void?]
|
[(void? x) void?]
|
||||||
[(undefined? x) undefined?]
|
|
||||||
[else x]))
|
[else x]))
|
||||||
elems))
|
elems))
|
||||||
(apply or/c or/c-args))
|
(apply or/c or/c-args))
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
racket/stxparam
|
racket/stxparam
|
||||||
syntax/parse)
|
syntax/parse)
|
||||||
racket/stxparam
|
racket/stxparam
|
||||||
|
racket/undefined
|
||||||
"class-wrapped.rkt"
|
"class-wrapped.rkt"
|
||||||
"class-internal.rkt"
|
"class-internal.rkt"
|
||||||
"../contract/base.rkt"
|
"../contract/base.rkt"
|
||||||
|
@ -20,8 +21,6 @@
|
||||||
build-internal-class/c internal-class/c-proj
|
build-internal-class/c internal-class/c-proj
|
||||||
class/c-internal-name-clauses)
|
class/c-internal-name-clauses)
|
||||||
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
|
|
||||||
;; Shorthand contracts that treat the implicit object argument as if it were
|
;; Shorthand contracts that treat the implicit object argument as if it were
|
||||||
;; contracted with any/c.
|
;; contracted with any/c.
|
||||||
(define-syntax-rule (->m . stx)
|
(define-syntax-rule (->m . stx)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(only-in "../contract/region.rkt" current-contract-region)
|
(only-in "../contract/region.rkt" current-contract-region)
|
||||||
"../contract/base.rkt"
|
"../contract/base.rkt"
|
||||||
"../contract/combinator.rkt"
|
"../contract/combinator.rkt"
|
||||||
|
racket/undefined
|
||||||
(for-syntax racket/stxparam
|
(for-syntax racket/stxparam
|
||||||
syntax/kerncase
|
syntax/kerncase
|
||||||
syntax/stx
|
syntax/stx
|
||||||
|
@ -4375,8 +4376,6 @@ An example
|
||||||
;; misc utils
|
;; misc utils
|
||||||
;;--------------------------------------------------------------------
|
;;--------------------------------------------------------------------
|
||||||
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
|
|
||||||
(define-struct (exn:fail:object exn:fail) () #:inspector insp)
|
(define-struct (exn:fail:object exn:fail) () #:inspector insp)
|
||||||
|
|
||||||
(struct as-write (content))
|
(struct as-write (content))
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
(require syntax/stx
|
(require syntax/stx
|
||||||
(for-syntax racket/base)
|
(for-syntax racket/base)
|
||||||
(for-template racket/base
|
(for-template racket/base
|
||||||
|
racket/undefined
|
||||||
"class-wrapped.rkt"))
|
"class-wrapped.rkt"))
|
||||||
|
|
||||||
(define insp (variable-reference->module-declaration-inspector
|
(define insp (variable-reference->module-declaration-inspector
|
||||||
|
@ -83,12 +84,12 @@
|
||||||
[(id . args)
|
[(id . args)
|
||||||
(with-syntax ([bindings (syntax/loc stx ([obj obj-expr]))]
|
(with-syntax ([bindings (syntax/loc stx ([obj obj-expr]))]
|
||||||
[call (quasisyntax/loc stx
|
[call (quasisyntax/loc stx
|
||||||
(((unsyntax field-accessor) obj) . args))])
|
((check-not-undefined ((unsyntax field-accessor) obj) 'id) . args))])
|
||||||
(syntax/loc stx (let* bindings call)))]
|
(syntax/loc stx (let* bindings call)))]
|
||||||
[id
|
[id
|
||||||
(with-syntax ([bindings (syntax/loc stx ([obj obj-expr]))]
|
(with-syntax ([bindings (syntax/loc stx ([obj obj-expr]))]
|
||||||
[get (quasisyntax/loc stx
|
[get (quasisyntax/loc stx
|
||||||
((unsyntax field-accessor) obj))])
|
(check-not-undefined ((unsyntax field-accessor) obj) 'id))])
|
||||||
(syntax/loc stx (let* bindings get)))])))))))
|
(syntax/loc stx (let* bindings get)))])))))))
|
||||||
|
|
||||||
(define (make-method-map the-finder the-obj the-binder the-binder-localized method-accessor)
|
(define (make-method-map the-finder the-obj the-binder the-binder-localized method-accessor)
|
||||||
|
|
|
@ -179,7 +179,8 @@
|
||||||
procedure->method procedure-rename
|
procedure->method procedure-rename
|
||||||
chaperone-procedure impersonate-procedure
|
chaperone-procedure impersonate-procedure
|
||||||
assq assv assoc
|
assq assv assoc
|
||||||
prop:incomplete-arity prop:method-arity-error)
|
prop:incomplete-arity prop:method-arity-error
|
||||||
|
check-not-undefined undefined)
|
||||||
(all-from "reqprov.rkt")
|
(all-from "reqprov.rkt")
|
||||||
(all-from-except "for.rkt"
|
(all-from-except "for.rkt"
|
||||||
define-in-vector-like
|
define-in-vector-like
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
(require (for-syntax "unit-syntax.rkt" racket/base))
|
(require (for-syntax "unit-syntax.rkt" racket/base))
|
||||||
(provide define-syntax/err-param
|
(provide define-syntax/err-param
|
||||||
undefined (rename-out [make-a-unit make-unit]) unit-import-sigs unit-export-sigs unit-go unit? unit-deps
|
(rename-out [make-a-unit make-unit]) unit-import-sigs unit-export-sigs unit-go unit? unit-deps
|
||||||
check-unit check-no-imports check-sigs check-deps check-helper)
|
check-unit check-no-imports check-sigs check-deps check-helper)
|
||||||
|
|
||||||
(define-syntax define-syntax/err-param
|
(define-syntax define-syntax/err-param
|
||||||
|
@ -12,9 +12,6 @@
|
||||||
(parameterize ((error-syntax arg))
|
(parameterize ((error-syntax arg))
|
||||||
body)))))
|
body)))))
|
||||||
|
|
||||||
;; initial value
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
|
|
||||||
;; for named structures
|
;; for named structures
|
||||||
(define insp (current-inspector))
|
(define insp (current-inspector))
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
syntax/kerncase
|
syntax/kerncase
|
||||||
syntax/struct
|
syntax/struct
|
||||||
racket/struct-info
|
racket/struct-info
|
||||||
racket/include))
|
racket/include)
|
||||||
|
racket/undefined)
|
||||||
|
|
||||||
(provide shared)
|
(provide shared)
|
||||||
|
|
||||||
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
|
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
|
||||||
(#%variable-reference)))
|
(#%variable-reference)))
|
||||||
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
(require (only-in racket/base [cons the-cons]))
|
(require (only-in racket/base [cons the-cons]))
|
||||||
|
|
||||||
(define-syntax shared
|
(define-syntax shared
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
(require '#%kernel)
|
||||||
|
|
||||||
(provide undefined)
|
(provide check-not-undefined
|
||||||
|
undefined
|
||||||
|
undefined?)
|
||||||
|
|
||||||
;; In a future version of Racket, this `letrec` pattern
|
(define (undefined? v) (eq? v undefined))
|
||||||
;; will not work, but the `racket/undefined` library will
|
|
||||||
;; still export an `undefined`:
|
|
||||||
(define undefined (letrec ([x x]) x))
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"private/unit-syntax.rkt"))
|
"private/unit-syntax.rkt"))
|
||||||
|
|
||||||
(require racket/block
|
(require racket/block
|
||||||
|
racket/undefined
|
||||||
racket/contract/base
|
racket/contract/base
|
||||||
racket/contract/region
|
racket/contract/region
|
||||||
racket/stxparam
|
racket/stxparam
|
||||||
|
@ -1186,7 +1187,8 @@
|
||||||
(lambda (int/ext-name index ctc)
|
(lambda (int/ext-name index ctc)
|
||||||
(bound-identifier-mapping-put! def-table
|
(bound-identifier-mapping-put! def-table
|
||||||
(car int/ext-name)
|
(car int/ext-name)
|
||||||
#`(vector-ref #,v #,index))
|
#`(check-not-undefined (vector-ref #,v #,index)
|
||||||
|
'#,(car int/ext-name)))
|
||||||
(bound-identifier-mapping-put! ctc-table
|
(bound-identifier-mapping-put! ctc-table
|
||||||
(car int/ext-name)
|
(car int/ext-name)
|
||||||
ctc)
|
ctc)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(module toplevel racket/base
|
(module toplevel racket/base
|
||||||
(require "kerncase.rkt")
|
(require "kerncase.rkt"
|
||||||
|
racket/undefined)
|
||||||
|
|
||||||
(provide eval-compile-time-part-of-top-level
|
(provide eval-compile-time-part-of-top-level
|
||||||
eval-compile-time-part-of-top-level/compile
|
eval-compile-time-part-of-top-level/compile
|
||||||
|
@ -74,8 +75,7 @@
|
||||||
(begin0
|
(begin0
|
||||||
(when compile? (compile-syntax stx))
|
(when compile? (compile-syntax stx))
|
||||||
(for-each (lambda (id)
|
(for-each (lambda (id)
|
||||||
(with-syntax ([id id]
|
(with-syntax ([id id])
|
||||||
[undefined (letrec ([x x]) x)])
|
|
||||||
(eval-syntax (syntax (define-values (id) undefined)))))
|
(eval-syntax (syntax (define-values (id) undefined)))))
|
||||||
(syntax->list (syntax (id ...)))))]
|
(syntax->list (syntax (id ...)))))]
|
||||||
[_else
|
[_else
|
||||||
|
|
|
@ -76,6 +76,7 @@ OBJS = salloc.@LTO@ \
|
||||||
jitprep.@LTO@ \
|
jitprep.@LTO@ \
|
||||||
jitstack.@LTO@ \
|
jitstack.@LTO@ \
|
||||||
jitstate.@LTO@ \
|
jitstate.@LTO@ \
|
||||||
|
letrec_check.@LTO@ \
|
||||||
list.@LTO@ \
|
list.@LTO@ \
|
||||||
marshal.@LTO@ \
|
marshal.@LTO@ \
|
||||||
module.@LTO@ \
|
module.@LTO@ \
|
||||||
|
@ -135,6 +136,7 @@ XSRCS = $(XSRCDIR)/salloc.c \
|
||||||
$(XSRCDIR)/jitprep.c \
|
$(XSRCDIR)/jitprep.c \
|
||||||
$(XSRCDIR)/jitstack.c \
|
$(XSRCDIR)/jitstack.c \
|
||||||
$(XSRCDIR)/jitstate.c \
|
$(XSRCDIR)/jitstate.c \
|
||||||
|
$(XSRCDIR)/letrec_check.c \
|
||||||
$(XSRCDIR)/list.c \
|
$(XSRCDIR)/list.c \
|
||||||
$(XSRCDIR)/marshal.c \
|
$(XSRCDIR)/marshal.c \
|
||||||
$(XSRCDIR)/module.c \
|
$(XSRCDIR)/module.c \
|
||||||
|
@ -253,6 +255,8 @@ $(XSRCDIR)/marshal.c: ../src/marshal.@LTO@ $(XFORMDEP) $(SRCDIR)/mzrt.h
|
||||||
$(XFORM) $(XSRCDIR)/marshal.c $(SRCDIR)/marshal.c
|
$(XFORM) $(XSRCDIR)/marshal.c $(SRCDIR)/marshal.c
|
||||||
$(XSRCDIR)/module.c: ../src/module.@LTO@ $(XFORMDEP) $(SRCDIR)/mzrt.h
|
$(XSRCDIR)/module.c: ../src/module.@LTO@ $(XFORMDEP) $(SRCDIR)/mzrt.h
|
||||||
$(XFORM) $(XSRCDIR)/module.c $(SRCDIR)/module.c
|
$(XFORM) $(XSRCDIR)/module.c $(SRCDIR)/module.c
|
||||||
|
$(XSRCDIR)/letrec_check.c: ../src/letrec_check.@LTO@ $(XFORMDEP)
|
||||||
|
$(XFORM) $(XSRCDIR)/letrec_check.c $(SRCDIR)/letrec_check.c
|
||||||
$(XSRCDIR)/list.c: ../src/list.@LTO@ $(XFORMDEP)
|
$(XSRCDIR)/list.c: ../src/list.@LTO@ $(XFORMDEP)
|
||||||
$(XFORM) $(XSRCDIR)/list.c $(SRCDIR)/list.c
|
$(XFORM) $(XSRCDIR)/list.c $(SRCDIR)/list.c
|
||||||
$(XSRCDIR)/network.c: ../src/network.@LTO@ $(XFORMDEP)
|
$(XSRCDIR)/network.c: ../src/network.@LTO@ $(XFORMDEP)
|
||||||
|
@ -360,6 +364,8 @@ jitstack.@LTO@: $(XSRCDIR)/jitstack.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/jitstack.c -o jitstack.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/jitstack.c -o jitstack.@LTO@
|
||||||
jitstate.@LTO@: $(XSRCDIR)/jitstate.c
|
jitstate.@LTO@: $(XSRCDIR)/jitstate.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/jitstate.c -o jitstate.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/jitstate.c -o jitstate.@LTO@
|
||||||
|
letrec_check.@LTO@: $(XSRCDIR)/letrec_check.c
|
||||||
|
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/letrec_check.c -o letrec_check.@LTO@
|
||||||
list.@LTO@: $(XSRCDIR)/list.c
|
list.@LTO@: $(XSRCDIR)/list.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/list.c -o list.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/list.c -o list.@LTO@
|
||||||
marshal.@LTO@: $(XSRCDIR)/marshal.c
|
marshal.@LTO@: $(XSRCDIR)/marshal.c
|
||||||
|
|
|
@ -39,6 +39,7 @@ OBJS = salloc.@LTO@ \
|
||||||
jitprep.@LTO@ \
|
jitprep.@LTO@ \
|
||||||
jitstack.@LTO@ \
|
jitstack.@LTO@ \
|
||||||
jitstate.@LTO@ \
|
jitstate.@LTO@ \
|
||||||
|
letrec_check.@LTO@ \
|
||||||
list.@LTO@ \
|
list.@LTO@ \
|
||||||
marshal.@LTO@ \
|
marshal.@LTO@ \
|
||||||
module.@LTO@ \
|
module.@LTO@ \
|
||||||
|
@ -96,6 +97,7 @@ SRCS = $(srcdir)/salloc.c \
|
||||||
$(srcdir)/jitprep.c \
|
$(srcdir)/jitprep.c \
|
||||||
$(srcdir)/jitstack.c \
|
$(srcdir)/jitstack.c \
|
||||||
$(srcdir)/jitstate.c \
|
$(srcdir)/jitstate.c \
|
||||||
|
$(srcdir)/letrec_check.c \
|
||||||
$(srcdir)/list.c \
|
$(srcdir)/list.c \
|
||||||
$(srcdir)/marshal.c \
|
$(srcdir)/marshal.c \
|
||||||
$(srcdir)/module.c \
|
$(srcdir)/module.c \
|
||||||
|
@ -226,6 +228,8 @@ jitstack.@LTO@: $(srcdir)/jitstack.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(srcdir)/jitstack.c -o jitstack.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(srcdir)/jitstack.c -o jitstack.@LTO@
|
||||||
jitstate.@LTO@: $(srcdir)/jitstate.c
|
jitstate.@LTO@: $(srcdir)/jitstate.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(srcdir)/jitstate.c -o jitstate.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(srcdir)/jitstate.c -o jitstate.@LTO@
|
||||||
|
letrec_check.@LTO@: $(srcdir)/letrec_check.c
|
||||||
|
$(CC) $(ALL_CFLAGS) -c $(srcdir)/letrec_check.c -o letrec_check.@LTO@
|
||||||
list.@LTO@: $(srcdir)/list.c
|
list.@LTO@: $(srcdir)/list.c
|
||||||
$(CC) $(ALL_CFLAGS) -c $(srcdir)/list.c -o list.@LTO@
|
$(CC) $(ALL_CFLAGS) -c $(srcdir)/list.c -o list.@LTO@
|
||||||
marshal.@LTO@: $(srcdir)/marshal.c
|
marshal.@LTO@: $(srcdir)/marshal.c
|
||||||
|
@ -362,6 +366,8 @@ jitprep.@LTO@: $(COMMON_HEADERS) \
|
||||||
jitstack.@LTO@: $(COMMON_HEADERS) $(JIT_HEADERS) $(srcdir)/codetab.inc \
|
jitstack.@LTO@: $(COMMON_HEADERS) $(JIT_HEADERS) $(srcdir)/codetab.inc \
|
||||||
$(srcdir)/unwind/libunwind.h
|
$(srcdir)/unwind/libunwind.h
|
||||||
jitstate.@LTO@: $(COMMON_HEADERS) $(JIT_HEADERS)
|
jitstate.@LTO@: $(COMMON_HEADERS) $(JIT_HEADERS)
|
||||||
|
letrec_check.@LTO@: $(COMMON_HEADERS) \
|
||||||
|
$(srcdir)/stypes.h
|
||||||
list.@LTO@: $(COMMON_HEADERS) \
|
list.@LTO@: $(COMMON_HEADERS) \
|
||||||
$(srcdir)/stypes.h
|
$(srcdir)/stypes.h
|
||||||
marshal.@LTO@: $(COMMON_HEADERS) \
|
marshal.@LTO@: $(COMMON_HEADERS) \
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
|
|
||||||
#define TABLE_CACHE_MAX_SIZE 2048
|
#define TABLE_CACHE_MAX_SIZE 2048
|
||||||
|
|
||||||
|
/* Pre-allocate local variable reference objects.
|
||||||
|
first dimension: position in the current stack frame
|
||||||
|
second dimension: 0 for local variables, 1 for unboxed local variables
|
||||||
|
third dimension: flags. TODO has to do with whether something is an unboxed fixnum, flonum, or extnum */
|
||||||
READ_ONLY static Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][MAX_CONST_LOCAL_TYPES][MAX_CONST_LOCAL_FLAG_VAL + 1];
|
READ_ONLY static Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][MAX_CONST_LOCAL_TYPES][MAX_CONST_LOCAL_FLAG_VAL + 1];
|
||||||
READ_ONLY static Scheme_Object *toplevels[MAX_CONST_TOPLEVEL_DEPTH][MAX_CONST_TOPLEVEL_POS][SCHEME_TOPLEVEL_FLAGS_MASK + 1];
|
READ_ONLY static Scheme_Object *toplevels[MAX_CONST_TOPLEVEL_DEPTH][MAX_CONST_TOPLEVEL_POS][SCHEME_TOPLEVEL_FLAGS_MASK + 1];
|
||||||
|
|
||||||
|
@ -853,11 +857,14 @@ static Scheme_Object *alloc_local(short type, int pos)
|
||||||
return (Scheme_Object *)v;
|
return (Scheme_Object *)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* type should be either scheme_local_type or scheme_local_unbox_type
|
||||||
|
TODO: double check that */
|
||||||
Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags)
|
Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
Scheme_Object *v, *key;
|
Scheme_Object *v, *key;
|
||||||
|
|
||||||
|
/* k is 0 if type is scheme_local_type and 1 if type is scheme_local_unbox_type */
|
||||||
k = type - scheme_local_type;
|
k = type - scheme_local_type;
|
||||||
|
|
||||||
/* Helper for reading bytecode: make sure flags is a valid value */
|
/* Helper for reading bytecode: make sure flags is a valid value */
|
||||||
|
@ -899,7 +906,9 @@ static Scheme_Local *get_frame_loc(Scheme_Comp_Env *frame,
|
||||||
int cnt, u;
|
int cnt, u;
|
||||||
|
|
||||||
u = COMPILE_DATA(frame)->use[i];
|
u = COMPILE_DATA(frame)->use[i];
|
||||||
|
|
||||||
|
// flags -= (flags & SCHEME_APP_POS);
|
||||||
|
|
||||||
u |= (((flags & (SCHEME_APP_POS | SCHEME_SETTING))
|
u |= (((flags & (SCHEME_APP_POS | SCHEME_SETTING))
|
||||||
? CONSTRAINED_USE
|
? CONSTRAINED_USE
|
||||||
: ((u & (ARBITRARY_USE | ONE_ARBITRARY_USE)) ? ARBITRARY_USE : ONE_ARBITRARY_USE))
|
: ((u & (ARBITRARY_USE | ONE_ARBITRARY_USE)) ? ARBITRARY_USE : ONE_ARBITRARY_USE))
|
||||||
|
|
|
@ -1210,18 +1210,6 @@ set_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec,
|
||||||
rec[drec].value_name = SCHEME_STX_SYM(name);
|
rec[drec].value_name = SCHEME_STX_SYM(name);
|
||||||
|
|
||||||
val = scheme_compile_expr(body, scheme_no_defines(env), rec, drec);
|
val = scheme_compile_expr(body, scheme_no_defines(env), rec, drec);
|
||||||
|
|
||||||
/* check for (set! x x) */
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(var), SCHEME_TYPE(val))) {
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(var), scheme_local_type)
|
|
||||||
|| SAME_TYPE(SCHEME_TYPE(var), scheme_local_unbox_type)) {
|
|
||||||
/* local */
|
|
||||||
if (SCHEME_LOCAL_POS(var) == SCHEME_LOCAL_POS(val))
|
|
||||||
return scheme_compiled_void();
|
|
||||||
} else {
|
|
||||||
/* global; can't do anything b/c var might be undefined or constant */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_undef = (rec[drec].comp_flags & COMP_ALLOW_SET_UNDEFINED);
|
set_undef = (rec[drec].comp_flags & COMP_ALLOW_SET_UNDEFINED);
|
||||||
|
|
||||||
|
@ -2073,7 +2061,7 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname,
|
||||||
int star, int recursive, int multi, Scheme_Compile_Info *rec, int drec,
|
int star, int recursive, int multi, Scheme_Compile_Info *rec, int drec,
|
||||||
Scheme_Comp_Env *frame_already)
|
Scheme_Comp_Env *frame_already)
|
||||||
{
|
{
|
||||||
Scheme_Object *bindings, *l, *binding, *name, **names, *forms, *defname;
|
Scheme_Object *bindings, *l, *binding, *name, **names, **clv_names, *forms, *defname;
|
||||||
int num_clauses, num_bindings, i, j, k, m, pre_k;
|
int num_clauses, num_bindings, i, j, k, m, pre_k;
|
||||||
Scheme_Comp_Env *frame, *env, *rhs_env;
|
Scheme_Comp_Env *frame, *env, *rhs_env;
|
||||||
Scheme_Compile_Info *recs;
|
Scheme_Compile_Info *recs;
|
||||||
|
@ -2110,6 +2098,7 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname,
|
||||||
post_bind = !recursive && !star;
|
post_bind = !recursive && !star;
|
||||||
rev_bind_order = recursive;
|
rev_bind_order = recursive;
|
||||||
|
|
||||||
|
/* forms ends up being the let body */
|
||||||
forms = SCHEME_STX_CDR(form);
|
forms = SCHEME_STX_CDR(form);
|
||||||
forms = SCHEME_STX_CDR(forms);
|
forms = SCHEME_STX_CDR(forms);
|
||||||
forms = scheme_datum_to_syntax(forms, form, form, 0, 0);
|
forms = scheme_datum_to_syntax(forms, form, form, 0, 0);
|
||||||
|
@ -2266,6 +2255,16 @@ gen_let_syntax (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname,
|
||||||
lv->count = (k - pre_k);
|
lv->count = (k - pre_k);
|
||||||
lv->position = pre_k;
|
lv->position = pre_k;
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
/* The names are only used for recursive bindings (in letrec_check),
|
||||||
|
currently. It would be ok if we record extra names, though. */
|
||||||
|
clv_names = MALLOC_N(Scheme_Object*, lv->count);
|
||||||
|
for (m = pre_k; m < k; m++) {
|
||||||
|
clv_names[m - pre_k] = SCHEME_STX_SYM(names[m]);
|
||||||
|
}
|
||||||
|
lv->names = clv_names;
|
||||||
|
}
|
||||||
|
|
||||||
if (lv->count == 1)
|
if (lv->count == 1)
|
||||||
recs[i].value_name = SCHEME_STX_SYM(names[pre_k]);
|
recs[i].value_name = SCHEME_STX_SYM(names[pre_k]);
|
||||||
|
|
||||||
|
@ -2827,6 +2826,8 @@ do_begin_syntax(char *name,
|
||||||
if (zero)
|
if (zero)
|
||||||
env = scheme_no_defines(env);
|
env = scheme_no_defines(env);
|
||||||
|
|
||||||
|
/* if the begin has only one expression inside, drop the begin
|
||||||
|
TODO: is this right */
|
||||||
if (SCHEME_STX_NULLP(SCHEME_STX_CDR(forms))) {
|
if (SCHEME_STX_NULLP(SCHEME_STX_CDR(forms))) {
|
||||||
forms = SCHEME_STX_CAR(forms);
|
forms = SCHEME_STX_CAR(forms);
|
||||||
return scheme_compile_expr(forms, env, rec, drec);
|
return scheme_compile_expr(forms, env, rec, drec);
|
||||||
|
@ -2924,9 +2925,9 @@ Scheme_Object *scheme_make_sequence_compilation(Scheme_Object *seq, int opt)
|
||||||
/* "Inline" nested begins */
|
/* "Inline" nested begins */
|
||||||
count += ((Scheme_Sequence *)v)->count;
|
count += ((Scheme_Sequence *)v)->count;
|
||||||
total++;
|
total++;
|
||||||
} else if (opt
|
} else if (opt
|
||||||
&& (((opt > 0) && !last) || ((opt < 0) && !first))
|
&& (((opt > 0) && !last) || ((opt < 0) && !first))
|
||||||
&& scheme_omittable_expr(v, -1, -1, 0, NULL, NULL, -1, 0)) {
|
&& scheme_omittable_expr(v, -1, -1, 0, NULL, NULL, -1, 1)) {
|
||||||
/* A value that is not the result. We'll drop it. */
|
/* A value that is not the result. We'll drop it. */
|
||||||
total++;
|
total++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2954,7 +2955,7 @@ Scheme_Object *scheme_make_sequence_compilation(Scheme_Object *seq, int opt)
|
||||||
/* can't optimize away a begin0 at read time; it's too late, since the
|
/* can't optimize away a begin0 at read time; it's too late, since the
|
||||||
return is combined with EXPD_BEGIN0 */
|
return is combined with EXPD_BEGIN0 */
|
||||||
addconst = 1;
|
addconst = 1;
|
||||||
} else if ((opt < 0) && !scheme_omittable_expr(SCHEME_CAR(seq), 1, -1, 0, NULL, NULL, -1, 0)) {
|
} else if ((opt < 0) && !scheme_omittable_expr(SCHEME_CAR(seq), 1, -1, 0, NULL, NULL, -1, 1)) {
|
||||||
/* We can't optimize (begin0 expr cont) to expr because
|
/* We can't optimize (begin0 expr cont) to expr because
|
||||||
exp is not in tail position in the original (so we'd mess
|
exp is not in tail position in the original (so we'd mess
|
||||||
up continuation marks). */
|
up continuation marks). */
|
||||||
|
@ -2986,7 +2987,7 @@ Scheme_Object *scheme_make_sequence_compilation(Scheme_Object *seq, int opt)
|
||||||
} else if (opt
|
} else if (opt
|
||||||
&& (((opt > 0) && (k < total))
|
&& (((opt > 0) && (k < total))
|
||||||
|| ((opt < 0) && k))
|
|| ((opt < 0) && k))
|
||||||
&& scheme_omittable_expr(v, -1, -1, 0, NULL, NULL, -1, 0)) {
|
&& scheme_omittable_expr(v, -1, -1, 0, NULL, NULL, -1, 1)) {
|
||||||
/* Value not the result. Do nothing. */
|
/* Value not the result. Do nothing. */
|
||||||
} else
|
} else
|
||||||
o->array[i++] = v;
|
o->array[i++] = v;
|
||||||
|
@ -3574,6 +3575,8 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object
|
||||||
|
|
||||||
a = scheme_compile_expr_lift_to_let(a, eenv, &mrec, 0);
|
a = scheme_compile_expr_lift_to_let(a, eenv, &mrec, 0);
|
||||||
|
|
||||||
|
a = scheme_letrec_check_expr(a);
|
||||||
|
|
||||||
oi = scheme_optimize_info_create(eenv->prefix, 1);
|
oi = scheme_optimize_info_create(eenv->prefix, 1);
|
||||||
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
||||||
scheme_optimize_info_never_inline(oi);
|
scheme_optimize_info_never_inline(oi);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -249,6 +249,7 @@ Scheme_Env *scheme_engine_instance_init()
|
||||||
|
|
||||||
scheme_init_portable_case();
|
scheme_init_portable_case();
|
||||||
scheme_init_compenv();
|
scheme_init_compenv();
|
||||||
|
scheme_init_letrec_check();
|
||||||
scheme_init_optimize();
|
scheme_init_optimize();
|
||||||
scheme_init_resolve();
|
scheme_init_resolve();
|
||||||
scheme_init_sfs();
|
scheme_init_sfs();
|
||||||
|
|
|
@ -4061,6 +4061,8 @@ static void *compile_k(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o = scheme_letrec_check_expr(o);
|
||||||
|
|
||||||
oi = scheme_optimize_info_create(cenv->prefix, 1);
|
oi = scheme_optimize_info_create(cenv->prefix, 1);
|
||||||
scheme_optimize_info_enforce_const(oi, enforce_consts);
|
scheme_optimize_info_enforce_const(oi, enforce_consts);
|
||||||
if (!(comp_flags & COMP_CAN_INLINE))
|
if (!(comp_flags & COMP_CAN_INLINE))
|
||||||
|
|
|
@ -86,6 +86,7 @@ READ_ONLY Scheme_Object *scheme_values_func; /* the function bound to `values' *
|
||||||
READ_ONLY Scheme_Object *scheme_procedure_p_proc;
|
READ_ONLY Scheme_Object *scheme_procedure_p_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_procedure_arity_includes_proc;
|
READ_ONLY Scheme_Object *scheme_procedure_arity_includes_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_void_proc;
|
READ_ONLY Scheme_Object *scheme_void_proc;
|
||||||
|
READ_ONLY Scheme_Object *scheme_check_not_undefined;
|
||||||
READ_ONLY Scheme_Object *scheme_apply_proc;
|
READ_ONLY Scheme_Object *scheme_apply_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_call_with_values_proc; /* the function bound to `call-with-values' */
|
READ_ONLY Scheme_Object *scheme_call_with_values_proc; /* the function bound to `call-with-values' */
|
||||||
READ_ONLY Scheme_Object *scheme_reduced_procedure_struct;
|
READ_ONLY Scheme_Object *scheme_reduced_procedure_struct;
|
||||||
|
@ -160,6 +161,7 @@ static Scheme_Object *extract_one_cc_mark (int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv[]);
|
static Scheme_Object *call_with_immediate_cc_mark (int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *void_func (int argc, Scheme_Object *argv[]);
|
static Scheme_Object *void_func (int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *void_p (int argc, Scheme_Object *argv[]);
|
static Scheme_Object *void_p (int argc, Scheme_Object *argv[]);
|
||||||
|
static Scheme_Object *check_not_undefined (int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *dynamic_wind (int argc, Scheme_Object *argv[]);
|
static Scheme_Object *dynamic_wind (int argc, Scheme_Object *argv[]);
|
||||||
#ifdef TIME_SYNTAX
|
#ifdef TIME_SYNTAX
|
||||||
static Scheme_Object *time_apply(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *time_apply(int argc, Scheme_Object *argv[]);
|
||||||
|
@ -490,6 +492,14 @@ scheme_init_fun (Scheme_Env *env)
|
||||||
| SCHEME_PRIM_IS_OMITABLE);
|
| SCHEME_PRIM_IS_OMITABLE);
|
||||||
scheme_add_global_constant("void?", o, env);
|
scheme_add_global_constant("void?", o, env);
|
||||||
|
|
||||||
|
/* adds the new primitive check-undefined to the kernel langauge
|
||||||
|
check-undefined has an arity of 1 and no flags */
|
||||||
|
REGISTER_SO(scheme_check_not_undefined);
|
||||||
|
scheme_check_not_undefined = scheme_make_prim_w_arity(check_not_undefined, "check-not-undefined", 2, 2);
|
||||||
|
scheme_add_global_constant("check-not-undefined", scheme_check_not_undefined, env);
|
||||||
|
|
||||||
|
scheme_add_global_constant("undefined", scheme_undefined, env);
|
||||||
|
|
||||||
#ifdef TIME_SYNTAX
|
#ifdef TIME_SYNTAX
|
||||||
scheme_add_global_constant("time-apply",
|
scheme_add_global_constant("time-apply",
|
||||||
scheme_make_prim_w_arity2(time_apply,
|
scheme_make_prim_w_arity2(time_apply,
|
||||||
|
@ -2523,6 +2533,23 @@ void_p (int argc, Scheme_Object *argv[])
|
||||||
return SAME_OBJ(argv[0], scheme_void) ? scheme_true : scheme_false;
|
return SAME_OBJ(argv[0], scheme_void) ? scheme_true : scheme_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *
|
||||||
|
check_not_undefined (int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
if (!SCHEME_SYMBOLP(argv[1]))
|
||||||
|
scheme_wrong_contract("check-not-undefined", "symbol?", 1, argc, argv);
|
||||||
|
|
||||||
|
if (SAME_OBJ(argv[0], scheme_undefined)) {
|
||||||
|
scheme_raise_exn(MZEXN_FAIL_CONTRACT_VARIABLE,
|
||||||
|
argv[1],
|
||||||
|
"%S: variable used before its definition",
|
||||||
|
argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return argv[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *
|
||||||
procedure_p (int argc, Scheme_Object *argv[])
|
procedure_p (int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
|
|
1854
racket/src/racket/src/letrec_check.c
Normal file
1854
racket/src/racket/src/letrec_check.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(define re:start "^START ([a-z]+);")
|
(define re:start "^START ([a-z_]+);")
|
||||||
(define re:end "^END ([a-z]+);")
|
(define re:end "^END ([a-z_]+);")
|
||||||
|
|
||||||
(define re:form "^([a-zA-Z0-9_]+) [{]")
|
(define re:form "^([a-zA-Z0-9_]+) [{]")
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
(loop (cdr l) (not skip?))]
|
(loop (cdr l) (not skip?))]
|
||||||
[skip?
|
[skip?
|
||||||
(loop (cdr l) #t)]
|
(loop (cdr l) #t)]
|
||||||
[(regexp-match? #rx"(START|END)_[A-Z]+_ONLY;" (car l))
|
[(regexp-match? #rx"(START|END)_[A-Z_]+_ONLY;" (car l))
|
||||||
(loop (cdr l) skip?)]
|
(loop (cdr l) skip?)]
|
||||||
[else
|
[else
|
||||||
(printf "~a\n" (car l))
|
(printf "~a\n" (car l))
|
||||||
|
|
|
@ -8404,11 +8404,13 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env
|
||||||
/* Note: don't use MZCONFIG_USE_JIT for module bodies */
|
/* Note: don't use MZCONFIG_USE_JIT for module bodies */
|
||||||
use_jit = scheme_startup_use_jit;
|
use_jit = scheme_startup_use_jit;
|
||||||
|
|
||||||
|
o = scheme_letrec_check_expr((Scheme_Object *)env->genv->module);
|
||||||
|
|
||||||
oi = scheme_optimize_info_create(env->prefix, 1);
|
oi = scheme_optimize_info_create(env->prefix, 1);
|
||||||
scheme_optimize_info_enforce_const(oi, rec[drec].comp_flags & COMP_ENFORCE_CONSTS);
|
scheme_optimize_info_enforce_const(oi, rec[drec].comp_flags & COMP_ENFORCE_CONSTS);
|
||||||
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
||||||
scheme_optimize_info_never_inline(oi);
|
scheme_optimize_info_never_inline(oi);
|
||||||
o = scheme_optimize_expr((Scheme_Object *)env->genv->module, oi, 0);
|
o = scheme_optimize_expr(o, oi, 0);
|
||||||
|
|
||||||
rp = scheme_resolve_prefix(0, env->prefix, 1);
|
rp = scheme_resolve_prefix(0, env->prefix, 1);
|
||||||
ri = scheme_resolve_info_create(rp);
|
ri = scheme_resolve_info_create(rp);
|
||||||
|
@ -9014,6 +9016,8 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_
|
||||||
if (!for_stx)
|
if (!for_stx)
|
||||||
lifted_reqs = scheme_append(scheme_frame_get_require_lifts(eenv), lifted_reqs);
|
lifted_reqs = scheme_append(scheme_frame_get_require_lifts(eenv), lifted_reqs);
|
||||||
|
|
||||||
|
m = scheme_letrec_check_expr(m);
|
||||||
|
|
||||||
oi = scheme_optimize_info_create(eenv->prefix, 1);
|
oi = scheme_optimize_info_create(eenv->prefix, 1);
|
||||||
scheme_optimize_info_set_context(oi, (Scheme_Object *)env->genv->module);
|
scheme_optimize_info_set_context(oi, (Scheme_Object *)env->genv->module);
|
||||||
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
if (!(rec[drec].comp_flags & COMP_CAN_INLINE))
|
||||||
|
|
78
racket/src/racket/src/mzmark_letrec_check.inc
Normal file
78
racket/src/racket/src/mzmark_letrec_check.inc
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* >>>> Generated by mkmark.rkt from mzmarksrc.c <<<< */
|
||||||
|
|
||||||
|
static int mark_letrec_check_frame_SIZE(void *p, struct NewGC *gc) {
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mark_letrec_check_frame_MARK(void *p, struct NewGC *gc) {
|
||||||
|
Letrec_Check_Frame *frame = (Letrec_Check_Frame *)p;
|
||||||
|
|
||||||
|
gcMARK2(frame->def, gc);
|
||||||
|
gcMARK2(frame->next, gc);
|
||||||
|
gcMARK2(frame->ref, gc);
|
||||||
|
gcMARK2(frame->checked, gc);
|
||||||
|
gcMARK2(frame->head, gc);
|
||||||
|
gcMARK2(frame->deferred_with_rhs_ref, gc);
|
||||||
|
gcMARK2(frame->deferred_with_body_ref, gc);
|
||||||
|
gcMARK2(frame->deferred_with_no_ref, gc);
|
||||||
|
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mark_letrec_check_frame_FIXUP(void *p, struct NewGC *gc) {
|
||||||
|
Letrec_Check_Frame *frame = (Letrec_Check_Frame *)p;
|
||||||
|
|
||||||
|
gcFIXUP2(frame->def, gc);
|
||||||
|
gcFIXUP2(frame->next, gc);
|
||||||
|
gcFIXUP2(frame->ref, gc);
|
||||||
|
gcFIXUP2(frame->checked, gc);
|
||||||
|
gcFIXUP2(frame->head, gc);
|
||||||
|
gcFIXUP2(frame->deferred_with_rhs_ref, gc);
|
||||||
|
gcFIXUP2(frame->deferred_with_body_ref, gc);
|
||||||
|
gcFIXUP2(frame->deferred_with_no_ref, gc);
|
||||||
|
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mark_letrec_check_frame_IS_ATOMIC 0
|
||||||
|
#define mark_letrec_check_frame_IS_CONST_SIZE 1
|
||||||
|
|
||||||
|
|
||||||
|
static int mark_scheme_deferred_expr_SIZE(void *p, struct NewGC *gc) {
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mark_scheme_deferred_expr_MARK(void *p, struct NewGC *gc) {
|
||||||
|
Scheme_Deferred_Expr *clos = (Scheme_Deferred_Expr *)p;
|
||||||
|
|
||||||
|
gcMARK2(clos->expr, gc);
|
||||||
|
gcMARK2(clos->frame, gc);
|
||||||
|
gcMARK2(clos->uvars, gc);
|
||||||
|
gcMARK2(clos->pvars, gc);
|
||||||
|
gcMARK2(clos->subexpr_ls, gc);
|
||||||
|
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mark_scheme_deferred_expr_FIXUP(void *p, struct NewGC *gc) {
|
||||||
|
Scheme_Deferred_Expr *clos = (Scheme_Deferred_Expr *)p;
|
||||||
|
|
||||||
|
gcFIXUP2(clos->expr, gc);
|
||||||
|
gcFIXUP2(clos->frame, gc);
|
||||||
|
gcFIXUP2(clos->uvars, gc);
|
||||||
|
gcFIXUP2(clos->pvars, gc);
|
||||||
|
gcFIXUP2(clos->subexpr_ls, gc);
|
||||||
|
|
||||||
|
return
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mark_scheme_deferred_expr_IS_ATOMIC 0
|
||||||
|
#define mark_scheme_deferred_expr_IS_CONST_SIZE 1
|
||||||
|
|
||||||
|
|
|
@ -628,6 +628,7 @@ static int comp_let_value_MARK(void *p, struct NewGC *gc) {
|
||||||
gcMARK2(c->flags, gc);
|
gcMARK2(c->flags, gc);
|
||||||
gcMARK2(c->value, gc);
|
gcMARK2(c->value, gc);
|
||||||
gcMARK2(c->body, gc);
|
gcMARK2(c->body, gc);
|
||||||
|
gcMARK2(c->names, gc);
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
||||||
|
@ -639,6 +640,7 @@ static int comp_let_value_FIXUP(void *p, struct NewGC *gc) {
|
||||||
gcFIXUP2(c->flags, gc);
|
gcFIXUP2(c->flags, gc);
|
||||||
gcFIXUP2(c->value, gc);
|
gcFIXUP2(c->value, gc);
|
||||||
gcFIXUP2(c->body, gc);
|
gcFIXUP2(c->body, gc);
|
||||||
|
gcFIXUP2(c->names, gc);
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
||||||
|
@ -1660,6 +1662,9 @@ static int input_port_MARK(void *p, struct NewGC *gc) {
|
||||||
gcMARK2(ip->input_extras_ready, gc);
|
gcMARK2(ip->input_extras_ready, gc);
|
||||||
gcMARK2(ip->unless, gc);
|
gcMARK2(ip->unless, gc);
|
||||||
gcMARK2(ip->unless_cache, gc);
|
gcMARK2(ip->unless_cache, gc);
|
||||||
|
#ifdef WINDOWS_FILE_HANDLES
|
||||||
|
gcMARK2(ip->bufwidths, gc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port));
|
||||||
|
@ -1687,6 +1692,9 @@ static int input_port_FIXUP(void *p, struct NewGC *gc) {
|
||||||
gcFIXUP2(ip->input_extras_ready, gc);
|
gcFIXUP2(ip->input_extras_ready, gc);
|
||||||
gcFIXUP2(ip->unless, gc);
|
gcFIXUP2(ip->unless, gc);
|
||||||
gcFIXUP2(ip->unless_cache, gc);
|
gcFIXUP2(ip->unless_cache, gc);
|
||||||
|
#ifdef WINDOWS_FILE_HANDLES
|
||||||
|
gcFIXUP2(ip->bufwidths, gc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Input_Port));
|
||||||
|
|
|
@ -235,6 +235,7 @@ comp_let_value {
|
||||||
gcMARK2(c->flags, gc);
|
gcMARK2(c->flags, gc);
|
||||||
gcMARK2(c->value, gc);
|
gcMARK2(c->value, gc);
|
||||||
gcMARK2(c->body, gc);
|
gcMARK2(c->body, gc);
|
||||||
|
gcMARK2(c->names, gc);
|
||||||
|
|
||||||
size:
|
size:
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Compiled_Let_Value));
|
||||||
|
@ -1327,6 +1328,43 @@ END sfs;
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
|
START letrec_check;
|
||||||
|
|
||||||
|
mark_letrec_check_frame {
|
||||||
|
mark:
|
||||||
|
Letrec_Check_Frame *frame = (Letrec_Check_Frame *)p;
|
||||||
|
|
||||||
|
gcMARK2(frame->def, gc);
|
||||||
|
gcMARK2(frame->next, gc);
|
||||||
|
gcMARK2(frame->ref, gc);
|
||||||
|
gcMARK2(frame->checked, gc);
|
||||||
|
gcMARK2(frame->head, gc);
|
||||||
|
gcMARK2(frame->deferred_with_rhs_ref, gc);
|
||||||
|
gcMARK2(frame->deferred_with_body_ref, gc);
|
||||||
|
gcMARK2(frame->deferred_with_no_ref, gc);
|
||||||
|
|
||||||
|
size:
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Letrec_Check_Frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
mark_scheme_deferred_expr {
|
||||||
|
mark:
|
||||||
|
Scheme_Deferred_Expr *clos = (Scheme_Deferred_Expr *)p;
|
||||||
|
|
||||||
|
gcMARK2(clos->expr, gc);
|
||||||
|
gcMARK2(clos->frame, gc);
|
||||||
|
gcMARK2(clos->uvars, gc);
|
||||||
|
gcMARK2(clos->pvars, gc);
|
||||||
|
gcMARK2(clos->subexpr_ls, gc);
|
||||||
|
|
||||||
|
size:
|
||||||
|
gcBYTES_TO_WORDS(sizeof(Scheme_Deferred_Expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
END letrec_check;
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
START optimize;
|
START optimize;
|
||||||
|
|
||||||
mark_optimize_info {
|
mark_optimize_info {
|
||||||
|
|
|
@ -250,7 +250,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
|
||||||
If warn_info is supplied, complain when a mismatch is detected.
|
If warn_info is supplied, complain when a mismatch is detected.
|
||||||
If no_id is 1, then an identifier doesn't count as omittable,
|
If no_id is 1, then an identifier doesn't count as omittable,
|
||||||
unless the identifier is a consistent top-level; currently, this
|
unless the identifier is a consistent top-level; currently, this
|
||||||
is used to imply the absece of a continuation-mark impersonator. */
|
is used to imply the absence of a continuation-mark impersonator. */
|
||||||
{
|
{
|
||||||
Scheme_Type vtype;
|
Scheme_Type vtype;
|
||||||
|
|
||||||
|
@ -439,6 +439,15 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for (set! x x) */
|
||||||
|
if (vtype == scheme_set_bang_type) {
|
||||||
|
Scheme_Set_Bang *sb = (Scheme_Set_Bang *)o;
|
||||||
|
if (SAME_TYPE(scheme_local_type, SCHEME_TYPE(sb->var))
|
||||||
|
&& SAME_TYPE(scheme_local_type, SCHEME_TYPE(sb->val))
|
||||||
|
&& (SCHEME_LOCAL_POS(sb->var) == SCHEME_LOCAL_POS(sb->val)))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* check for struct-type declaration: */
|
/* check for struct-type declaration: */
|
||||||
{
|
{
|
||||||
Scheme_Object *auto_e;
|
Scheme_Object *auto_e;
|
||||||
|
@ -2568,6 +2577,16 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf
|
||||||
|
|
||||||
app = (Scheme_App3_Rec *)o;
|
app = (Scheme_App3_Rec *)o;
|
||||||
|
|
||||||
|
if (SAME_OBJ(app->rator, scheme_check_not_undefined)
|
||||||
|
&& SCHEME_SYMBOLP(app->rand2)) {
|
||||||
|
scheme_log(info->logger,
|
||||||
|
SCHEME_LOG_WARNING,
|
||||||
|
0,
|
||||||
|
"warning%s: use-before-definition check inserted on variable: %S",
|
||||||
|
scheme_optimize_context_to_string(info->context),
|
||||||
|
app->rand2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for (apply ... (list ...)) early: */
|
/* Check for (apply ... (list ...)) early: */
|
||||||
le = direct_apply((Scheme_Object *)app, app->rator, app->rand2, info);
|
le = direct_apply((Scheme_Object *)app, app->rator, app->rand2, info);
|
||||||
if (le) return scheme_optimize_expr(le, info, context);
|
if (le) return scheme_optimize_expr(le, info, context);
|
||||||
|
|
|
@ -2028,6 +2028,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht,
|
||||||
if (compact && (SCHEME_PROCP(obj)
|
if (compact && (SCHEME_PROCP(obj)
|
||||||
|| SCHEME_STRUCT_TYPEP(obj)
|
|| SCHEME_STRUCT_TYPEP(obj)
|
||||||
|| SCHEME_EOFP(obj)
|
|| SCHEME_EOFP(obj)
|
||||||
|
|| SAME_OBJ(scheme_undefined, obj)
|
||||||
|| SAME_TYPE(scheme_always_evt_type, SCHEME_TYPE(obj))
|
|| SAME_TYPE(scheme_always_evt_type, SCHEME_TYPE(obj))
|
||||||
|| SAME_TYPE(scheme_never_evt_type, SCHEME_TYPE(obj))
|
|| SAME_TYPE(scheme_never_evt_type, SCHEME_TYPE(obj))
|
||||||
|| SAME_TYPE(scheme_struct_property_type, SCHEME_TYPE(obj))
|
|| SAME_TYPE(scheme_struct_property_type, SCHEME_TYPE(obj))
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#define USE_COMPILED_STARTUP 1
|
#define USE_COMPILED_STARTUP 1
|
||||||
|
|
||||||
#define EXPECTED_PRIM_COUNT 1116
|
#define EXPECTED_PRIM_COUNT 1118
|
||||||
#define EXPECTED_UNSAFE_COUNT 101
|
#define EXPECTED_UNSAFE_COUNT 101
|
||||||
#define EXPECTED_FLFXNUM_COUNT 69
|
#define EXPECTED_FLFXNUM_COUNT 69
|
||||||
#define EXPECTED_EXTFL_COUNT 45
|
#define EXPECTED_EXTFL_COUNT 45
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#ifndef __mzscheme_private__
|
#ifndef __mzscheme_private__
|
||||||
#define __mzscheme_private__
|
#define __mzscheme_private__
|
||||||
|
|
||||||
|
// #define MZ_GC_STRESS_TESTING 1
|
||||||
|
|
||||||
#include "scheme.h"
|
#include "scheme.h"
|
||||||
#include "longdouble/longdouble.h"
|
#include "longdouble/longdouble.h"
|
||||||
|
|
||||||
|
@ -263,6 +265,7 @@ void scheme_init_type();
|
||||||
void scheme_init_custodian_extractors();
|
void scheme_init_custodian_extractors();
|
||||||
void scheme_init_bignum();
|
void scheme_init_bignum();
|
||||||
void scheme_init_compenv();
|
void scheme_init_compenv();
|
||||||
|
void scheme_init_letrec_check();
|
||||||
void scheme_init_optimize();
|
void scheme_init_optimize();
|
||||||
void scheme_init_resolve();
|
void scheme_init_resolve();
|
||||||
void scheme_init_sfs();
|
void scheme_init_sfs();
|
||||||
|
@ -432,6 +435,7 @@ extern Scheme_Object *scheme_values_func;
|
||||||
extern Scheme_Object *scheme_procedure_p_proc;
|
extern Scheme_Object *scheme_procedure_p_proc;
|
||||||
extern Scheme_Object *scheme_procedure_arity_includes_proc;
|
extern Scheme_Object *scheme_procedure_arity_includes_proc;
|
||||||
extern Scheme_Object *scheme_void_proc;
|
extern Scheme_Object *scheme_void_proc;
|
||||||
|
extern Scheme_Object *scheme_check_not_undefined;
|
||||||
extern Scheme_Object *scheme_pair_p_proc;
|
extern Scheme_Object *scheme_pair_p_proc;
|
||||||
extern Scheme_Object *scheme_mpair_p_proc;
|
extern Scheme_Object *scheme_mpair_p_proc;
|
||||||
extern Scheme_Object *scheme_unsafe_cons_list_proc;
|
extern Scheme_Object *scheme_unsafe_cons_list_proc;
|
||||||
|
@ -1346,6 +1350,7 @@ typedef struct Scheme_Compiled_Let_Value {
|
||||||
int *flags;
|
int *flags;
|
||||||
Scheme_Object *value;
|
Scheme_Object *value;
|
||||||
Scheme_Object *body;
|
Scheme_Object *body;
|
||||||
|
Scheme_Object **names; /* NULL after letrec_check phase */
|
||||||
} Scheme_Compiled_Let_Value;
|
} Scheme_Compiled_Let_Value;
|
||||||
|
|
||||||
#define SCHEME_CLV_FLAGS(clv) MZ_OPT_HASH_KEY(&(clv)->iso)
|
#define SCHEME_CLV_FLAGS(clv) MZ_OPT_HASH_KEY(&(clv)->iso)
|
||||||
|
@ -2856,6 +2861,8 @@ typedef struct Scheme_Set_Bang {
|
||||||
|
|
||||||
Scheme_Object *scheme_protect_quote(Scheme_Object *expr);
|
Scheme_Object *scheme_protect_quote(Scheme_Object *expr);
|
||||||
|
|
||||||
|
Scheme_Object *scheme_letrec_check_expr(Scheme_Object *);
|
||||||
|
|
||||||
Scheme_Object *scheme_optimize_expr(Scheme_Object *, Optimize_Info *, int context);
|
Scheme_Object *scheme_optimize_expr(Scheme_Object *, Optimize_Info *, int context);
|
||||||
Scheme_Object *scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, int context);
|
Scheme_Object *scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, int context);
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "6.0.1.1"
|
#define MZSCHEME_VERSION "6.0.1.2"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 6
|
#define MZSCHEME_VERSION_X 6
|
||||||
#define MZSCHEME_VERSION_Y 0
|
#define MZSCHEME_VERSION_Y 0
|
||||||
#define MZSCHEME_VERSION_Z 1
|
#define MZSCHEME_VERSION_Z 1
|
||||||
#define MZSCHEME_VERSION_W 1
|
#define MZSCHEME_VERSION_W 2
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
|
@ -288,7 +288,9 @@ enum {
|
||||||
scheme_rt_lightweight_cont, /* 260 */
|
scheme_rt_lightweight_cont, /* 260 */
|
||||||
scheme_rt_export_info, /* 261 */
|
scheme_rt_export_info, /* 261 */
|
||||||
scheme_rt_cont_jmp, /* 262 */
|
scheme_rt_cont_jmp, /* 262 */
|
||||||
|
scheme_rt_letrec_check_frame, /* 263 */
|
||||||
#endif
|
#endif
|
||||||
|
scheme_deferred_expr_type, /* 264 */
|
||||||
|
|
||||||
_scheme_last_type_
|
_scheme_last_type_
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user