3 * Copyright (c) 2007 Brandon L Black
4 * Copyright (c) 2007, 2008 Larry Wall and others
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
12 * 'Which order shall we go in?' said Frodo. 'Eldest first, or quickest first?
13 * You'll be last either way, Master Peregrin.'
15 * [p.101 of _The Lord of the Rings_, I/iii: "A Conspiracy Unmasked"]
21 These functions are related to the method resolution order of perl classes
31 AV *(*resolve)(pTHX_ HV* stash, U32 level);
34 U16 kflags; /* For the hash API - set HVhek_UTF8 if name is UTF-8 */
38 /* First one is the default */
39 static struct mro_alg mros[] = {
40 {S_mro_get_linear_isa_dfs, "dfs", 3, 0, 0},
41 {S_mro_get_linear_isa_c3, "c3", 2, 0, 0}
44 #define NUMBER_OF_MROS (sizeof(mros)/sizeof(struct mro_alg))
46 #define dfs_alg (&mros[0])
47 #define c3_alg (&mros[1])
50 Perl_mro_get_private_data(pTHX_ struct mro_meta *const smeta,
51 const struct mro_alg *const which)
54 PERL_ARGS_ASSERT_MRO_GET_PRIVATE_DATA;
56 data = Perl_hv_common(aTHX_ MUTABLE_HV(smeta->mro_linear_dfs), NULL,
57 which->name, which->length, which->kflags,
58 HV_FETCH_JUST_SV, NULL, which->hash);
62 /* If we've been asked to look up the private data for the current MRO, then
64 if (smeta->mro_which == which)
65 smeta->mro_linear_c3 = MUTABLE_AV(*data);
71 Perl_mro_set_private_data(pTHX_ struct mro_meta *const smeta,
72 const struct mro_alg *const which, SV *const data)
74 PERL_ARGS_ASSERT_MRO_SET_PRIVATE_DATA;
76 /* If we've been asked to look up the private data for the current MRO, then
78 if (smeta->mro_which == which)
79 smeta->mro_linear_c3 = MUTABLE_AV(data);
81 if (!smeta->mro_linear_dfs) {
82 HV *const hv = newHV();
83 HvMAX(hv) = 0; /* Start with 1 bucket. It's unlikely we'll need more.
85 smeta->mro_linear_dfs = MUTABLE_AV(hv);
88 if (!Perl_hv_common(aTHX_ MUTABLE_HV(smeta->mro_linear_dfs), NULL,
89 which->name, which->length, which->kflags,
90 HV_FETCH_ISSTORE, data, which->hash)) {
91 Perl_croak(aTHX_ "panic: hv_store() failed in set_mro_private_data() "
92 "for '%.*s' %d", (int) which->length, which->name,
99 static const struct mro_alg *
100 S_get_mro_from_name(pTHX_ const char *const name) {
101 const struct mro_alg *algo = mros;
102 const struct mro_alg *const end = mros + NUMBER_OF_MROS;
104 if(strEQ(name, algo->name))
112 Perl_mro_meta_init(pTHX_ HV* stash)
114 struct mro_meta* newmeta;
116 PERL_ARGS_ASSERT_MRO_META_INIT;
117 assert(HvAUX(stash));
118 assert(!(HvAUX(stash)->xhv_mro_meta));
119 Newxz(newmeta, 1, struct mro_meta);
120 HvAUX(stash)->xhv_mro_meta = newmeta;
121 newmeta->cache_gen = 1;
122 newmeta->pkg_gen = 1;
123 newmeta->mro_which = mros;
128 #if defined(USE_ITHREADS)
130 /* for sv_dup on new threads */
132 Perl_mro_meta_dup(pTHX_ struct mro_meta* smeta, CLONE_PARAMS* param)
134 struct mro_meta* newmeta;
136 PERL_ARGS_ASSERT_MRO_META_DUP;
138 Newx(newmeta, 1, struct mro_meta);
139 Copy(smeta, newmeta, 1, struct mro_meta);
141 if (newmeta->mro_linear_dfs)
142 newmeta->mro_linear_dfs
143 = MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_dfs, param)));
144 newmeta->mro_linear_c3 = NULL;
145 if (newmeta->mro_nextmethod)
146 newmeta->mro_nextmethod
147 = MUTABLE_HV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_nextmethod, param)));
150 = MUTABLE_HV(SvREFCNT_inc(sv_dup((const SV *)newmeta->isa, param)));
155 #endif /* USE_ITHREADS */
158 Perl_get_isa_hash(pTHX_ HV *const stash)
161 struct mro_meta *const meta = HvMROMETA(stash);
163 PERL_ARGS_ASSERT_GET_ISA_HASH;
166 AV *const isa = mro_get_linear_isa(stash);
168 HV *const isa_hash = newHV();
169 /* Linearisation didn't build it for us, so do it here. */
170 SV *const *svp = AvARRAY(isa);
171 SV *const *const svp_end = svp + AvFILLp(isa) + 1;
172 const HEK *const canon_name = HvNAME_HEK(stash);
174 while (svp < svp_end) {
175 (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
178 (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
179 HEK_LEN(canon_name), HEK_FLAGS(canon_name),
180 HV_FETCH_ISSTORE, &PL_sv_undef,
181 HEK_HASH(canon_name));
182 (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
184 SvREADONLY_on(isa_hash);
186 meta->isa = isa_hash;
193 =for apidoc mro_get_linear_isa_dfs
195 Returns the Depth-First Search linearization of @ISA
196 the given stash. The return value is a read-only AV*.
197 C<level> should be 0 (it is used internally in this
198 function's recursion).
200 You are responsible for C<SvREFCNT_inc()> on the
201 return value if you plan to store it anywhere
202 semi-permanently (otherwise it might be deleted
203 out from under you the next time the cache is
209 S_mro_get_linear_isa_dfs(pTHX_ HV *stash, U32 level)
216 struct mro_meta* meta;
220 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA_DFS;
221 assert(HvAUX(stash));
223 stashhek = HvNAME_HEK(stash);
225 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
228 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
231 meta = HvMROMETA(stash);
233 /* return cache if valid */
234 if((retval = MUTABLE_AV(MRO_GET_PRIVATE_DATA(meta, dfs_alg)))) {
238 /* not in cache, make a new one */
240 retval = MUTABLE_AV(sv_2mortal(MUTABLE_SV(newAV())));
241 /* We use this later in this function, but don't need a reference to it
242 beyond the end of this function, so reference count is fine. */
243 our_name = newSVhek(stashhek);
244 av_push(retval, our_name); /* add ourselves at the top */
247 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
248 av = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
250 /* "stored" is used to keep track of all of the classnames we have added to
251 the MRO so far, so we can do a quick exists check and avoid adding
252 duplicate classnames to the MRO as we go.
253 It's then retained to be re-used as a fast lookup for ->isa(), by adding
254 our own name and "UNIVERSAL" to it. */
256 stored = MUTABLE_HV(sv_2mortal(MUTABLE_SV(newHV())));
258 if(av && AvFILLp(av) >= 0) {
260 SV **svp = AvARRAY(av);
261 I32 items = AvFILLp(av) + 1;
265 SV* const sv = *svp++;
266 HV* const basestash = gv_stashsv(sv, 0);
271 /* if no stash exists for this @ISA member,
272 simply add it to the MRO and move on */
277 /* otherwise, recurse into ourselves for the MRO
278 of this @ISA member, and append their MRO to ours.
279 The recursive call could throw an exception, which
280 has memory management implications here, hence the use of
282 const AV *const subrv
283 = mro_get_linear_isa_dfs(basestash, level + 1);
285 subrv_p = AvARRAY(subrv);
286 subrv_items = AvFILLp(subrv) + 1;
288 while(subrv_items--) {
289 SV *const subsv = *subrv_p++;
290 /* LVALUE fetch will create a new undefined SV if necessary
292 HE *const he = hv_fetch_ent(stored, subsv, 1, 0);
294 if(HeVAL(he) != &PL_sv_undef) {
295 /* It was newly created. Steal it for our new SV, and
296 replace it in the hash with the "real" thing. */
297 SV *const val = HeVAL(he);
298 HEK *const key = HeKEY_hek(he);
300 HeVAL(he) = &PL_sv_undef;
301 /* Save copying by making a shared hash key scalar. We
302 inline this here rather than calling Perl_newSVpvn_share
303 because we already have the scalar, and we already have
305 assert(SvTYPE(val) == SVt_NULL);
306 sv_upgrade(val, SVt_PV);
307 SvPV_set(val, HEK_KEY(share_hek_hek(key)));
308 SvCUR_set(val, HEK_LEN(key));
315 av_push(retval, val);
321 (void) hv_store_ent(stored, our_name, &PL_sv_undef, 0);
322 (void) hv_store(stored, "UNIVERSAL", 9, &PL_sv_undef, 0);
324 SvREFCNT_inc_simple_void_NN(stored);
326 SvREADONLY_on(stored);
330 /* now that we're past the exception dangers, grab our own reference to
331 the AV we're about to use for the result. The reference owned by the
332 mortals' stack will be released soon, so everything will balance. */
333 SvREFCNT_inc_simple_void_NN(retval);
336 /* we don't want anyone modifying the cache entry but us,
337 and we do so by replacing it completely */
338 SvREADONLY_on(retval);
340 return MUTABLE_AV(Perl_mro_set_private_data(aTHX_ meta, dfs_alg,
341 MUTABLE_SV(retval)));
345 =for apidoc mro_get_linear_isa_c3
347 Returns the C3 linearization of @ISA
348 the given stash. The return value is a read-only AV*.
349 C<level> should be 0 (it is used internally in this
350 function's recursion).
352 You are responsible for C<SvREFCNT_inc()> on the
353 return value if you plan to store it anywhere
354 semi-permanently (otherwise it might be deleted
355 out from under you the next time the cache is
362 S_mro_get_linear_isa_c3(pTHX_ HV* stash, U32 level)
369 struct mro_meta* meta;
371 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA_C3;
372 assert(HvAUX(stash));
374 stashhek = HvNAME_HEK(stash);
376 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
379 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
382 meta = HvMROMETA(stash);
384 /* return cache if valid */
385 if((retval = MUTABLE_AV(MRO_GET_PRIVATE_DATA(meta, c3_alg)))) {
389 /* not in cache, make a new one */
391 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
392 isa = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
394 /* For a better idea how the rest of this works, see the much clearer
395 pure perl version in Algorithm::C3 0.01:
396 http://search.cpan.org/src/STEVAN/Algorithm-C3-0.01/lib/Algorithm/C3.pm
397 (later versions go about it differently than this code for speed reasons)
400 if(isa && AvFILLp(isa) >= 0) {
403 HV* const tails = MUTABLE_HV(sv_2mortal(MUTABLE_SV(newHV())));
404 AV *const seqs = MUTABLE_AV(sv_2mortal(MUTABLE_SV(newAV())));
407 /* This builds @seqs, which is an array of arrays.
408 The members of @seqs are the MROs of
409 the members of @ISA, followed by @ISA itself.
411 I32 items = AvFILLp(isa) + 1;
412 SV** isa_ptr = AvARRAY(isa);
414 SV* const isa_item = *isa_ptr++;
415 HV* const isa_item_stash = gv_stashsv(isa_item, 0);
416 if(!isa_item_stash) {
417 /* if no stash, make a temporary fake MRO
418 containing just itself */
419 AV* const isa_lin = newAV();
420 av_push(isa_lin, newSVsv(isa_item));
421 av_push(seqs, MUTABLE_SV(isa_lin));
425 AV* const isa_lin = mro_get_linear_isa_c3(isa_item_stash, level + 1);
426 av_push(seqs, SvREFCNT_inc_simple_NN(MUTABLE_SV(isa_lin)));
429 av_push(seqs, SvREFCNT_inc_simple_NN(MUTABLE_SV(isa)));
431 /* This builds "heads", which as an array of integer array
432 indices, one per seq, which point at the virtual "head"
433 of the seq (initially zero) */
434 Newxz(heads, AvFILLp(seqs)+1, I32);
436 /* This builds %tails, which has one key for every class
437 mentioned in the tail of any sequence in @seqs (tail meaning
438 everything after the first class, the "head"). The value
439 is how many times this key appears in the tails of @seqs.
441 seqs_ptr = AvARRAY(seqs);
442 seqs_items = AvFILLp(seqs) + 1;
443 while(seqs_items--) {
444 AV *const seq = MUTABLE_AV(*seqs_ptr++);
445 I32 seq_items = AvFILLp(seq);
447 SV** seq_ptr = AvARRAY(seq) + 1;
449 SV* const seqitem = *seq_ptr++;
450 /* LVALUE fetch will create a new undefined SV if necessary
452 HE* const he = hv_fetch_ent(tails, seqitem, 1, 0);
454 SV* const val = HeVAL(he);
455 /* This will increment undef to 1, which is what we
456 want for a newly created entry. */
463 /* Initialize retval to build the return value in */
465 av_push(retval, newSVhek(stashhek)); /* us first */
467 /* This loop won't terminate until we either finish building
468 the MRO, or get an exception. */
474 /* "foreach $seq (@seqs)" */
475 SV** const avptr = AvARRAY(seqs);
476 for(s = 0; s <= AvFILLp(seqs); s++) {
478 AV * const seq = MUTABLE_AV(avptr[s]);
480 if(!seq) continue; /* skip empty seqs */
481 svp = av_fetch(seq, heads[s], 0);
482 seqhead = *svp; /* seqhead = head of this seq */
486 /* if we haven't found a winner for this round yet,
487 and this seqhead is not in tails (or the count
488 for it in tails has dropped to zero), then this
489 seqhead is our new winner, and is added to the
490 final MRO immediately */
492 if((tail_entry = hv_fetch_ent(tails, cand, 0, 0))
493 && (val = HeVAL(tail_entry))
496 winner = newSVsv(cand);
497 av_push(retval, winner);
498 /* note however that even when we find a winner,
499 we continue looping over @seqs to do housekeeping */
501 if(!sv_cmp(seqhead, winner)) {
502 /* Once we have a winner (including the iteration
503 where we first found him), inc the head ptr
504 for any seq which had the winner as a head,
505 NULL out any seq which is now empty,
506 and adjust tails for consistency */
508 const int new_head = ++heads[s];
509 if(new_head > AvFILLp(seq)) {
510 SvREFCNT_dec(avptr[s]);
516 /* Because we know this new seqhead used to be
517 a tail, we can assume it is in tails and has
518 a positive value, which we need to dec */
519 svp = av_fetch(seq, new_head, 0);
521 tail_entry = hv_fetch_ent(tails, seqhead, 0, 0);
522 val = HeVAL(tail_entry);
528 /* if we found no candidates, we are done building the MRO.
529 !cand means no seqs have any entries left to check */
535 /* If we had candidates, but nobody won, then the @ISA
536 hierarchy is not C3-incompatible */
538 /* we have to do some cleanup before we croak */
540 SvREFCNT_dec(retval);
543 Perl_croak(aTHX_ "Inconsistent hierarchy during C3 merge of class '%s': "
544 "merging failed on parent '%"SVf"'", HEK_KEY(stashhek), SVfARG(cand));
548 else { /* @ISA was undefined or empty */
549 /* build a retval containing only ourselves */
551 av_push(retval, newSVhek(stashhek));
554 /* we don't want anyone modifying the cache entry but us,
555 and we do so by replacing it completely */
556 SvREADONLY_on(retval);
558 return MUTABLE_AV(Perl_mro_set_private_data(aTHX_ meta, c3_alg,
559 MUTABLE_SV(retval)));
564 =for apidoc mro_get_linear_isa
566 Returns either C<mro_get_linear_isa_c3> or
567 C<mro_get_linear_isa_dfs> for the given stash,
568 dependant upon which MRO is in effect
569 for that stash. The return value is a
572 You are responsible for C<SvREFCNT_inc()> on the
573 return value if you plan to store it anywhere
574 semi-permanently (otherwise it might be deleted
575 out from under you the next time the cache is
581 Perl_mro_get_linear_isa(pTHX_ HV *stash)
583 struct mro_meta* meta;
585 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA;
587 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
589 meta = HvMROMETA(stash);
590 if (!meta->mro_which)
591 Perl_croak(aTHX_ "panic: invalid MRO!");
592 return meta->mro_which->resolve(aTHX_ stash, 0);
596 =for apidoc mro_isa_changed_in
598 Takes the necessary steps (cache invalidations, mostly)
599 when the @ISA of the given package has changed. Invoked
600 by the C<setisa> magic, should not need to invoke directly.
605 Perl_mro_isa_changed_in(pTHX_ HV* stash)
614 struct mro_meta * meta;
616 const char * const stashname = HvNAME_get(stash);
617 const STRLEN stashname_len = HvNAMELEN_get(stash);
619 PERL_ARGS_ASSERT_MRO_ISA_CHANGED_IN;
622 Perl_croak(aTHX_ "Can't call mro_isa_changed_in() on anonymous symbol table");
624 /* wipe out the cached linearizations for this stash */
625 meta = HvMROMETA(stash);
626 SvREFCNT_dec(MUTABLE_SV(meta->mro_linear_dfs));
627 meta->mro_linear_dfs = NULL;
628 meta->mro_linear_c3 = NULL;
630 SvREFCNT_dec(meta->isa);
634 /* Inc the package generation, since our @ISA changed */
637 /* Wipe the global method cache if this package
638 is UNIVERSAL or one of its parents */
640 svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
641 isarev = svp ? MUTABLE_HV(*svp) : NULL;
643 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
644 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
648 else { /* Wipe the local method cache otherwise */
650 is_universal = FALSE;
653 /* wipe next::method cache too */
654 if(meta->mro_nextmethod) hv_clear(meta->mro_nextmethod);
656 /* Iterate the isarev (classes that are our children),
657 wiping out their linearization and method caches */
660 while((iter = hv_iternext(isarev))) {
662 const char* const revkey = hv_iterkey(iter, &len);
663 HV* revstash = gv_stashpvn(revkey, len, 0);
664 struct mro_meta* revmeta;
666 if(!revstash) continue;
667 revmeta = HvMROMETA(revstash);
668 SvREFCNT_dec(MUTABLE_SV(revmeta->mro_linear_dfs));
669 revmeta->mro_linear_dfs = NULL;
670 revmeta->mro_linear_c3 = NULL;
672 revmeta->cache_gen++;
673 if(revmeta->mro_nextmethod)
674 hv_clear(revmeta->mro_nextmethod);
678 /* Now iterate our MRO (parents), and do a few things:
679 1) instantiate with the "fake" flag if they don't exist
680 2) flag them as universal if we are universal
681 3) Add everything from our isarev to their isarev
684 /* We're starting at the 2nd element, skipping ourselves here */
685 linear_mro = mro_get_linear_isa(stash);
686 svp = AvARRAY(linear_mro) + 1;
687 items = AvFILLp(linear_mro);
690 SV* const sv = *svp++;
693 HE *he = hv_fetch_ent(PL_isarev, sv, TRUE, 0);
695 /* That fetch should not fail. But if it had to create a new SV for
696 us, then will need to upgrade it to an HV (which sv_upgrade() can
699 mroisarev = MUTABLE_HV(HeVAL(he));
701 SvUPGRADE(MUTABLE_SV(mroisarev), SVt_PVHV);
703 /* This hash only ever contains PL_sv_yes. Storing it over itself is
704 almost as cheap as calling hv_exists, so on aggregate we expect to
705 save time by not making two calls to the common HV code for the
706 case where it doesn't exist. */
708 (void)hv_store(mroisarev, stashname, stashname_len, &PL_sv_yes, 0);
712 while((iter = hv_iternext(isarev))) {
714 char* const revkey = hv_iterkey(iter, &revkeylen);
715 (void)hv_store(mroisarev, revkey, revkeylen, &PL_sv_yes, 0);
722 =for apidoc mro_method_changed_in
724 Invalidates method caching on any child classes
725 of the given stash, so that they might notice
726 the changes in this one.
728 Ideally, all instances of C<PL_sub_generation++> in
729 perl source outside of C<mro.c> should be
730 replaced by calls to this.
732 Perl automatically handles most of the common
733 ways a method might be redefined. However, there
734 are a few ways you could change a method in a stash
735 without the cache code noticing, in which case you
736 need to call this method afterwards:
738 1) Directly manipulating the stash HV entries from
741 2) Assigning a reference to a readonly scalar
742 constant into a stash entry in order to create
743 a constant subroutine (like constant.pm
746 This same method is available from pure perl
747 via, C<mro::method_changed_in(classname)>.
752 Perl_mro_method_changed_in(pTHX_ HV *stash)
754 const char * const stashname = HvNAME_get(stash);
755 const STRLEN stashname_len = HvNAMELEN_get(stash);
757 SV ** const svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
758 HV * const isarev = svp ? MUTABLE_HV(*svp) : NULL;
760 PERL_ARGS_ASSERT_MRO_METHOD_CHANGED_IN;
763 Perl_croak(aTHX_ "Can't call mro_method_changed_in() on anonymous symbol table");
765 /* Inc the package generation, since a local method changed */
766 HvMROMETA(stash)->pkg_gen++;
768 /* If stash is UNIVERSAL, or one of UNIVERSAL's parents,
769 invalidate all method caches globally */
770 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
771 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
776 /* else, invalidate the method caches of all child classes,
782 while((iter = hv_iternext(isarev))) {
784 const char* const revkey = hv_iterkey(iter, &len);
785 HV* const revstash = gv_stashpvn(revkey, len, 0);
786 struct mro_meta* mrometa;
788 if(!revstash) continue;
789 mrometa = HvMROMETA(revstash);
790 mrometa->cache_gen++;
791 if(mrometa->mro_nextmethod)
792 hv_clear(mrometa->mro_nextmethod);
797 /* These two are static helpers for next::method and friends,
798 and re-implement a bunch of the code from pp_caller() in
799 a more efficient manner for this particular usage.
803 __dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) {
805 for (i = startingblock; i >= 0; i--) {
806 if(CxTYPE((PERL_CONTEXT*)(&cxstk[i])) == CXt_SUB) return i;
813 XS(XS_mro_get_linear_isa);
816 XS(XS_mro_get_isarev);
817 XS(XS_mro_is_universal);
818 XS(XS_mro_invalidate_method_caches);
819 XS(XS_mro_method_changed_in);
820 XS(XS_mro_get_pkg_gen);
824 Perl_boot_core_mro(pTHX)
827 static const char file[] = __FILE__;
829 newXSproto("mro::get_linear_isa", XS_mro_get_linear_isa, file, "$;$");
830 newXSproto("mro::set_mro", XS_mro_set_mro, file, "$$");
831 newXSproto("mro::get_mro", XS_mro_get_mro, file, "$");
832 newXSproto("mro::get_isarev", XS_mro_get_isarev, file, "$");
833 newXSproto("mro::is_universal", XS_mro_is_universal, file, "$");
834 newXSproto("mro::invalidate_all_method_caches", XS_mro_invalidate_method_caches, file, "");
835 newXSproto("mro::method_changed_in", XS_mro_method_changed_in, file, "$");
836 newXSproto("mro::get_pkg_gen", XS_mro_get_pkg_gen, file, "$");
837 newXS("mro::_nextcan", XS_mro_nextcan, file);
840 XS(XS_mro_get_linear_isa) {
847 if(items < 1 || items > 2)
848 croak_xs_usage(cv, "classname [, type ]");
851 class_stash = gv_stashsv(classname, 0);
854 /* No stash exists yet, give them just the classname */
855 AV* isalin = newAV();
856 av_push(isalin, newSVsv(classname));
857 ST(0) = sv_2mortal(newRV_noinc(MUTABLE_SV(isalin)));
861 const char* const which = SvPV_nolen(ST(1));
862 const struct mro_alg *const algo = S_get_mro_from_name(aTHX_ which);
864 Perl_croak(aTHX_ "Invalid mro name: '%s'", which);
865 RETVAL = algo->resolve(aTHX_ class_stash, 0);
868 RETVAL = mro_get_linear_isa(class_stash);
871 ST(0) = newRV_inc(MUTABLE_SV(RETVAL));
881 const char* whichstr;
882 const struct mro_alg *which;
884 struct mro_meta* meta;
887 croak_xs_usage(cv, "classname, type");
890 whichstr = SvPV_nolen(ST(1));
891 class_stash = gv_stashsv(classname, GV_ADD);
892 if(!class_stash) Perl_croak(aTHX_ "Cannot create class: '%"SVf"'!", SVfARG(classname));
893 meta = HvMROMETA(class_stash);
895 which = S_get_mro_from_name(aTHX_ whichstr);
897 Perl_croak(aTHX_ "Invalid mro name: '%s'", whichstr);
899 if(meta->mro_which != which) {
900 meta->mro_which = which;
901 /* Scrub our cached pointer to the private data. */
902 meta->mro_linear_c3 = NULL;
903 /* Only affects local method cache, not
904 even child classes */
906 if(meta->mro_nextmethod)
907 hv_clear(meta->mro_nextmethod);
922 croak_xs_usage(cv, "classname");
925 class_stash = gv_stashsv(classname, 0);
927 ST(0) = sv_2mortal(newSVpv(class_stash
928 ? HvMROMETA(class_stash)->mro_which->name
933 XS(XS_mro_get_isarev)
943 croak_xs_usage(cv, "classname");
950 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
951 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
957 while((iter = hv_iternext(isarev)))
958 av_push(ret_array, newSVsv(hv_iterkeysv(iter)));
960 mXPUSHs(newRV_noinc(MUTABLE_SV(ret_array)));
966 XS(XS_mro_is_universal)
973 STRLEN classname_len;
977 croak_xs_usage(cv, "classname");
981 classname_pv = SvPV(classname,classname_len);
983 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
984 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
986 if((classname_len == 9 && strEQ(classname_pv, "UNIVERSAL"))
987 || (isarev && hv_exists(isarev, "UNIVERSAL", 9)))
993 XS(XS_mro_invalidate_method_caches)
999 croak_xs_usage(cv, "");
1001 PL_sub_generation++;
1006 XS(XS_mro_method_changed_in)
1014 croak_xs_usage(cv, "classname");
1018 class_stash = gv_stashsv(classname, 0);
1019 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
1021 mro_method_changed_in(class_stash);
1026 XS(XS_mro_get_pkg_gen)
1034 croak_xs_usage(cv, "classname");
1038 class_stash = gv_stashsv(classname, 0);
1042 mXPUSHi(class_stash ? HvMROMETA(class_stash)->pkg_gen : 0);
1053 const I32 throw_nomethod = SvIVX(ST(1));
1054 register I32 cxix = cxstack_ix;
1055 register const PERL_CONTEXT *ccstack = cxstack;
1056 const PERL_SI *top_si = PL_curstackinfo;
1059 const char *fq_subname;
1060 const char *subname;
1061 STRLEN stashname_len;
1069 struct mro_meta* selfmeta;
1073 PERL_UNUSED_ARG(cv);
1077 if(sv_isobject(self))
1078 selfstash = SvSTASH(SvRV(self));
1080 selfstash = gv_stashsv(self, GV_ADD);
1084 hvname = HvNAME_get(selfstash);
1086 Perl_croak(aTHX_ "Can't use anonymous symbol table for method lookup");
1088 /* This block finds the contextually-enclosing fully-qualified subname,
1089 much like looking at (caller($i))[3] until you find a real sub that
1090 isn't ANON, etc (also skips over pureperl next::method, etc) */
1091 for(i = 0; i < 2; i++) {
1092 cxix = __dopoptosub_at(ccstack, cxix);
1095 STRLEN fq_subname_len;
1097 /* we may be in a higher stacklevel, so dig down deeper */
1099 if(top_si->si_type == PERLSI_MAIN)
1100 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method must be used in method context");
1101 top_si = top_si->si_prev;
1102 ccstack = top_si->si_cxstack;
1103 cxix = __dopoptosub_at(ccstack, top_si->si_cxix);
1106 if(CxTYPE((PERL_CONTEXT*)(&ccstack[cxix])) != CXt_SUB
1107 || (PL_DBsub && GvCV(PL_DBsub) && ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub))) {
1108 cxix = __dopoptosub_at(ccstack, cxix - 1);
1113 const I32 dbcxix = __dopoptosub_at(ccstack, cxix - 1);
1114 if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) {
1115 if(CxTYPE((PERL_CONTEXT*)(&ccstack[dbcxix])) != CXt_SUB) {
1122 cvgv = CvGV(ccstack[cxix].blk_sub.cv);
1125 cxix = __dopoptosub_at(ccstack, cxix - 1);
1129 /* we found a real sub here */
1130 sv = sv_2mortal(newSV(0));
1132 gv_efullname3(sv, cvgv, NULL);
1134 fq_subname = SvPVX(sv);
1135 fq_subname_len = SvCUR(sv);
1137 subname = strrchr(fq_subname, ':');
1139 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method cannot find enclosing method");
1142 subname_len = fq_subname_len - (subname - fq_subname);
1143 if(subname_len == 8 && strEQ(subname, "__ANON__")) {
1144 cxix = __dopoptosub_at(ccstack, cxix - 1);
1152 /* If we made it to here, we found our context */
1154 /* Initialize the next::method cache for this stash
1156 selfmeta = HvMROMETA(selfstash);
1157 if(!(nmcache = selfmeta->mro_nextmethod)) {
1158 nmcache = selfmeta->mro_nextmethod = newHV();
1160 else { /* Use the cached coderef if it exists */
1161 HE* cache_entry = hv_fetch_ent(nmcache, sv, 0, 0);
1163 SV* const val = HeVAL(cache_entry);
1164 if(val == &PL_sv_undef) {
1166 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
1169 mXPUSHs(newRV_inc(val));
1174 /* beyond here is just for cache misses, so perf isn't as critical */
1176 stashname_len = subname - fq_subname - 2;
1177 stashname = newSVpvn_flags(fq_subname, stashname_len, SVs_TEMP);
1179 linear_av = mro_get_linear_isa_c3(selfstash, 0); /* has ourselves at the top of the list */
1181 linear_svp = AvARRAY(linear_av);
1182 entries = AvFILLp(linear_av) + 1;
1184 /* Walk down our MRO, skipping everything up
1185 to the contextually enclosing class */
1187 SV * const linear_sv = *linear_svp++;
1189 if(sv_eq(linear_sv, stashname))
1193 /* Now search the remainder of the MRO for the
1194 same method name as the contextually enclosing
1198 SV * const linear_sv = *linear_svp++;
1204 curstash = gv_stashsv(linear_sv, FALSE);
1207 if (ckWARN(WARN_SYNTAX))
1208 Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Can't locate package %"SVf" for @%s::ISA",
1209 (void*)linear_sv, hvname);
1215 gvp = (GV**)hv_fetch(curstash, subname, subname_len, 0);
1221 if (SvTYPE(candidate) != SVt_PVGV)
1222 gv_init(candidate, curstash, subname, subname_len, TRUE);
1224 /* Notably, we only look for real entries, not method cache
1225 entries, because in C3 the method cache of a parent is not
1226 valid for the child */
1227 if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) {
1228 SvREFCNT_inc_simple_void_NN(MUTABLE_SV(cand_cv));
1229 (void)hv_store_ent(nmcache, newSVsv(sv), MUTABLE_SV(cand_cv), 0);
1230 mXPUSHs(newRV_inc(MUTABLE_SV(cand_cv)));
1236 (void)hv_store_ent(nmcache, newSVsv(sv), &PL_sv_undef, 0);
1238 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
1244 * c-indentation-style: bsd
1246 * indent-tabs-mode: t
1249 * ex: set ts=8 sts=4 sw=4 noet: