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