fix problem with chaperone of chaperoned hash

This commit is contained in:
Matthew Flatt 2010-05-05 09:23:36 -06:00
parent a60a083802
commit 27cd77c16c
3 changed files with 39 additions and 4 deletions

View File

@ -250,7 +250,7 @@ application) operations on the chaperoned hash table redirected. When
@scheme[hash-set] or @scheme[hash-remove] is used on a chaperoned hash @scheme[hash-set] or @scheme[hash-remove] is used on a chaperoned hash
table, the resulting hash table is given all of the chaperones of the table, the resulting hash table is given all of the chaperones of the
given hash table. In addition, operations like given hash table. In addition, operations like
@scheme[hash-iterate-key] or @scheme[hash-iterate-map], which extract @scheme[hash-iterate-key] or @scheme[hash-map], which extract
keys from the table, use @scheme[key-proc] to filter keys extracted keys from the table, use @scheme[key-proc] to filter keys extracted
from the table. Operations like @scheme[hash-iterate-value] or from the table. Operations like @scheme[hash-iterate-value] or
@scheme[hash-iterate-map] implicitly use @scheme[hash-ref] and @scheme[hash-iterate-map] implicitly use @scheme[hash-ref] and

View File

@ -626,6 +626,37 @@
;; ---------------------------------------- ;; ----------------------------------------
(letrec ([wrap
(lambda (v)
(cond
[(hash? v)
(chaperone-hash v
(lambda (h k)
(values (wrap k)
(lambda (h k v) (wrap v))))
(lambda (h k v)
(values (wrap k) (wrap v)))
(lambda (h k)
(wrap k))
(lambda (h k)
(wrap k)))]
[(procedure? v) (chaperone-procedure
v
(lambda args
(apply values
(lambda args
(apply values (map wrap args)))
(map wrap args))))]
[(number? v) v]
[else (error 'wrap "cannot wrap: ~v" v)]))])
(let ([ht (wrap (wrap (make-hash)))])
(hash-set! ht add1 sub1)
(test 9 (hash-ref ht add1) 10)
(test '(10) 'for-hash (for/list ([(k v) (in-hash ht)])
(k (v 10))))))
;; ----------------------------------------
(let () (let ()
(define-struct a (x y) #:transparent) (define-struct a (x y) #:transparent)
(let* ([a1 (make-a 1 2)] (let* ([a1 (make-a 1 2)]

View File

@ -2692,6 +2692,7 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem
while (1) { while (1) {
if (!SCHEME_NP_CHAPERONEP(o)) { if (!SCHEME_NP_CHAPERONEP(o)) {
if (mode == 0) { if (mode == 0) {
/* hash-ref */
if (SCHEME_HASHTP(o)) if (SCHEME_HASHTP(o))
return scheme_hash_get((Scheme_Hash_Table *)o, k); return scheme_hash_get((Scheme_Hash_Table *)o, k);
else if (SCHEME_HASHTRP(o)) else if (SCHEME_HASHTRP(o))
@ -2699,6 +2700,7 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem
else else
return scheme_lookup_in_table((Scheme_Bucket_Table *)o, (const char *)k); return scheme_lookup_in_table((Scheme_Bucket_Table *)o, (const char *)k);
} else if ((mode == 1) || (mode == 2)) { } else if ((mode == 1) || (mode == 2)) {
/* hash-set! or hash-remove! */
if (SCHEME_HASHTP(o)) if (SCHEME_HASHTP(o))
scheme_hash_set((Scheme_Hash_Table *)o, k, v); scheme_hash_set((Scheme_Hash_Table *)o, k, v);
else if (SCHEME_HASHTRP(o)) { else if (SCHEME_HASHTRP(o)) {
@ -2734,9 +2736,10 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem
if (mode == 0) if (mode == 0)
orig = NULL; orig = NULL;
else if (mode == 3) else if (mode == 3) {
orig = chaperone_hash_op(who, px->prev, k, v, mode); orig = chaperone_hash_op(who, px->prev, k, v, mode);
else if (mode == 2) k = orig;
} else if (mode == 2)
orig = k; orig = k;
else else
orig = v; orig = v;
@ -2753,7 +2756,7 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem
a[2] = orig; a[2] = orig;
if ((mode == 0) || (mode == 1)) { if ((mode == 0) || (mode == 1)) {
/* hash-set! */ /* hash-ref or hash-set! */
Scheme_Object **vals; Scheme_Object **vals;
int cnt; int cnt;
Scheme_Thread *p; Scheme_Thread *p;
@ -2790,6 +2793,7 @@ static Scheme_Object *chaperone_hash_op(const char *who, Scheme_Object *o, Schem
o = vals[1]; o = vals[1];
if (mode == 0) { if (mode == 0) {
/* hash-ref */
red = o; red = o;
if (!scheme_check_proc_arity(NULL, 3, 1, 2, vals)) if (!scheme_check_proc_arity(NULL, 3, 1, 2, vals))
scheme_raise_exn(MZEXN_FAIL_CONTRACT, scheme_raise_exn(MZEXN_FAIL_CONTRACT,