diff --git a/src/racket/src/hash.c b/src/racket/src/hash.c index 1dc23f6e64..70f9c8e16c 100644 --- a/src/racket/src/hash.c +++ b/src/racket/src/hash.c @@ -930,6 +930,7 @@ END_XFORM_SKIP; typedef struct Hash_Info { intptr_t depth; /* always odd */ Scheme_Object *recur; + Scheme_Object *insp; /* obtained lazily */ } Hash_Info; static uintptr_t equal_hash_key(Scheme_Object *o, uintptr_t k, Hash_Info *hi); @@ -942,6 +943,7 @@ static Scheme_Object *hash_recur(int argc, Scheme_Object **argv, Scheme_Object * hi = (Hash_Info *)SCHEME_PRIM_CLOSURE_ELS(prim)[0]; hi->depth += 2; + hi->insp = NULL; /* in case recursive call is `parameterize'd */ v = to_signed_hash(equal_hash_key(argv[0], 0, hi)); @@ -1297,8 +1299,16 @@ static uintptr_t equal_hash_key(Scheme_Object *o, uintptr_t k, Hash_Info *hi) } } else { Scheme_Object *insp; - insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); - if (scheme_inspector_sees_part(o, insp, -2)) { + if (scheme_struct_is_transparent(o)) + insp = NULL; + else { + insp = hi->insp; + if (!insp) { + insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); + hi->insp = insp; + } + } + if (!insp || scheme_inspector_sees_part(o, insp, -2)) { int i; Scheme_Structure *s1 = (Scheme_Structure *)o; @@ -1476,6 +1486,7 @@ intptr_t scheme_equal_hash_key(Scheme_Object *o) hi.depth = 1; hi.recur = NULL; + hi.insp = NULL; return to_signed_hash(equal_hash_key(o, 0, &hi)); } @@ -1486,6 +1497,7 @@ intptr_t scheme_equal_hash_key2(Scheme_Object *o) hi.depth = 1; hi.recur = NULL; + hi.insp = NULL; return to_signed_hash(equal_hash_key2(o, &hi)); } @@ -1753,8 +1765,15 @@ static uintptr_t equal_hash_key2(Scheme_Object *o, Hash_Info *hi) } } else { Scheme_Object *insp; - insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); - if (scheme_inspector_sees_part(o, insp, -2)) { + if (scheme_struct_is_transparent(o)) + insp = NULL; + else { + if (!insp) { + insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); + hi->insp = insp; + } + } + if (!insp || scheme_inspector_sees_part(o, insp, -2)) { int i; uintptr_t k = 0; Scheme_Structure *s1 = (Scheme_Structure *)o; diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index 7367a4819b..dc2eb7e9a0 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -817,6 +817,7 @@ typedef struct Scheme_Struct_Property { } Scheme_Struct_Property; int scheme_inspector_sees_part(Scheme_Object *s, Scheme_Object *insp, int pos); +int scheme_struct_is_transparent(Scheme_Object *s); typedef struct Scheme_Struct_Type { Scheme_Inclhash_Object iso; /* scheme_struct_type_type */ diff --git a/src/racket/src/struct.c b/src/racket/src/struct.c index 55e00f2076..b085de8a1d 100644 --- a/src/racket/src/struct.c +++ b/src/racket/src/struct.c @@ -3051,6 +3051,23 @@ int scheme_inspector_sees_part(Scheme_Object *s, Scheme_Object *insp, int pos) } } +int scheme_struct_is_transparent(Scheme_Object *s) +{ + Scheme_Struct_Type *stype; + int p; + + if (SCHEME_CHAPERONEP(s)) + s = SCHEME_CHAPERONE_VAL(s); + + stype = ((Scheme_Structure *)s)->stype; + + for (p = stype->name_pos; p--; ) { + if (SCHEME_TRUEP(stype->parent_types[p]->inspector)) + return 0; + } + + return 1; +} #define STRUCT_mPROCP(o, v) \ (SCHEME_PRIMP(o) && ((((Scheme_Primitive_Proc *)o)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK) == (v)))