From e36787bdebb7403ea180a140d88cf695d5eaea4c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 4 Nov 2010 11:21:40 -0400 Subject: [PATCH] Fixed potential danger with fixnum optimizations. (cherry picked from commit c0a6137c67228933ad94d88409ffd86e30e922ae) --- .../typed-scheme/typecheck/tc-expr-unit.rkt | 17 ++++++++++++++--- collects/typed-scheme/types/abbrev.rkt | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index d0788b9a7c..0fd0402a41 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -21,6 +21,17 @@ (import tc-if^ tc-lambda^ tc-app^ tc-let^ check-subforms^) (export tc-expr^) +;; Is the number a fixnum on all the platforms Racket supports? +;; This check is done at compile time to typecheck literals. +;; Since a zo file compiled on a 64-bit system can be used on 32-bit +;; systems, we can't use the host fixnum? predicate, or large 64-bit +;; fixnums will typecheck as fixnums but not be actual fixnums on the +;; target system. In combination with fixnum typed optimizations, bad +;; things could happen. +(define (portable-fixnum? n) + (and (exact-integer? n) + (< n (expt 2 31)))) + ;; return the type of a literal value ;; scheme-value -> type (define (tc-literal v-stx [expected #f]) @@ -34,9 +45,9 @@ [i:boolean (-val (syntax-e #'i))] [i:identifier (-val (syntax-e #'i))] [0 -Zero] - [(~var i (3d (conjoin number? fixnum? positive?))) -PositiveFixnum] - [(~var i (3d (conjoin number? fixnum? negative?))) -NegativeFixnum] - [(~var i (3d (conjoin number? fixnum?))) -Fixnum] + [(~var i (3d (conjoin number? portable-fixnum? positive?))) -PositiveFixnum] + [(~var i (3d (conjoin number? portable-fixnum? negative?))) -NegativeFixnum] + [(~var i (3d (conjoin number? portable-fixnum?))) -Fixnum] [(~var i (3d exact-positive-integer?)) -ExactPositiveInteger] [(~var i (3d exact-nonnegative-integer?)) -ExactNonnegativeInteger] [(~var i (3d exact-integer?)) -Integer] diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index e69967b355..68bbdbfc4d 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -174,6 +174,9 @@ (define -ExactPositiveInteger (make-Base 'Exact-Positive-Integer #'exact-positive-integer?)) +;; We can safely use the fixnum? prediate here, unlike in tc-expr-unit. +;; The fixnum? here will be part of the generated contracts, which run +;; on the target system, so we're safe. (define -PositiveFixnum (make-Base 'Positive-Fixnum #'(and/c number? fixnum? positive?))) (define -NegativeFixnum