3 * Copyright (c) 2007 Brandon L Black
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.
11 * "Which order shall we go in?" said Frodo. "Eldest first, or quickest first?
12 * You'll be last either way, Master Peregrin."
18 These functions are related to the method resolution order of perl classes
27 Perl_mro_meta_init(pTHX_ HV* stash)
29 struct mro_meta* newmeta;
33 assert(!(HvAUX(stash)->xhv_mro_meta));
34 Newxc(newmeta, sizeof(struct mro_meta), char, struct mro_meta);
35 HvAUX(stash)->xhv_mro_meta = newmeta;
36 newmeta->sub_generation = 1;
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
43 if(HvNAMELEN_get(stash) == 9
44 && strEQ(HEK_KEY(HvAUX(stash)->xhv_name), "UNIVERSAL")) {
45 HvMROMETA(stash)->is_universal = 1;
51 #if defined(USE_ITHREADS)
53 /* for sv_dup on new threads */
55 Perl_mro_meta_dup(pTHX_ struct mro_meta* smeta, CLONE_PARAMS* param)
57 struct mro_meta* newmeta;
61 Newxc(newmeta, sizeof(struct mro_meta), char, struct mro_meta);
63 newmeta->mro_which = smeta->mro_which;
64 newmeta->sub_generation = smeta->sub_generation;
65 newmeta->is_universal = smeta->is_universal;
66 newmeta->fake = smeta->fake;
67 newmeta->mro_linear_dfs = smeta->mro_linear_dfs
68 ? (AV*) SvREFCNT_inc(sv_dup((SV*)smeta->mro_linear_dfs, param))
70 newmeta->mro_linear_c3 = smeta->mro_linear_c3
71 ? (AV*) SvREFCNT_inc(sv_dup((SV*)smeta->mro_linear_c3, param))
73 newmeta->mro_isarev = smeta->mro_isarev
74 ? (HV*) SvREFCNT_inc(sv_dup((SV*)smeta->mro_isarev, param))
76 newmeta->mro_nextmethod = smeta->mro_nextmethod
77 ? (HV*) SvREFCNT_inc(sv_dup((SV*)smeta->mro_nextmethod, param))
83 #endif /* USE_ITHREADS */
86 =for apidoc mro_get_linear_isa_dfs
88 Returns the Depth-First Search linearization of @ISA
89 the given stash. The return value is a read-only AV*.
90 C<level> should be 0 (it is used internally in this
91 function's recursion).
96 Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
107 const char* stashname;
108 struct mro_meta* meta;
111 assert(HvAUX(stash));
113 stashname = HvNAME_get(stash);
116 "Can't linearize anonymous symbol table");
119 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
122 meta = HvMROMETA(stash);
123 if((retval = meta->mro_linear_dfs)) {
124 /* return cache if valid */
128 /* not in cache, make a new one */
130 av_push(retval, newSVpv(stashname, 0)); /* add ourselves at the top */
132 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
133 av = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
136 HV* stored = (HV*)sv_2mortal((SV*)newHV());
138 items = AvFILLp(av) + 1;
140 SV* const sv = *svp++;
141 HV* const basestash = gv_stashsv(sv, 0);
144 if(!hv_exists_ent(stored, sv, 0)) {
145 av_push(retval, newSVsv(sv));
146 hv_store_ent(stored, sv, &PL_sv_undef, 0);
150 subrv = mro_get_linear_isa_dfs(basestash, level + 1);
151 subrv_p = AvARRAY(subrv);
152 subrv_items = AvFILLp(subrv) + 1;
153 while(subrv_items--) {
154 SV* subsv = *subrv_p++;
155 if(!hv_exists_ent(stored, subsv, 0)) {
156 av_push(retval, newSVsv(subsv));
157 hv_store_ent(stored, subsv, &PL_sv_undef, 0);
164 SvREADONLY_on(retval);
165 meta->mro_linear_dfs = retval;
170 =for apidoc mro_get_linear_isa_c3
172 Returns the C3 linearization of @ISA
173 the given stash. The return value is a read-only AV*.
174 C<level> should be 0 (it is used internally in this
175 function's recursion).
181 Perl_mro_get_linear_isa_c3(pTHX_ HV* stash, I32 level)
187 const char* stashname;
188 STRLEN stashname_len;
189 struct mro_meta* meta;
192 assert(HvAUX(stash));
194 stashname = HvNAME_get(stash);
195 stashname_len = HvNAMELEN_get(stash);
198 "Can't linearize anonymous symbol table");
201 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
204 meta = HvMROMETA(stash);
205 if((retval = meta->mro_linear_c3)) {
206 /* return cache if valid */
210 /* not in cache, make a new one */
213 av_push(retval, newSVpvn(stashname, stashname_len)); /* us first */
215 gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
216 isa = (gvp && (gv = *gvp) && isGV_with_GP(gv)) ? GvAV(gv) : NULL;
218 if(isa && AvFILLp(isa) >= 0) {
221 HV* tails = (HV*)sv_2mortal((SV*)newHV());
222 AV* seqs = (AV*)sv_2mortal((SV*)newAV());
223 I32 items = AvFILLp(isa) + 1;
224 SV** isa_ptr = AvARRAY(isa);
227 SV* isa_item = *isa_ptr++;
228 HV* isa_item_stash = gv_stashsv(isa_item, 0);
229 if(!isa_item_stash) {
231 av_push(isa_lin, newSVsv(isa_item));
234 isa_lin = mro_get_linear_isa_c3(isa_item_stash, level + 1); /* recursion */
236 av_push(seqs, (SV*)av_make(AvFILLp(isa_lin)+1, AvARRAY(isa_lin)));
238 av_push(seqs, (SV*)av_make(AvFILLp(isa)+1, AvARRAY(isa)));
240 seqs_ptr = AvARRAY(seqs);
241 seqs_items = AvFILLp(seqs) + 1;
242 while(seqs_items--) {
243 AV* seq = (AV*)*seqs_ptr++;
244 I32 seq_items = AvFILLp(seq);
246 SV** seq_ptr = AvARRAY(seq) + 1;
248 SV* seqitem = *seq_ptr++;
249 HE* he = hv_fetch_ent(tails, seqitem, 0, 0);
251 hv_store_ent(tails, seqitem, newSViv(1), 0);
268 SV** avptr = AvARRAY(seqs);
269 items = AvFILLp(seqs)+1;
273 if(AvFILLp(seq) < 0) continue;
274 svp = av_fetch(seq, 0, 0);
278 if((tail_entry = hv_fetch_ent(tails, cand, 0, 0))
279 && (val = HeVAL(tail_entry))
282 winner = newSVsv(cand);
283 av_push(retval, winner);
285 if(!sv_cmp(seqhead, winner)) {
287 /* this is basically shift(@seq) in void context */
288 SvREFCNT_dec(*AvARRAY(seq));
289 *AvARRAY(seq) = &PL_sv_undef;
290 AvARRAY(seq) = AvARRAY(seq) + 1;
294 if(AvFILLp(seq) < 0) continue;
295 svp = av_fetch(seq, 0, 0);
297 tail_entry = hv_fetch_ent(tails, seqhead, 0, 0);
298 val = HeVAL(tail_entry);
304 SvREFCNT_dec(retval);
305 Perl_croak(aTHX_ "Inconsistent hierarchy during C3 merge of class '%s': "
306 "merging failed on parent '%"SVf"'", stashname, SVfARG(cand));
311 SvREADONLY_on(retval);
312 meta->mro_linear_c3 = retval;
317 =for apidoc mro_get_linear_isa
319 Returns either C<mro_get_linear_isa_c3> or
320 C<mro_get_linear_isa_dfs> for the given stash,
321 dependant upon which MRO is in effect
322 for that stash. The return value is a
328 Perl_mro_get_linear_isa(pTHX_ HV *stash)
330 struct mro_meta* meta;
332 assert(HvAUX(stash));
334 meta = HvMROMETA(stash);
335 if(meta->mro_which == MRO_DFS) {
336 return mro_get_linear_isa_dfs(stash, 0);
337 } else if(meta->mro_which == MRO_C3) {
338 return mro_get_linear_isa_c3(stash, 0);
340 Perl_croak(aTHX_ "panic: invalid MRO!");
345 =for apidoc mro_isa_changed_in
347 Takes the neccesary steps (cache invalidations, mostly)
348 when the @ISA of the given package has changed. Invoked
349 by the C<setisa> magic, should not need to invoke directly.
354 Perl_mro_isa_changed_in(pTHX_ HV* stash)
362 struct mro_meta* meta;
365 stashname = HvNAME_get(stash);
367 /* wipe out the cached linearizations for this stash */
368 meta = HvMROMETA(stash);
369 SvREFCNT_dec((SV*)meta->mro_linear_dfs);
370 SvREFCNT_dec((SV*)meta->mro_linear_c3);
371 meta->mro_linear_dfs = NULL;
372 meta->mro_linear_c3 = NULL;
374 /* Wipe the global method cache if this package
375 is UNIVERSAL or one of its parents */
376 if(meta->is_universal)
379 /* Wipe the local method cache otherwise */
381 meta->sub_generation++;
383 /* wipe next::method cache too */
384 if(meta->mro_nextmethod) hv_clear(meta->mro_nextmethod);
386 /* Iterate the isarev (classes that are our children),
387 wiping out their linearization and method caches */
388 if((isarev = meta->mro_isarev)) {
390 while((iter = hv_iternext(isarev))) {
391 SV* revkey = hv_iterkeysv(iter);
392 HV* revstash = gv_stashsv(revkey, 0);
393 struct mro_meta* revmeta = HvMROMETA(revstash);
394 SvREFCNT_dec((SV*)revmeta->mro_linear_dfs);
395 SvREFCNT_dec((SV*)revmeta->mro_linear_c3);
396 revmeta->mro_linear_dfs = NULL;
397 revmeta->mro_linear_c3 = NULL;
398 if(!meta->is_universal)
399 revmeta->sub_generation++;
400 if(revmeta->mro_nextmethod)
401 hv_clear(revmeta->mro_nextmethod);
405 /* we're starting at the 2nd element, skipping ourselves here */
406 linear_mro = mro_get_linear_isa(stash);
407 svp = AvARRAY(linear_mro) + 1;
408 items = AvFILLp(linear_mro);
410 SV* const sv = *svp++;
411 struct mro_meta* mrometa;
414 HV* mrostash = gv_stashsv(sv, 0);
416 mrostash = gv_stashsv(sv, GV_ADD);
418 We created the package on the fly, so
419 that we could store isarev information.
420 This flag lets gv_fetchmeth know about it,
421 so that it can still generate the very useful
422 "Can't locate package Foo for @Bar::ISA" warning.
424 HvMROMETA(mrostash)->fake = 1;
427 mrometa = HvMROMETA(mrostash);
428 mroisarev = mrometa->mro_isarev;
430 /* is_universal is viral */
431 if(meta->is_universal)
432 mrometa->is_universal = 1;
435 mroisarev = mrometa->mro_isarev = newHV();
437 if(!hv_exists(mroisarev, stashname, strlen(stashname)))
438 hv_store(mroisarev, stashname, strlen(stashname), &PL_sv_yes, 0);
442 while((iter = hv_iternext(isarev))) {
443 SV* revkey = hv_iterkeysv(iter);
444 if(!hv_exists_ent(mroisarev, revkey, 0))
445 hv_store_ent(mroisarev, revkey, &PL_sv_yes, 0);
452 =for apidoc mro_method_changed_in
454 Like C<mro_isa_changed_in>, but invalidates method
455 caching on any child classes of the given stash, so
456 that they might notice the changes in this one.
458 Ideally, all instances of C<PL_sub_generation++> in
459 the perl source should be replaced by calls to this.
460 Some already are, but some are more difficult to
463 Perl has always had problems with method caches
464 getting out of sync when one directly manipulates
465 stashes via things like C<%{Foo::} = %{Bar::}> or
466 C<${Foo::}{bar} = ...> or the equivalent. If
467 you do this in core or XS code, call this afterwards
468 on the destination stash to get things back in sync.
470 If you're doing such a thing from pure perl, use
471 C<mro::method_changed_in(classname)>, which
477 Perl_mro_method_changed_in(pTHX_ HV *stash)
479 struct mro_meta* meta = HvMROMETA(stash);
483 /* If stash is UNIVERSAL, or one of UNIVERSAL's parents,
484 invalidate all method caches globally */
485 if(meta->is_universal) {
490 /* else, invalidate the method caches of all child classes,
492 if((isarev = meta->mro_isarev)) {
494 while((iter = hv_iternext(isarev))) {
495 SV* revkey = hv_iterkeysv(iter);
496 HV* revstash = gv_stashsv(revkey, 0);
497 struct mro_meta* mrometa = HvMROMETA(revstash);
498 mrometa->sub_generation++;
499 if(mrometa->mro_nextmethod)
500 hv_clear(mrometa->mro_nextmethod);
505 /* These two are static helpers for next::method and friends,
506 and re-implement a bunch of the code from pp_caller() in
507 a more efficient manner for this particular usage.
511 __dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) {
513 for (i = startingblock; i >= 0; i--) {
514 if(CxTYPE((PERL_CONTEXT*)(&cxstk[i])) == CXt_SUB) return i;
520 __nextcan(pTHX_ SV* self, I32 throw_nomethod)
523 register const PERL_CONTEXT *ccstack = cxstack;
524 const PERL_SI *top_si = PL_curstackinfo;
528 const char *fq_subname;
530 STRLEN fq_subname_len;
531 STRLEN stashname_len;
539 GV* candidate = NULL;
543 struct mro_meta* selfmeta;
547 if(sv_isobject(self))
548 selfstash = SvSTASH(SvRV(self));
550 selfstash = gv_stashsv(self, 0);
554 hvname = HvNAME_get(selfstash);
556 Perl_croak(aTHX_ "Can't use anonymous symbol table for method lookup");
558 cxix = __dopoptosub_at(cxstack, cxstack_ix);
560 /* This block finds the contextually-enclosing fully-qualified subname,
561 much like looking at (caller($i))[3] until you find a real sub that
564 /* we may be in a higher stacklevel, so dig down deeper */
566 if(top_si->si_type == PERLSI_MAIN)
567 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method must be used in method context");
568 top_si = top_si->si_prev;
569 ccstack = top_si->si_cxstack;
570 cxix = __dopoptosub_at(ccstack, top_si->si_cxix);
573 if(CxTYPE((PERL_CONTEXT*)(&ccstack[cxix])) != CXt_SUB
574 || (PL_DBsub && GvCV(PL_DBsub) && ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub))) {
575 cxix = __dopoptosub_at(ccstack, cxix - 1);
580 const I32 dbcxix = __dopoptosub_at(ccstack, cxix - 1);
581 if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) {
582 if(CxTYPE((PERL_CONTEXT*)(&ccstack[dbcxix])) != CXt_SUB) {
589 cvgv = CvGV(ccstack[cxix].blk_sub.cv);
592 cxix = __dopoptosub_at(ccstack, cxix - 1);
596 /* we found a real sub here */
597 sv = sv_2mortal(newSV(0));
599 gv_efullname3(sv, cvgv, NULL);
601 fq_subname = SvPVX(sv);
602 fq_subname_len = SvCUR(sv);
604 subname = strrchr(fq_subname, ':');
606 Perl_croak(aTHX_ "next::method/next::can/maybe::next::method cannot find enclosing method");
609 subname_len = fq_subname_len - (subname - fq_subname);
610 if(subname_len == 8 && strEQ(subname, "__ANON__")) {
611 cxix = __dopoptosub_at(ccstack, cxix - 1);
617 /* If we made it to here, we found our context */
619 selfmeta = HvMROMETA(selfstash);
620 if(!(nmcache = selfmeta->mro_nextmethod)) {
621 nmcache = selfmeta->mro_nextmethod = newHV();
624 if((cache_entry = hv_fetch_ent(nmcache, sv, 0, 0))) {
625 SV* val = HeVAL(cache_entry);
626 if(val == &PL_sv_undef) {
628 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
633 /* beyond here is just for cache misses, so perf isn't as critical */
635 stashname_len = subname - fq_subname - 2;
636 stashname = sv_2mortal(newSVpvn(fq_subname, stashname_len));
638 linear_av = mro_get_linear_isa_c3(selfstash, 0); /* has ourselves at the top of the list */
640 linear_svp = AvARRAY(linear_av);
641 items = AvFILLp(linear_av) + 1;
644 linear_sv = *linear_svp++;
646 if(sv_eq(linear_sv, stashname))
652 linear_sv = *linear_svp++;
654 curstash = gv_stashsv(linear_sv, FALSE);
656 if (!curstash || (HvMROMETA(curstash)->fake && !HvFILL(curstash))) {
657 if (ckWARN(WARN_SYNTAX))
658 Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Can't locate package %"SVf" for @%s::ISA",
659 (void*)linear_sv, hvname);
665 gvp = (GV**)hv_fetch(curstash, subname, subname_len, 0);
671 if (SvTYPE(candidate) != SVt_PVGV)
672 gv_init(candidate, curstash, subname, subname_len, TRUE);
673 if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) {
674 SvREFCNT_inc_simple_void_NN((SV*)cand_cv);
675 hv_store_ent(nmcache, newSVsv(sv), (SV*)cand_cv, 0);
681 hv_store_ent(nmcache, newSVsv(sv), &PL_sv_undef, 0);
683 Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
689 XS(XS_mro_get_linear_isa);
692 XS(XS_mro_get_isarev);
693 XS(XS_mro_is_universal);
694 XS(XS_mro_get_global_sub_generation);
695 XS(XS_mro_invalidate_all_method_caches);
696 XS(XS_mro_get_sub_generation);
697 XS(XS_mro_method_changed_in);
700 XS(XS_maybe_next_method);
703 Perl_boot_core_mro(pTHX)
706 static const char file[] = __FILE__;
708 newXSproto("mro::get_linear_isa", XS_mro_get_linear_isa, file, "$;$");
709 newXSproto("mro::set_mro", XS_mro_set_mro, file, "$$");
710 newXSproto("mro::get_mro", XS_mro_get_mro, file, "$");
711 newXSproto("mro::get_isarev", XS_mro_get_isarev, file, "$");
712 newXSproto("mro::is_universal", XS_mro_is_universal, file, "$");
713 newXSproto("mro::get_global_sub_generation", XS_mro_get_global_sub_generation, file, "");
714 newXSproto("mro::invalidate_all_method_caches", XS_mro_invalidate_all_method_caches, file, "");
715 newXSproto("mro::get_sub_generation", XS_mro_get_sub_generation, file, "$");
716 newXSproto("mro::method_changed_in", XS_mro_method_changed_in, file, "$");
717 newXS("next::can", XS_next_can, file);
718 newXS("next::method", XS_next_method, file);
719 newXS("maybe::next::method", XS_maybe_next_method, file);
722 XS(XS_mro_get_linear_isa) {
731 if(items < 1 || items > 2)
732 Perl_croak(aTHX_ "Usage: mro::get_linear_isa(classname [, type ])");
735 class_stash = gv_stashsv(classname, 0);
736 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
739 char* which = SvPV_nolen(ST(1));
740 if(strEQ(which, "dfs"))
741 RETVAL = mro_get_linear_isa_dfs(class_stash, 0);
742 else if(strEQ(which, "c3"))
743 RETVAL = mro_get_linear_isa_c3(class_stash, 0);
745 Perl_croak(aTHX_ "Invalid mro name: '%s'", which);
748 RETVAL = mro_get_linear_isa(class_stash);
751 ST(0) = newRV_inc((SV*)RETVAL);
764 struct mro_meta* meta;
769 Perl_croak(aTHX_ "Usage: mro::set_mro(classname, type)");
772 whichstr = SvPV_nolen(ST(1));
773 class_stash = gv_stashsv(classname, GV_ADD);
774 if(!class_stash) Perl_croak(aTHX_ "Cannot create class: '%"SVf"'!", SVfARG(classname));
775 meta = HvMROMETA(class_stash);
777 if(strEQ(whichstr, "dfs"))
779 else if(strEQ(whichstr, "c3"))
782 Perl_croak(aTHX_ "Invalid mro name: '%s'", whichstr);
784 if(meta->mro_which != which) {
785 meta->mro_which = which;
786 /* Only affects local method cache, not
787 even child classes */
788 meta->sub_generation++;
789 if(meta->mro_nextmethod)
790 hv_clear(meta->mro_nextmethod);
803 struct mro_meta* meta;
808 Perl_croak(aTHX_ "Usage: mro::get_mro(classname)");
811 class_stash = gv_stashsv(classname, 0);
812 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
813 meta = HvMROMETA(class_stash);
815 if(meta->mro_which == MRO_DFS)
816 ST(0) = sv_2mortal(newSVpvn("dfs", 3));
818 ST(0) = sv_2mortal(newSVpvn("c3", 2));
823 XS(XS_mro_get_isarev)
834 Perl_croak(aTHX_ "Usage: mro::get_isarev(classname)");
838 class_stash = gv_stashsv(classname, 0);
839 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
843 if((isarev = HvMROMETA(class_stash)->mro_isarev)) {
846 while((iter = hv_iternext(isarev)))
847 XPUSHs(hv_iterkeysv(iter));
854 XS(XS_mro_is_universal)
864 Perl_croak(aTHX_ "Usage: mro::get_mro(classname)");
867 class_stash = gv_stashsv(classname, 0);
868 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
870 if (HvMROMETA(class_stash)->is_universal)
876 XS(XS_mro_get_global_sub_generation)
884 Perl_croak(aTHX_ "Usage: mro::get_global_sub_generation()");
886 ST(0) = sv_2mortal(newSViv(PL_sub_generation));
890 XS(XS_mro_invalidate_all_method_caches)
898 Perl_croak(aTHX_ "Usage: mro::invalidate_all_method_caches()");
905 XS(XS_mro_get_sub_generation)
915 Perl_croak(aTHX_ "Usage: mro::get_sub_generation(classname)");
918 class_stash = gv_stashsv(classname, 0);
919 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
921 ST(0) = sv_2mortal(newSViv(HvMROMETA(class_stash)->sub_generation));
925 XS(XS_mro_method_changed_in)
935 Perl_croak(aTHX_ "Usage: mro::method_changed_in(classname)");
939 class_stash = gv_stashsv(classname, 0);
940 if(!class_stash) Perl_croak(aTHX_ "No such class: '%"SVf"'!", SVfARG(classname));
942 mro_method_changed_in(class_stash);
952 SV* methcv = __nextcan(aTHX_ self, 0);
955 PERL_UNUSED_VAR(items);
957 if(methcv == &PL_sv_undef) {
958 ST(0) = &PL_sv_undef;
961 ST(0) = sv_2mortal(newRV_inc(methcv));
972 SV* methcv = __nextcan(aTHX_ self, 1);
977 call_sv(methcv, GIMME_V);
980 XS(XS_maybe_next_method)
985 SV* methcv = __nextcan(aTHX_ self, 0);
989 if(methcv == &PL_sv_undef) {
990 ST(0) = &PL_sv_undef;
995 call_sv(methcv, GIMME_V);
1000 * c-indentation-style: bsd
1002 * indent-tabs-mode: t
1005 * ex: set ts=8 sts=4 sw=4 noet: