@@ -31,6 +31,18 @@ init_MY_CXT(pTHX_ pMY_CXT)
31
31
SvREADONLY_on (MY_CXT .sv_ISA );
32
32
}
33
33
34
+ static SV *
35
+ S_mro_newSVsvhekok (pTHX_ SV * sv )
36
+ {
37
+ char * pv = SvPVX (sv );
38
+ if ( ((SvFLAGS (sv ) & (SVf_POK |SVs_GMG )) == SVf_POK )
39
+ && SvIsCOW_shared_hash (sv ))
40
+ return newSVhek (SvSHARED_HEK_FROM_PV (pv ));
41
+ else
42
+ return newSVsv (sv );
43
+ }
44
+ #define mro_newSVsvhekok (_sv ) S_mro_newSVsvhekok(aTHX_ _sv)
45
+
34
46
/*
35
47
=for apidoc mro_get_linear_isa_c3
36
48
@@ -110,7 +122,7 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
110
122
/* if no stash, make a temporary fake MRO
111
123
containing just itself */
112
124
AV * const isa_lin = newAV_alloc_xz (4 );
113
- av_push_simple (isa_lin , newSVsv (isa_item ));
125
+ av_push_simple (isa_lin , mro_newSVsvhekok (isa_item ));
114
126
av_push_simple (seqs , MUTABLE_SV (isa_lin ));
115
127
}
116
128
else {
@@ -139,16 +151,17 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
139
151
/* First entry is this class. We happen to make a shared
140
152
hash key scalar because it's the cheapest and fastest
141
153
way to do it. */
142
- * svp ++ = newSVhek (stashhek );
154
+ * svp ++ = newSVhek (stashhek ); /* Ex: Diamond_A */
143
155
144
156
while (subrv_items -- ) {
145
157
/* These values are unlikely to be shared hash key
146
158
scalars, so no point in adding code to optimising
147
159
for a case that is unlikely to be true.
148
160
(Or prove me wrong and do it.) */
149
-
161
+ /* Update: Example SVPV HEK*s seen on this line:
162
+ MRO_A MRO_B Diamond_A */
150
163
SV * const val = * subrv_p ++ ;
151
- * svp ++ = newSVsv (val );
164
+ * svp ++ = mro_newSVsvhekok (val );
152
165
}
153
166
154
167
SvREFCNT_inc (retval );
@@ -223,7 +236,9 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
223
236
&& (val = HeVAL (tail_entry ))
224
237
&& (SvIVX (val ) > 0 ))
225
238
continue ;
226
- winner = newSVsv (cand );
239
+ /* Examples: SVPVHEK*s MRO_A HEK Diamond_B or a 0xd byte
240
+ unprintable string. Rarely a NewXed buffer like "Test::O" */
241
+ winner = mro_newSVsvhekok (cand );
227
242
av_push_simple (retval , winner );
228
243
/* note however that even when we find a winner,
229
244
we continue looping over @seqs to do housekeeping */
@@ -371,7 +386,7 @@ mro_get_linear_isa(...)
371
386
if (!class_stash ) {
372
387
/* No stash exists yet, give them just the classname */
373
388
AV * isalin = newAV_alloc_xz (4 );
374
- av_push_simple (isalin , newSVsv (classname ));
389
+ av_push_simple (isalin , mro_newSVsvhekok (classname ));
375
390
ST (0 ) = sv_2mortal (newRV_noinc (MUTABLE_SV (isalin )));
376
391
XSRETURN (1 );
377
392
}
0 commit comments