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