(load-relative "loadtest.ss") (Section 'deep) ; Test deep stacks (define (nontail-loop n esc) (let loop ([n n]) (if (zero? n) (esc 0) (sub1 (loop (sub1 n)))))) (define proc-depth (find-depth (lambda (n) (nontail-loop n (lambda (x) x))))) (printf "non-tail loop overflows at ~a~n" proc-depth) (test (- proc-depth) 'deep-recursion (nontail-loop proc-depth (lambda (x) x))) (test 0 'deep-recursion-escape/ec (let/ec k (nontail-loop proc-depth k))) (test 0 'deep-recursion-escape/cc (let/cc k (nontail-loop proc-depth k))) (test 0 'deep-recursion-resume/escape ((let/ec k (nontail-loop proc-depth (lambda (v) (let/cc inside (k inside)) (k (lambda () 0))))))) (test 0 'deep-recursion-resume/abort (call-with-continuation-prompt (lambda () (nontail-loop proc-depth (lambda (v) (abort-current-continuation (default-continuation-prompt-tag) (lambda () 0))))))) (test 0 'deep-recursion-resume/escape/thread (let ([v #f]) (thread-wait (thread (lambda () (set! v ((let/ec k (nontail-loop proc-depth (lambda (v) (let/cc inside (k (lambda () (thread-wait (thread inside)) 0))) (k (lambda () 0)))))))))) v)) (test (- proc-depth) 'deep-recursion-resume ((lambda (x) (if (procedure? x) (x) x)) (let/ec k (nontail-loop proc-depth (lambda (v) (let/cc inside (k inside)) 0))))) (define (read-deep depth) (define paren-port (let* ([depth depth] [closing? #f] [count depth]) (make-input-port 'name (lambda (s) (bytes-set! s 0 (cond [closing? (if (= count depth) eof (begin (set! count (add1 count)) (char->integer #\)) ))] [else (set! count (sub1 count)) (when (zero? count) (set! closing? #t)) (char->integer #\()])) 1) #f void))) (read paren-port)) (define read-depth (find-depth read-deep)) (printf "nested paren read overflows at ~a~n" read-depth) (define deep-list (read-deep read-depth)) (test #t 'read-deep (pair? deep-list)) (define s (open-output-string)) (display deep-list s) (test 'ok 'display 'ok) (test #t 'equal? (equal? deep-list (read (open-input-string (get-output-string s))))) (define (try-pairs mk-a mk-d cons) (let () (define l1 (mk-a 0)) (define l2 (mk-a 0)) (define l3 (mk-a 1)) (test #t equal? l1 l2) (test #f equal? l1 l3) (test #t equal? (cons l1 l3) (cons l2 l3)) (test #f equal? (cons l1 l2) (cons l2 l3)) (test #t = (equal-hash-code l1) (equal-hash-code l2))) (let () (define l1 (mk-d #f)) (define l2 (mk-d #f)) (define l3 (mk-d #t)) (test #t equal? l1 l2) (test #f equal? l1 l3) (test #t equal? (cons l1 l3) (cons l2 l3)) (test #f equal? (cons l1 l2) (cons l2 l3)) (test #t = (equal-hash-code l1) (equal-hash-code l2)))) (try-pairs (lambda (v) (read (open-input-string (format "#0=(cons ~a #0#)" v)))) (lambda (v) (read (open-input-string (format "#0=(cons #0# ~a)" v)))) cons) (try-pairs (lambda (v) (let ([p (mcons v v)]) (set-mcdr! p p) p)) (lambda (v) (let ([p (mcons v v)]) (set-mcar! p p) p)) mcons) (define (vec-test i) (define l1 (vector 0 0)) (define l2 (vector 0 0)) (define l3 (vector 1 1)) (vector-set! l1 i l1) (vector-set! l2 i l2) (vector-set! l3 i l3) (test #t equal? l1 l2) (test #f equal? l1 l3) (test #t equal? (vector l1 l3) (vector l2 l3)) (test #f equal? (vector l1 l2) (vector l2 l3)) (test #t = (equal-hash-code l1) (equal-hash-code l2))) (vec-test 0) (vec-test 1) (define-struct a (b c) #:inspector (make-inspector) #:mutable) (define l1 (make-a 0 #f)) (set-a-b! l1 l1) (define l2 (make-a 0 #f)) (set-a-b! l2 l2) (define l3 (make-a 0 #t)) (set-a-b! l3 l2) (test #t equal? l1 l2) (test #f equal? l1 l3) (test #t equal? (make-a l1 l3) (make-a l2 l3)) (test #f equal? (make-a l1 l2) (make-a l2 l3)) (test #t = (equal-hash-code l1) (equal-hash-code l2)) (define l1 (box 0)) (set-box! l1 l1) (define l2 (box 0)) (set-box! l2 l2) (test #t equal? l1 l2) (test #t = (equal-hash-code l1) (equal-hash-code l2)) ;; ---------------------------------------- ;; Overflow in hashing: (define (hash-deep n) (let loop ([n n][a null]) (if (zero? n) a (loop (sub1 n) (list a "apple"))))) (define (init-hash-table ht) (let loop ([n 25]) (unless (zero? n) (hash-set! ht (gensym) (gensym)) (loop (sub1 n))))) (define hash-depth (let ([ht (make-hash)]) (init-hash-table ht) (find-depth (lambda (n) (nontail-loop (quotient proc-depth 3) (lambda (x) (hash-set! ht (hash-deep n) #t) x)))))) (printf "hashing overflows at ~a\n" hash-depth) (define (try-deep-hash hash-depth put-depth get-depth) (let* ([ht (make-hash)] [val (gensym)] [key (hash-deep hash-depth)] [code (equal-hash-code key)]) (init-hash-table ht) (nontail-loop put-depth (lambda (x) (test code 'code (equal-hash-code key)) (hash-set! ht key val) x)) (nontail-loop get-depth (lambda (x) (test code 'code (equal-hash-code key)) (test val 'deep-hash (hash-ref ht key)) x)))) (for-each (lambda (hash-depth) (for-each (lambda (proc-depth) (try-deep-hash hash-depth 0 proc-depth)) (list 0 (quotient proc-depth 2) (quotient proc-depth 3) (quotient proc-depth 4)))) (list hash-depth (* 2 hash-depth) (quotient hash-depth 2))) ;; ---------------------------------------- (report-errs)