@@ -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
@@ -113,7 +125,7 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
113
125
/* if no stash, make a temporary fake MRO
114
126
containing just itself */
115
127
AV * const isa_lin = newAV_alloc_xz (4 );
116
- av_push_simple (isa_lin , newSVsv (isa_item ));
128
+ av_push_simple (isa_lin , mro_newSVsvhekok (isa_item ));
117
129
av_push_simple (seqs , MUTABLE_SV (isa_lin ));
118
130
}
119
131
else {
@@ -142,16 +154,17 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
142
154
/* First entry is this class. We happen to make a shared
143
155
hash key scalar because it's the cheapest and fastest
144
156
way to do it. */
145
- * svp ++ = newSVhek (stashhek );
157
+ * svp ++ = newSVhek (stashhek ); /* Ex: Diamond_A */
146
158
147
159
while (subrv_items -- ) {
148
160
/* These values are unlikely to be shared hash key
149
161
scalars, so no point in adding code to optimising
150
162
for a case that is unlikely to be true.
151
163
(Or prove me wrong and do it.) */
152
-
164
+ /* Update: Example SVPV HEK*s seen on this line:
165
+ MRO_A MRO_B Diamond_A */
153
166
SV * const val = * subrv_p ++ ;
154
- * svp ++ = newSVsv (val );
167
+ * svp ++ = mro_newSVsvhekok (val );
155
168
}
156
169
157
170
SvREFCNT_inc (retval );
@@ -226,7 +239,9 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
226
239
&& (val = HeVAL (tail_entry ))
227
240
&& (SvIVX (val ) > 0 ))
228
241
continue ;
229
- winner = newSVsv (cand );
242
+ /* Examples: SVPVHEK*s MRO_A HEK Diamond_B or a 0xd byte
243
+ unprintable string. Rarely a NewXed buffer like "Test::O" */
244
+ winner = mro_newSVsvhekok (cand );
230
245
av_push_simple (retval , winner );
231
246
/* note however that even when we find a winner,
232
247
we continue looping over @seqs to do housekeeping */
@@ -374,7 +389,7 @@ mro_get_linear_isa(...)
374
389
if (!class_stash ) {
375
390
/* No stash exists yet, give them just the classname */
376
391
AV * isalin = newAV_alloc_xz (4 );
377
- av_push_simple (isalin , newSVsv (classname ));
392
+ av_push_simple (isalin , mro_newSVsvhekok (classname ));
378
393
ST (0 ) = sv_2mortal (newRV_noinc (MUTABLE_SV (isalin )));
379
394
XSRETURN (1 );
380
395
}
0 commit comments