
controversial, unless I damaged something in the process of integrating them with other recent changes. the user's guide and release notes have been updated as well to reflect the changes of interest to end users. - the body of load-library is now wrapped in a $pass-time with to show the time spent loading libraries separately from the time spent in expand. syntax.ss - interpret now plays the pass-time game interpret.ss - added compile-time-value? predicate and compile-time-value-value accessor syntax.ss, primdata.ss, 8.ms, primvars.ms, root-experr* - $pass-stats now returns accurrate stats for the currently timed pass. 7.ss - compile-whole-program and compile-whole-library now propagate recompile info from the named wpo file to the object file to support maybe-compile-program and maybe-compile-library in the case where compile-whole-{program,library} overwrites the original object file. compile.ss, 7.ms, mat.ss, primvars.ms - replaced the ancient and unusable bintar with one that creates a useful tarball for binary installs bintar - generated Mf-install InstallBin (InstallLib, InstallMan) now correctly indirects through InstallPrefix if the --installbin (--installlib, --installman) configure flag is not present. src/configure - removed definition of generate-procedure-source-information patch.ss - guardian tconc cells are now allocated in generation 0 in the hope that they can be released more quickly. gc.c - added ftype-guardian syntax: (ftype-guardian A) creates a new guardian for ftype pointers of type A, the first base field (or one of the first base fields in the case of unions) of which must be a word-sized integer with native endianness representing a reference count. ftype pointers are registered with and retrieved from the guardian just like objects are registered with and retrieved from any guardian. the difference is that the garbage collector decrements the reference count before resurrecting an ftype pointer and resurrects only those whose reference counts become zero, i.e., are ready for deallocation. ftype.ss, cp0.ss, cmacros.ss, cpnanopass.ss, prims.ss, primdata.ss, gc.c, 4.ms, root-experr* - fixed a bug in automatic recompilation handling of missing include files specified with absolute pathnames or pathnames starting with "./" or "..": was erroring out in file-modification-time with a file-not-found or other exception rather than recompiling. syntax.ss, 7.ms, root-experr*, patch* - changed inline vector-for-each and string-for-each code to put the last call to the procedure in tail position, as was already done for the library definitions and for the inline code for for-each. cp0.ss, 5_4.ms, 5_6.ms - the compiler now generates better inline code for the bytevector procedure. instead of one byte memory write for each argument, it writes up to 4 (32-bit machines) or 8 (64-bit machines) bytes at a time, which almost always results in fewer instructions and fewer writes. cpnanopass.ss, bytevector.ms - packaged unchanging implicit reader arguments into a single record to reduce the number of arguments. read.ss - recoded run-vector to handle zero-length vectors. it appears we're not presently generating empty vectors (representing empty groups), but the fasl format permits them. 7.ss original commit: 7be1d190de7171f74a1ee71e348d3e6310392686
802 lines
34 KiB
Scheme
802 lines
34 KiB
Scheme
;;; primvars.ms
|
|
;;; Copyright 1984-2017 Cisco Systems, Inc.
|
|
;;;
|
|
;;; Licensed under the Apache License, Version 2.0 (the "License");
|
|
;;; you may not use this file except in compliance with the License.
|
|
;;; You may obtain a copy of the License at
|
|
;;;
|
|
;;; http://www.apache.org/licenses/LICENSE-2.0
|
|
;;;
|
|
;;; Unless required by applicable law or agreed to in writing, software
|
|
;;; distributed under the License is distributed on an "AS IS" BASIS,
|
|
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
;;; See the License for the specific language governing permissions and
|
|
;;; limitations under the License.
|
|
|
|
(mat primvars
|
|
(let loop ([ls (oblist)] [bad '()])
|
|
(if (null? ls)
|
|
(or (null? bad)
|
|
(begin
|
|
(pretty-print bad)
|
|
(errorf #f "incorrect library-entry bindings for symbols ~s" bad)))
|
|
(let ([x (car ls)])
|
|
(if (let ([i (#%$sgetprop x '*library-entry* #f)])
|
|
(or (not i) (#%$lookup-library-entry i)))
|
|
(loop (cdr ls) bad)
|
|
(loop (cdr ls) (cons x bad))))))
|
|
|
|
(let ()
|
|
(define (get-cte x) (#%$sgetprop x '*cte* #f))
|
|
(define (keyword? x)
|
|
(cond
|
|
[(get-cte x) => (lambda (b) (not (eq? (car b) 'primitive)))]
|
|
[else #f]))
|
|
(define (variable? x)
|
|
(cond
|
|
[(get-cte x) => (lambda (b) (eq? (car b) 'primitive))]
|
|
[else #t]))
|
|
(define (scheme? x) (eq? (#%$sgetprop x '*scheme* #f) x))
|
|
(let loop ([ls (remp gensym? (oblist))] [bad '()])
|
|
(if (null? ls)
|
|
(or (null? bad)
|
|
(begin
|
|
(pretty-print bad)
|
|
(errorf #f "incorrect system/scheme bindings for symbols ~s" bad)))
|
|
(let ([x (car ls)])
|
|
(if (case (#%$symbol-type x)
|
|
[(system)
|
|
(and (#%$top-level-bound? x)
|
|
(top-level-syntax? x)
|
|
(not (top-level-syntax? x (scheme-environment)))
|
|
(variable? x)
|
|
(not (keyword? x))
|
|
(not (scheme? x)))]
|
|
[(system-keyword)
|
|
(and (not (#%$top-level-bound? x))
|
|
(top-level-syntax? x)
|
|
(not (top-level-syntax? x (scheme-environment)))
|
|
(not (variable? x))
|
|
(keyword? x)
|
|
(not (scheme? x)))]
|
|
[(primitive)
|
|
(and (#%$top-level-bound? x)
|
|
(top-level-syntax? x)
|
|
(top-level-syntax? x (scheme-environment))
|
|
(variable? x)
|
|
(not (keyword? x))
|
|
(scheme? x))]
|
|
[(keyword)
|
|
(and (not (#%$top-level-bound? x))
|
|
(top-level-syntax? x)
|
|
(top-level-syntax? x (scheme-environment))
|
|
(not (variable? x))
|
|
(keyword? x)
|
|
(scheme? x))]
|
|
[(library-uid) ; same as keyword, except top-evel-bound
|
|
(and (#%$top-level-bound? x)
|
|
(top-level-syntax? x)
|
|
(top-level-syntax? x (scheme-environment))
|
|
(not (variable? x))
|
|
(keyword? x)
|
|
(scheme? x))]
|
|
[(system-library-uid)
|
|
(and (#%$top-level-bound? x) ; same as system-keyword, except top-evel-bound
|
|
(top-level-syntax? x)
|
|
(not (top-level-syntax? x (scheme-environment)))
|
|
(not (variable? x))
|
|
(keyword? x)
|
|
(not (scheme? x)))]
|
|
[else
|
|
(and (not (#%$top-level-bound? x))
|
|
(top-level-syntax? x)
|
|
(not (top-level-syntax? x (scheme-environment)))
|
|
(not (get-cte x))
|
|
(not (scheme? x)))])
|
|
(loop (cdr ls) bad)
|
|
(loop (cdr ls) (cons x bad))))))
|
|
#t)
|
|
|
|
(let ()
|
|
(define (get-cte x) (#%$sgetprop x '*cte* #f))
|
|
(define (scheme? x) (eq? (#%$sgetprop x '*scheme* #f) x))
|
|
(define (mat-id? x)
|
|
(memq x
|
|
'(equivalent-expansion? pretty-equal? mat-run
|
|
show-mat-source-info mat-file enable-cp0 windows? embedded?
|
|
*examples-directory* *scheme*
|
|
*fuzz* ~= fl~= cfl~= == nan pi +pi +pi/2 +pi/4 -pi -pi/2 -pi/4 +e -e
|
|
separate-compile separate-eval run-script patch-exec-path $record->vector
|
|
$cat_flush
|
|
test-cp0-expansion
|
|
mkfile rm-rf touch)))
|
|
(let loop ([ls (remp gensym? (oblist))] [bad '()])
|
|
(if (null? ls)
|
|
(or (null? bad)
|
|
(begin
|
|
(pretty-print bad)
|
|
(errorf #f "incorrect top-level bindings for symbols ~s" bad)))
|
|
(loop (cdr ls)
|
|
(let ([x (car ls)])
|
|
(if (let ([loc (#%$sgetprop x '*top* #f)])
|
|
(case (#%$symbol-type x)
|
|
[(keyword) (eq? loc x)]
|
|
[(primitive)
|
|
(and
|
|
(top-level-bound? x)
|
|
(eq? (top-level-value x) (top-level-value x (scheme-environment)))
|
|
(eq? loc x))]
|
|
[else
|
|
(or (mat-id? x)
|
|
(not loc)
|
|
(not (top-level-bound? x))
|
|
(guard (c [else #t])
|
|
(#2%top-level-value x)
|
|
#f))]))
|
|
bad
|
|
(cons x bad)))))))
|
|
)
|
|
|
|
(mat arity
|
|
(or (= (optimize-level) 3)
|
|
(let ()
|
|
(define oops #f)
|
|
(define (prefix=? prefix str)
|
|
(let ([n (string-length prefix)])
|
|
(and (>= (string-length str) n)
|
|
(string=? (substring str 0 n) prefix))))
|
|
(define (check prim n)
|
|
(define (okay-condition? c)
|
|
(and (violation? c)
|
|
(message-condition? c)
|
|
(irritants-condition? c)
|
|
(let ([msg (condition-message c)] [args (condition-irritants c)])
|
|
(or (and (prefix=? "incorrect number of arguments" msg)
|
|
(and (list? args) (= (length args) 1))
|
|
(let ([unprefixed (#%$sgetprop prim '*unprefixed* prim)])
|
|
(or (and (procedure? (car args))
|
|
(let ([name (#%$procedure-name (car args))])
|
|
(or (not name) (equal? name (symbol->string unprefixed)))))
|
|
(and (pair? (car args)) (eq? (caar args) unprefixed)))))
|
|
(and (prefix=? "incorrect argument count" msg)
|
|
(and (list? args) (= (length args) 1) (string? (car args)))
|
|
(let ([unprefixed (#%$sgetprop prim '*unprefixed* prim)])
|
|
(prefix=? (format "(~s" unprefixed) (car args))))))))
|
|
(let ([call `(,prim ,@(make-list n `',(void)))])
|
|
(unless (guard (c [else (okay-condition? c)])
|
|
(eval `(begin ,call #f)))
|
|
(set! oops #t)
|
|
(printf "no argcount error for ~s\n" call))))
|
|
(for-each
|
|
(lambda (prim)
|
|
(let ([a* (#%$sgetprop prim '*arity* #f)])
|
|
(when a*
|
|
(let loop ([n 0] [a* a*])
|
|
(cond
|
|
[(null? a*) (check prim n)]
|
|
[(= (- -1 (car a*)) n) (void)]
|
|
[(= (car a*) n) (loop (+ n 1) (cdr a*))]
|
|
[else (check prim n) (loop (+ n 1) a*)])))))
|
|
(oblist))
|
|
(not oops)))
|
|
(or (= (optimize-level) 3)
|
|
(let ()
|
|
(define oops #f)
|
|
(define (prefix=? prefix str)
|
|
(let ([n (string-length prefix)])
|
|
(and (>= (string-length str) n)
|
|
(string=? (substring str 0 n) prefix))))
|
|
(define (write-and-load x)
|
|
(with-output-to-file "testfile.ss"
|
|
(lambda () (pretty-print x))
|
|
'replace)
|
|
(load "testfile.ss"))
|
|
(define (check prim n)
|
|
(define (okay-condition? c)
|
|
(and (violation? c)
|
|
(message-condition? c)
|
|
(irritants-condition? c)
|
|
(let ([msg (condition-message c)] [args (condition-irritants c)])
|
|
(or (and (prefix=? "incorrect number of arguments" msg)
|
|
(and (list? args) (= (length args) 1))
|
|
(let ([unprefixed (#%$sgetprop prim '*unprefixed* prim)])
|
|
(or (and (procedure? (car args))
|
|
(let ([name (#%$procedure-name (car args))])
|
|
(or (not name) (equal? name (symbol->string unprefixed)))))
|
|
(and (pair? (car args)) (eq? (caar args) unprefixed)))))
|
|
(and (prefix=? "incorrect argument count" msg)
|
|
(and (list? args) (= (length args) 1) (string? (car args)))
|
|
(let ([unprefixed (#%$sgetprop prim '*unprefixed* prim)])
|
|
(prefix=? (format "(~s" unprefixed) (car args))))))))
|
|
(let ([call `(,prim ,@(make-list n '(void)))])
|
|
(let ([warn? #f] [error? #f])
|
|
(guard (c [(okay-condition? c) (set! error? #t)])
|
|
(with-exception-handler
|
|
(lambda (x) (if (warning? x) (begin (set! warn? #t) (values)) (raise-continuable x)))
|
|
(lambda () (write-and-load `(begin ,call #f)) #f)))
|
|
(unless warn? (printf "no argcount warning for ~s\n" call) (set! oops #t))
|
|
(unless error? (printf "no argcount error for ~s\n" call) (set! oops #t)))))
|
|
(for-each
|
|
(lambda (prim)
|
|
(let ([a* (#%$sgetprop prim '*arity* #f)])
|
|
(when a*
|
|
(let loop ([n 0] [a* a*])
|
|
(cond
|
|
[(null? a*) (check prim n)]
|
|
[(= (- -1 (car a*)) n) (void)]
|
|
[(= (car a*) n) (loop (+ n 1) (cdr a*))]
|
|
[else (check prim n) (loop (+ n 1) a*)])))))
|
|
(oblist))
|
|
(not oops)))
|
|
)
|
|
|
|
(mat check-prim-arg-errors
|
|
(or (= (optimize-level) 3)
|
|
(let ()
|
|
; check-prim-arg-errors use the signatures in primdata.ss, when possible, to verify that
|
|
; primitives perform required argument type checks. for each argument to each primitive
|
|
; and for each specified 'bad' value, it passes the 'bad' value for that argument and
|
|
; 'good' values for each other argument. for some arguments to some primitives, e.g., the
|
|
; first argument to remove, there is no 'bad' value, so that argument is not checked.
|
|
;
|
|
; the test has several deficiencies:
|
|
; - for arguments labeled sub-<type>, it cannot determine a 'good' value. this can be
|
|
; addressed only by refining the types given in primdata.ss, including adding
|
|
; dependent types for things like list-ref, the range of whose second argument
|
|
; depends on its first.
|
|
; - it doesn't verify that the raised condition is appropriate, other than ruling out
|
|
; warning conditions, non-violation conditions, and invalid memory references.
|
|
(meta define feature*
|
|
(call-with-port
|
|
(open-input-file (let ([fn (format "../s/~a.def" (machine-type))])
|
|
(if (file-exists? fn) fn (format "../~a" fn))))
|
|
(lambda (ip)
|
|
(let loop ()
|
|
(let ([x (read ip)])
|
|
(cond
|
|
[(eof-object? x) '()]
|
|
[(and (list? x) (eq? (car x) 'features)) (cdr x)]
|
|
[else (loop)]))))))
|
|
(define-syntax define-symbol-flags*
|
|
(lambda (x)
|
|
(define construct-name
|
|
(lambda (template-identifier . args)
|
|
(datum->syntax
|
|
template-identifier
|
|
(string->symbol
|
|
(apply string-append
|
|
(map (lambda (x) (format "~a" (syntax->datum x)))
|
|
args))))))
|
|
(syntax-case x (libraries flags)
|
|
[(_ ([libraries lib ...] [flags shared-flag ...]) entry ...)
|
|
(andmap identifier? #'(shared-flag ...))
|
|
(let ()
|
|
(define prim-name
|
|
(lambda (x)
|
|
(syntax-case x ()
|
|
[(prefix prim)
|
|
(and (identifier? #'prefix) (identifier? #'prim))
|
|
(with-syntax ([prefix:prim (construct-name #'prim #'prefix #'prim)])
|
|
#'(prim . prefix:prim))]
|
|
[prim (identifier? #'prim) #'(prim . prim)])))
|
|
(define ins-and-outs
|
|
(lambda (ins outs)
|
|
(syntax-case ins (->)
|
|
[((in ...) ...) #`(((in ...) #,outs) ...)])))
|
|
(define do-entry
|
|
(lambda (x)
|
|
(syntax-case x (feature sig flags ->)
|
|
[(prim [feature f] . more)
|
|
(if (memq (datum f) feature*)
|
|
(do-entry #'(prim . more))
|
|
#'(void))]
|
|
[(prim [flags flag ...]) (do-entry #'(prim [sig] [flags flag ...]))]
|
|
[(prim [sig [(in ...) ... -> (out ...)] ...] [flags flag ...])
|
|
(with-syntax ([(unprefixed . prim) (prim-name #'prim)])
|
|
(with-syntax ([((((in ...) (out ...)) ...) ...)
|
|
(map ins-and-outs #'(((in ...) ...) ...) #'((out ...) ...))])
|
|
#'(fuzz-prim-args 'prim 'unprefixed '(lib ...)
|
|
'(shared-flag ... flag ...)
|
|
'([(in ...) . (out ...)] ... ...))))])))
|
|
#`(begin #,@(map do-entry #'(entry ...))))])))
|
|
(define env
|
|
(let ([env (copy-environment (scheme-environment) #t)])
|
|
(define-syntax def
|
|
(syntax-rules ()
|
|
[(_ name val)
|
|
(define-top-level-value 'name val env)]))
|
|
(def *env env)
|
|
(let* ([bv (string->utf8 "(if #f #f)")]
|
|
[binary-input-port (open-bytevector-input-port bv)]
|
|
[sfd (make-source-file-descriptor "foo" binary-input-port #t)]
|
|
[source-object (make-source-object sfd 2 3)]
|
|
[annotation (make-annotation '(if #f #f) source-object '(source expr))])
|
|
(def *binary-input-port binary-input-port)
|
|
(def *sfd sfd)
|
|
(def *source-object source-object)
|
|
(def *annotation annotation))
|
|
(let-values ([(binary-output-port getter) (open-bytevector-output-port)])
|
|
(def *binary-output-port binary-output-port)
|
|
(def *binary-port binary-output-port))
|
|
(def *cost-center (make-cost-center))
|
|
(def *date (current-date))
|
|
(def *eq-hashtable (make-eq-hashtable))
|
|
(def *ftype-pointer (make-ftype-pointer double 0))
|
|
(def *symbol-hashtable (make-hashtable symbol-hash eq?))
|
|
(def *genny (gensym))
|
|
(def *old-hash-table (make-hash-table))
|
|
(let ()
|
|
(define rtd (make-record-type-descriptor 'foo #f #f #f #f '#((mutable x))))
|
|
(define rcd (make-record-constructor-descriptor rtd #f #f))
|
|
(def *rtd rtd)
|
|
(def *rcd rcd)
|
|
(def *record ((record-constructor rcd) 3)))
|
|
(def *sstats (statistics))
|
|
(def *time (make-time 'time-duration 0 5))
|
|
(cond
|
|
[(fx< (fixnum-width) 32)
|
|
(def *max-iptr (- (expt 2 31) 1))
|
|
(def *min-iptr (- (expt 2 31)))
|
|
(def *max-uptr (- (expt 2 32) 1))]
|
|
[(fx< (fixnum-width) 64)
|
|
(def *max-iptr (- (expt 2 63) 1))
|
|
(def *min-iptr (- (expt 2 63)))
|
|
(def *max-uptr (- (expt 2 64) 1))]
|
|
[else (errorf 'fuzz-prim-args "unexpected fixnum width ~s" (fixnum-width))])
|
|
env))
|
|
(define type-table
|
|
(let ()
|
|
(define ht (make-hashtable symbol-hash eq?))
|
|
(define-syntax declare-types
|
|
(syntax-rules ()
|
|
[(_ ((type ...) good bad ...) ...)
|
|
(begin
|
|
(let ([payload '(good bad ...)])
|
|
(for-each
|
|
(lambda (t) (symbol-hashtable-set! ht t payload))
|
|
'(type ...)))
|
|
...)]))
|
|
(declare-types
|
|
[(annotation) *annotation '() #f]
|
|
[(annotation-options) (annotation-options debug) 1/2 #f]
|
|
[(binary-input-port) *binary-input-port 0 *binary-output-port (current-input-port) #f]
|
|
[(binary-output-port) *binary-output-port *binary-input-port (current-output-port) #f]
|
|
[(binary-port) *binary-output-port (current-input-port) #f]
|
|
[(bit) 0 7 1.0 'a #f]
|
|
[(boolean) #f '()]
|
|
[(box) &a '((a)) #f]
|
|
[(bytevector) '#vu8(0) "a" #f]
|
|
[(cflonum) 0.0+1.0i 0 'a #f]
|
|
[(char) #\a 0 #f]
|
|
[(codec) latin-1-codec 0 #f]
|
|
[(code) (closure-code 'values) 0 #f]
|
|
[(compile-time-value) (make-compile-time-value 17)]
|
|
[(condition) (make-who-condition 'me) 'the-who]
|
|
[(continuation-condition) (call/cc make-continuation-condition) (make-who-condition 'who) #f]
|
|
[(cost-center) *cost-center '(a) #f]
|
|
[(date) *date *time #f]
|
|
[(enum-set) (file-options compressed) 0 #f]
|
|
[(environment) *env '((a . b)) #f]
|
|
[(eq-hashtable) *eq-hashtable *symbol-hashtable #f]
|
|
[(exact-integer) (- (most-negative-fixnum) 1) 1/2 #f]
|
|
[(exception-state) (current-exception-state) 0 #f]
|
|
[(fasl-strip-options) (fasl-strip-options inspector-source) (file-options compressed) #f]
|
|
[(file-options) (file-options compressed) 1/2 #f]
|
|
[(fixnum) -1 'q (+ (most-positive-fixnum) 1) (- (most-negative-fixnum) 1)]
|
|
[(flonum) 0.0 0 0.0+1.0i 'a #f]
|
|
[(ftype-pointer) *ftype-pointer 0 *time #f]
|
|
[(fxvector) '#vfx(0) "a" #f]
|
|
[(gensym) *genny sym #f]
|
|
[(hashtable) *eq-hashtable '((a . b)) #f]
|
|
[(identifier) #'x x 17 #f]
|
|
[(import-spec) (chezscheme) 0 '(a . b) #f]
|
|
[(input-port) (current-input-port) 0 *binary-output-port (transcoded-port *binary-output-port (native-transcoder)) #f]
|
|
[(integer) 0.0 1/2 1.0+0.0i 'a #f]
|
|
[(i/o-encoding-error) (make-i/o-encoding-error 17 23) (make-who-condition 'who) 1/2 #f]
|
|
[(i/o-filename-error) (make-i/o-filename-error 17) (make-who-condition 'who) 3 #f]
|
|
[(i/o-invalid-position-error) (make-i/o-invalid-position-error 17) (make-who-condition 'who) "" #f]
|
|
[(i/o-port-error) (make-i/o-port-error 17) (make-who-condition 'who) '(a) #f]
|
|
[(irritants-condition) (make-irritants-condition 17) (make-who-condition 'who) 'a #f]
|
|
[(length) 0 -1 (+ (most-positive-fixnum) 1) 'a #f]
|
|
[(library-requirements-options) (library-requirements-options import invoke) 1/2 #f]
|
|
[(list) '(a) '#1=(a . #1#) 17 '#() #f]
|
|
[(maybe-binary-output-port) *binary-output-port *binary-input-port (current-output-port)]
|
|
[(maybe-char) #\a 0]
|
|
[(maybe-pathname) "a" 'a]
|
|
[(maybe-procedure) values 0]
|
|
[(maybe-rtd) *rtd *record ""]
|
|
[(maybe-sfd) *sfd '(q)]
|
|
[(maybe-string) "a" 'a]
|
|
[(maybe-symbol) 'a 0 "a"]
|
|
[(maybe-textual-output-port) (current-output-port) 0 *binary-output-port (transcoded-port *binary-input-port (native-transcoder))]
|
|
[(maybe-transcoder) (native-transcoder) 0]
|
|
[(maybe-ufixnum) 0 -1 (+ (most-positive-fixnum) 1) 'a]
|
|
[(maybe-uint) 0 -1 'a]
|
|
[(message-condition) (make-message-condition 17) (make-who-condition 'who) 'q #f]
|
|
[(number) 1+2i 'oops #f]
|
|
[(old-hash-table) *old-hash-table '((a . b)) #f]
|
|
[(output-port) (current-output-port) 0 *binary-input-port (transcoded-port *binary-input-port (native-transcoder)) #f]
|
|
[(pair) '(a . b) 'a #f]
|
|
[(pathname) "a" 'a #f]
|
|
[(pfixnum) 1 0 #f]
|
|
[(port) (current-input-port) 0 #f]
|
|
[(procedure) values 0 #f]
|
|
[(ptr) 1.0+2.0i]
|
|
[(rational) 1/2 1+2i #f]
|
|
[(rcd) *rcd *rtd "" #f]
|
|
[(real) 1/2 1+2i #f]
|
|
[(record) *record '#(a) #f]
|
|
[(rtd) *rtd *record "" #f]
|
|
[(s16) -1 'q (expt 2 15) (- -1 (expt 2 15)) #f]
|
|
[(s24) -1 'q (expt 2 23) (- -1 (expt 2 23)) #f]
|
|
[(s32) -1 'q (expt 2 31) (- -1 (expt 2 31)) #f]
|
|
[(s40) -1 'q (expt 2 39) (- -1 (expt 2 39)) #f]
|
|
[(s48) -1 'q (expt 2 47) (- -1 (expt 2 47)) #f]
|
|
[(s56) -1 'q (expt 2 55) (- -1 (expt 2 55)) #f]
|
|
[(s64) -1 'q (expt 2 63) (- -1 (expt 2 63)) #f]
|
|
[(s8) -1 'q (expt 2 7) (- -1 (expt 2 7)) #f]
|
|
[(sfd) *sfd '(q)]
|
|
[(sint) -1 'q]
|
|
[(source-condition) (make-source-condition 17) (make-who-condition 'who) #f]
|
|
[(source-object) *source-object '#&a #f]
|
|
[(sstats) *sstats '#(0 2 7 3) #f]
|
|
[(string) "a" 'a #f]
|
|
[(sub-ptr) no-good]
|
|
[(sub-uint sub-ufixnum sub-index sub-length sub-list sub-fixnum sub-flonum sub-integer sub-number sub-port sub-rtd sub-sint sub-string sub-symbol sub-textual-output-port sub-vector maybe-sub-rcd maybe-sub-symbol) no-good #!eof]
|
|
[(symbol) 'a 0 "a" #f]
|
|
[(symbol-hashtable) *symbol-hashtable *eq-hashtable '() #f]
|
|
[(syntax-violation) (make-syntax-violation '(if) #f) 'oops #f]
|
|
[(textual-input-port) (current-input-port) 0 *binary-input-port (transcoded-port *binary-output-port (native-transcoder)) #f]
|
|
[(textual-output-port) (current-output-port) 0 *binary-output-port (transcoded-port *binary-input-port (native-transcoder)) #f]
|
|
[(time) *time "no-time" #f]
|
|
[(timeout) *time "no-time"]
|
|
[(transcoder) (native-transcoder) 0 #f]
|
|
[(u16) 0 -1 (expt 2 16) "a" #f]
|
|
[(u24) 0 -1 (expt 2 24) "a" #f]
|
|
[(u32) 0 -1 (expt 2 32) "a" #f]
|
|
[(u40) 0 -1 (expt 2 40) "a" #f]
|
|
[(u48) 0 -1 (expt 2 48) "a" #f]
|
|
[(u56) 0 -1 (expt 2 56) "a" #f]
|
|
[(u64) 0 -1 (expt 2 64) "a" #f]
|
|
[(u8) 0 -1 (expt 2 8) "a" #f]
|
|
[(u8/s8) -1 'q (expt 2 8) (- -1 (expt 2 7)) #f]
|
|
[(ufixnum) 0 -1 (+ (most-positive-fixnum) 1) 'a #f]
|
|
[(uint) 0 -1 'a #f]
|
|
[(uinteger) 9.0 -1 -1.0 'a #f]
|
|
[(uptr) 0 -1 'a (+ *max-uptr 1) #f]
|
|
[(uptr/iptr) -1 'q (+ *max-uptr 1) (- *min-iptr 1) #f]
|
|
[(vector) '#(a) "a" #f]
|
|
[(who-condition) (make-who-condition 'me) (make-message-condition "hello") 'the-who]
|
|
[(who) 'who 17])
|
|
(meta-cond
|
|
[(memq 'pthreads feature*)
|
|
(declare-types
|
|
[(condition-object) (make-condition) "not a mutex" #f]
|
|
[(mutex) (make-mutex) "not a mutex" #f])])
|
|
ht))
|
|
(define (fuzz-prim-args name unprefixed-name lib* flag* in*/out**)
|
|
(define-syntax flags-set? (syntax-rules () [(_ x ...) (and (memq 'x flag*) ...)]))
|
|
(define good/bad
|
|
(lambda (in* k)
|
|
(unless (null? (remq '... (remq 'ptr in*)))
|
|
(let loop ([in* in*] [rgood* '()] [rbad** '()])
|
|
(if (null? in*)
|
|
(k (reverse rgood*) (reverse rbad**))
|
|
(let ([in (car in*)] [in* (cdr in*)])
|
|
(cond
|
|
[(eq? in '...)
|
|
(assert (not (null? rgood*)))
|
|
(let ([good (car rgood*)] [bad* (car rbad**)])
|
|
(loop in* (cdr rgood*) (cdr rbad**))
|
|
(loop in* rgood* rbad**)
|
|
(loop in* (cons good rgood*) (cons bad* rbad**))
|
|
(loop in* (cons* good good rgood*) (cons* bad* bad* rbad**)))]
|
|
[(pair? in)
|
|
(loop in*
|
|
(cons `'(quote ,(let f ([x in])
|
|
(cond
|
|
[(pair? x) (cons (f (car x)) (f (cdr x)))]
|
|
[(eq? x 'ptr) 0]
|
|
[else (errorf 'fuzz-prim-args "unhandled type ~s" in)])))
|
|
rgood*)
|
|
(cons '((quote ())) rbad**))]
|
|
[(symbol-hashtable-ref type-table in #f) =>
|
|
(lambda (good.bad*)
|
|
(loop in* (cons (car good.bad*) rgood*) (cons (cdr good.bad*) rbad**)))]
|
|
[else (errorf 'fuzz-prim-args "unhandled type ~s" in)])))))))
|
|
(when (flags-set? primitive proc)
|
|
(for-each
|
|
(lambda (in*)
|
|
(good/bad in*
|
|
(lambda (good* bad**)
|
|
(let loop ([good* good*] [bad** bad**] [rgood* '()])
|
|
(unless (null? good*)
|
|
(unless (or (memq 'no-good rgood*) (memq 'no-good (cdr good*)))
|
|
(for-each
|
|
(lambda (bad)
|
|
(let ([call `(,name ,@(reverse rgood*) ,bad ,@(cdr good*))])
|
|
(printf "testing ~s..." call)
|
|
(flush-output-port)
|
|
(let ([c (call/cc
|
|
(lambda (k)
|
|
(with-exception-handler
|
|
(lambda (c) (unless (warning? c) (k c)))
|
|
(lambda () (eval call env) #f))))])
|
|
(if c
|
|
(if (and (violation? c)
|
|
(not (and (syntax-violation? c)
|
|
(message-condition? c)
|
|
(equal? (condition-message c) "invalid syntax")))
|
|
(not (and (irritants-condition? c)
|
|
; split up so we can grep for "invalid memory reference" in mat output and not see this
|
|
(member (string-append "invalid" " " "memory reference") (condition-irritants c)))))
|
|
(begin
|
|
(display-condition c)
|
|
(newline))
|
|
(errorf 'fuzz-prim-args "unexpected exception occurred evaluating ~s: ~a" call
|
|
(with-output-to-string (lambda () (display-condition c)))))
|
|
(errorf 'fuzz-prim-args "no exception occurred evaluating ~s" call)))))
|
|
(car bad**)))
|
|
(loop (cdr good*) (cdr bad**) (cons (car good*) rgood*)))))))
|
|
(map car in*/out**))))
|
|
(meta-cond
|
|
[(file-exists? "../s/primdata.ss") (include "../s/primdata.ss")]
|
|
[else (include "../../s/primdata.ss")])
|
|
#t))
|
|
)
|
|
|
|
(mat nonprocedure-value
|
|
(begin
|
|
(for-each
|
|
(lambda (x)
|
|
(guard (c [else (unless (equal? (condition-message c) "variable ~:s is not bound")
|
|
(errorf #f "wrong error for ~s (~a)" x (with-output-to-string (lambda () (display-condition c)))))])
|
|
(parameterize ([optimize-level 2])
|
|
(eval `(,x)))
|
|
(errorf #f "no error for ~s" x)))
|
|
(remp (lambda (x) (or (top-level-bound? x) (top-level-syntax? x))) (oblist)))
|
|
#t)
|
|
(begin
|
|
(for-each
|
|
(lambda (x)
|
|
(guard (c [else (unless (equal? (condition-message c) "attempt to apply non-procedure ~s")
|
|
(errorf #f "wrong error for ~s (~a)" x (with-output-to-string (lambda () (display-condition c)))))])
|
|
(parameterize ([optimize-level 2])
|
|
(eval `(,x)))
|
|
(errorf #f "no error for ~s" x)))
|
|
(filter (lambda (x) (and (top-level-bound? x) (not (procedure? (top-level-value x))))) (oblist)))
|
|
#t)
|
|
)
|
|
|
|
(mat make-parameter
|
|
(begin (define p (make-parameter #f not)) #t)
|
|
(p)
|
|
(begin (p #f) (p))
|
|
(begin (p #t) (not (p)))
|
|
(begin (define q (make-parameter #t)) #t)
|
|
(q)
|
|
(begin (q #f) (not (q)))
|
|
(begin (q #t) (q))
|
|
(error? (make-parameter 1 2))
|
|
(begin
|
|
(define p
|
|
(make-parameter 5
|
|
(lambda (x) (+ x 1))))
|
|
#t)
|
|
(eqv? (p) 6)
|
|
(error? (p 'a))
|
|
(error? (make-parameter 3 (lambda (x y) x)))
|
|
)
|
|
|
|
(mat parameterize
|
|
(begin (define p (make-parameter #f not)) #t)
|
|
(begin (define q (make-parameter #t)) #t)
|
|
(begin (p #f) (p))
|
|
(begin (q #t) (q))
|
|
(parameterize ([p #t] [q #f])
|
|
(and (not (p)) (not (q))))
|
|
(not (p))
|
|
(q)
|
|
(parameterize () #t)
|
|
(eq? (parameterize () (define x 4) x) 4)
|
|
(let* ((x (make-parameter 'a)) (f (lambda () (x))))
|
|
(and
|
|
(parameterize ((x 'b))
|
|
(and (eq? (x) 'b) (eq? (f) 'b)))
|
|
(eq? (x) 'a)
|
|
(eq? (f) 'a)))
|
|
(let* ((x (make-parameter 'a)) (f (lambda () (x))))
|
|
(and
|
|
(call/cc
|
|
(lambda (return)
|
|
(parameterize ((x 'b))
|
|
(return (and (eq? (x) 'b) (eq? (f) 'b))))))
|
|
(eq? (x) 'a)
|
|
(eq? (f) 'a)))
|
|
(equal?
|
|
(let* ((x (make-parameter 'a)) (f (lambda () (x))))
|
|
((call/cc
|
|
(lambda (return)
|
|
(parameterize ((x 'b))
|
|
(call/cc
|
|
(lambda (back)
|
|
(return back)))
|
|
(let ((ans (f))) (lambda (y) (list ans (x)))))))
|
|
'()))
|
|
'(b a))
|
|
(error? ; invalid number of arguments to #<procedure x>
|
|
(let ([x (lambda (x) #t)]) (parameterize ([x 7]) 4)))
|
|
; make sure nothing silly happens if we parameterize the same parameter
|
|
(begin (define q (make-parameter 0)) #t)
|
|
(eqv? (parameterize ([q 2] [q 2]) (q)) 2)
|
|
(eqv? (q) 0)
|
|
)
|
|
|
|
(define id (lambda (x) x))
|
|
|
|
(define $big (+ (most-positive-fixnum) 1))
|
|
|
|
(define ok
|
|
(lambda (p v)
|
|
(parameterize ([p v]) (equal? (p) v))))
|
|
|
|
(mat case-sensitive
|
|
(case-sensitive)
|
|
(ok case-sensitive #f)
|
|
(ok case-sensitive #t)
|
|
)
|
|
|
|
(mat collect-generation-radix
|
|
(fxpositive? (collect-generation-radix))
|
|
(ok collect-generation-radix 1)
|
|
(error? (collect-generation-radix 'a))
|
|
(error? (collect-generation-radix -1))
|
|
(error? (collect-generation-radix 0))
|
|
)
|
|
|
|
(mat collect-notify
|
|
(not (collect-notify))
|
|
(ok collect-notify #t)
|
|
(ok collect-notify #f)
|
|
)
|
|
|
|
(mat collect-request-handler
|
|
(procedure? (collect-request-handler))
|
|
(ok collect-request-handler (collect-request-handler))
|
|
(error? (collect-request-handler #f))
|
|
)
|
|
|
|
(mat collect-trip-bytes
|
|
(fxpositive? (collect-trip-bytes))
|
|
(ok collect-trip-bytes 100)
|
|
(error? (collect-trip-bytes -100))
|
|
(error? (collect-trip-bytes $big))
|
|
)
|
|
|
|
(mat current-eval
|
|
(procedure? (current-eval))
|
|
(ok current-eval id)
|
|
(error? (current-eval '#()))
|
|
)
|
|
|
|
(mat current-input-port
|
|
(input-port? (current-input-port))
|
|
(ok current-input-port (open-input-string ""))
|
|
(error? (current-input-port (open-output-string)))
|
|
)
|
|
|
|
(mat current-output-port
|
|
(output-port? (current-output-port))
|
|
(ok current-output-port (open-output-string))
|
|
(error? (current-output-port (open-input-string "hello")))
|
|
)
|
|
|
|
(mat eval-syntax-expanders-when
|
|
(= (length (eval-syntax-expanders-when)) 3)
|
|
(equal?
|
|
(andmap (lambda (x) (memq x '(compile load eval)))
|
|
(eval-syntax-expanders-when))
|
|
'(eval))
|
|
(ok eval-syntax-expanders-when '(compile))
|
|
(ok eval-syntax-expanders-when '())
|
|
(error? (eval-syntax-expanders-when '(compiling)))
|
|
)
|
|
|
|
(mat generate-interrupt-trap
|
|
(generate-interrupt-trap)
|
|
(ok generate-interrupt-trap #t)
|
|
(ok generate-interrupt-trap #f)
|
|
)
|
|
|
|
(mat gensym-count
|
|
(nonnegative? (gensym-count))
|
|
(ok gensym-count 0)
|
|
(ok gensym-count $big)
|
|
(error? (gensym-count "g"))
|
|
)
|
|
|
|
(mat gensym-prefix
|
|
(string? (gensym-prefix))
|
|
(ok gensym-prefix "hi")
|
|
)
|
|
|
|
(mat keyboard-interrupt-handler
|
|
(procedure? (keyboard-interrupt-handler))
|
|
(ok keyboard-interrupt-handler id)
|
|
(error? (keyboard-interrupt-handler 0))
|
|
)
|
|
|
|
(mat optimize-level
|
|
(fx<= 0 (optimize-level) 3)
|
|
(ok optimize-level 0)
|
|
(ok optimize-level 1)
|
|
(ok optimize-level 2)
|
|
(ok optimize-level 3)
|
|
(error? (optimize-level 4))
|
|
)
|
|
|
|
(mat pretty-line-length
|
|
(fxpositive? (pretty-line-length))
|
|
(ok pretty-line-length 10)
|
|
(error? (pretty-line-length -1))
|
|
(error? (pretty-line-length $big))
|
|
)
|
|
|
|
(mat pretty-one-line-limit
|
|
(fxpositive? (pretty-one-line-limit))
|
|
(ok pretty-one-line-limit 100)
|
|
(error? (pretty-one-line-limit 0))
|
|
(error? (pretty-one-line-limit $big))
|
|
)
|
|
|
|
(mat print-gensym
|
|
(print-gensym)
|
|
(ok print-gensym #f)
|
|
(ok print-gensym #t)
|
|
(ok print-gensym 'pretty)
|
|
)
|
|
|
|
(mat print-graph
|
|
(not (print-graph))
|
|
(ok print-graph #f)
|
|
(ok print-graph #t)
|
|
)
|
|
|
|
(mat print-length
|
|
(not (print-length))
|
|
(ok print-length 100)
|
|
(ok print-length #f)
|
|
(error? (print-length -1))
|
|
(error? (print-length $big))
|
|
(error? (print-length '()))
|
|
)
|
|
|
|
(mat print-level
|
|
(not (print-level))
|
|
(ok print-level 100)
|
|
(ok print-level #f)
|
|
(error? (print-level -1))
|
|
(error? (print-level $big))
|
|
)
|
|
|
|
(mat print-radix
|
|
(fx= (print-radix) 10)
|
|
(ok print-radix 2)
|
|
(ok print-radix 36)
|
|
(error? (print-radix 37))
|
|
(error? (print-radix 1))
|
|
)
|
|
|
|
(mat timer-interrupt-handler
|
|
(procedure? (timer-interrupt-handler))
|
|
(ok timer-interrupt-handler id)
|
|
(error? (timer-interrupt-handler 'midnight))
|
|
)
|
|
|
|
(mat trace-output-port
|
|
(eq? (trace-output-port) (console-output-port))
|
|
(ok trace-output-port (open-output-string))
|
|
(error? (trace-output-port (open-input-string "hello")))
|
|
)
|
|
|