fix hash-ref' bugs on immutable
eq?'-based tables
There were two: * new: after finding a hash code, the key wasn't always checked to be `eq?' to the desired key * old: the hash code wan't downshifted by 2, so changes in the low two bits (like when a pair is determined to start a list) could break lookup Merge to 5.1.2
This commit is contained in:
parent
35c9bd90ab
commit
e765231dad
|
@ -2388,9 +2388,11 @@
|
|||
(check-all-bad hash-iterate-key)
|
||||
(check-all-bad hash-iterate-value))
|
||||
|
||||
(test (list 1 2 3) hash-keys #hasheq((1 . a)(2 . b)(3 . c)))
|
||||
(test (list 'a 'b 'c) hash-values #hasheq((1 . a)(2 . b)(3 . c)))
|
||||
(test (list (cons 1 'a) (cons 2 'b) (cons 3 'c)) hash->list #hasheq((1 . a)(2 . b)(3 . c)))
|
||||
(test (list 1 2 3) sort (hash-keys #hasheq((1 . a) (2 . b) (3 . c))) <)
|
||||
(test (list 'a 'b 'c)
|
||||
sort (hash-values #hasheq((1 . a) (2 . b) (3 . c))) string<? #:key symbol->string)
|
||||
(test (list (cons 1 'a) (cons 2 'b) (cons 3 'c))
|
||||
sort (hash->list #hasheq((1 . a) (2 . b) (3 . c))) < #:key car)
|
||||
|
||||
(err/rt-test (hash-set*! im-t 1 2) exn:fail?)
|
||||
(err/rt-test (hash-set* (make-hasheq null) 1 2) exn:fail?)
|
||||
|
@ -2495,6 +2497,19 @@
|
|||
(test (equal-hash-code ht) values (equal-hash-code ht2))
|
||||
(test (equal-secondary-hash-code ht) values (equal-secondary-hash-code ht2))))
|
||||
|
||||
;; Check that immutable hash trees aren't confused by an
|
||||
;; "is a list" bit set in a key:
|
||||
(let ()
|
||||
(define p (list 1 2 3 4))
|
||||
(define ht (hasheq p 1 'a 7 'b 10 'c 13))
|
||||
(test 1 hash-ref ht p #f)
|
||||
(list? p)
|
||||
(list? p)
|
||||
(list? (list* 1 2 p))
|
||||
(list? (list* 1 2 p))
|
||||
(list? (list* 1 2 p))
|
||||
(test 1 hash-ref ht p #f))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Misc
|
||||
|
||||
|
|
|
@ -2276,6 +2276,7 @@ Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *ke
|
|||
}
|
||||
} else {
|
||||
h = PTR_TO_LONG((Scheme_Object *)key);
|
||||
h = h >> 2;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
|
@ -2417,6 +2418,7 @@ Scheme_Object *scheme_eq_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *ke
|
|||
RBNode *rb;
|
||||
|
||||
h = PTR_TO_LONG((Scheme_Object *)key);
|
||||
h = h >> 2;
|
||||
|
||||
rb = rb_find(h, tree->root);
|
||||
if (rb) {
|
||||
|
@ -2429,7 +2431,7 @@ Scheme_Object *scheme_eq_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *ke
|
|||
return SCHEME_CDR(a);
|
||||
prs = SCHEME_CDR(prs);
|
||||
}
|
||||
} else
|
||||
} else if (SAME_OBJ(rb->key, key))
|
||||
return rb->val;
|
||||
}
|
||||
|
||||
|
|
|
@ -258,12 +258,6 @@ typedef struct Thread_Cell {
|
|||
Scheme_Object so;
|
||||
char inherited, assigned;
|
||||
Scheme_Object *def_val;
|
||||
/* A thread's thread_cell table maps cells to keys weakly.
|
||||
This table maps keys to values weakly. The two weak
|
||||
levels ensure that thread cells are properly GCed
|
||||
when the value of a thread cell references the thread
|
||||
cell. */
|
||||
Scheme_Bucket_Table *vals;
|
||||
} Thread_Cell;
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
|
|
Loading…
Reference in New Issue
Block a user