2 ==================================================================
3 --- Makefile.micro (/local/perl-current) (revision 12599)
4 +++ Makefile.micro (/local/perl-c3) (revision 12599)
8 O = uav$(_O) udeb$(_O) udoio$(_O) udoop$(_O) udump$(_O) \
9 - uglobals$(_O) ugv$(_O) uhv$(_O) \
10 + uglobals$(_O) ugv$(_O) uhv$(_O) umro$(_O)\
11 umg$(_O) uperlmain$(_O) uop$(_O) ureentr$(_O) \
12 upad$(_O) uperl$(_O) uperlio$(_O) uperly$(_O) upp$(_O) \
13 upp_ctl$(_O) upp_hot$(_O) upp_sys$(_O) upp_pack$(_O) upp_sort$(_O) \
16 $(CC) -c -o $@ $(CFLAGS) gv.c
18 +umro$(_O): $(HE) mro.c
19 + $(CC) -c -o $@ $(CFLAGS) mro.c
22 $(CC) -c -o $@ $(CFLAGS) hv.c
25 ==================================================================
26 --- embed.h (/local/perl-current) (revision 12599)
27 +++ embed.h (/local/perl-c3) (revision 12599)
29 #define gv_efullname Perl_gv_efullname
30 #define gv_efullname4 Perl_gv_efullname4
31 #define gv_fetchfile Perl_gv_fetchfile
32 +#define mro_meta_init Perl_mro_meta_init
33 +#define mro_linear Perl_mro_linear
34 +#define mro_linear_c3 Perl_mro_linear_c3
35 +#define mro_linear_dfs Perl_mro_linear_dfs
36 #define gv_fetchmeth Perl_gv_fetchmeth
37 #define gv_fetchmeth_autoload Perl_gv_fetchmeth_autoload
38 #define gv_fetchmethod_autoload Perl_gv_fetchmethod_autoload
39 @@ -2474,6 +2478,10 @@
40 #define gv_efullname(a,b) Perl_gv_efullname(aTHX_ a,b)
41 #define gv_efullname4(a,b,c,d) Perl_gv_efullname4(aTHX_ a,b,c,d)
42 #define gv_fetchfile(a) Perl_gv_fetchfile(aTHX_ a)
43 +#define mro_meta_init(a) Perl_mro_meta_init(aTHX_ a)
44 +#define mro_linear(a) Perl_mro_linear(aTHX_ a)
45 +#define mro_linear_c3(a,b) Perl_mro_linear_c3(aTHX_ a,b)
46 +#define mro_linear_dfs(a,b) Perl_mro_linear_dfs(aTHX_ a,b)
47 #define gv_fetchmeth(a,b,c,d) Perl_gv_fetchmeth(aTHX_ a,b,c,d)
48 #define gv_fetchmeth_autoload(a,b,c,d) Perl_gv_fetchmeth_autoload(aTHX_ a,b,c,d)
49 #define gv_fetchmethod_autoload(a,b,c) Perl_gv_fetchmethod_autoload(aTHX_ a,b,c)
51 ==================================================================
52 --- embedvar.h (/local/perl-current) (revision 12599)
53 +++ embedvar.h (/local/perl-c3) (revision 12599)
55 #define PL_incgv (vTHX->Iincgv)
56 #define PL_initav (vTHX->Iinitav)
57 #define PL_inplace (vTHX->Iinplace)
58 +#define PL_isa_generation (vTHX->Iisa_generation)
59 #define PL_known_layers (vTHX->Iknown_layers)
60 #define PL_last_lop (vTHX->Ilast_lop)
61 #define PL_last_lop_op (vTHX->Ilast_lop_op)
63 #define PL_Iincgv PL_incgv
64 #define PL_Iinitav PL_initav
65 #define PL_Iinplace PL_inplace
66 +#define PL_Iisa_generation PL_isa_generation
67 #define PL_Iknown_layers PL_known_layers
68 #define PL_Ilast_lop PL_last_lop
69 #define PL_Ilast_lop_op PL_last_lop_op
71 ==================================================================
72 --- pod/perlapi.pod (/local/perl-current) (revision 12599)
73 +++ pod/perlapi.pod (/local/perl-c3) (revision 12599)
75 The argument C<level> should be either 0 or -1. If C<level==0>, as a
76 side-effect creates a glob with the given C<name> in the given C<stash>
77 which in the case of success contains an alias for the subroutine, and sets
78 -up caching info for this glob. Similarly for all the searched stashes.
79 +up caching info for this glob.
81 This function grants C<"SUPER"> token as a postfix of the stash name. The
82 GV returned from C<gv_fetchmeth> may be a method cache entry, which is not
84 ==================================================================
85 --- global.sym (/local/perl-current) (revision 12599)
86 +++ global.sym (/local/perl-c3) (revision 12599)
96 Perl_gv_fetchmeth_autoload
99 ==================================================================
100 --- universal.c (/local/perl-current) (revision 12599)
101 +++ universal.c (/local/perl-c3) (revision 12599)
111 + AV* stash_linear_isa;
116 /* A stash/class can go by many names (ie. User == main::User), so
117 we compare the stash itself just in case */
119 if (strEQ(name, "UNIVERSAL"))
123 - Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
126 - gvp = (GV**)hv_fetchs(stash, "::ISA::CACHE::", FALSE);
128 - if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (subgen = GvSV(gv))
129 - && (hv = GvHV(gv)))
131 - if (SvIV(subgen) == (IV)PL_sub_generation) {
132 - SV** const svp = (SV**)hv_fetch(hv, name, len, FALSE);
134 - SV * const sv = *svp;
136 - if (sv != &PL_sv_undef)
137 - DEBUG_o( Perl_deb(aTHX_ "Using cached ISA %s for package %s\n",
140 - return (sv == &PL_sv_yes);
142 + stash_linear_isa = sv_2mortal(mro_linear(stash));
143 + svp = AvARRAY(stash_linear_isa) + 1;
144 + items = AvFILLp(stash_linear_isa);
146 + SV* const basename_sv = *svp++;
147 + HV* basestash = gv_stashsv(basename_sv, FALSE);
149 + if (ckWARN(WARN_MISC))
150 + Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
151 + "Can't locate package %"SVf" for the parents of %s",
152 + (void*)basename_sv, hvname);
156 - DEBUG_o( Perl_deb(aTHX_ "ISA Cache in package %s is stale\n",
159 - sv_setiv(subgen, PL_sub_generation);
161 + if(name_stash == basestash || strEQ(name, SvPVX(basename_sv)))
165 - gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
167 - if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (av = GvAV(gv))) {
168 - if (!hv || !subgen) {
169 - gvp = (GV**)hv_fetchs(stash, "::ISA::CACHE::", TRUE);
173 - if (SvTYPE(gv) != SVt_PVGV)
174 - gv_init(gv, stash, "::ISA::CACHE::", 14, TRUE);
179 - subgen = newSViv(PL_sub_generation);
184 - SV** svp = AvARRAY(av);
185 - /* NOTE: No support for tied ISA */
186 - I32 items = AvFILLp(av) + 1;
188 - SV* const sv = *svp++;
189 - HV* const basestash = gv_stashsv(sv, FALSE);
191 - if (ckWARN(WARN_MISC))
192 - Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
193 - "Can't locate package %"SVf" for @%s::ISA",
194 - (void*)sv, hvname);
197 - if (isa_lookup(basestash, name, name_stash, len, level + 1)) {
198 - (void)hv_store(hv,name,len,&PL_sv_yes,0);
202 - (void)hv_store(hv,name,len,&PL_sv_no,0);
209 ==================================================================
210 --- gv.c (/local/perl-current) (revision 12599)
211 +++ gv.c (/local/perl-c3) (revision 12599)
213 The argument C<level> should be either 0 or -1. If C<level==0>, as a
214 side-effect creates a glob with the given C<name> in the given C<stash>
215 which in the case of success contains an alias for the subroutine, and sets
216 -up caching info for this glob. Similarly for all the searched stashes.
217 +up caching info for this glob.
219 This function grants C<"SUPER"> token as a postfix of the stash name. The
220 GV returned from C<gv_fetchmeth> may be a method cache entry, which is not
221 @@ -309,133 +309,137 @@
225 +/* NOTE: No support for tied ISA */
228 Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
240 + GV* candidate = NULL;
241 + CV* cand_cv = NULL;
245 - HV* lastchance = NULL;
246 + I32 create = (level >= 0) ? 1 : 0;
250 /* UNIVERSAL methods should be callable without a stash */
252 - level = -1; /* probably appropriate */
253 + create = 0; /* probably appropriate */
254 if(!(stash = gv_stashpvs("UNIVERSAL", FALSE)))
260 hvname = HvNAME_get(stash);
263 - "Can't use anonymous symbol table for method lookup");
264 + Perl_croak(aTHX_ "Can't use anonymous symbol table for method lookup");
266 - if ((level > 100) || (level < -100))
267 - Perl_croak(aTHX_ "Recursive inheritance detected while looking for method '%s' in package '%s'",
273 DEBUG_o( Perl_deb(aTHX_ "Looking for method %s in package %s\n",name,hvname) );
275 - gvp = (GV**)hv_fetch(stash, name, len, (level >= 0));
278 + /* check locally for a real method or a cache entry */
279 + gvp = (GV**)hv_fetch(stash, name, len, create);
283 + if (SvTYPE(topgv) != SVt_PVGV)
284 + gv_init(topgv, stash, name, len, TRUE);
285 + if ((cand_cv = GvCV(topgv))) {
286 + /* If genuine method or valid cache entry, use it */
287 + if (!GvCVGEN(topgv) || GvCVGEN(topgv) == PL_sub_generation) {
291 + /* stale cache entry, junk it and move on */
292 + SvREFCNT_dec(cand_cv);
293 + GvCV(topgv) = cand_cv = NULL;
294 + GvCVGEN(topgv) = 0;
297 + else if (GvCVGEN(topgv) == PL_sub_generation) {
298 + /* cache indicates no such method definitively */
303 + packlen = HvNAMELEN_get(stash);
304 + if (packlen >= 7 && strEQ(hvname + packlen - 7, "::SUPER")) {
307 + basestash = gv_stashpvn(hvname, packlen, TRUE);
308 + linear_av = mro_linear(basestash);
312 - if (SvTYPE(topgv) != SVt_PVGV)
313 - gv_init(topgv, stash, name, len, TRUE);
314 - if ((cv = GvCV(topgv))) {
315 - /* If genuine method or valid cache entry, use it */
316 - if (!GvCVGEN(topgv) || GvCVGEN(topgv) == PL_sub_generation)
318 - /* Stale cached entry: junk it */
320 - GvCV(topgv) = cv = NULL;
321 - GvCVGEN(topgv) = 0;
323 - else if (GvCVGEN(topgv) == PL_sub_generation)
324 - return 0; /* cache indicates sub doesn't exist */
325 + linear_av = mro_linear(stash); /* has ourselves at the top of the list */
327 + sv_2mortal((SV*)linear_av);
329 - gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
330 - av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : NULL;
331 + linear_svp = AvARRAY(linear_av) + 1; /* skip over self */
332 + items = AvFILLp(linear_av); /* no +1, to skip over self */
334 + linear_sv = *linear_svp++;
336 + curstash = gv_stashsv(linear_sv, FALSE);
338 - /* create and re-create @.*::SUPER::ISA on demand */
339 - if (!av || !SvMAGIC(av)) {
340 - STRLEN packlen = HvNAMELEN_get(stash);
342 + if (ckWARN(WARN_MISC))
343 + Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %"SVf" for @%s::ISA",
344 + (void*)linear_sv, hvname);
348 - if (packlen >= 7 && strEQ(hvname + packlen - 7, "::SUPER")) {
353 - basestash = gv_stashpvn(hvname, packlen, TRUE);
354 - gvp = (GV**)hv_fetchs(basestash, "ISA", FALSE);
355 - if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (av = GvAV(gv))) {
356 - gvp = (GV**)hv_fetchs(stash, "ISA", TRUE);
357 - if (!gvp || !(gv = *gvp))
358 - Perl_croak(aTHX_ "Cannot create %s::ISA", hvname);
359 - if (SvTYPE(gv) != SVt_PVGV)
360 - gv_init(gv, stash, "ISA", 3, TRUE);
361 - SvREFCNT_dec(GvAV(gv));
362 - GvAV(gv) = (AV*)SvREFCNT_inc_simple(av);
365 + gvp = (GV**)hv_fetch(curstash, name, len, 0);
366 + if (!gvp) continue;
369 + if (SvTYPE(candidate) != SVt_PVGV) gv_init(candidate, curstash, name, len, TRUE);
370 + if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) {
372 + * Found real method, cache method in topgv if:
373 + * 1. topgv has no synonyms (else inheritance crosses wires)
374 + * 2. method isn't a stub (else AUTOLOAD fails spectacularly)
376 + if (topgv && (GvREFCNT(topgv) == 1) && (CvROOT(cand_cv) || CvXSUB(cand_cv))) {
377 + if ((old_cv = GvCV(topgv))) SvREFCNT_dec(old_cv);
378 + SvREFCNT_inc_simple_void_NN(cand_cv);
379 + GvCV(topgv) = cand_cv;
380 + GvCVGEN(topgv) = PL_sub_generation;
387 - SV** svp = AvARRAY(av);
388 - /* NOTE: No support for tied ISA */
389 - I32 items = AvFILLp(av) + 1;
391 - SV* const sv = *svp++;
392 - HV* const basestash = gv_stashsv(sv, FALSE);
394 - if (ckWARN(WARN_MISC))
395 - Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %"SVf" for @%s::ISA",
396 - (void*)sv, hvname);
399 - gv = gv_fetchmeth(basestash, name, len,
400 - (level >= 0) ? level + 1 : level - 1);
404 + /* Check UNIVERSAL without caching */
405 + if(level == 0 || level == -1) {
406 + candidate = gv_fetchmeth(NULL, name, len, 1);
408 + cand_cv = GvCV(candidate);
409 + if (topgv && (GvREFCNT(topgv) == 1) && (CvROOT(cand_cv) || CvXSUB(cand_cv))) {
410 + if ((old_cv = GvCV(topgv))) SvREFCNT_dec(old_cv);
411 + SvREFCNT_inc_simple_void_NN(cand_cv);
412 + GvCV(topgv) = cand_cv;
413 + GvCVGEN(topgv) = PL_sub_generation;
419 - /* if at top level, try UNIVERSAL */
421 - if (level == 0 || level == -1) {
422 - lastchance = gv_stashpvs("UNIVERSAL", FALSE);
425 - if ((gv = gv_fetchmeth(lastchance, name, len,
426 - (level >= 0) ? level + 1 : level - 1)))
430 - * Cache method in topgv if:
431 - * 1. topgv has no synonyms (else inheritance crosses wires)
432 - * 2. method isn't a stub (else AUTOLOAD fails spectacularly)
435 - GvREFCNT(topgv) == 1 &&
437 - (CvROOT(cv) || CvXSUB(cv)))
439 - if ((cv = GvCV(topgv)))
441 - GvCV(topgv) = (CV*)SvREFCNT_inc(GvCV(gv));
442 - GvCVGEN(topgv) = PL_sub_generation;
446 - else if (topgv && GvREFCNT(topgv) == 1) {
447 - /* cache the fact that the method is not defined */
448 - GvCVGEN(topgv) = PL_sub_generation;
451 + if (topgv && GvREFCNT(topgv) == 1) {
452 + /* cache the fact that the method is not defined */
453 + GvCVGEN(topgv) = PL_sub_generation;
458 ==================================================================
459 --- perlapi.h (/local/perl-current) (revision 12599)
460 +++ perlapi.h (/local/perl-c3) (revision 12599)
462 #define PL_initav (*Perl_Iinitav_ptr(aTHX))
464 #define PL_inplace (*Perl_Iinplace_ptr(aTHX))
465 +#undef PL_isa_generation
466 +#define PL_isa_generation (*Perl_Iisa_generation_ptr(aTHX))
467 #undef PL_known_layers
468 #define PL_known_layers (*Perl_Iknown_layers_ptr(aTHX))
471 ==================================================================
472 --- win32/Makefile (/local/perl-current) (revision 12599)
473 +++ win32/Makefile (/local/perl-c3) (revision 12599)
482 === win32/makefile.mk
483 ==================================================================
484 --- win32/makefile.mk (/local/perl-current) (revision 12599)
485 +++ win32/makefile.mk (/local/perl-c3) (revision 12599)
494 === win32/Makefile.ce
495 ==================================================================
496 --- win32/Makefile.ce (/local/perl-current) (revision 12599)
497 +++ win32/Makefile.ce (/local/perl-c3) (revision 12599)
508 $(DLLDIR)\globals.obj \
512 $(DLLDIR)\locale.obj \
513 $(DLLDIR)\mathoms.obj \
515 ==================================================================
516 --- NetWare/Makefile (/local/perl-current) (revision 12599)
517 +++ NetWare/Makefile (/local/perl-c3) (revision 12599)
526 === vms/descrip_mms.template
527 ==================================================================
528 --- vms/descrip_mms.template (/local/perl-current) (revision 12599)
529 +++ vms/descrip_mms.template (/local/perl-c3) (revision 12599)
530 @@ -279,13 +279,13 @@
532 #### End of system configuration section. ####
534 -c0 = $(MALLOC_C) $(SOCKC) av.c deb.c doio.c doop.c dump.c globals.c gv.c hv.c
535 +c0 = $(MALLOC_C) $(SOCKC) av.c deb.c doio.c doop.c dump.c globals.c gv.c hv.c mro.c
536 c1 = mg.c locale.c mathoms.c miniperlmain.c numeric.c op.c pad.c perl.c perlapi.c perlio.c
537 c2 = perly.c pp.c pp_ctl.c pp_hot.c pp_pack.c pp_sort.c pp_sys.c regcomp.c regexec.c reentr.c
538 c3 = run.c scope.c sv.c taint.c toke.c universal.c utf8.c util.c vms.c xsutils.c
539 c = $(c0) $(c1) $(c2) $(c3)
541 -obj0 = $(MALLOC_O) $(SOCKO) av$(O) deb$(O) doio$(O) doop$(O) dump$(O)
542 +obj0 = $(MALLOC_O) $(SOCKO) av$(O) deb$(O) doio$(O) doop$(O) dump$(O) mro$(O)
543 obj1 = globals$(O) gv$(O) hv$(O) locale$(O) mathoms$(O) mg$(O) miniperlmain$(O) numeric$(O) op$(O) pad$(O)
544 obj2 = perl$(O) perlapi$(O) perlio$(O) perly$(O) pp$(O) pp_ctl$(O) pp_hot$(O) reentr$(O)
545 obj3 = pp_pack$(O) pp_sort$(O) pp_sys$(O) regcomp$(O) regexec$(O) run$(O) scope$(O) sv$(O) taint$(O) toke$(O)
546 @@ -1594,6 +1594,8 @@
547 $(CC) $(CORECFLAGS) $(MMS$SOURCE)
549 $(CC) $(CORECFLAGS) $(MMS$SOURCE)
550 +mro$(O) : mro.c $(h)
551 + $(CC) $(CORECFLAGS) $(MMS$SOURCE)
553 $(CC) $(CORECFLAGS) $(MMS$SOURCE)
554 locale$(O) : locale.c $(h)
556 ==================================================================
557 --- Makefile.SH (/local/perl-current) (revision 12599)
558 +++ Makefile.SH (/local/perl-c3) (revision 12599)
560 h5 = utf8.h warnings.h
561 h = $(h1) $(h2) $(h3) $(h4) $(h5)
563 -c1 = av.c scope.c op.c doop.c doio.c dump.c gv.c hv.c mg.c reentr.c perl.c
564 +c1 = av.c scope.c op.c doop.c doio.c dump.c gv.c hv.c mg.c reentr.c mro.c perl.c
565 c2 = perly.c pp.c pp_hot.c pp_ctl.c pp_sys.c regcomp.c regexec.c utf8.c sv.c
566 c3 = taint.c toke.c util.c deb.c run.c universal.c xsutils.c pad.c globals.c
567 c4 = perlio.c perlapi.c numeric.c mathoms.c locale.c pp_pack.c pp_sort.c
570 c = $(c1) $(c2) $(c3) $(c4) $(c5) miniperlmain.c perlmain.c opmini.c
572 -obj1 = $(madlyobj) $(mallocobj) gv$(OBJ_EXT) toke$(OBJ_EXT) perly$(OBJ_EXT) op$(OBJ_EXT) pad$(OBJ_EXT) regcomp$(OBJ_EXT) dump$(OBJ_EXT) util$(OBJ_EXT) mg$(OBJ_EXT) reentr$(OBJ_EXT)
573 +obj1 = $(madlyobj) $(mallocobj) gv$(OBJ_EXT) toke$(OBJ_EXT) perly$(OBJ_EXT) op$(OBJ_EXT) pad$(OBJ_EXT) regcomp$(OBJ_EXT) dump$(OBJ_EXT) util$(OBJ_EXT) mg$(OBJ_EXT) reentr$(OBJ_EXT) mro$(OBJ_EXT)
574 obj2 = hv$(OBJ_EXT) av$(OBJ_EXT) perl$(OBJ_EXT) run$(OBJ_EXT) pp_hot$(OBJ_EXT) sv$(OBJ_EXT) pp$(OBJ_EXT) scope$(OBJ_EXT) pp_ctl$(OBJ_EXT) pp_sys$(OBJ_EXT)
575 obj3 = doop$(OBJ_EXT) doio$(OBJ_EXT) regexec$(OBJ_EXT) utf8$(OBJ_EXT) taint$(OBJ_EXT) deb$(OBJ_EXT) universal$(OBJ_EXT) xsutils$(OBJ_EXT) globals$(OBJ_EXT) perlio$(OBJ_EXT) perlapi$(OBJ_EXT) numeric$(OBJ_EXT) mathoms$(OBJ_EXT) locale$(OBJ_EXT) pp_pack$(OBJ_EXT) pp_sort$(OBJ_EXT)
578 ==================================================================
579 --- proto.h (/local/perl-current) (revision 12599)
580 +++ proto.h (/local/perl-c3) (revision 12599)
582 PERL_CALLCONV GV* Perl_gv_fetchfile(pTHX_ const char* name)
583 __attribute__nonnull__(pTHX_1);
585 +PERL_CALLCONV struct mro_meta* Perl_mro_meta_init(pTHX_ HV* stash)
586 + __attribute__nonnull__(pTHX_1);
588 +PERL_CALLCONV AV* Perl_mro_linear(pTHX_ HV* stash)
589 + __attribute__nonnull__(pTHX_1);
591 +PERL_CALLCONV AV* Perl_mro_linear_c3(pTHX_ HV* stash, I32 level)
592 + __attribute__nonnull__(pTHX_1);
594 +PERL_CALLCONV AV* Perl_mro_linear_dfs(pTHX_ HV* stash, I32 level)
595 + __attribute__nonnull__(pTHX_1);
597 PERL_CALLCONV GV* Perl_gv_fetchmeth(pTHX_ HV* stash, const char* name, STRLEN len, I32 level)
598 __attribute__nonnull__(pTHX_2);
600 === ext/B/t/concise-xs.t
601 ==================================================================
602 --- ext/B/t/concise-xs.t (/local/perl-current) (revision 12599)
603 +++ ext/B/t/concise-xs.t (/local/perl-c3) (revision 12599)
606 use Test::More tests => ( # per-pkg tests (function ct + require_ok)
607 40 + 16 # Data::Dumper, Digest::MD5
608 - + 517 + 238 # B::Deparse, B
609 + + 517 + 239 # B::Deparse, B
610 + 595 + 190 # POSIX, IO::Socket
612 + 16 * ($] >= 5.009003)
614 formfeed end_av dowarn diehook defstash curstash
615 cstring comppadlist check_av cchar cast_I32 bootstrap
616 begin_av amagic_generation sub_generation address
618 + unitcheck_av isa_generation
623 ==================================================================
624 --- ext/B/B.xs (/local/perl-current) (revision 12599)
625 +++ ext/B/B.xs (/local/perl-c3) (revision 12599)
627 #define B_main_start() PL_main_start
628 #define B_amagic_generation() PL_amagic_generation
629 #define B_sub_generation() PL_sub_generation
630 +#define B_isa_generation() PL_isa_generation
631 #define B_defstash() PL_defstash
632 #define B_curstash() PL_curstash
633 #define B_dowarn() PL_dowarn
645 ==================================================================
646 --- ext/B/B.pm (/local/perl-current) (revision 12599)
647 +++ ext/B/B.pm (/local/perl-c3) (revision 12599)
649 parents comppadlist sv_undef compile_stats timing_info
650 begin_av init_av unitcheck_av check_av end_av regex_padav
651 dowarn defstash curstash warnhook diehook inc_gv
656 === ext/mro/t/basic_01_dfs.t
657 ==================================================================
658 --- ext/mro/t/basic_01_dfs.t (/local/perl-current) (revision 12599)
659 +++ ext/mro/t/basic_01_dfs.t (/local/perl-c3) (revision 12599)
666 + unless (-d 'blib') {
667 + chdir 't' if -d 't';
672 +use Test::More tests => 4;
677 +This tests the classic diamond inheritence pattern.
689 + sub hello { 'Diamond_A::hello' }
693 + use base 'Diamond_A';
697 + use base 'Diamond_A';
699 + sub hello { 'Diamond_C::hello' }
703 + use base ('Diamond_B', 'Diamond_C');
708 + mro::get_mro_linear('Diamond_D'),
709 + [ qw(Diamond_D Diamond_B Diamond_A Diamond_C Diamond_A) ],
710 + '... got the right MRO for Diamond_D');
712 +is(Diamond_D->hello, 'Diamond_A::hello', '... method resolved itself as expected');
713 +is(Diamond_D->can('hello')->(), 'Diamond_A::hello', '... can(method) resolved itself as expected');
714 +is(UNIVERSAL::can("Diamond_D", 'hello')->(), 'Diamond_A::hello', '... can(method) resolved itself as expected');
715 === ext/mro/t/vulcan_c3.t
716 ==================================================================
717 --- ext/mro/t/vulcan_c3.t (/local/perl-current) (revision 12599)
718 +++ ext/mro/t/vulcan_c3.t (/local/perl-c3) (revision 12599)
725 + unless (-d 'blib') {
726 + chdir 't' if -d 't';
731 +use Test::More tests => 1;
736 +example taken from: L<http://gauss.gwydiondylan.org/books/drm/drm_50.html>
747 + Intelligent Humanoid
752 + define class <sentient> (<life-form>) end class;
753 + define class <bipedal> (<life-form>) end class;
754 + define class <intelligent> (<sentient>) end class;
755 + define class <humanoid> (<bipedal>) end class;
756 + define class <vulcan> (<intelligent>, <humanoid>) end class;
770 + use base 'LifeForm';
774 + use base 'LifeForm';
776 + package Intelligent;
778 + use base 'Sentient';
782 + use base 'BiPedal';
786 + use base ('Intelligent', 'Humanoid');
790 + mro::get_mro_linear('Vulcan'),
791 + [ qw(Vulcan Intelligent Sentient Humanoid BiPedal LifeForm Object) ],
792 + '... got the right MRO for the Vulcan Dylan Example');
793 === ext/mro/t/basic_02_dfs.t
794 ==================================================================
795 --- ext/mro/t/basic_02_dfs.t (/local/perl-current) (revision 12599)
796 +++ ext/mro/t/basic_02_dfs.t (/local/perl-c3) (revision 12599)
803 + unless (-d 'blib') {
804 + chdir 't' if -d 't';
809 +use Test::More tests => 10;
814 +This example is take from: http://www.python.org/2.3/mro.html
828 +Level 3 | O | (more general)
834 +Level 2 3 | D | 4| E | | F | 5 |
840 +Level 1 1 | B | | C | 2 |
845 +Level 0 0 | A | (more specialized)
856 + use base 'Test::O';
859 + use base 'Test::O';
862 + sub C_or_E { 'Test::E' }
866 + use base 'Test::O';
868 + sub C_or_D { 'Test::D' }
871 + use base ('Test::D', 'Test::F');
874 + sub C_or_D { 'Test::C' }
875 + sub C_or_E { 'Test::C' }
879 + use base ('Test::D', 'Test::E');
882 + use base ('Test::B', 'Test::C');
887 + mro::get_mro_linear('Test::F'),
888 + [ qw(Test::F Test::O) ],
889 + '... got the right MRO for Test::F');
892 + mro::get_mro_linear('Test::E'),
893 + [ qw(Test::E Test::O) ],
894 + '... got the right MRO for Test::E');
897 + mro::get_mro_linear('Test::D'),
898 + [ qw(Test::D Test::O) ],
899 + '... got the right MRO for Test::D');
902 + mro::get_mro_linear('Test::C'),
903 + [ qw(Test::C Test::D Test::O Test::F Test::O) ],
904 + '... got the right MRO for Test::C');
907 + mro::get_mro_linear('Test::B'),
908 + [ qw(Test::B Test::D Test::O Test::E Test::O) ],
909 + '... got the right MRO for Test::B');
912 + mro::get_mro_linear('Test::A'),
913 + [ qw(Test::A Test::B Test::D Test::O Test::E Test::O Test::C Test::D Test::O Test::F Test::O) ],
914 + '... got the right MRO for Test::A');
916 +is(Test::A->C_or_D, 'Test::D', '... got the expected method output');
917 +is(Test::A->can('C_or_D')->(), 'Test::D', '... can got the expected method output');
918 +is(Test::A->C_or_E, 'Test::E', '... got the expected method output');
919 +is(Test::A->can('C_or_E')->(), 'Test::E', '... can got the expected method output');
920 === ext/mro/t/basic_03_dfs.t
921 ==================================================================
922 --- ext/mro/t/basic_03_dfs.t (/local/perl-current) (revision 12599)
923 +++ ext/mro/t/basic_03_dfs.t (/local/perl-c3) (revision 12599)
930 + unless (-d 'blib') {
931 + chdir 't' if -d 't';
936 +use Test::More tests => 4;
941 +This example is take from: http://www.python.org/2.3/mro.html
960 +Level 2 2 | E | 4 | D | | F | 5
966 +Level 1 1 | B | | C | 3
975 +(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>,
976 +<class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>,
985 + sub O_or_D { 'Test::O' }
986 + sub O_or_F { 'Test::O' }
989 + use base 'Test::O';
992 + sub O_or_F { 'Test::F' }
995 + use base 'Test::O';
999 + use base 'Test::O';
1002 + sub O_or_D { 'Test::D' }
1003 + sub C_or_D { 'Test::D' }
1006 + use base ('Test::D', 'Test::F');
1009 + sub C_or_D { 'Test::C' }
1012 + use base ('Test::E', 'Test::D');
1016 + use base ('Test::B', 'Test::C');
1021 + mro::get_mro_linear('Test::A'),
1022 + [ qw(Test::A Test::B Test::E Test::O Test::D Test::O Test::C Test::D Test::O Test::F Test::O) ],
1023 + '... got the right MRO for Test::A');
1025 +is(Test::A->O_or_D, 'Test::O', '... got the right method dispatch');
1026 +is(Test::A->O_or_F, 'Test::O', '... got the right method dispatch');
1029 +# this test is particularly interesting because the p5 dispatch
1030 +# would actually call Test::D before Test::C and Test::D is a
1031 +# subclass of Test::C
1032 +is(Test::A->C_or_D, 'Test::D', '... got the right method dispatch');
1033 === ext/mro/t/basic_04_dfs.t
1034 ==================================================================
1035 --- ext/mro/t/basic_04_dfs.t (/local/perl-current) (revision 12599)
1036 +++ ext/mro/t/basic_04_dfs.t (/local/perl-c3) (revision 12599)
1043 + unless (-d 'blib') {
1044 + chdir 't' if -d 't';
1049 +use Test::More tests => 1;
1054 +From the parrot test t/pmc/object-meths.t
1066 + package t::lib::A; use mro 'dfs';
1067 + package t::lib::B; use mro 'dfs';
1068 + package t::lib::E; use mro 'dfs';
1069 + package t::lib::C; use mro 'dfs'; use base ('t::lib::A', 't::lib::B');
1070 + package t::lib::D; use mro 'dfs'; use base ('t::lib::A', 't::lib::E');
1071 + package t::lib::F; use mro 'dfs'; use base ('t::lib::C', 't::lib::D');
1075 + mro::get_mro_linear('t::lib::F'),
1076 + [ qw(t::lib::F t::lib::C t::lib::A t::lib::B t::lib::D t::lib::A t::lib::E) ],
1077 + '... got the right MRO for t::lib::F');
1079 === ext/mro/t/basic_05_dfs.t
1080 ==================================================================
1081 --- ext/mro/t/basic_05_dfs.t (/local/perl-current) (revision 12599)
1082 +++ ext/mro/t/basic_05_dfs.t (/local/perl-c3) (revision 12599)
1089 + unless (-d 'blib') {
1090 + chdir 't' if -d 't';
1095 +use Test::More tests => 2;
1100 +This tests a strange bug found by Matt S. Trout
1101 +while building DBIx::Class. Thanks Matt!!!!
1112 + package Diamond_A;
1115 + sub foo { 'Diamond_A::foo' }
1118 + package Diamond_B;
1119 + use base 'Diamond_A';
1122 + sub foo { 'Diamond_B::foo => ' . (shift)->SUPER::foo }
1125 + package Diamond_C;
1127 + use base 'Diamond_A';
1131 + package Diamond_D;
1132 + use base ('Diamond_C', 'Diamond_B');
1135 + sub foo { 'Diamond_D::foo => ' . (shift)->SUPER::foo }
1139 + mro::get_mro_linear('Diamond_D'),
1140 + [ qw(Diamond_D Diamond_C Diamond_A Diamond_B Diamond_A) ],
1141 + '... got the right MRO for Diamond_D');
1144 + 'Diamond_D::foo => Diamond_A::foo',
1145 + '... got the right next::method dispatch path');
1146 === ext/mro/t/vulcan_dfs.t
1147 ==================================================================
1148 --- ext/mro/t/vulcan_dfs.t (/local/perl-current) (revision 12599)
1149 +++ ext/mro/t/vulcan_dfs.t (/local/perl-c3) (revision 12599)
1156 + unless (-d 'blib') {
1157 + chdir 't' if -d 't';
1162 +use Test::More tests => 1;
1167 +example taken from: L<http://gauss.gwydiondylan.org/books/drm/drm_50.html>
1178 + Intelligent Humanoid
1183 + define class <sentient> (<life-form>) end class;
1184 + define class <bipedal> (<life-form>) end class;
1185 + define class <intelligent> (<sentient>) end class;
1186 + define class <humanoid> (<bipedal>) end class;
1187 + define class <vulcan> (<intelligent>, <humanoid>) end class;
1197 + use base 'Object';
1201 + use base 'LifeForm';
1205 + use base 'LifeForm';
1207 + package Intelligent;
1209 + use base 'Sentient';
1213 + use base 'BiPedal';
1217 + use base ('Intelligent', 'Humanoid');
1221 + mro::get_mro_linear('Vulcan'),
1222 + [ qw(Vulcan Intelligent Sentient LifeForm Object Humanoid BiPedal LifeForm Object) ],
1223 + '... got the right MRO for the Vulcan Dylan Example');
1224 === ext/mro/t/dbic_c3.t
1225 ==================================================================
1226 --- ext/mro/t/dbic_c3.t (/local/perl-current) (revision 12599)
1227 +++ ext/mro/t/dbic_c3.t (/local/perl-c3) (revision 12599)
1234 + unless (-d 'blib') {
1235 + chdir 't' if -d 't';
1240 +use Test::More tests => 1;
1245 +This example is taken from the inheritance graph of DBIx::Class::Core in DBIx::Class v0.07002:
1246 +(No ASCII art this time, this graph is insane)
1248 +The xx:: prefixes are just to be sure these bogus declarations never stomp on real ones
1253 + package xx::DBIx::Class::Core; use mro 'c3';
1255 + xx::DBIx::Class::Serialize::Storable
1256 + xx::DBIx::Class::InflateColumn
1257 + xx::DBIx::Class::Relationship
1258 + xx::DBIx::Class::PK::Auto
1259 + xx::DBIx::Class::PK
1260 + xx::DBIx::Class::Row
1261 + xx::DBIx::Class::ResultSourceProxy::Table
1262 + xx::DBIx::Class::AccessorGroup
1265 + package xx::DBIx::Class::InflateColumn; use mro 'c3';
1266 + our @ISA = qw/ xx::DBIx::Class::Row /;
1268 + package xx::DBIx::Class::Row; use mro 'c3';
1269 + our @ISA = qw/ xx::DBIx::Class /;
1271 + package xx::DBIx::Class; use mro 'c3';
1273 + xx::DBIx::Class::Componentised
1274 + xx::Class::Data::Accessor
1277 + package xx::DBIx::Class::Relationship; use mro 'c3';
1279 + xx::DBIx::Class::Relationship::Helpers
1280 + xx::DBIx::Class::Relationship::Accessor
1281 + xx::DBIx::Class::Relationship::CascadeActions
1282 + xx::DBIx::Class::Relationship::ProxyMethods
1283 + xx::DBIx::Class::Relationship::Base
1287 + package xx::DBIx::Class::Relationship::Helpers; use mro 'c3';
1289 + xx::DBIx::Class::Relationship::HasMany
1290 + xx::DBIx::Class::Relationship::HasOne
1291 + xx::DBIx::Class::Relationship::BelongsTo
1292 + xx::DBIx::Class::Relationship::ManyToMany
1295 + package xx::DBIx::Class::Relationship::ProxyMethods; use mro 'c3';
1296 + our @ISA = qw/ xx::DBIx::Class /;
1298 + package xx::DBIx::Class::Relationship::Base; use mro 'c3';
1299 + our @ISA = qw/ xx::DBIx::Class /;
1301 + package xx::DBIx::Class::PK::Auto; use mro 'c3';
1302 + our @ISA = qw/ xx::DBIx::Class /;
1304 + package xx::DBIx::Class::PK; use mro 'c3';
1305 + our @ISA = qw/ xx::DBIx::Class::Row /;
1307 + package xx::DBIx::Class::ResultSourceProxy::Table; use mro 'c3';
1309 + xx::DBIx::Class::AccessorGroup
1310 + xx::DBIx::Class::ResultSourceProxy
1313 + package xx::DBIx::Class::ResultSourceProxy; use mro 'c3';
1314 + our @ISA = qw/ xx::DBIx::Class /;
1316 + package xx::Class::Data::Accessor; our @ISA = (); use mro 'c3';
1317 + package xx::DBIx::Class::Relationship::HasMany; our @ISA = (); use mro 'c3';
1318 + package xx::DBIx::Class::Relationship::HasOne; our @ISA = (); use mro 'c3';
1319 + package xx::DBIx::Class::Relationship::BelongsTo; our @ISA = (); use mro 'c3';
1320 + package xx::DBIx::Class::Relationship::ManyToMany; our @ISA = (); use mro 'c3';
1321 + package xx::DBIx::Class::Componentised; our @ISA = (); use mro 'c3';
1322 + package xx::DBIx::Class::AccessorGroup; our @ISA = (); use mro 'c3';
1323 + package xx::DBIx::Class::Serialize::Storable; our @ISA = (); use mro 'c3';
1324 + package xx::DBIx::Class::Relationship::Accessor; our @ISA = (); use mro 'c3';
1325 + package xx::DBIx::Class::Relationship::CascadeActions; our @ISA = (); use mro 'c3';
1329 + mro::get_mro_linear('xx::DBIx::Class::Core'),
1331 + xx::DBIx::Class::Core
1332 + xx::DBIx::Class::Serialize::Storable
1333 + xx::DBIx::Class::InflateColumn
1334 + xx::DBIx::Class::Relationship
1335 + xx::DBIx::Class::Relationship::Helpers
1336 + xx::DBIx::Class::Relationship::HasMany
1337 + xx::DBIx::Class::Relationship::HasOne
1338 + xx::DBIx::Class::Relationship::BelongsTo
1339 + xx::DBIx::Class::Relationship::ManyToMany
1340 + xx::DBIx::Class::Relationship::Accessor
1341 + xx::DBIx::Class::Relationship::CascadeActions
1342 + xx::DBIx::Class::Relationship::ProxyMethods
1343 + xx::DBIx::Class::Relationship::Base
1344 + xx::DBIx::Class::PK::Auto
1345 + xx::DBIx::Class::PK
1346 + xx::DBIx::Class::Row
1347 + xx::DBIx::Class::ResultSourceProxy::Table
1348 + xx::DBIx::Class::AccessorGroup
1349 + xx::DBIx::Class::ResultSourceProxy
1351 + xx::DBIx::Class::Componentised
1352 + xx::Class::Data::Accessor
1354 + '... got the right C3 merge order for xx::DBIx::Class::Core');
1355 === ext/mro/t/complex_c3.t
1356 ==================================================================
1357 --- ext/mro/t/complex_c3.t (/local/perl-current) (revision 12599)
1358 +++ ext/mro/t/complex_c3.t (/local/perl-c3) (revision 12599)
1365 + unless (-d 'blib') {
1366 + chdir 't' if -d 't';
1371 +use Test::More tests => 11;
1376 +This example is taken from: http://rt.cpan.org/Public/Bug/Display.html?id=20879
1379 +Level 5 8 | A | 9 | B | A | C | (More General)
1391 +Level 3 4 | G | 6 | E | |
1396 +Level 2 3 | H | 5 | F | |
1404 +Level 1 1 | J | 2 | I | |
1409 +Level 0 0 | K | (More Specialized)
1419 + package Test::A; use mro 'c3';
1421 + package Test::B; use mro 'c3';
1423 + package Test::C; use mro 'c3';
1425 + package Test::D; use mro 'c3';
1426 + use base qw/Test::A Test::B Test::C/;
1428 + package Test::E; use mro 'c3';
1429 + use base qw/Test::D/;
1431 + package Test::F; use mro 'c3';
1432 + use base qw/Test::E/;
1434 + package Test::G; use mro 'c3';
1435 + use base qw/Test::D/;
1437 + package Test::H; use mro 'c3';
1438 + use base qw/Test::G/;
1440 + package Test::I; use mro 'c3';
1441 + use base qw/Test::H Test::F/;
1443 + package Test::J; use mro 'c3';
1444 + use base qw/Test::F/;
1446 + package Test::K; use mro 'c3';
1447 + use base qw/Test::J Test::I/;
1451 + mro::get_mro_linear('Test::A'),
1453 + '... got the right C3 merge order for Test::A');
1456 + mro::get_mro_linear('Test::B'),
1458 + '... got the right C3 merge order for Test::B');
1461 + mro::get_mro_linear('Test::C'),
1463 + '... got the right C3 merge order for Test::C');
1466 + mro::get_mro_linear('Test::D'),
1467 + [ qw(Test::D Test::A Test::B Test::C) ],
1468 + '... got the right C3 merge order for Test::D');
1471 + mro::get_mro_linear('Test::E'),
1472 + [ qw(Test::E Test::D Test::A Test::B Test::C) ],
1473 + '... got the right C3 merge order for Test::E');
1476 + mro::get_mro_linear('Test::F'),
1477 + [ qw(Test::F Test::E Test::D Test::A Test::B Test::C) ],
1478 + '... got the right C3 merge order for Test::F');
1481 + mro::get_mro_linear('Test::G'),
1482 + [ qw(Test::G Test::D Test::A Test::B Test::C) ],
1483 + '... got the right C3 merge order for Test::G');
1486 + mro::get_mro_linear('Test::H'),
1487 + [ qw(Test::H Test::G Test::D Test::A Test::B Test::C) ],
1488 + '... got the right C3 merge order for Test::H');
1491 + mro::get_mro_linear('Test::I'),
1492 + [ qw(Test::I Test::H Test::G Test::F Test::E Test::D Test::A Test::B Test::C) ],
1493 + '... got the right C3 merge order for Test::I');
1496 + mro::get_mro_linear('Test::J'),
1497 + [ qw(Test::J Test::F Test::E Test::D Test::A Test::B Test::C) ],
1498 + '... got the right C3 merge order for Test::J');
1501 + mro::get_mro_linear('Test::K'),
1502 + [ qw(Test::K Test::J Test::I Test::H Test::G Test::F Test::E Test::D Test::A Test::B Test::C) ],
1503 + '... got the right C3 merge order for Test::K');
1504 === ext/mro/t/dbic_dfs.t
1505 ==================================================================
1506 --- ext/mro/t/dbic_dfs.t (/local/perl-current) (revision 12599)
1507 +++ ext/mro/t/dbic_dfs.t (/local/perl-c3) (revision 12599)
1514 + unless (-d 'blib') {
1515 + chdir 't' if -d 't';
1520 +use Test::More tests => 1;
1525 +This example is taken from the inheritance graph of DBIx::Class::Core in DBIx::Class v0.07002:
1526 +(No ASCII art this time, this graph is insane)
1528 +The xx:: prefixes are just to be sure these bogus declarations never stomp on real ones
1533 + package xx::DBIx::Class::Core; use mro 'dfs';
1535 + xx::DBIx::Class::Serialize::Storable
1536 + xx::DBIx::Class::InflateColumn
1537 + xx::DBIx::Class::Relationship
1538 + xx::DBIx::Class::PK::Auto
1539 + xx::DBIx::Class::PK
1540 + xx::DBIx::Class::Row
1541 + xx::DBIx::Class::ResultSourceProxy::Table
1542 + xx::DBIx::Class::AccessorGroup
1545 + package xx::DBIx::Class::InflateColumn; use mro 'dfs';
1546 + our @ISA = qw/ xx::DBIx::Class::Row /;
1548 + package xx::DBIx::Class::Row; use mro 'dfs';
1549 + our @ISA = qw/ xx::DBIx::Class /;
1551 + package xx::DBIx::Class; use mro 'dfs';
1553 + xx::DBIx::Class::Componentised
1554 + xx::Class::Data::Accessor
1557 + package xx::DBIx::Class::Relationship; use mro 'dfs';
1559 + xx::DBIx::Class::Relationship::Helpers
1560 + xx::DBIx::Class::Relationship::Accessor
1561 + xx::DBIx::Class::Relationship::CascadeActions
1562 + xx::DBIx::Class::Relationship::ProxyMethods
1563 + xx::DBIx::Class::Relationship::Base
1567 + package xx::DBIx::Class::Relationship::Helpers; use mro 'dfs';
1569 + xx::DBIx::Class::Relationship::HasMany
1570 + xx::DBIx::Class::Relationship::HasOne
1571 + xx::DBIx::Class::Relationship::BelongsTo
1572 + xx::DBIx::Class::Relationship::ManyToMany
1575 + package xx::DBIx::Class::Relationship::ProxyMethods; use mro 'dfs';
1576 + our @ISA = qw/ xx::DBIx::Class /;
1578 + package xx::DBIx::Class::Relationship::Base; use mro 'dfs';
1579 + our @ISA = qw/ xx::DBIx::Class /;
1581 + package xx::DBIx::Class::PK::Auto; use mro 'dfs';
1582 + our @ISA = qw/ xx::DBIx::Class /;
1584 + package xx::DBIx::Class::PK; use mro 'dfs';
1585 + our @ISA = qw/ xx::DBIx::Class::Row /;
1587 + package xx::DBIx::Class::ResultSourceProxy::Table; use mro 'dfs';
1589 + xx::DBIx::Class::AccessorGroup
1590 + xx::DBIx::Class::ResultSourceProxy
1593 + package xx::DBIx::Class::ResultSourceProxy; use mro 'dfs';
1594 + our @ISA = qw/ xx::DBIx::Class /;
1596 + package xx::Class::Data::Accessor; our @ISA = (); use mro 'dfs';
1597 + package xx::DBIx::Class::Relationship::HasMany; our @ISA = (); use mro 'dfs';
1598 + package xx::DBIx::Class::Relationship::HasOne; our @ISA = (); use mro 'dfs';
1599 + package xx::DBIx::Class::Relationship::BelongsTo; our @ISA = (); use mro 'dfs';
1600 + package xx::DBIx::Class::Relationship::ManyToMany; our @ISA = (); use mro 'dfs';
1601 + package xx::DBIx::Class::Componentised; our @ISA = (); use mro 'dfs';
1602 + package xx::DBIx::Class::AccessorGroup; our @ISA = (); use mro 'dfs';
1603 + package xx::DBIx::Class::Serialize::Storable; our @ISA = (); use mro 'dfs';
1604 + package xx::DBIx::Class::Relationship::Accessor; our @ISA = (); use mro 'dfs';
1605 + package xx::DBIx::Class::Relationship::CascadeActions; our @ISA = (); use mro 'dfs';
1609 + mro::get_mro_linear('xx::DBIx::Class::Core'),
1611 + xx::DBIx::Class::Core
1612 + xx::DBIx::Class::Serialize::Storable
1613 + xx::DBIx::Class::InflateColumn
1614 + xx::DBIx::Class::Row
1616 + xx::DBIx::Class::Componentised
1617 + xx::Class::Data::Accessor
1618 + xx::DBIx::Class::Relationship
1619 + xx::DBIx::Class::Relationship::Helpers
1620 + xx::DBIx::Class::Relationship::HasMany
1621 + xx::DBIx::Class::Relationship::HasOne
1622 + xx::DBIx::Class::Relationship::BelongsTo
1623 + xx::DBIx::Class::Relationship::ManyToMany
1624 + xx::DBIx::Class::Relationship::Accessor
1625 + xx::DBIx::Class::Relationship::CascadeActions
1626 + xx::DBIx::Class::Relationship::ProxyMethods
1628 + xx::DBIx::Class::Componentised
1629 + xx::Class::Data::Accessor
1630 + xx::DBIx::Class::Relationship::Base
1632 + xx::DBIx::Class::Componentised
1633 + xx::Class::Data::Accessor
1635 + xx::DBIx::Class::Componentised
1636 + xx::Class::Data::Accessor
1637 + xx::DBIx::Class::PK::Auto
1639 + xx::DBIx::Class::Componentised
1640 + xx::Class::Data::Accessor
1641 + xx::DBIx::Class::PK
1642 + xx::DBIx::Class::Row
1644 + xx::DBIx::Class::Componentised
1645 + xx::Class::Data::Accessor
1646 + xx::DBIx::Class::Row
1648 + xx::DBIx::Class::Componentised
1649 + xx::Class::Data::Accessor
1650 + xx::DBIx::Class::ResultSourceProxy::Table
1651 + xx::DBIx::Class::AccessorGroup
1652 + xx::DBIx::Class::ResultSourceProxy
1654 + xx::DBIx::Class::Componentised
1655 + xx::Class::Data::Accessor
1656 + xx::DBIx::Class::AccessorGroup
1658 + '... got the right DFS merge order for xx::DBIx::Class::Core');
1659 === ext/mro/t/recursion_c3.t
1660 ==================================================================
1661 --- ext/mro/t/recursion_c3.t (/local/perl-current) (revision 12599)
1662 +++ ext/mro/t/recursion_c3.t (/local/perl-c3) (revision 12599)
1669 + unless (-d 'blib') {
1670 + chdir 't' if -d 't';
1678 +# XXX needs translation back to classes, etc
1680 +plan skip_all => "Your system has no SIGALRM" if !exists $SIG{ALRM};
1685 +These are like the 010_complex_merge_classless test,
1686 +but an infinite loop has been made in the heirarchy,
1687 +to test that we can fail cleanly instead of going
1688 +into an infinite loop
1692 +# initial setup, everything sane
1695 + our @ISA = qw/J I/;
1699 + our @ISA = qw/H F/;
1709 + our @ISA = qw/A B C/;
1718 +# A series of 8 abberations that would cause infinite loops,
1719 +# each one undoing the work of the previous
1721 + sub { @E::ISA = qw/F/ },
1722 + sub { @E::ISA = qw/D/; @C::ISA = qw/F/ },
1723 + sub { @C::ISA = qw//; @A::ISA = qw/K/ },
1724 + sub { @A::ISA = qw//; @J::ISA = qw/F K/ },
1725 + sub { @J::ISA = qw/F/; @H::ISA = qw/K G/ },
1726 + sub { @H::ISA = qw/G/; @B::ISA = qw/B/ },
1727 + sub { @B::ISA = qw//; @K::ISA = qw/K J I/ },
1728 + sub { @K::ISA = qw/J I/; @D::ISA = qw/A H B C/ },
1731 +foreach my $loopy (@loopies) {
1733 + local $SIG{ALRM} = sub { die "ALRMTimeout" };
1736 + mro::get_mro_linear_c3('K');
1739 + if(my $err = $@) {
1740 + if($err =~ /ALRMTimeout/) {
1741 + ok(0, "Loop terminated by SIGALRM");
1743 + elsif($err =~ /Recursive inheritance detected/) {
1744 + ok(1, "Graceful exception thrown");
1747 + ok(0, "Unrecognized exception: $err");
1751 + ok(0, "Infinite loop apparently succeeded???");
1754 === ext/mro/t/overload_c3.t
1755 ==================================================================
1756 --- ext/mro/t/overload_c3.t (/local/perl-current) (revision 12599)
1757 +++ ext/mro/t/overload_c3.t (/local/perl-c3) (revision 12599)
1764 + unless (-d 'blib') {
1765 + chdir 't' if -d 't';
1770 +use Test::More tests => 7;
1779 + package OverloadingTest;
1783 + use base 'BaseTest';
1784 + use overload '""' => sub { ref(shift) . " stringified" },
1787 + sub new { bless {} => shift }
1789 + package InheritingFromOverloadedTest;
1792 + use base 'OverloadingTest';
1796 +my $x = InheritingFromOverloadedTest->new();
1797 +isa_ok($x, 'InheritingFromOverloadedTest');
1799 +my $y = OverloadingTest->new();
1800 +isa_ok($y, 'OverloadingTest');
1802 +is("$x", 'InheritingFromOverloadedTest stringified', '... got the right value when stringifing');
1803 +is("$y", 'OverloadingTest stringified', '... got the right value when stringifing');
1805 +ok(($y eq 'OverloadingTest stringified'), '... eq was handled correctly');
1809 + $result = $x eq 'InheritingFromOverloadedTest stringified'
1811 +ok(!$@, '... this should not throw an exception');
1812 +ok($result, '... and we should get the true value');
1814 === ext/mro/t/complex_dfs.t
1815 ==================================================================
1816 --- ext/mro/t/complex_dfs.t (/local/perl-current) (revision 12599)
1817 +++ ext/mro/t/complex_dfs.t (/local/perl-c3) (revision 12599)
1824 + unless (-d 'blib') {
1825 + chdir 't' if -d 't';
1830 +use Test::More tests => 11;
1835 +This example is taken from: http://rt.cpan.org/Public/Bug/Display.html?id=20879
1838 +Level 5 8 | A | 9 | B | A | C | (More General)
1850 +Level 3 4 | G | 6 | E | |
1855 +Level 2 3 | H | 5 | F | |
1863 +Level 1 1 | J | 2 | I | |
1868 +Level 0 0 | K | (More Specialized)
1878 + package Test::A; use mro 'dfs';
1880 + package Test::B; use mro 'dfs';
1882 + package Test::C; use mro 'dfs';
1884 + package Test::D; use mro 'dfs';
1885 + use base qw/Test::A Test::B Test::C/;
1887 + package Test::E; use mro 'dfs';
1888 + use base qw/Test::D/;
1890 + package Test::F; use mro 'dfs';
1891 + use base qw/Test::E/;
1893 + package Test::G; use mro 'dfs';
1894 + use base qw/Test::D/;
1896 + package Test::H; use mro 'dfs';
1897 + use base qw/Test::G/;
1899 + package Test::I; use mro 'dfs';
1900 + use base qw/Test::H Test::F/;
1902 + package Test::J; use mro 'dfs';
1903 + use base qw/Test::F/;
1905 + package Test::K; use mro 'dfs';
1906 + use base qw/Test::J Test::I/;
1910 + mro::get_mro_linear('Test::A'),
1912 + '... got the right DFS merge order for Test::A');
1915 + mro::get_mro_linear('Test::B'),
1917 + '... got the right DFS merge order for Test::B');
1920 + mro::get_mro_linear('Test::C'),
1922 + '... got the right DFS merge order for Test::C');
1925 + mro::get_mro_linear('Test::D'),
1926 + [ qw(Test::D Test::A Test::B Test::C) ],
1927 + '... got the right DFS merge order for Test::D');
1930 + mro::get_mro_linear('Test::E'),
1931 + [ qw(Test::E Test::D Test::A Test::B Test::C) ],
1932 + '... got the right DFS merge order for Test::E');
1935 + mro::get_mro_linear('Test::F'),
1936 + [ qw(Test::F Test::E Test::D Test::A Test::B Test::C) ],
1937 + '... got the right DFS merge order for Test::F');
1940 + mro::get_mro_linear('Test::G'),
1941 + [ qw(Test::G Test::D Test::A Test::B Test::C) ],
1942 + '... got the right DFS merge order for Test::G');
1945 + mro::get_mro_linear('Test::H'),
1946 + [ qw(Test::H Test::G Test::D Test::A Test::B Test::C) ],
1947 + '... got the right DFS merge order for Test::H');
1950 + mro::get_mro_linear('Test::I'),
1951 + [ qw(Test::I Test::H Test::G Test::D Test::A Test::B Test::C Test::F Test::E Test::D Test::A Test::B Test::C) ],
1952 + '... got the right DFS merge order for Test::I');
1955 + mro::get_mro_linear('Test::J'),
1956 + [ qw(Test::J Test::F Test::E Test::D Test::A Test::B Test::C) ],
1957 + '... got the right DFS merge order for Test::J');
1960 + mro::get_mro_linear('Test::K'),
1961 + [ qw(Test::K Test::J Test::F Test::E Test::D Test::A Test::B Test::C Test::I Test::H Test::G Test::D Test::A Test::B Test::C Test::F Test::E Test::D Test::A Test::B Test::C) ],
1962 + '... got the right DFS merge order for Test::K');
1963 === ext/mro/t/inconsistent_c3.t
1964 ==================================================================
1965 --- ext/mro/t/inconsistent_c3.t (/local/perl-current) (revision 12599)
1966 +++ ext/mro/t/inconsistent_c3.t (/local/perl-c3) (revision 12599)
1973 + unless (-d 'blib') {
1974 + chdir 't' if -d 't';
1979 +use Test::More tests => 1;
1984 +This example is take from: http://www.python.org/2.3/mro.html
1986 +"Serious order disagreement" # From Guido
1993 + class Z(A,B): pass #creates Z(A,B) in Python 2.2
1995 + pass # Z(A,B) cannot be created in Python 2.3
2005 + our @ISA = ('X', 'Y');
2008 + our @ISA = ('Y', 'X');
2011 + our @ISA = ('XY', 'YX');
2014 +eval { mro::get_mro_linear_c3('Z') };
2015 +like($@, qr/^Inconsistent /, '... got the right error with an inconsistent hierarchy');
2016 === ext/mro/t/recursion_dfs.t
2017 ==================================================================
2018 --- ext/mro/t/recursion_dfs.t (/local/perl-current) (revision 12599)
2019 +++ ext/mro/t/recursion_dfs.t (/local/perl-c3) (revision 12599)
2026 + unless (-d 'blib') {
2027 + chdir 't' if -d 't';
2035 +# XXX needs translation back to classes, etc
2037 +plan skip_all => "Your system has no SIGALRM" if !exists $SIG{ALRM};
2042 +These are like the 010_complex_merge_classless test,
2043 +but an infinite loop has been made in the heirarchy,
2044 +to test that we can fail cleanly instead of going
2045 +into an infinite loop
2049 +# initial setup, everything sane
2052 + our @ISA = qw/J I/;
2056 + our @ISA = qw/H F/;
2066 + our @ISA = qw/A B C/;
2075 +# A series of 8 abberations that would cause infinite loops,
2076 +# each one undoing the work of the previous
2078 + sub { @E::ISA = qw/F/ },
2079 + sub { @E::ISA = qw/D/; @C::ISA = qw/F/ },
2080 + sub { @C::ISA = qw//; @A::ISA = qw/K/ },
2081 + sub { @A::ISA = qw//; @J::ISA = qw/F K/ },
2082 + sub { @J::ISA = qw/F/; @H::ISA = qw/K G/ },
2083 + sub { @H::ISA = qw/G/; @B::ISA = qw/B/ },
2084 + sub { @B::ISA = qw//; @K::ISA = qw/K J I/ },
2085 + sub { @K::ISA = qw/J I/; @D::ISA = qw/A H B C/ },
2088 +foreach my $loopy (@loopies) {
2090 + local $SIG{ALRM} = sub { die "ALRMTimeout" };
2093 + mro::get_mro_linear_dfs('K');
2096 + if(my $err = $@) {
2097 + if($err =~ /ALRMTimeout/) {
2098 + ok(0, "Loop terminated by SIGALRM");
2100 + elsif($err =~ /Recursive inheritance detected/) {
2101 + ok(1, "Graceful exception thrown");
2104 + ok(0, "Unrecognized exception: $err");
2108 + ok(0, "Infinite loop apparently succeeded???");
2111 === ext/mro/t/basic_01_c3.t
2112 ==================================================================
2113 --- ext/mro/t/basic_01_c3.t (/local/perl-current) (revision 12599)
2114 +++ ext/mro/t/basic_01_c3.t (/local/perl-c3) (revision 12599)
2121 + unless (-d 'blib') {
2122 + chdir 't' if -d 't';
2127 +use Test::More tests => 4;
2132 +This tests the classic diamond inheritence pattern.
2143 + package Diamond_A;
2144 + sub hello { 'Diamond_A::hello' }
2147 + package Diamond_B;
2148 + use base 'Diamond_A';
2151 + package Diamond_C;
2152 + use base 'Diamond_A';
2154 + sub hello { 'Diamond_C::hello' }
2157 + package Diamond_D;
2158 + use base ('Diamond_B', 'Diamond_C');
2163 + mro::get_mro_linear('Diamond_D'),
2164 + [ qw(Diamond_D Diamond_B Diamond_C Diamond_A) ],
2165 + '... got the right MRO for Diamond_D');
2167 +is(Diamond_D->hello, 'Diamond_C::hello', '... method resolved itself as expected');
2168 +is(Diamond_D->can('hello')->(), 'Diamond_C::hello', '... can(method) resolved itself as expected');
2169 +is(UNIVERSAL::can("Diamond_D", 'hello')->(), 'Diamond_C::hello', '... can(method) resolved itself as expected');
2170 === ext/mro/t/basic_02_c3.t
2171 ==================================================================
2172 --- ext/mro/t/basic_02_c3.t (/local/perl-current) (revision 12599)
2173 +++ ext/mro/t/basic_02_c3.t (/local/perl-c3) (revision 12599)
2180 + unless (-d 'blib') {
2181 + chdir 't' if -d 't';
2186 +use Test::More tests => 10;
2191 +This example is take from: http://www.python.org/2.3/mro.html
2205 +Level 3 | O | (more general)
2211 +Level 2 3 | D | 4| E | | F | 5 |
2217 +Level 1 1 | B | | C | 2 |
2222 +Level 0 0 | A | (more specialized)
2233 + use base 'Test::O';
2236 + use base 'Test::O';
2239 + sub C_or_E { 'Test::E' }
2243 + use base 'Test::O';
2245 + sub C_or_D { 'Test::D' }
2248 + use base ('Test::D', 'Test::F');
2251 + sub C_or_D { 'Test::C' }
2252 + sub C_or_E { 'Test::C' }
2256 + use base ('Test::D', 'Test::E');
2259 + use base ('Test::B', 'Test::C');
2264 + mro::get_mro_linear('Test::F'),
2265 + [ qw(Test::F Test::O) ],
2266 + '... got the right MRO for Test::F');
2269 + mro::get_mro_linear('Test::E'),
2270 + [ qw(Test::E Test::O) ],
2271 + '... got the right MRO for Test::E');
2274 + mro::get_mro_linear('Test::D'),
2275 + [ qw(Test::D Test::O) ],
2276 + '... got the right MRO for Test::D');
2279 + mro::get_mro_linear('Test::C'),
2280 + [ qw(Test::C Test::D Test::F Test::O) ],
2281 + '... got the right MRO for Test::C');
2284 + mro::get_mro_linear('Test::B'),
2285 + [ qw(Test::B Test::D Test::E Test::O) ],
2286 + '... got the right MRO for Test::B');
2289 + mro::get_mro_linear('Test::A'),
2290 + [ qw(Test::A Test::B Test::C Test::D Test::E Test::F Test::O) ],
2291 + '... got the right MRO for Test::A');
2293 +is(Test::A->C_or_D, 'Test::C', '... got the expected method output');
2294 +is(Test::A->can('C_or_D')->(), 'Test::C', '... can got the expected method output');
2295 +is(Test::A->C_or_E, 'Test::C', '... got the expected method output');
2296 +is(Test::A->can('C_or_E')->(), 'Test::C', '... can got the expected method output');
2297 === ext/mro/t/overload_dfs.t
2298 ==================================================================
2299 --- ext/mro/t/overload_dfs.t (/local/perl-current) (revision 12599)
2300 +++ ext/mro/t/overload_dfs.t (/local/perl-c3) (revision 12599)
2307 + unless (-d 'blib') {
2308 + chdir 't' if -d 't';
2313 +use Test::More tests => 7;
2322 + package OverloadingTest;
2326 + use base 'BaseTest';
2327 + use overload '""' => sub { ref(shift) . " stringified" },
2330 + sub new { bless {} => shift }
2332 + package InheritingFromOverloadedTest;
2335 + use base 'OverloadingTest';
2339 +my $x = InheritingFromOverloadedTest->new();
2340 +isa_ok($x, 'InheritingFromOverloadedTest');
2342 +my $y = OverloadingTest->new();
2343 +isa_ok($y, 'OverloadingTest');
2345 +is("$x", 'InheritingFromOverloadedTest stringified', '... got the right value when stringifing');
2346 +is("$y", 'OverloadingTest stringified', '... got the right value when stringifing');
2348 +ok(($y eq 'OverloadingTest stringified'), '... eq was handled correctly');
2352 + $result = $x eq 'InheritingFromOverloadedTest stringified'
2354 +ok(!$@, '... this should not throw an exception');
2355 +ok($result, '... and we should get the true value');
2357 === ext/mro/t/basic_03_c3.t
2358 ==================================================================
2359 --- ext/mro/t/basic_03_c3.t (/local/perl-current) (revision 12599)
2360 +++ ext/mro/t/basic_03_c3.t (/local/perl-c3) (revision 12599)
2367 + unless (-d 'blib') {
2368 + chdir 't' if -d 't';
2373 +use Test::More tests => 4;
2378 +This example is take from: http://www.python.org/2.3/mro.html
2380 +"My second example"
2397 +Level 2 2 | E | 4 | D | | F | 5
2403 +Level 1 1 | B | | C | 3
2412 +(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>,
2413 +<class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>,
2422 + sub O_or_D { 'Test::O' }
2423 + sub O_or_F { 'Test::O' }
2426 + use base 'Test::O';
2429 + sub O_or_F { 'Test::F' }
2432 + use base 'Test::O';
2436 + use base 'Test::O';
2439 + sub O_or_D { 'Test::D' }
2440 + sub C_or_D { 'Test::D' }
2443 + use base ('Test::D', 'Test::F');
2446 + sub C_or_D { 'Test::C' }
2449 + use base ('Test::E', 'Test::D');
2453 + use base ('Test::B', 'Test::C');
2458 + mro::get_mro_linear('Test::A'),
2459 + [ qw(Test::A Test::B Test::E Test::C Test::D Test::F Test::O) ],
2460 + '... got the right MRO for Test::A');
2462 +is(Test::A->O_or_D, 'Test::D', '... got the right method dispatch');
2463 +is(Test::A->O_or_F, 'Test::F', '... got the right method dispatch');
2466 +# this test is particularly interesting because the p5 dispatch
2467 +# would actually call Test::D before Test::C and Test::D is a
2468 +# subclass of Test::C
2469 +is(Test::A->C_or_D, 'Test::C', '... got the right method dispatch');
2470 === ext/mro/t/basic_04_c3.t
2471 ==================================================================
2472 --- ext/mro/t/basic_04_c3.t (/local/perl-current) (revision 12599)
2473 +++ ext/mro/t/basic_04_c3.t (/local/perl-c3) (revision 12599)
2480 + unless (-d 'blib') {
2481 + chdir 't' if -d 't';
2486 +use Test::More tests => 1;
2491 +From the parrot test t/pmc/object-meths.t
2503 + package t::lib::A; use mro 'c3';
2504 + package t::lib::B; use mro 'c3';
2505 + package t::lib::E; use mro 'c3';
2506 + package t::lib::C; use mro 'c3'; use base ('t::lib::A', 't::lib::B');
2507 + package t::lib::D; use mro 'c3'; use base ('t::lib::A', 't::lib::E');
2508 + package t::lib::F; use mro 'c3'; use base ('t::lib::C', 't::lib::D');
2512 + mro::get_mro_linear('t::lib::F'),
2513 + [ qw(t::lib::F t::lib::C t::lib::D t::lib::A t::lib::B t::lib::E) ],
2514 + '... got the right MRO for t::lib::F');
2516 === ext/mro/t/basic_05_c3.t
2517 ==================================================================
2518 --- ext/mro/t/basic_05_c3.t (/local/perl-current) (revision 12599)
2519 +++ ext/mro/t/basic_05_c3.t (/local/perl-c3) (revision 12599)
2526 + unless (-d 'blib') {
2527 + chdir 't' if -d 't';
2532 +use Test::More tests => 2;
2537 +This tests a strange bug found by Matt S. Trout
2538 +while building DBIx::Class. Thanks Matt!!!!
2549 + package Diamond_A;
2552 + sub foo { 'Diamond_A::foo' }
2555 + package Diamond_B;
2556 + use base 'Diamond_A';
2559 + sub foo { 'Diamond_B::foo => ' . (shift)->SUPER::foo }
2562 + package Diamond_C;
2564 + use base 'Diamond_A';
2568 + package Diamond_D;
2569 + use base ('Diamond_C', 'Diamond_B');
2572 + sub foo { 'Diamond_D::foo => ' . (shift)->SUPER::foo }
2576 + mro::get_mro_linear('Diamond_D'),
2577 + [ qw(Diamond_D Diamond_C Diamond_B Diamond_A) ],
2578 + '... got the right MRO for Diamond_D');
2581 + 'Diamond_D::foo => Diamond_B::foo => Diamond_A::foo',
2582 + '... got the right next::method dispatch path');
2584 ==================================================================
2585 --- ext/mro/mro.xs (/local/perl-current) (revision 12599)
2586 +++ ext/mro/mro.xs (/local/perl-c3) (revision 12599)
2590 + * Copyright (c) 2006 Brandon L Black
2592 + * You may distribute under the terms of either the GNU General Public
2593 + * License or the Artistic License, as specified in the README file.
2597 +#define PERL_NO_GET_CONTEXT
2598 +#include "EXTERN.h"
2602 +MODULE = mro PACKAGE = mro
2605 +get_mro_linear(classname)
2609 + class_stash = gv_stashsv(classname, 0);
2610 + if(!class_stash) croak("No such class: '%"SVf"'!", classname);
2611 + RETVAL = mro_linear(class_stash);
2616 +get_mro_linear_dfs(classname)
2620 + class_stash = gv_stashsv(classname, 0);
2621 + if(!class_stash) croak("No such class: '%"SVf"'!", classname);
2622 + RETVAL = mro_linear_dfs(class_stash, 0);
2627 +get_mro_linear_c3(classname)
2631 + class_stash = gv_stashsv(classname, 0);
2632 + if(!class_stash) croak("No such class: '%"SVf"'!", classname);
2633 + RETVAL = mro_linear_c3(class_stash, 0);
2638 +set_mro_dfs(classname)
2642 + struct mro_meta* meta;
2643 + class_stash = gv_stashsv(classname, 1);
2644 + if(!class_stash) croak("Cannot create class: '%"SVf"'!", classname);
2645 + meta = HvMROMETA(class_stash);
2646 + meta->mro_which = MRO_DFS;
2647 + PL_sub_generation++;
2650 +set_mro_c3(classname)
2654 + struct mro_meta* meta;
2655 + class_stash = gv_stashsv(classname, 1);
2656 + if(!class_stash) croak("Cannot create class: '%"SVf"'!", classname);
2657 + meta = HvMROMETA(class_stash);
2658 + meta->mro_which = MRO_C3;
2659 + PL_sub_generation++;
2662 +is_mro_dfs(classname)
2666 + struct mro_meta* meta;
2667 + class_stash = gv_stashsv(classname, 0);
2668 + if(!class_stash) croak("No such class: '%"SVf"'!", classname);
2669 + meta = HvMROMETA(class_stash);
2670 + RETVAL = (meta->mro_which == MRO_DFS);
2675 +is_mro_c3(classname)
2679 + struct mro_meta* meta;
2680 + class_stash = gv_stashsv(classname, 0);
2681 + if(!class_stash) croak("No such class: '%"SVf"'!", classname);
2682 + meta = HvMROMETA(class_stash);
2683 + RETVAL = (meta->mro_which == MRO_C3);
2686 === ext/mro/Makefile.PL
2687 ==================================================================
2688 --- ext/mro/Makefile.PL (/local/perl-current) (revision 12599)
2689 +++ ext/mro/Makefile.PL (/local/perl-c3) (revision 12599)
2691 +use ExtUtils::MakeMaker;
2695 +my $e = $Config{'exe_ext'};
2696 +my $o = $Config{'obj_ext'};
2697 +my $exeout_flag = '-o ';
2698 +if ($^O eq 'MSWin32') {
2699 + if ($Config{'cc'} =~ /^cl/i) {
2700 + $exeout_flag = '-Fe';
2702 + elsif ($Config{'cc'} =~ /^bcc/i) {
2703 + $exeout_flag = '-e';
2709 + VERSION_FROM => "mro.pm",
2712 + FILES => "perl$e *$o mro.c *~"
2718 +sub post_constants {
2719 + "\nLIBS = $Config::Config{libs}\n"
2723 + File::Spec->catfile(File::Spec->updir,
2724 + File::Spec->updir, $_[0]);
2727 ==================================================================
2728 --- ext/mro/mro.pm (/local/perl-current) (revision 12599)
2729 +++ ext/mro/mro.pm (/local/perl-c3) (revision 12599)
2733 +# Copyright (c) 2006 Brandon L Black
2735 +# You may distribute under the terms of either the GNU General Public
2736 +# License or the Artistic License, as specified in the README file.
2742 +our $VERSION = '0.01';
2749 + if($arg eq 'c3') {
2750 + set_mro_c3(scalar(caller));
2752 + elsif($arg eq 'dfs') {
2753 + set_mro_dfs(scalar(caller));
2758 +XSLoader::load 'mro';
2766 +mro - Method Resolution Order
2770 + use mro; # just gain access to mro::* functions
2771 + use mro 'c3'; # enable C3 mro for this class
2772 + use mro 'dfs'; # enable DFS mro for this class (Perl default)
2784 +All of these take a scalar classname as the only argument
2788 +Return an arrayref which is the linearized MRO of the given class.
2789 +Uses whichever MRO is currently in effect for that class.
2791 +=head2 mro_linear_dfs
2793 +Return an arrayref which is the linearized MRO of the given classname.
2794 +Uses the DFS (perl default) MRO algorithm.
2796 +=head2 mro_linear_c3
2798 +Return an arrayref which is the linearized MRO of the given class.
2799 +Uses the C3 MRO algorithm.
2803 +Sets the MRO of the given class to DFS (perl default).
2807 +Sets the MRO of the given class to C3.
2811 +Return boolean indicating whether the given class is using the DFS (Perl default) MRO.
2815 +Return boolean indicating whether the given class is using the C3 MRO.
2819 +Brandon L Black, C<blblack@gmail.com>
2823 ==================================================================
2824 --- MANIFEST (/local/perl-current) (revision 12599)
2825 +++ MANIFEST (/local/perl-c3) (revision 12599)
2826 @@ -893,6 +893,30 @@
2827 ext/MIME/Base64/t/quoted-print.t See whether MIME::QuotedPrint works
2828 ext/MIME/Base64/t/unicode.t See whether MIME::Base64 works
2829 ext/MIME/Base64/t/warn.t See whether MIME::Base64 works
2830 +ext/mro/Makefile.PL mro extension
2831 +ext/mro/mro.xs mro extension
2832 +ext/mro/mro.pm mro extension
2833 +ext/mro/t/basic_01_c3.t mro tests
2834 +ext/mro/t/basic_01_dfs.t mro tests
2835 +ext/mro/t/basic_02_c3.t mro tests
2836 +ext/mro/t/basic_02_dfs.t mro tests
2837 +ext/mro/t/basic_03_c3.t mro tests
2838 +ext/mro/t/basic_03_dfs.t mro tests
2839 +ext/mro/t/basic_04_c3.t mro tests
2840 +ext/mro/t/basic_04_dfs.t mro tests
2841 +ext/mro/t/basic_05_c3.t mro tests
2842 +ext/mro/t/basic_05_dfs.t mro tests
2843 +ext/mro/t/complex_c3.t mro tests
2844 +ext/mro/t/complex_dfs.t mro tests
2845 +ext/mro/t/dbic_c3.t mro tests
2846 +ext/mro/t/dbic_dfs.t mro tests
2847 +ext/mro/t/inconsistent_c3.t mro tests
2848 +ext/mro/t/overload_c3.t mro tests
2849 +ext/mro/t/overload_dfs.t mro tests
2850 +ext/mro/t/recursion_c3.t mro tests
2851 +ext/mro/t/recursion_dfs.t mro tests
2852 +ext/mro/t/vulcan_c3.t mro tests
2853 +ext/mro/t/vulcan_dfs.t mro tests
2854 ext/NDBM_File/hints/cygwin.pl Hint for NDBM_File for named architecture
2855 ext/NDBM_File/hints/dec_osf.pl Hint for NDBM_File for named architecture
2856 ext/NDBM_File/hints/dynixptx.pl Hint for NDBM_File for named architecture
2857 @@ -2796,6 +2820,7 @@
2858 mpeix/mpeix_setjmp.c MPE/iX port
2859 mpeix/nm MPE/iX port
2860 mpeix/relink MPE/iX port
2861 +mro.c Method Resolution Order code
2862 myconfig.SH Prints summary of the current configuration
2863 NetWare/bat/Buildtype.bat NetWare port
2864 NetWare/bat/SetCodeWar.bat NetWare port
2866 ==================================================================
2867 --- mro.c (/local/perl-current) (revision 12599)
2868 +++ mro.c (/local/perl-c3) (revision 12599)
2872 + * Copyright (C) 2006 by Larry Wall and others
2874 + * You may distribute under the terms of either the GNU General Public
2875 + * License or the Artistic License, as specified in the README file.
2880 +=head1 MRO Functions
2882 +These functions are related to the method resolution order of perl classes
2887 +#include "EXTERN.h"
2891 +Perl_mro_meta_init(pTHX_ HV* stash) {
2892 + struct mro_meta* newmeta;
2894 + assert(HvAUX(stash));
2895 + assert(!(HvAUX(stash)->xhv_mro_meta));
2896 + Newxz(newmeta, sizeof(struct mro_meta), char);
2897 + HvAUX(stash)->xhv_mro_meta = newmeta;
2902 +=for apidoc mro_linear_dfs
2904 +Returns the Depth-First Search linearization of @ISA
2905 +the given stash. The return value is a read-only AV*,
2906 +and is cached based on C<PL_isa_generation>.
2911 +Perl_mro_linear_dfs(pTHX_ HV *stash, I32 level) {
2921 + const char* stashname;
2922 + struct mro_meta* meta;
2925 + assert(HvAUX(stash));
2927 + stashname = HvNAME_get(stash);
2930 + "Can't linearize anonymous symbol table");
2933 + Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
2936 + meta = HvMROMETA(stash);
2937 + if((retval = meta->mro_linear_dfs)) {
2938 + if(meta->mro_linear_dfs_gen == PL_isa_generation) {
2939 + /* return the cached linearization if valid */
2940 + SvREFCNT_inc_simple_void_NN(retval);
2943 + /* decref old cache and forget it */
2944 + SvREFCNT_dec(retval);
2945 + meta->mro_linear_dfs = NULL;
2948 + /* make a new one */
2950 + retval = (AV*)sv_2mortal((SV*)newAV());
2951 + av_push(retval, newSVpv(stashname, 0)); /* add ourselves at the top */
2953 + gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
2954 + av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : NULL;
2957 + svp = AvARRAY(av);
2958 + items = AvFILLp(av) + 1;
2960 + SV* const sv = *svp++;
2961 + HV* const basestash = gv_stashsv(sv, FALSE);
2963 + if (ckWARN(WARN_MISC))
2964 + Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %"SVf" for @%s::ISA",
2965 + (void*)sv, stashname);
2968 + subrv = (AV*)sv_2mortal((SV*)mro_linear_dfs(basestash, level + 1));
2969 + subrv_p = AvARRAY(subrv);
2970 + subrv_items = AvFILLp(subrv) + 1;
2971 + while(subrv_items--) {
2972 + SV* subsv = *subrv_p++;
2973 + av_push(retval, newSVsv(subsv));
2978 + SvREADONLY_on(retval);
2979 + SvREFCNT_inc_simple_void_NN(retval); /* for meta storage */
2980 + SvREFCNT_inc_simple_void_NN(retval); /* for return to caller */
2981 + meta->mro_linear_dfs = retval;
2982 + meta->mro_linear_dfs_gen = PL_isa_generation;
2987 +=for apidoc mro_linear_c3
2989 +Returns the C3 linearization of @ISA
2990 +the given stash. The return value is a read-only AV*,
2991 +and is cached based on C<PL_isa_generation>.
2997 +Perl_mro_linear_c3(pTHX_ HV* stash, I32 level) {
3002 + const char* stashname;
3003 + STRLEN stashname_len;
3004 + struct mro_meta* meta;
3007 + assert(HvAUX(stash));
3009 + stashname = HvNAME_get(stash);
3010 + stashname_len = HvNAMELEN_get(stash);
3013 + "Can't linearize anonymous symbol table");
3016 + Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
3019 + meta = HvMROMETA(stash);
3020 + if((retval = meta->mro_linear_c3)) {
3021 + if(meta->mro_linear_c3_gen == PL_isa_generation) {
3022 + /* return cache if valid */
3023 + SvREFCNT_inc_simple_void_NN(retval);
3026 + /* decref old cache and forget it */
3027 + SvREFCNT_dec(retval);
3028 + meta->mro_linear_c3 = NULL;
3031 + retval = (AV*)sv_2mortal((SV*)newAV());
3032 + av_push(retval, newSVpvn(stashname, stashname_len)); /* us first */
3034 + gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
3035 + isa = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : NULL;
3037 + if(isa && AvFILLp(isa) >= 0) {
3040 + HV* tails = (HV*)sv_2mortal((SV*)newHV());
3041 + AV* seqs = (AV*)sv_2mortal((SV*)newAV());
3042 + I32 items = AvFILLp(isa) + 1;
3043 + SV** isa_ptr = AvARRAY(isa);
3046 + SV* isa_item = *isa_ptr++;
3047 + HV* isa_item_stash = gv_stashsv(isa_item, FALSE);
3048 + if(!isa_item_stash)
3049 + Perl_croak(aTHX_ "Cannot find class %"SVf" for @%s::ISA", isa_item, stashname);
3050 + isa_lin = (AV*)sv_2mortal((SV*)mro_linear_c3(isa_item_stash, level + 1)); /* recursion */
3051 + av_push(seqs, (SV*)av_make(AvFILLp(isa_lin)+1, AvARRAY(isa_lin)));
3053 + av_push(seqs, (SV*)av_make(AvFILLp(isa)+1, AvARRAY(isa)));
3055 + seqs_ptr = AvARRAY(seqs);
3056 + seqs_items = AvFILLp(seqs) + 1;
3057 + while(seqs_items--) {
3058 + AV* seq = (AV*)*seqs_ptr++;
3059 + I32 seq_items = AvFILLp(seq);
3060 + if(seq_items > 0) {
3061 + SV** seq_ptr = AvARRAY(seq) + 1;
3062 + while(seq_items--) {
3063 + SV* seqitem = *seq_ptr++;
3064 + HE* he = hv_fetch_ent(tails, seqitem, 0, 0);
3066 + hv_store_ent(tails, seqitem, newSViv(1), 0);
3069 + SV* val = HeVAL(he);
3077 + SV* seqhead = NULL;
3079 + SV* winner = NULL;
3083 + SV** avptr = AvARRAY(seqs);
3084 + items = AvFILLp(seqs)+1;
3087 + seq = (AV*)*avptr++;
3088 + if(AvFILLp(seq) < 0) continue;
3089 + svp = av_fetch(seq, 0, 0);
3093 + if((tail_entry = hv_fetch_ent(tails, cand, 0, 0))
3094 + && (val = HeVAL(tail_entry))
3095 + && (SvIVx(val) > 0))
3097 + winner = newSVsv(cand);
3098 + av_push(retval, winner);
3100 + if(!sv_cmp(seqhead, winner)) {
3102 + /* this is basically shift(@seq) in void context */
3103 + SvREFCNT_dec(*AvARRAY(seq));
3104 + *AvARRAY(seq) = &PL_sv_undef;
3105 + AvARRAY(seq) = AvARRAY(seq) + 1;
3109 + if(AvFILLp(seq) < 0) continue;
3110 + svp = av_fetch(seq, 0, 0);
3112 + tail_entry = hv_fetch_ent(tails, seqhead, 0, 0);
3113 + val = HeVAL(tail_entry);
3119 + Perl_croak(aTHX_ "Inconsistent inheritance hierarchy during C3 merge of class '%s': "
3120 + "merging failed on parent '%"SVf"'", stashname, cand);
3124 + SvREADONLY_on(retval);
3125 + SvREFCNT_inc_simple_void_NN(retval); /* for meta storage */
3126 + SvREFCNT_inc_simple_void_NN(retval); /* for return to caller */
3127 + meta->mro_linear_c3 = retval;
3128 + meta->mro_linear_c3_gen = PL_isa_generation;
3133 +=for apidoc mro_linear
3135 +Returns either C<mro_linear_c3> or C<mro_linear_dfs> for
3136 +the given stash, dependant upon which MRO is in effect
3137 +for that stash. The return value is a read-only AV*,
3138 +and is cached based on C<PL_isa_generation>.
3143 +Perl_mro_linear(pTHX_ HV *stash)
3145 + struct mro_meta* meta;
3147 + assert(HvAUX(stash));
3149 + meta = HvMROMETA(stash);
3150 + if(meta->mro_which == MRO_DFS) {
3151 + return mro_linear_dfs(stash, 0);
3152 + } else if(meta->mro_which == MRO_C3) {
3153 + return mro_linear_c3(stash, 0);
3155 + Perl_croak(aTHX_ "Internal error: invalid MRO!");
3160 + * Local variables:
3161 + * c-indentation-style: bsd
3162 + * c-basic-offset: 4
3163 + * indent-tabs-mode: t
3166 + * ex: set ts=8 sts=4 sw=4 noet:
3169 ==================================================================
3170 --- hv.c (/local/perl-current) (revision 12599)
3171 +++ hv.c (/local/perl-c3) (revision 12599)
3172 @@ -1743,6 +1743,7 @@
3176 + struct mro_meta *meta;
3177 struct xpvhv_aux *iter = HvAUX(hv);
3178 /* If there are weak references to this HV, we need to avoid
3179 freeing them up here. In particular we need to keep the AV
3180 @@ -1774,6 +1775,13 @@
3181 iter->xhv_riter = -1; /* HvRITER(hv) = -1 */
3182 iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */
3184 + if(meta = iter->xhv_mro_meta) {
3185 + if(meta->mro_linear_dfs) SvREFCNT_dec(meta->mro_linear_dfs);
3186 + if(meta->mro_linear_c3) SvREFCNT_dec(meta->mro_linear_c3);
3188 + iter->xhv_mro_meta = NULL;
3191 /* There are now no allocated pointers in the aux structure. */
3193 SvFLAGS(hv) &= ~SVf_OOK; /* Goodbye, aux structure. */
3194 @@ -1895,6 +1903,7 @@
3195 iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */
3197 iter->xhv_backreferences = 0;
3198 + iter->xhv_mro_meta = NULL;
3203 ==================================================================
3204 --- hv.h (/local/perl-current) (revision 12599)
3205 +++ hv.h (/local/perl-c3) (revision 12599)
3208 /* Subject to change.
3209 Don't access this directly.
3210 + Use the funcs in mro.c
3219 + AV *mro_linear_dfs; /* cached dfs @ISA linearization */
3220 + AV *mro_linear_c3; /* cached c3 @ISA linearization */
3221 + U32 mro_linear_dfs_gen; /* PL_isa_generation for above */
3222 + U32 mro_linear_c3_gen; /* PL_isa_generation for above */
3223 + mro_alg mro_which; /* which mro alg is in use? */
3226 +/* Subject to change.
3227 + Don't access this directly.
3231 HEK *xhv_name; /* name, if a symbol table */
3232 AV *xhv_backreferences; /* back references for weak references */
3233 HE *xhv_eiter; /* current entry of iterator */
3234 I32 xhv_riter; /* current root of iterator */
3235 + struct mro_meta *xhv_mro_meta;
3238 /* hash structure: */
3240 #define HvRITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1)
3241 #define HvEITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : 0)
3242 #define HvNAME(hv) HvNAME_get(hv)
3243 +#define HvMROMETA(hv) (HvAUX(hv)->xhv_mro_meta ? HvAUX(hv)->xhv_mro_meta : mro_meta_init(hv))
3244 /* FIXME - all of these should use a UTF8 aware API, which should also involve
3245 getting the length. */
3246 /* This macro may go away without notice. */
3248 ==================================================================
3249 --- mg.c (/local/perl-current) (revision 12599)
3250 +++ mg.c (/local/perl-c3) (revision 12599)
3251 @@ -1520,6 +1520,7 @@
3252 PERL_UNUSED_ARG(sv);
3253 PERL_UNUSED_ARG(mg);
3254 PL_sub_generation++;
3255 + PL_isa_generation++;
3260 ==================================================================
3261 --- intrpvar.h (/local/perl-current) (revision 12599)
3262 +++ intrpvar.h (/local/perl-c3) (revision 12599)
3264 PERLVARI(Iutf8cache, I8, 1) /* Is the utf8 caching code enabled? */
3267 +PERLVARI(Iisa_generation,U32,1) /* incr to invalidate @ISA linearization cache */
3268 /* New variables must be added to the very end, before this comment,
3269 * for binary compatibility (the offsets of the old members must not change).
3270 * (Don't forget to add your variable also to perl_clone()!)
3272 ==================================================================
3273 --- sv.c (/local/perl-current) (revision 12599)
3274 +++ sv.c (/local/perl-c3) (revision 12599)
3275 @@ -11061,6 +11061,7 @@
3276 PL_initav = av_dup_inc(proto_perl->Iinitav, param);
3278 PL_sub_generation = proto_perl->Isub_generation;
3279 + PL_isa_generation = proto_perl->Iisa_generation;
3281 /* funky return mechanisms */
3282 PL_forkprocess = proto_perl->Iforkprocess;
3284 ==================================================================
3285 --- embed.fnc (/local/perl-current) (revision 12599)
3286 +++ embed.fnc (/local/perl-c3) (revision 12599)
3287 @@ -278,6 +278,10 @@
3288 Apmb |void |gv_efullname3 |NN SV* sv|NN const GV* gv|NULLOK const char* prefix
3289 Ap |void |gv_efullname4 |NN SV* sv|NN const GV* gv|NULLOK const char* prefix|bool keepmain
3290 Ap |GV* |gv_fetchfile |NN const char* name
3291 +ApM |struct mro_meta* |mro_meta_init |NN HV* stash
3292 +ApM |AV* |mro_linear |NN HV* stash
3293 +ApM |AV* |mro_linear_c3 |NN HV* stash|I32 level
3294 +ApM |AV* |mro_linear_dfs |NN HV* stash|I32 level
3295 Apd |GV* |gv_fetchmeth |NULLOK HV* stash|NN const char* name|STRLEN len|I32 level
3296 Apd |GV* |gv_fetchmeth_autoload |NULLOK HV* stash|NN const char* name|STRLEN len|I32 level
3297 Apdmb |GV* |gv_fetchmethod |NULLOK HV* stash|NN const char* name
3299 Property changes on:
3300 ___________________________________________________________________
3302 +2679d79f-d018-0410-a353-0f906ad2929c:/local/perl-current:12598