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