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
30 static const struct mro_alg dfs_alg =
31 {S_mro_get_linear_isa_dfs, "dfs", 3, 0, 0};
34 Perl_mro_get_private_data(pTHX_ struct mro_meta *const smeta,
35 const struct mro_alg *const which)
38 PERL_ARGS_ASSERT_MRO_GET_PRIVATE_DATA;
40 data = Perl_hv_common(aTHX_ MUTABLE_HV(smeta->mro_linear_dfs), NULL,
41 which->name, which->length, which->kflags,
42 HV_FETCH_JUST_SV, NULL, which->hash);
46 /* If we've been asked to look up the private data for the current MRO, then
48 if (smeta->mro_which == which)
49 smeta->mro_linear_c3 = MUTABLE_AV(*data);
55 Perl_mro_set_private_data(pTHX_ struct mro_meta *const smeta,
56 const struct mro_alg *const which, SV *const data)
58 PERL_ARGS_ASSERT_MRO_SET_PRIVATE_DATA;
60 if (!smeta->mro_linear_dfs) {
61 if (smeta->mro_which == which) {
62 /* If all we need to store is the current MRO's data, then don't use
63 memory on a hash with 1 element - store it direct, and signal
64 this by leaving the would-be-hash NULL. */
65 smeta->mro_linear_c3 = MUTABLE_AV(data);
68 HV *const hv = newHV();
69 /* Start with 2 buckets. It's unlikely we'll need more. */
71 smeta->mro_linear_dfs = MUTABLE_AV(hv);
73 if (smeta->mro_linear_c3) {
74 /* If we were storing something directly, put it in the hash
76 Perl_mro_set_private_data(aTHX_ smeta, smeta->mro_which,
77 MUTABLE_SV(smeta->mro_linear_c3));
82 /* We get here if we're storing more than one linearisation for this stash,
83 or the linearisation we are storing is not that if its current MRO. */
85 if (smeta->mro_which == which) {
86 /* If we've been asked to store the private data for the current MRO,
88 smeta->mro_linear_c3 = MUTABLE_AV(data);
91 if (!Perl_hv_common(aTHX_ MUTABLE_HV(smeta->mro_linear_dfs), NULL,
92 which->name, which->length, which->kflags,
93 HV_FETCH_ISSTORE, data, which->hash)) {
94 Perl_croak(aTHX_ "panic: hv_store() failed in set_mro_private_data() "
95 "for '%.*s' %d", (int) which->length, which->name,
102 const struct mro_alg *
103 Perl_mro_get_from_name(pTHX_ SV *name) {
106 PERL_ARGS_ASSERT_MRO_GET_FROM_NAME;
108 data = Perl_hv_common(aTHX_ PL_registered_mros, name, NULL, 0, 0,
109 HV_FETCH_JUST_SV, NULL, 0);
112 assert(SvTYPE(*data) == SVt_IV);
113 assert(SvIOK(*data));
114 return INT2PTR(const struct mro_alg *, SvUVX(*data));
118 Perl_mro_register(pTHX_ const struct mro_alg *mro) {
119 SV *wrapper = newSVuv(PTR2UV(mro));
121 PERL_ARGS_ASSERT_MRO_REGISTER;
124 if (!Perl_hv_common(aTHX_ PL_registered_mros, NULL,
125 mro->name, mro->length, mro->kflags,
126 HV_FETCH_ISSTORE, wrapper, mro->hash)) {
127 SvREFCNT_dec(wrapper);
128 Perl_croak(aTHX_ "panic: hv_store() failed in mro_register() "
129 "for '%.*s' %d", (int) mro->length, mro->name, mro->kflags);
134 Perl_mro_meta_init(pTHX_ HV* stash)
136 struct mro_meta* newmeta;
138 PERL_ARGS_ASSERT_MRO_META_INIT;
139 assert(HvAUX(stash));
140 assert(!(HvAUX(stash)->xhv_mro_meta));
141 Newxz(newmeta, 1, struct mro_meta);
142 HvAUX(stash)->xhv_mro_meta = newmeta;
143 newmeta->cache_gen = 1;
144 newmeta->pkg_gen = 1;
145 newmeta->mro_which = &dfs_alg;
150 #if defined(USE_ITHREADS)
152 /* for sv_dup on new threads */
154 Perl_mro_meta_dup(pTHX_ struct mro_meta* smeta, CLONE_PARAMS* param)
156 struct mro_meta* newmeta;
158 PERL_ARGS_ASSERT_MRO_META_DUP;
160 Newx(newmeta, 1, struct mro_meta);
161 Copy(smeta, newmeta, 1, struct mro_meta);
163 if (newmeta->mro_linear_dfs) {
164 newmeta->mro_linear_dfs
165 = MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_dfs, param)));
166 /* This is just acting as a shortcut pointer, and will be automatically
167 updated on the first get. */
168 newmeta->mro_linear_c3 = NULL;
169 } else if (newmeta->mro_linear_c3) {
170 /* Only the current MRO is stored, so this owns the data. */
171 newmeta->mro_linear_c3
172 = MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_c3, param)));
175 if (newmeta->mro_nextmethod)
176 newmeta->mro_nextmethod
177 = MUTABLE_HV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_nextmethod, param)));
180 = MUTABLE_HV(SvREFCNT_inc(sv_dup((const SV *)newmeta->isa, param)));
185 #endif /* USE_ITHREADS */
188 Perl_get_isa_hash(pTHX_ HV *const stash)
191 struct mro_meta *const meta = HvMROMETA(stash);
193 PERL_ARGS_ASSERT_GET_ISA_HASH;
196 AV *const isa = mro_get_linear_isa(stash);
198 HV *const isa_hash = newHV();
199 /* Linearisation didn't build it for us, so do it here. */
200 SV *const *svp = AvARRAY(isa);
201 SV *const *const svp_end = svp + AvFILLp(isa) + 1;
202 const HEK *const canon_name = HvNAME_HEK(stash);
204 while (svp < svp_end) {
205 (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
208 (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
209 HEK_LEN(canon_name), HEK_FLAGS(canon_name),
210 HV_FETCH_ISSTORE, &PL_sv_undef,
211 HEK_HASH(canon_name));
212 (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
214 SvREADONLY_on(isa_hash);
216 meta->isa = isa_hash;
223 =for apidoc mro_get_linear_isa_dfs
225 Returns the Depth-First Search linearization of @ISA
226 the given stash. The return value is a read-only AV*.
227 C<level> should be 0 (it is used internally in this
228 function's recursion).
230 You are responsible for C<SvREFCNT_inc()> on the
231 return value if you plan to store it anywhere
232 semi-permanently (otherwise it might be deleted
233 out from under you the next time the cache is
239 S_mro_get_linear_isa_dfs(pTHX_ HV *stash, U32 level)
246 struct mro_meta* meta;
250 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA_DFS;
251 assert(HvAUX(stash));
253 stashhek = HvNAME_HEK(stash);
255 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
258 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
261 meta = HvMROMETA(stash);
263 /* return cache if valid */
264 if((retval = MUTABLE_AV(MRO_GET_PRIVATE_DATA(meta, &dfs_alg)))) {
268 /* not in cache, make a new one */
270 retval = MUTABLE_AV(sv_2mortal(MUTABLE_SV(newAV())));
271 /* We use this later in this function, but don't need a reference to it
272 beyond the end of this function, so reference count is fine. */
273 our_name = newSVhek(stashhek);
274 av_push(retval, our_name); /* add ourselves at the top */
277 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
278 av = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
280 /* "stored" is used to keep track of all of the classnames we have added to
281 the MRO so far, so we can do a quick exists check and avoid adding
282 duplicate classnames to the MRO as we go.
283 It's then retained to be re-used as a fast lookup for ->isa(), by adding
284 our own name and "UNIVERSAL" to it. */
286 stored = MUTABLE_HV(sv_2mortal(MUTABLE_SV(newHV())));
288 if(av && AvFILLp(av) >= 0) {
290 SV **svp = AvARRAY(av);
291 I32 items = AvFILLp(av) + 1;
295 SV* const sv = *svp++;
296 HV* const basestash = gv_stashsv(sv, 0);
301 /* if no stash exists for this @ISA member,
302 simply add it to the MRO and move on */
307 /* otherwise, recurse into ourselves for the MRO
308 of this @ISA member, and append their MRO to ours.
309 The recursive call could throw an exception, which
310 has memory management implications here, hence the use of
312 const AV *const subrv
313 = mro_get_linear_isa_dfs(basestash, level + 1);
315 subrv_p = AvARRAY(subrv);
316 subrv_items = AvFILLp(subrv) + 1;
318 while(subrv_items--) {
319 SV *const subsv = *subrv_p++;
320 /* LVALUE fetch will create a new undefined SV if necessary
322 HE *const he = hv_fetch_ent(stored, subsv, 1, 0);
324 if(HeVAL(he) != &PL_sv_undef) {
325 /* It was newly created. Steal it for our new SV, and
326 replace it in the hash with the "real" thing. */
327 SV *const val = HeVAL(he);
328 HEK *const key = HeKEY_hek(he);
330 HeVAL(he) = &PL_sv_undef;
331 /* Save copying by making a shared hash key scalar. We
332 inline this here rather than calling Perl_newSVpvn_share
333 because we already have the scalar, and we already have
335 assert(SvTYPE(val) == SVt_NULL);
336 sv_upgrade(val, SVt_PV);
337 SvPV_set(val, HEK_KEY(share_hek_hek(key)));
338 SvCUR_set(val, HEK_LEN(key));
345 av_push(retval, val);
351 (void) hv_store_ent(stored, our_name, &PL_sv_undef, 0);
352 (void) hv_store(stored, "UNIVERSAL", 9, &PL_sv_undef, 0);
354 SvREFCNT_inc_simple_void_NN(stored);
356 SvREADONLY_on(stored);
360 /* now that we're past the exception dangers, grab our own reference to
361 the AV we're about to use for the result. The reference owned by the
362 mortals' stack will be released soon, so everything will balance. */
363 SvREFCNT_inc_simple_void_NN(retval);
366 /* we don't want anyone modifying the cache entry but us,
367 and we do so by replacing it completely */
368 SvREADONLY_on(retval);
370 return MUTABLE_AV(Perl_mro_set_private_data(aTHX_ meta, &dfs_alg,
371 MUTABLE_SV(retval)));
375 =for apidoc mro_get_linear_isa
377 Returns either C<mro_get_linear_isa_c3> or
378 C<mro_get_linear_isa_dfs> for the given stash,
379 dependant upon which MRO is in effect
380 for that stash. The return value is a
383 You are responsible for C<SvREFCNT_inc()> on the
384 return value if you plan to store it anywhere
385 semi-permanently (otherwise it might be deleted
386 out from under you the next time the cache is
392 Perl_mro_get_linear_isa(pTHX_ HV *stash)
394 struct mro_meta* meta;
396 PERL_ARGS_ASSERT_MRO_GET_LINEAR_ISA;
398 Perl_croak(aTHX_ "Can't linearize anonymous symbol table");
400 meta = HvMROMETA(stash);
401 if (!meta->mro_which)
402 Perl_croak(aTHX_ "panic: invalid MRO!");
403 return meta->mro_which->resolve(aTHX_ stash, 0);
407 =for apidoc mro_isa_changed_in
409 Takes the necessary steps (cache invalidations, mostly)
410 when the @ISA of the given package has changed. Invoked
411 by the C<setisa> magic, should not need to invoke directly.
416 Perl_mro_isa_changed_in(pTHX_ HV* stash)
425 struct mro_meta * meta;
427 const char * const stashname = HvNAME_get(stash);
428 const STRLEN stashname_len = HvNAMELEN_get(stash);
430 PERL_ARGS_ASSERT_MRO_ISA_CHANGED_IN;
433 Perl_croak(aTHX_ "Can't call mro_isa_changed_in() on anonymous symbol table");
435 /* wipe out the cached linearizations for this stash */
436 meta = HvMROMETA(stash);
437 if (meta->mro_linear_dfs) {
438 SvREFCNT_dec(MUTABLE_SV(meta->mro_linear_dfs));
439 meta->mro_linear_dfs = NULL;
440 /* This is just acting as a shortcut pointer. */
441 meta->mro_linear_c3 = NULL;
442 } else if (meta->mro_linear_c3) {
443 /* Only the current MRO is stored, so this owns the data. */
444 SvREFCNT_dec(MUTABLE_SV(meta->mro_linear_c3));
445 meta->mro_linear_c3 = NULL;
448 SvREFCNT_dec(meta->isa);
452 /* Inc the package generation, since our @ISA changed */
455 /* Wipe the global method cache if this package
456 is UNIVERSAL or one of its parents */
458 svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
459 isarev = svp ? MUTABLE_HV(*svp) : NULL;
461 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
462 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
466 else { /* Wipe the local method cache otherwise */
468 is_universal = FALSE;
471 /* wipe next::method cache too */
472 if(meta->mro_nextmethod) hv_clear(meta->mro_nextmethod);
474 /* Iterate the isarev (classes that are our children),
475 wiping out their linearization and method caches */
478 while((iter = hv_iternext(isarev))) {
480 const char* const revkey = hv_iterkey(iter, &len);
481 HV* revstash = gv_stashpvn(revkey, len, 0);
482 struct mro_meta* revmeta;
484 if(!revstash) continue;
485 revmeta = HvMROMETA(revstash);
486 if (revmeta->mro_linear_dfs) {
487 SvREFCNT_dec(MUTABLE_SV(revmeta->mro_linear_dfs));
488 revmeta->mro_linear_dfs = NULL;
489 /* This is just acting as a shortcut pointer. */
490 revmeta->mro_linear_c3 = NULL;
491 } else if (revmeta->mro_linear_c3) {
492 /* Only the current MRO is stored, so this owns the data. */
493 SvREFCNT_dec(MUTABLE_SV(revmeta->mro_linear_c3));
494 revmeta->mro_linear_c3 = NULL;
497 revmeta->cache_gen++;
498 if(revmeta->mro_nextmethod)
499 hv_clear(revmeta->mro_nextmethod);
503 /* Now iterate our MRO (parents), and do a few things:
504 1) instantiate with the "fake" flag if they don't exist
505 2) flag them as universal if we are universal
506 3) Add everything from our isarev to their isarev
509 /* We're starting at the 2nd element, skipping ourselves here */
510 linear_mro = mro_get_linear_isa(stash);
511 svp = AvARRAY(linear_mro) + 1;
512 items = AvFILLp(linear_mro);
515 SV* const sv = *svp++;
518 HE *he = hv_fetch_ent(PL_isarev, sv, TRUE, 0);
520 /* That fetch should not fail. But if it had to create a new SV for
521 us, then will need to upgrade it to an HV (which sv_upgrade() can
524 mroisarev = MUTABLE_HV(HeVAL(he));
526 SvUPGRADE(MUTABLE_SV(mroisarev), SVt_PVHV);
528 /* This hash only ever contains PL_sv_yes. Storing it over itself is
529 almost as cheap as calling hv_exists, so on aggregate we expect to
530 save time by not making two calls to the common HV code for the
531 case where it doesn't exist. */
533 (void)hv_store(mroisarev, stashname, stashname_len, &PL_sv_yes, 0);
537 while((iter = hv_iternext(isarev))) {
539 char* const revkey = hv_iterkey(iter, &revkeylen);
540 (void)hv_store(mroisarev, revkey, revkeylen, &PL_sv_yes, 0);
547 =for apidoc mro_method_changed_in
549 Invalidates method caching on any child classes
550 of the given stash, so that they might notice
551 the changes in this one.
553 Ideally, all instances of C<PL_sub_generation++> in
554 perl source outside of C<mro.c> should be
555 replaced by calls to this.
557 Perl automatically handles most of the common
558 ways a method might be redefined. However, there
559 are a few ways you could change a method in a stash
560 without the cache code noticing, in which case you
561 need to call this method afterwards:
563 1) Directly manipulating the stash HV entries from
566 2) Assigning a reference to a readonly scalar
567 constant into a stash entry in order to create
568 a constant subroutine (like constant.pm
571 This same method is available from pure perl
572 via, C<mro::method_changed_in(classname)>.
577 Perl_mro_method_changed_in(pTHX_ HV *stash)
579 const char * const stashname = HvNAME_get(stash);
580 const STRLEN stashname_len = HvNAMELEN_get(stash);
582 SV ** const svp = hv_fetch(PL_isarev, stashname, stashname_len, 0);
583 HV * const isarev = svp ? MUTABLE_HV(*svp) : NULL;
585 PERL_ARGS_ASSERT_MRO_METHOD_CHANGED_IN;
588 Perl_croak(aTHX_ "Can't call mro_method_changed_in() on anonymous symbol table");
590 /* Inc the package generation, since a local method changed */
591 HvMROMETA(stash)->pkg_gen++;
593 /* If stash is UNIVERSAL, or one of UNIVERSAL's parents,
594 invalidate all method caches globally */
595 if((stashname_len == 9 && strEQ(stashname, "UNIVERSAL"))
596 || (isarev && hv_exists(isarev, "UNIVERSAL", 9))) {
601 /* else, invalidate the method caches of all child classes,
607 while((iter = hv_iternext(isarev))) {
609 const char* const revkey = hv_iterkey(iter, &len);
610 HV* const revstash = gv_stashpvn(revkey, len, 0);
611 struct mro_meta* mrometa;
613 if(!revstash) continue;
614 mrometa = HvMROMETA(revstash);
615 mrometa->cache_gen++;
616 if(mrometa->mro_nextmethod)
617 hv_clear(mrometa->mro_nextmethod);
624 XS(XS_mro_get_linear_isa);
627 XS(XS_mro_get_isarev);
628 XS(XS_mro_is_universal);
629 XS(XS_mro_invalidate_method_caches);
630 XS(XS_mro_method_changed_in);
631 XS(XS_mro_get_pkg_gen);
634 Perl_boot_core_mro(pTHX)
637 static const char file[] = __FILE__;
639 Perl_mro_register(aTHX_ &dfs_alg);
641 newXSproto("mro::get_linear_isa", XS_mro_get_linear_isa, file, "$;$");
642 newXSproto("mro::set_mro", XS_mro_set_mro, file, "$$");
643 newXSproto("mro::get_mro", XS_mro_get_mro, file, "$");
644 newXSproto("mro::get_isarev", XS_mro_get_isarev, file, "$");
645 newXSproto("mro::is_universal", XS_mro_is_universal, file, "$");
646 newXSproto("mro::invalidate_all_method_caches", XS_mro_invalidate_method_caches, file, "");
647 newXSproto("mro::method_changed_in", XS_mro_method_changed_in, file, "$");
648 newXSproto("mro::get_pkg_gen", XS_mro_get_pkg_gen, file, "$");
651 XS(XS_mro_get_linear_isa) {
658 if(items < 1 || items > 2)
659 croak_xs_usage(cv, "classname [, type ]");
662 class_stash = gv_stashsv(classname, 0);
665 /* No stash exists yet, give them just the classname */
666 AV* isalin = newAV();
667 av_push(isalin, newSVsv(classname));
668 ST(0) = sv_2mortal(newRV_noinc(MUTABLE_SV(isalin)));
672 const struct mro_alg *const algo = Perl_mro_get_from_name(aTHX_ ST(1));
674 Perl_croak(aTHX_ "Invalid mro name: '%"SVf"'", ST(1));
675 RETVAL = algo->resolve(aTHX_ class_stash, 0);
678 RETVAL = mro_get_linear_isa(class_stash);
681 ST(0) = newRV_inc(MUTABLE_SV(RETVAL));
691 const struct mro_alg *which;
693 struct mro_meta* meta;
696 croak_xs_usage(cv, "classname, type");
699 class_stash = gv_stashsv(classname, GV_ADD);
700 if(!class_stash) Perl_croak(aTHX_ "Cannot create class: '%"SVf"'!", SVfARG(classname));
701 meta = HvMROMETA(class_stash);
703 which = Perl_mro_get_from_name(aTHX_ ST(1));
705 Perl_croak(aTHX_ "Invalid mro name: '%"SVf"'", ST(1));
707 if(meta->mro_which != which) {
708 if (meta->mro_linear_c3 && !meta->mro_linear_dfs) {
709 /* If we were storing something directly, put it in the hash before
711 Perl_mro_set_private_data(aTHX_ meta, meta->mro_which,
712 MUTABLE_SV(meta->mro_linear_c3));
714 meta->mro_which = which;
715 /* Scrub our cached pointer to the private data. */
716 meta->mro_linear_c3 = NULL;
717 /* Only affects local method cache, not
718 even child classes */
720 if(meta->mro_nextmethod)
721 hv_clear(meta->mro_nextmethod);
736 croak_xs_usage(cv, "classname");
739 class_stash = gv_stashsv(classname, 0);
741 ST(0) = sv_2mortal(newSVpv(class_stash
742 ? HvMROMETA(class_stash)->mro_which->name
747 XS(XS_mro_get_isarev)
757 croak_xs_usage(cv, "classname");
764 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
765 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
771 while((iter = hv_iternext(isarev)))
772 av_push(ret_array, newSVsv(hv_iterkeysv(iter)));
774 mXPUSHs(newRV_noinc(MUTABLE_SV(ret_array)));
780 XS(XS_mro_is_universal)
787 STRLEN classname_len;
791 croak_xs_usage(cv, "classname");
795 classname_pv = SvPV(classname,classname_len);
797 he = hv_fetch_ent(PL_isarev, classname, 0, 0);
798 isarev = he ? MUTABLE_HV(HeVAL(he)) : NULL;
800 if((classname_len == 9 && strEQ(classname_pv, "UNIVERSAL"))
801 || (isarev && hv_exists(isarev, "UNIVERSAL", 9)))
807 XS(XS_mro_invalidate_method_caches)
813 croak_xs_usage(cv, "");
820 XS(XS_mro_method_changed_in)
828 croak_xs_usage(cv, "classname");
832 class_stash = gv_stashsv(classname, 0);
833 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
835 mro_method_changed_in(class_stash);
840 XS(XS_mro_get_pkg_gen)
848 croak_xs_usage(cv, "classname");
852 class_stash = gv_stashsv(classname, 0);
856 mXPUSHi(class_stash ? HvMROMETA(class_stash)->pkg_gen : 0);
864 * c-indentation-style: bsd
866 * indent-tabs-mode: t
869 * ex: set ts=8 sts=4 sw=4 noet: