Change 34627 didn't realise that if S_find_uninit_var() takes a
[p5sagit/p5-mst-13.2.git] / mro.c
CommitLineData
e1a479c5 1/* mro.c
2 *
3 * Copyright (c) 2007 Brandon L Black
1129b882 4 * Copyright (c) 2007, 2008 Larry Wall and others
e1a479c5 5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
9 */
10
11/*
cac98860 12 * "Which order shall we go in?" said Frodo. "Eldest first, or quickest first?
13 * You'll be last either way, Master Peregrin."
14 */
15
16/*
e1a479c5 17=head1 MRO Functions
18
19These functions are related to the method resolution order of perl classes
20
21=cut
22*/
23
24#include "EXTERN.h"
4befac30 25#define PERL_IN_MRO_C
e1a479c5 26#include "perl.h"
27
3d76853f 28struct mro_alg {
29 const char *name;
30 AV *(*resolve)(pTHX_ HV* stash, I32 level);
31};
32
33/* First one is the default */
34static struct mro_alg mros[] = {
35 {"dfs", S_mro_get_linear_isa_dfs},
36 {"c3", S_mro_get_linear_isa_c3}
37};
38
39#define NUMBER_OF_MROS (sizeof(mros)/sizeof(struct mro_alg))
40
41static const struct mro_alg *
42S_get_mro_from_name(pTHX_ const char *const name) {
43 const struct mro_alg *algo = mros;
44 const struct mro_alg *const end = mros + NUMBER_OF_MROS;
45 while (algo < end) {
46 if(strEQ(name, algo->name))
47 return algo;
48 ++algo;
49 }
50 return NULL;
51}
52
e1a479c5 53struct mro_meta*
54Perl_mro_meta_init(pTHX_ HV* stash)
55{
9fe4aecf 56 struct mro_meta* newmeta;
e1a479c5 57
7918f24d 58 PERL_ARGS_ASSERT_MRO_META_INIT;
e1a479c5 59 assert(HvAUX(stash));
60 assert(!(HvAUX(stash)->xhv_mro_meta));
183086be 61 Newxz(newmeta, 1, struct mro_meta);
9fe4aecf 62 HvAUX(stash)->xhv_mro_meta = newmeta;
dd69841b 63 newmeta->cache_gen = 1;
70cd14a1 64 newmeta->pkg_gen = 1;
edf2cad7 65 newmeta->mro_which = mros;
e1a479c5 66
67 return newmeta;
68}
69
70#if defined(USE_ITHREADS)
71
72/* for sv_dup on new threads */
73struct mro_meta*
74Perl_mro_meta_dup(pTHX_ struct mro_meta* smeta, CLONE_PARAMS* param)
75{
e1a479c5 76 struct mro_meta* newmeta;
77
7918f24d 78 PERL_ARGS_ASSERT_MRO_META_DUP;
e1a479c5 79
33e12d9d 80 Newx(newmeta, 1, struct mro_meta);
81 Copy(smeta, newmeta, 1, struct mro_meta);
82
83 if (newmeta->mro_linear_dfs)
84 newmeta->mro_linear_dfs
502c6561 85 = MUTABLE_AV(SvREFCNT_inc(sv_dup((SV*)newmeta->mro_linear_dfs, param)));
33e12d9d 86 if (newmeta->mro_linear_c3)
87 newmeta->mro_linear_c3
502c6561 88 = MUTABLE_AV(SvREFCNT_inc(sv_dup((SV*)newmeta->mro_linear_c3, param)));
33e12d9d 89 if (newmeta->mro_nextmethod)
90 newmeta->mro_nextmethod
85fbaab2 91 = MUTABLE_HV(SvREFCNT_inc(sv_dup((SV*)newmeta->mro_nextmethod, param)));
a49ba3fc 92 if (newmeta->isa)
93 newmeta->isa
85fbaab2 94 = MUTABLE_HV(SvREFCNT_inc(sv_dup((SV*)newmeta->isa, param)));
e1a479c5 95
96 return newmeta;
97}
98
99#endif /* USE_ITHREADS */
100
a49ba3fc 101HV *
102Perl_get_isa_hash(pTHX_ HV *const stash)
103{
104 dVAR;
105 struct mro_meta *const meta = HvMROMETA(stash);
106
107 PERL_ARGS_ASSERT_GET_ISA_HASH;
108
6e4aef59 109 if (!meta->isa) {
110 AV *const isa = mro_get_linear_isa(stash);
111 if (!meta->isa) {
112 HV *const isa_hash = newHV();
113 /* Linearisation didn't build it for us, so do it here. */
114 SV *const *svp = AvARRAY(isa);
115 SV *const *const svp_end = svp + AvFILLp(isa) + 1;
116 const HEK *const canon_name = HvNAME_HEK(stash);
117
118 while (svp < svp_end) {
119 (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
120 }
121
122 (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
123 HEK_LEN(canon_name), HEK_FLAGS(canon_name),
124 HV_FETCH_ISSTORE, &PL_sv_undef,
125 HEK_HASH(canon_name));
126 (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
127
ed09b296 128 SvREADONLY_on(isa_hash);
129
6e4aef59 130 meta->isa = isa_hash;
131 }
132 }
a49ba3fc 133 return meta->isa;
134}
135
e1a479c5 136/*
137=for apidoc mro_get_linear_isa_dfs
138
139Returns the Depth-First Search linearization of @ISA
140the given stash. The return value is a read-only AV*.
141C<level> should be 0 (it is used internally in this
142function's recursion).
143
1c908217 144You are responsible for C<SvREFCNT_inc()> on the
145return value if you plan to store it anywhere
146semi-permanently (otherwise it might be deleted
147out from under you the next time the cache is
148invalidated).
149
e1a479c5 150=cut
151*/
4befac30 152static AV*
153S_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
e1a479c5 154{
155 AV* retval;
156 GV** gvp;
157 GV* gv;
158 AV* av;
190d0b22 159 const HEK* stashhek;
e1a479c5 160 struct mro_meta* meta;
a49ba3fc 161 SV *our_name;
162 HV *stored;
e1a479c5 163
7918f24d 164 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA_DFS;
e1a479c5 165 assert(HvAUX(stash));
166
190d0b22 167 stashhek = HvNAME_HEK(stash);
168 if (!stashhek)
1e05feb3 169 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
e1a479c5 170
171 if (level > 100)
172 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
190d0b22 173 HEK_KEY(stashhek));
e1a479c5 174
175 meta = HvMROMETA(stash);
1c908217 176
177 /* return cache if valid */
e1a479c5 178 if((retval = meta->mro_linear_dfs)) {
e1a479c5 179 return retval;
180 }
181
182 /* not in cache, make a new one */
1c908217 183
502c6561 184 retval = MUTABLE_AV(sv_2mortal((SV *)newAV()));
a49ba3fc 185 /* We use this later in this function, but don't need a reference to it
186 beyond the end of this function, so reference count is fine. */
187 our_name = newSVhek(stashhek);
188 av_push(retval, our_name); /* add ourselves at the top */
e1a479c5 189
1c908217 190 /* fetch our @ISA */
e1a479c5 191 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
192 av = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
193
a49ba3fc 194 /* "stored" is used to keep track of all of the classnames we have added to
195 the MRO so far, so we can do a quick exists check and avoid adding
196 duplicate classnames to the MRO as we go.
197 It's then retained to be re-used as a fast lookup for ->isa(), by adding
198 our own name and "UNIVERSAL" to it. */
199
85fbaab2 200 stored = MUTABLE_HV(sv_2mortal((SV*)newHV()));
1c908217 201
a49ba3fc 202 if(av && AvFILLp(av) >= 0) {
1c908217 203
ffd8da72 204 SV **svp = AvARRAY(av);
205 I32 items = AvFILLp(av) + 1;
1c908217 206
207 /* foreach(@ISA) */
e1a479c5 208 while (items--) {
209 SV* const sv = *svp++;
210 HV* const basestash = gv_stashsv(sv, 0);
ffd8da72 211 SV *const *subrv_p;
212 I32 subrv_items;
e1a479c5 213
214 if (!basestash) {
1c908217 215 /* if no stash exists for this @ISA member,
216 simply add it to the MRO and move on */
ffd8da72 217 subrv_p = &sv;
218 subrv_items = 1;
e1a479c5 219 }
220 else {
1c908217 221 /* otherwise, recurse into ourselves for the MRO
b1d0c68a 222 of this @ISA member, and append their MRO to ours.
223 The recursive call could throw an exception, which
224 has memory management implications here, hence the use of
225 the mortal. */
ffd8da72 226 const AV *const subrv
227 = mro_get_linear_isa_dfs(basestash, level + 1);
228
229 subrv_p = AvARRAY(subrv);
230 subrv_items = AvFILLp(subrv) + 1;
231 }
232 while(subrv_items--) {
233 SV *const subsv = *subrv_p++;
8e45cc2b 234 /* LVALUE fetch will create a new undefined SV if necessary
235 */
236 HE *const he = hv_fetch_ent(stored, subsv, 1, 0);
237 assert(he);
238 if(HeVAL(he) != &PL_sv_undef) {
239 /* It was newly created. Steal it for our new SV, and
240 replace it in the hash with the "real" thing. */
241 SV *const val = HeVAL(he);
f46ee248 242 HEK *const key = HeKEY_hek(he);
8e45cc2b 243
244 HeVAL(he) = &PL_sv_undef;
f46ee248 245 /* Save copying by making a shared hash key scalar. We
246 inline this here rather than calling Perl_newSVpvn_share
247 because we already have the scalar, and we already have
248 the hash key. */
249 assert(SvTYPE(val) == SVt_NULL);
250 sv_upgrade(val, SVt_PV);
251 SvPV_set(val, HEK_KEY(share_hek_hek(key)));
252 SvCUR_set(val, HEK_LEN(key));
253 SvREADONLY_on(val);
254 SvFAKE_on(val);
255 SvPOK_on(val);
256 if (HEK_UTF8(key))
257 SvUTF8_on(val);
258
8e45cc2b 259 av_push(retval, val);
ffd8da72 260 }
e1a479c5 261 }
262 }
263 }
264
ed09b296 265 (void) hv_store_ent(stored, our_name, &PL_sv_undef, 0);
266 (void) hv_store(stored, "UNIVERSAL", 9, &PL_sv_undef, 0);
267
268 SvREFCNT_inc_simple_void_NN(stored);
269 SvTEMP_off(stored);
270 SvREADONLY_on(stored);
271
272 meta->isa = stored;
273
0fd7ece8 274 /* now that we're past the exception dangers, grab our own reference to
275 the AV we're about to use for the result. The reference owned by the
276 mortals' stack will be released soon, so everything will balance. */
277 SvREFCNT_inc_simple_void_NN(retval);
278 SvTEMP_off(retval);
fdef73f9 279
1c908217 280 /* we don't want anyone modifying the cache entry but us,
281 and we do so by replacing it completely */
e1a479c5 282 SvREADONLY_on(retval);
1c908217 283
e1a479c5 284 meta->mro_linear_dfs = retval;
285 return retval;
286}
287
288/*
289=for apidoc mro_get_linear_isa_c3
290
291Returns the C3 linearization of @ISA
292the given stash. The return value is a read-only AV*.
293C<level> should be 0 (it is used internally in this
294function's recursion).
295
1c908217 296You are responsible for C<SvREFCNT_inc()> on the
297return value if you plan to store it anywhere
298semi-permanently (otherwise it might be deleted
299out from under you the next time the cache is
300invalidated).
301
e1a479c5 302=cut
303*/
304
4befac30 305static AV*
306S_mro_get_linear_isa_c3(pTHX_ HV* stash, I32 level)
e1a479c5 307{
308 AV* retval;
309 GV** gvp;
310 GV* gv;
311 AV* isa;
190d0b22 312 const HEK* stashhek;
e1a479c5 313 struct mro_meta* meta;
314
7918f24d 315 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA_C3;
e1a479c5 316 assert(HvAUX(stash));
317
190d0b22 318 stashhek = HvNAME_HEK(stash);
319 if (!stashhek)
1e05feb3 320 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
e1a479c5 321
322 if (level > 100)
323 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
190d0b22 324 HEK_KEY(stashhek));
e1a479c5 325
326 meta = HvMROMETA(stash);
1c908217 327
328 /* return cache if valid */
e1a479c5 329 if((retval = meta->mro_linear_c3)) {
e1a479c5 330 return retval;
331 }
332
333 /* not in cache, make a new one */
334
e1a479c5 335 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
336 isa = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
337
1c908217 338 /* For a better idea how the rest of this works, see the much clearer
339 pure perl version in Algorithm::C3 0.01:
340 http://search.cpan.org/src/STEVAN/Algorithm-C3-0.01/lib/Algorithm/C3.pm
341 (later versions go about it differently than this code for speed reasons)
342 */
8638e433 343
e1a479c5 344 if(isa && AvFILLp(isa) >= 0) {
345 SV** seqs_ptr;
346 I32 seqs_items;
85fbaab2 347 HV* const tails = MUTABLE_HV(sv_2mortal((SV*)newHV()));
502c6561 348 AV *const seqs = MUTABLE_AV(sv_2mortal((SV*)newAV()));
8638e433 349 I32* heads;
350
351 /* This builds @seqs, which is an array of arrays.
352 The members of @seqs are the MROs of
353 the members of @ISA, followed by @ISA itself.
354 */
e1a479c5 355 I32 items = AvFILLp(isa) + 1;
356 SV** isa_ptr = AvARRAY(isa);
357 while(items--) {
1e05feb3 358 SV* const isa_item = *isa_ptr++;
359 HV* const isa_item_stash = gv_stashsv(isa_item, 0);
e1a479c5 360 if(!isa_item_stash) {
8638e433 361 /* if no stash, make a temporary fake MRO
362 containing just itself */
70cd14a1 363 AV* const isa_lin = newAV();
e1a479c5 364 av_push(isa_lin, newSVsv(isa_item));
70cd14a1 365 av_push(seqs, (SV*)isa_lin);
e1a479c5 366 }
367 else {
70cd14a1 368 /* recursion */
369 AV* const isa_lin = mro_get_linear_isa_c3(isa_item_stash, level + 1);
370 av_push(seqs, SvREFCNT_inc_simple_NN((SV*)isa_lin));
e1a479c5 371 }
e1a479c5 372 }
1dcae283 373 av_push(seqs, SvREFCNT_inc_simple_NN((SV*)isa));
8638e433 374
375 /* This builds "heads", which as an array of integer array
376 indices, one per seq, which point at the virtual "head"
377 of the seq (initially zero) */
378 Newxz(heads, AvFILLp(seqs)+1, I32);
379
380 /* This builds %tails, which has one key for every class
381 mentioned in the tail of any sequence in @seqs (tail meaning
382 everything after the first class, the "head"). The value
383 is how many times this key appears in the tails of @seqs.
384 */
e1a479c5 385 seqs_ptr = AvARRAY(seqs);
386 seqs_items = AvFILLp(seqs) + 1;
387 while(seqs_items--) {
502c6561 388 AV *const seq = MUTABLE_AV(*seqs_ptr++);
e1a479c5 389 I32 seq_items = AvFILLp(seq);
390 if(seq_items > 0) {
391 SV** seq_ptr = AvARRAY(seq) + 1;
392 while(seq_items--) {
1e05feb3 393 SV* const seqitem = *seq_ptr++;
694168e2 394 /* LVALUE fetch will create a new undefined SV if necessary
395 */
396 HE* const he = hv_fetch_ent(tails, seqitem, 1, 0);
397 if(he) {
1e05feb3 398 SV* const val = HeVAL(he);
694168e2 399 /* This will increment undef to 1, which is what we
400 want for a newly created entry. */
e1a479c5 401 sv_inc(val);
402 }
403 }
404 }
405 }
406
1dcae283 407 /* Initialize retval to build the return value in */
408 retval = newAV();
190d0b22 409 av_push(retval, newSVhek(stashhek)); /* us first */
1dcae283 410
8638e433 411 /* This loop won't terminate until we either finish building
412 the MRO, or get an exception. */
e1a479c5 413 while(1) {
e1a479c5 414 SV* cand = NULL;
415 SV* winner = NULL;
8638e433 416 int s;
417
418 /* "foreach $seq (@seqs)" */
1e05feb3 419 SV** const avptr = AvARRAY(seqs);
8638e433 420 for(s = 0; s <= AvFILLp(seqs); s++) {
e1a479c5 421 SV** svp;
502c6561 422 AV * const seq = MUTABLE_AV(avptr[s]);
1e05feb3 423 SV* seqhead;
8638e433 424 if(!seq) continue; /* skip empty seqs */
425 svp = av_fetch(seq, heads[s], 0);
426 seqhead = *svp; /* seqhead = head of this seq */
e1a479c5 427 if(!winner) {
1e05feb3 428 HE* tail_entry;
429 SV* val;
8638e433 430 /* if we haven't found a winner for this round yet,
431 and this seqhead is not in tails (or the count
432 for it in tails has dropped to zero), then this
433 seqhead is our new winner, and is added to the
434 final MRO immediately */
e1a479c5 435 cand = seqhead;
436 if((tail_entry = hv_fetch_ent(tails, cand, 0, 0))
437 && (val = HeVAL(tail_entry))
25270bc0 438 && (SvIVX(val) > 0))
e1a479c5 439 continue;
440 winner = newSVsv(cand);
441 av_push(retval, winner);
8638e433 442 /* note however that even when we find a winner,
443 we continue looping over @seqs to do housekeeping */
e1a479c5 444 }
445 if(!sv_cmp(seqhead, winner)) {
8638e433 446 /* Once we have a winner (including the iteration
447 where we first found him), inc the head ptr
448 for any seq which had the winner as a head,
449 NULL out any seq which is now empty,
450 and adjust tails for consistency */
451
1e05feb3 452 const int new_head = ++heads[s];
8638e433 453 if(new_head > AvFILLp(seq)) {
1dcae283 454 SvREFCNT_dec(avptr[s]);
8638e433 455 avptr[s] = NULL;
456 }
457 else {
1e05feb3 458 HE* tail_entry;
459 SV* val;
8638e433 460 /* Because we know this new seqhead used to be
461 a tail, we can assume it is in tails and has
462 a positive value, which we need to dec */
463 svp = av_fetch(seq, new_head, 0);
464 seqhead = *svp;
465 tail_entry = hv_fetch_ent(tails, seqhead, 0, 0);
466 val = HeVAL(tail_entry);
467 sv_dec(val);
468 }
e1a479c5 469 }
470 }
8638e433 471
472 /* if we found no candidates, we are done building the MRO.
473 !cand means no seqs have any entries left to check */
474 if(!cand) {
475 Safefree(heads);
476 break;
477 }
478
479 /* If we had candidates, but nobody won, then the @ISA
480 hierarchy is not C3-incompatible */
e1a479c5 481 if(!winner) {
8638e433 482 /* we have to do some cleanup before we croak */
8638e433 483
e1a479c5 484 SvREFCNT_dec(retval);
8638e433 485 Safefree(heads);
486
e1a479c5 487 Perl_croak(aTHX_ "Inconsistent hierarchy during C3 merge of class '%s': "
190d0b22 488 "merging failed on parent '%"SVf"'", HEK_KEY(stashhek), SVfARG(cand));
e1a479c5 489 }
490 }
491 }
1dcae283 492 else { /* @ISA was undefined or empty */
493 /* build a retval containing only ourselves */
494 retval = newAV();
190d0b22 495 av_push(retval, newSVhek(stashhek));
1dcae283 496 }
e1a479c5 497
1c908217 498 /* we don't want anyone modifying the cache entry but us,
499 and we do so by replacing it completely */
e1a479c5 500 SvREADONLY_on(retval);
1c908217 501
e1a479c5 502 meta->mro_linear_c3 = retval;
503 return retval;
504}
505
506/*
507=for apidoc mro_get_linear_isa
508
509Returns either C<mro_get_linear_isa_c3> or
510C<mro_get_linear_isa_dfs> for the given stash,
511dependant upon which MRO is in effect
512for that stash. The return value is a
513read-only AV*.
514
1c908217 515You are responsible for C<SvREFCNT_inc()> on the
516return value if you plan to store it anywhere
517semi-permanently (otherwise it might be deleted
518out from under you the next time the cache is
519invalidated).
520
e1a479c5 521=cut
522*/
523AV*
524Perl_mro_get_linear_isa(pTHX_ HV *stash)
525{
526 struct mro_meta* meta;
2c7f4b87 527
7918f24d 528 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA;
2c7f4b87 529 if(!SvOOK(stash))
530 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
e1a479c5 531
532 meta = HvMROMETA(stash);
3d76853f 533 if (!meta->mro_which)
14f97ce6 534 Perl_croak(aTHX_ "panic: invalid MRO!");
3d76853f 535 return meta->mro_which->resolve(aTHX_ stash, 0);
e1a479c5 536}
537
538/*
539=for apidoc mro_isa_changed_in
540
1c908217 541Takes the necessary steps (cache invalidations, mostly)
e1a479c5 542when the @ISA of the given package has changed. Invoked
543by the C<setisa> magic, should not need to invoke directly.
544
545=cut
546*/
547void
548Perl_mro_isa_changed_in(pTHX_ HV* stash)
549{
550 dVAR;
551 HV* isarev;
552 AV* linear_mro;
553 HE* iter;
554 SV** svp;
555 I32 items;
1e05feb3 556 bool is_universal;
2c7f4b87 557 struct mro_meta * meta;
e1a479c5 558
0fa56319 559 const char * const stashname = HvNAME_get(stash);
560 const STRLEN stashname_len = HvNAMELEN_get(stash);
e1a479c5 561
7918f24d 562 PERL_ARGS_ASSERT_MRO_ISA_CHANGED_IN;
563
2c7f4b87 564 if(!stashname)
565 Perl_croak(aTHX_ "Can't call mro_isa_changed_in() on anonymous symbol table");
566
e1a479c5 567 /* wipe out the cached linearizations for this stash */
2c7f4b87 568 meta = HvMROMETA(stash);
e1a479c5 569 SvREFCNT_dec((SV*)meta->mro_linear_dfs);
570 SvREFCNT_dec((SV*)meta->mro_linear_c3);
571 meta->mro_linear_dfs = NULL;
572 meta->mro_linear_c3 = NULL;
5782d502 573 if (meta->isa) {
574 SvREFCNT_dec(meta->isa);
575 meta->isa = NULL;
576 }
e1a479c5 577
70cd14a1 578 /* Inc the package generation, since our @ISA changed */
579 meta->pkg_gen++;
580
e1a479c5 581 /* Wipe the global method cache if this package
582 is UNIVERSAL or one of its parents */
dd69841b 583
584 svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
85fbaab2 585 isarev = svp ? MUTABLE_HV(*svp) : NULL;
dd69841b 586
587 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
588 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
e1a479c5 589 PL_sub_generation++;
dd69841b 590 is_universal = TRUE;
591 }
1e05feb3 592 else { /* Wipe the local method cache otherwise */
dd69841b 593 meta->cache_gen++;
1e05feb3 594 is_universal = FALSE;
595 }
e1a479c5 596
597 /* wipe next::method cache too */
598 if(meta->mro_nextmethod) hv_clear(meta->mro_nextmethod);
1e05feb3 599
e1a479c5 600 /* Iterate the isarev (classes that are our children),
601 wiping out their linearization and method caches */
dd69841b 602 if(isarev) {
e1a479c5 603 hv_iterinit(isarev);
604 while((iter = hv_iternext(isarev))) {
ec49eb61 605 I32 len;
606 const char* const revkey = hv_iterkey(iter, &len);
607 HV* revstash = gv_stashpvn(revkey, len, 0);
bc2cbbac 608 struct mro_meta* revmeta;
609
610 if(!revstash) continue;
611 revmeta = HvMROMETA(revstash);
e1a479c5 612 SvREFCNT_dec((SV*)revmeta->mro_linear_dfs);
613 SvREFCNT_dec((SV*)revmeta->mro_linear_c3);
614 revmeta->mro_linear_dfs = NULL;
615 revmeta->mro_linear_c3 = NULL;
dd69841b 616 if(!is_universal)
617 revmeta->cache_gen++;
e1a479c5 618 if(revmeta->mro_nextmethod)
619 hv_clear(revmeta->mro_nextmethod);
620 }
621 }
622
1c908217 623 /* Now iterate our MRO (parents), and do a few things:
624 1) instantiate with the "fake" flag if they don't exist
625 2) flag them as universal if we are universal
626 3) Add everything from our isarev to their isarev
627 */
628
629 /* We're starting at the 2nd element, skipping ourselves here */
e1a479c5 630 linear_mro = mro_get_linear_isa(stash);
631 svp = AvARRAY(linear_mro) + 1;
632 items = AvFILLp(linear_mro);
1c908217 633
e1a479c5 634 while (items--) {
635 SV* const sv = *svp++;
e1a479c5 636 HV* mroisarev;
637
117b69ca 638 HE *he = hv_fetch_ent(PL_isarev, sv, TRUE, 0);
639
640 /* That fetch should not fail. But if it had to create a new SV for
4ea50411 641 us, then will need to upgrade it to an HV (which sv_upgrade() can
642 now do for us. */
117b69ca 643
85fbaab2 644 mroisarev = MUTABLE_HV(HeVAL(he));
e1a479c5 645
4ea50411 646 SvUPGRADE((SV*)mroisarev, SVt_PVHV);
117b69ca 647
25270bc0 648 /* This hash only ever contains PL_sv_yes. Storing it over itself is
649 almost as cheap as calling hv_exists, so on aggregate we expect to
650 save time by not making two calls to the common HV code for the
651 case where it doesn't exist. */
652
04fe65b0 653 (void)hv_store(mroisarev, stashname, stashname_len, &PL_sv_yes, 0);
e1a479c5 654
655 if(isarev) {
656 hv_iterinit(isarev);
657 while((iter = hv_iternext(isarev))) {
dd69841b 658 I32 revkeylen;
1e05feb3 659 char* const revkey = hv_iterkey(iter, &revkeylen);
04fe65b0 660 (void)hv_store(mroisarev, revkey, revkeylen, &PL_sv_yes, 0);
e1a479c5 661 }
662 }
663 }
664}
665
666/*
667=for apidoc mro_method_changed_in
668
47c9dd14 669Invalidates method caching on any child classes
670of the given stash, so that they might notice
671the changes in this one.
e1a479c5 672
673Ideally, all instances of C<PL_sub_generation++> in
dd69841b 674perl source outside of C<mro.c> should be
675replaced by calls to this.
676
677Perl automatically handles most of the common
678ways a method might be redefined. However, there
679are a few ways you could change a method in a stash
680without the cache code noticing, in which case you
681need to call this method afterwards:
e1a479c5 682
dd69841b 6831) Directly manipulating the stash HV entries from
684XS code.
e1a479c5 685
dd69841b 6862) Assigning a reference to a readonly scalar
687constant into a stash entry in order to create
688a constant subroutine (like constant.pm
689does).
690
691This same method is available from pure perl
692via, C<mro::method_changed_in(classname)>.
e1a479c5 693
694=cut
695*/
696void
697Perl_mro_method_changed_in(pTHX_ HV *stash)
698{
1e05feb3 699 const char * const stashname = HvNAME_get(stash);
700 const STRLEN stashname_len = HvNAMELEN_get(stash);
dd69841b 701
1e05feb3 702 SV ** const svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
85fbaab2 703 HV * const isarev = svp ? MUTABLE_HV(*svp) : NULL;
e1a479c5 704
7918f24d 705 PERL_ARGS_ASSERT_MRO_METHOD_CHANGED_IN;
706
2c7f4b87 707 if(!stashname)
708 Perl_croak(aTHX_ "Can't call mro_method_changed_in() on anonymous symbol table");
709
70cd14a1 710 /* Inc the package generation, since a local method changed */
711 HvMROMETA(stash)->pkg_gen++;
712
e1a479c5 713 /* If stash is UNIVERSAL, or one of UNIVERSAL's parents,
714 invalidate all method caches globally */
dd69841b 715 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
716 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
e1a479c5 717 PL_sub_generation++;
718 return;
719 }
720
721 /* else, invalidate the method caches of all child classes,
722 but not itself */
dd69841b 723 if(isarev) {
1e05feb3 724 HE* iter;
725
e1a479c5 726 hv_iterinit(isarev);
727 while((iter = hv_iternext(isarev))) {
ec49eb61 728 I32 len;
729 const char* const revkey = hv_iterkey(iter, &len);
730 HV* const revstash = gv_stashpvn(revkey, len, 0);
bc2cbbac 731 struct mro_meta* mrometa;
732
733 if(!revstash) continue;
734 mrometa = HvMROMETA(revstash);
dd69841b 735 mrometa->cache_gen++;
e1a479c5 736 if(mrometa->mro_nextmethod)
737 hv_clear(mrometa->mro_nextmethod);
738 }
739 }
740}
741
742/* These two are static helpers for next::method and friends,
743 and re-implement a bunch of the code from pp_caller() in
744 a more efficient manner for this particular usage.
745*/
746
747STATIC I32
748__dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) {
749 I32 i;
750 for (i = startingblock; i >= 0; i--) {
751 if(CxTYPE((PERL_CONTEXT*)(&cxstk[i])) == CXt_SUB) return i;
752 }
753 return i;
754}
755
e1a479c5 756#include "XSUB.h"
757
758XS(XS_mro_get_linear_isa);
759XS(XS_mro_set_mro);
760XS(XS_mro_get_mro);
761XS(XS_mro_get_isarev);
762XS(XS_mro_is_universal);
c5860d66 763XS(XS_mro_invalidate_method_caches);
e1a479c5 764XS(XS_mro_method_changed_in);
70cd14a1 765XS(XS_mro_get_pkg_gen);
f58cd386 766XS(XS_mro_nextcan);
e1a479c5 767
768void
769Perl_boot_core_mro(pTHX)
770{
771 dVAR;
772 static const char file[] = __FILE__;
773
774 newXSproto("mro::get_linear_isa", XS_mro_get_linear_isa, file, "$;$");
775 newXSproto("mro::set_mro", XS_mro_set_mro, file, "$$");
776 newXSproto("mro::get_mro", XS_mro_get_mro, file, "$");
777 newXSproto("mro::get_isarev", XS_mro_get_isarev, file, "$");
778 newXSproto("mro::is_universal", XS_mro_is_universal, file, "$");
c5860d66 779 newXSproto("mro::invalidate_all_method_caches", XS_mro_invalidate_method_caches, file, "");
e1a479c5 780 newXSproto("mro::method_changed_in", XS_mro_method_changed_in, file, "$");
70cd14a1 781 newXSproto("mro::get_pkg_gen", XS_mro_get_pkg_gen, file, "$");
f58cd386 782 newXS("mro::_nextcan", XS_mro_nextcan, file);
e1a479c5 783}
784
785XS(XS_mro_get_linear_isa) {
786 dVAR;
787 dXSARGS;
788 AV* RETVAL;
789 HV* class_stash;
790 SV* classname;
791
e1a479c5 792 if(items < 1 || items > 2)
afa74d42 793 croak_xs_usage(cv, "classname [, type ]");
e1a479c5 794
795 classname = ST(0);
796 class_stash = gv_stashsv(classname, 0);
e1a479c5 797
70cd14a1 798 if(!class_stash) {
799 /* No stash exists yet, give them just the classname */
800 AV* isalin = newAV();
801 av_push(isalin, newSVsv(classname));
802 ST(0) = sv_2mortal(newRV_noinc((SV*)isalin));
803 XSRETURN(1);
804 }
805 else if(items > 1) {
1e05feb3 806 const char* const which = SvPV_nolen(ST(1));
3d76853f 807 const struct mro_alg *const algo = S_get_mro_from_name(aTHX_ which);
808 if (!algo)
809 Perl_croak(aTHX_ "Invalid mro name: '%s'", which);
84dccb35 810 RETVAL = algo->resolve(aTHX_ class_stash, 0);
e1a479c5 811 }
812 else {
813 RETVAL = mro_get_linear_isa(class_stash);
814 }
815
816 ST(0) = newRV_inc((SV*)RETVAL);
817 sv_2mortal(ST(0));
818 XSRETURN(1);
819}
820
821XS(XS_mro_set_mro)
822{
823 dVAR;
824 dXSARGS;
825 SV* classname;
3d76853f 826 const char* whichstr;
827 const struct mro_alg *which;
e1a479c5 828 HV* class_stash;
829 struct mro_meta* meta;
830
e1a479c5 831 if (items != 2)
afa74d42 832 croak_xs_usage(cv, "classname, type");
e1a479c5 833
834 classname = ST(0);
835 whichstr = SvPV_nolen(ST(1));
836 class_stash = gv_stashsv(classname, GV_ADD);
837 if(!class_stash) Perl_croak(aTHX_ "Cannot create class: '%"SVf"'!", SVfARG(classname));
838 meta = HvMROMETA(class_stash);
839
3d76853f 840 which = S_get_mro_from_name(aTHX_ whichstr);
841 if (!which)
e1a479c5 842 Perl_croak(aTHX_ "Invalid mro name: '%s'", whichstr);
843
844 if(meta->mro_which != which) {
845 meta->mro_which = which;
846 /* Only affects local method cache, not
847 even child classes */
dd69841b 848 meta->cache_gen++;
e1a479c5 849 if(meta->mro_nextmethod)
850 hv_clear(meta->mro_nextmethod);
851 }
852
853 XSRETURN_EMPTY;
854}
855
856
857XS(XS_mro_get_mro)
858{
859 dVAR;
860 dXSARGS;
861 SV* classname;
862 HV* class_stash;
e1a479c5 863
e1a479c5 864 if (items != 1)
afa74d42 865 croak_xs_usage(cv, "classname");
e1a479c5 866
867 classname = ST(0);
868 class_stash = gv_stashsv(classname, 0);
e1a479c5 869
3d76853f 870 ST(0) = sv_2mortal(newSVpv(class_stash
871 ? HvMROMETA(class_stash)->mro_which->name
872 : "dfs", 0));
e1a479c5 873 XSRETURN(1);
874}
875
876XS(XS_mro_get_isarev)
877{
878 dVAR;
879 dXSARGS;
880 SV* classname;
73968c7a 881 HE* he;
e1a479c5 882 HV* isarev;
70cd14a1 883 AV* ret_array;
e1a479c5 884
e1a479c5 885 if (items != 1)
afa74d42 886 croak_xs_usage(cv, "classname");
e1a479c5 887
888 classname = ST(0);
889
e1a479c5 890 SP -= items;
dd69841b 891
70cd14a1 892
73968c7a 893 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
85fbaab2 894 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
70cd14a1 895
896 ret_array = newAV();
dd69841b 897 if(isarev) {
e1a479c5 898 HE* iter;
899 hv_iterinit(isarev);
900 while((iter = hv_iternext(isarev)))
70cd14a1 901 av_push(ret_array, newSVsv(hv_iterkeysv(iter)));
e1a479c5 902 }
6e449a3a 903 mXPUSHs(newRV_noinc((SV*)ret_array));
e1a479c5 904
905 PUTBACK;
906 return;
907}
908
909XS(XS_mro_is_universal)
910{
911 dVAR;
912 dXSARGS;
913 SV* classname;
dd69841b 914 HV* isarev;
70cd14a1 915 char* classname_pv;
916 STRLEN classname_len;
73968c7a 917 HE* he;
e1a479c5 918
e1a479c5 919 if (items != 1)
afa74d42 920 croak_xs_usage(cv, "classname");
e1a479c5 921
922 classname = ST(0);
e1a479c5 923
cfff9797 924 classname_pv = SvPV(classname,classname_len);
dd69841b 925
73968c7a 926 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
85fbaab2 927 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
dd69841b 928
70cd14a1 929 if((classname_len == 9 && strEQ(classname_pv, "UNIVERSAL"))
dd69841b 930 || (isarev && hv_exists(isarev, "UNIVERSAL", 9)))
9edc5bb8 931 XSRETURN_YES;
932 else
933 XSRETURN_NO;
e1a479c5 934}
935
c5860d66 936XS(XS_mro_invalidate_method_caches)
e1a479c5 937{
938 dVAR;
939 dXSARGS;
940
e1a479c5 941 if (items != 0)
afa74d42 942 croak_xs_usage(cv, "");
e1a479c5 943
944 PL_sub_generation++;
945
946 XSRETURN_EMPTY;
947}
948
e1a479c5 949XS(XS_mro_method_changed_in)
950{
951 dVAR;
952 dXSARGS;
953 SV* classname;
954 HV* class_stash;
955
e1a479c5 956 if(items != 1)
afa74d42 957 croak_xs_usage(cv, "classname");
e1a479c5 958
959 classname = ST(0);
960
961 class_stash = gv_stashsv(classname, 0);
962 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
963
964 mro_method_changed_in(class_stash);
965
966 XSRETURN_EMPTY;
967}
968
70cd14a1 969XS(XS_mro_get_pkg_gen)
970{
971 dVAR;
972 dXSARGS;
973 SV* classname;
974 HV* class_stash;
975
70cd14a1 976 if(items != 1)
afa74d42 977 croak_xs_usage(cv, "classname");
70cd14a1 978
979 classname = ST(0);
980
981 class_stash = gv_stashsv(classname, 0);
982
983 SP -= items;
984
6e449a3a 985 mXPUSHi(class_stash ? HvMROMETA(class_stash)->pkg_gen : 0);
70cd14a1 986
987 PUTBACK;
988 return;
989}
990
f58cd386 991XS(XS_mro_nextcan)
e1a479c5 992{
993 dVAR;
994 dXSARGS;
f58cd386 995 SV* self = ST(0);
996 const I32 throw_nomethod = SvIVX(ST(1));
bbd28cb9 997 register I32 cxix = cxstack_ix;
f58cd386 998 register const PERL_CONTEXT *ccstack = cxstack;
999 const PERL_SI *top_si = PL_curstackinfo;
1000 HV* selfstash;
1001 SV *stashname;
1002 const char *fq_subname;
1003 const char *subname;
1004 STRLEN stashname_len;
1005 STRLEN subname_len;
1006 SV* sv;
1007 GV** gvp;
1008 AV* linear_av;
1009 SV** linear_svp;
1010 const char *hvname;
1011 I32 entries;
1012 struct mro_meta* selfmeta;
1013 HV* nmcache;
bbd28cb9 1014 I32 i;
e1a479c5 1015
48fc4736 1016 PERL_UNUSED_ARG(cv);
1017
f58cd386 1018 SP -= items;
1019
1020 if(sv_isobject(self))
1021 selfstash = SvSTASH(SvRV(self));
1022 else
5fa9f951 1023 selfstash = gv_stashsv(self, GV_ADD);
f58cd386 1024
1025 assert(selfstash);
1026
1027 hvname = HvNAME_get(selfstash);
1028 if (!hvname)
1029 Perl_croak(aTHX_ "Can't use anonymous symbol table for method lookup");
1030
f58cd386 1031 /* This block finds the contextually-enclosing fully-qualified subname,
1032 much like looking at (caller($i))[3] until you find a real sub that
bbd28cb9 1033 isn't ANON, etc (also skips over pureperl next::method, etc) */
1034 for(i = 0; i < 2; i++) {
1035 cxix = __dopoptosub_at(ccstack, cxix);
1036 for (;;) {
1037 GV* cvgv;
1038 STRLEN fq_subname_len;
1039
1040 /* we may be in a higher stacklevel, so dig down deeper */
1041 while (cxix < 0) {
1042 if(top_si->si_type == PERLSI_MAIN)
1043 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method must be used in method context");
1044 top_si = top_si->si_prev;
1045 ccstack = top_si->si_cxstack;
1046 cxix = __dopoptosub_at(ccstack, top_si->si_cxix);
1047 }
f58cd386 1048
bbd28cb9 1049 if(CxTYPE((PERL_CONTEXT*)(&ccstack[cxix])) != CXt_SUB
1050 || (PL_DBsub && GvCV(PL_DBsub) && ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub))) {
1051 cxix = __dopoptosub_at(ccstack, cxix - 1);
1052 continue;
1053 }
e1a479c5 1054
bbd28cb9 1055 {
1056 const I32 dbcxix = __dopoptosub_at(ccstack, cxix - 1);
1057 if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) {
1058 if(CxTYPE((PERL_CONTEXT*)(&ccstack[dbcxix])) != CXt_SUB) {
1059 cxix = dbcxix;
1060 continue;
1061 }
f58cd386 1062 }
1063 }
f58cd386 1064
bbd28cb9 1065 cvgv = CvGV(ccstack[cxix].blk_sub.cv);
f58cd386 1066
bbd28cb9 1067 if(!isGV(cvgv)) {
1068 cxix = __dopoptosub_at(ccstack, cxix - 1);
1069 continue;
1070 }
f58cd386 1071
bbd28cb9 1072 /* we found a real sub here */
1073 sv = sv_2mortal(newSV(0));
f58cd386 1074
bbd28cb9 1075 gv_efullname3(sv, cvgv, NULL);
f58cd386 1076
bbd28cb9 1077 fq_subname = SvPVX(sv);
1078 fq_subname_len = SvCUR(sv);
f58cd386 1079
bbd28cb9 1080 subname = strrchr(fq_subname, ':');
1081 if(!subname)
1082 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method cannot find enclosing method");
f58cd386 1083
bbd28cb9 1084 subname++;
1085 subname_len = fq_subname_len - (subname - fq_subname);
1086 if(subname_len == 8 && strEQ(subname, "__ANON__")) {
1087 cxix = __dopoptosub_at(ccstack, cxix - 1);
1088 continue;
1089 }
1090 break;
f58cd386 1091 }
bbd28cb9 1092 cxix--;
e1a479c5 1093 }
f58cd386 1094
1095 /* If we made it to here, we found our context */
1096
1097 /* Initialize the next::method cache for this stash
1098 if necessary */
1099 selfmeta = HvMROMETA(selfstash);
1100 if(!(nmcache = selfmeta->mro_nextmethod)) {
1101 nmcache = selfmeta->mro_nextmethod = newHV();
1102 }
1103 else { /* Use the cached coderef if it exists */
1104 HE* cache_entry = hv_fetch_ent(nmcache, sv, 0, 0);
1105 if (cache_entry) {
1106 SV* const val = HeVAL(cache_entry);
1107 if(val == &PL_sv_undef) {
1108 if(throw_nomethod)
1109 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
1110 XSRETURN_EMPTY;
1111 }
6e449a3a 1112 mXPUSHs(newRV_inc(val));
f58cd386 1113 XSRETURN(1);
1114 }
e1a479c5 1115 }
1116
f58cd386 1117 /* beyond here is just for cache misses, so perf isn't as critical */
e1a479c5 1118
f58cd386 1119 stashname_len = subname - fq_subname - 2;
59cd0e26 1120 stashname = newSVpvn_flags(fq_subname, stashname_len, SVs_TEMP);
e1a479c5 1121
f58cd386 1122 linear_av = mro_get_linear_isa_c3(selfstash, 0); /* has ourselves at the top of the list */
e1a479c5 1123
f58cd386 1124 linear_svp = AvARRAY(linear_av);
1125 entries = AvFILLp(linear_av) + 1;
e1a479c5 1126
f58cd386 1127 /* Walk down our MRO, skipping everything up
1128 to the contextually enclosing class */
1129 while (entries--) {
1130 SV * const linear_sv = *linear_svp++;
1131 assert(linear_sv);
1132 if(sv_eq(linear_sv, stashname))
1133 break;
1134 }
e1a479c5 1135
f58cd386 1136 /* Now search the remainder of the MRO for the
1137 same method name as the contextually enclosing
1138 method */
1139 if(entries > 0) {
1140 while (entries--) {
1141 SV * const linear_sv = *linear_svp++;
1142 HV* curstash;
1143 GV* candidate;
1144 CV* cand_cv;
e1a479c5 1145
f58cd386 1146 assert(linear_sv);
1147 curstash = gv_stashsv(linear_sv, FALSE);
1148
1149 if (!curstash) {
1150 if (ckWARN(WARN_SYNTAX))
1151 Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Can't locate package %"SVf" for @%s::ISA",
1152 (void*)linear_sv, hvname);
1153 continue;
1154 }
1155
1156 assert(curstash);
1157
1158 gvp = (GV**)hv_fetch(curstash, subname, subname_len, 0);
1159 if (!gvp) continue;
1160
1161 candidate = *gvp;
1162 assert(candidate);
1163
1164 if (SvTYPE(candidate) != SVt_PVGV)
1165 gv_init(candidate, curstash, subname, subname_len, TRUE);
1166
1167 /* Notably, we only look for real entries, not method cache
1168 entries, because in C3 the method cache of a parent is not
1169 valid for the child */
1170 if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) {
1171 SvREFCNT_inc_simple_void_NN((SV*)cand_cv);
04fe65b0 1172 (void)hv_store_ent(nmcache, newSVsv(sv), (SV*)cand_cv, 0);
6e449a3a 1173 mXPUSHs(newRV_inc((SV*)cand_cv));
f58cd386 1174 XSRETURN(1);
1175 }
1176 }
e1a479c5 1177 }
1178
04fe65b0 1179 (void)hv_store_ent(nmcache, newSVsv(sv), &PL_sv_undef, 0);
f58cd386 1180 if(throw_nomethod)
1181 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
1182 XSRETURN_EMPTY;
e1a479c5 1183}
1184
1185/*
1186 * Local variables:
1187 * c-indentation-style: bsd
1188 * c-basic-offset: 4
1189 * indent-tabs-mode: t
1190 * End:
1191 *
1192 * ex: set ts=8 sts=4 sw=4 noet:
1193 */