Add test for previous patch (deprecation of UNIVERSAL->import)
[p5sagit/p5-mst-13.2.git] / universal.c
index a69ab0d..d333d23 100644 (file)
@@ -9,9 +9,11 @@
  */
 
 /*
- * "The roots of those mountains must be roots indeed; there must be
- * great secrets buried there which have not been discovered since the
- * beginning." --Gandalf, relating Gollum's story
+ * '"The roots of those mountains must be roots indeed; there must be
+ *   great secrets buried there which have not been discovered since the
+ *   beginning."'                   --Gandalf, relating Gollum's history
+ *
+ *     [p.54 of _The Lord of the Rings_, I/ii: "The Shadow of the Past"]
  */
 
 /* This file contains the code that implements the functions in Perl's
 #include "perliol.h" /* For the PERLIO_F_XXX */
 #endif
 
+static HV *
+S_get_isa_hash(pTHX_ HV *const stash)
+{
+    dVAR;
+    struct mro_meta *const meta = HvMROMETA(stash);
+
+    PERL_ARGS_ASSERT_GET_ISA_HASH;
+
+    if (!meta->isa) {
+       AV *const isa = mro_get_linear_isa(stash);
+       if (!meta->isa) {
+           HV *const isa_hash = newHV();
+           /* Linearisation didn't build it for us, so do it here.  */
+           SV *const *svp = AvARRAY(isa);
+           SV *const *const svp_end = svp + AvFILLp(isa) + 1;
+           const HEK *const canon_name = HvNAME_HEK(stash);
+
+           while (svp < svp_end) {
+               (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
+           }
+
+           (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
+                            HEK_LEN(canon_name), HEK_FLAGS(canon_name),
+                            HV_FETCH_ISSTORE, &PL_sv_undef,
+                            HEK_HASH(canon_name));
+           (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
+
+           SvREADONLY_on(isa_hash);
+
+           meta->isa = isa_hash;
+       }
+    }
+    return meta->isa;
+}
+
 /*
  * Contributed by Graham Barr  <Graham.Barr@tiuk.ti.com>
  * The main guts of traverse_isa was actually copied from gv_fetchmeth
@@ -41,7 +78,7 @@ S_isa_lookup(pTHX_ HV *stash, const char * const name)
 {
     dVAR;
     const struct mro_meta *const meta = HvMROMETA(stash);
-    HV *const isa = meta->isa ? meta->isa : Perl_get_isa_hash(aTHX_ stash);
+    HV *const isa = meta->isa ? meta->isa : S_get_isa_hash(aTHX_ stash);
     STRLEN len = strlen(name);
     const HV *our_stash;
 
@@ -366,7 +403,7 @@ XS(XS_UNIVERSAL_can)
     rv = &PL_sv_undef;
 
     if (SvROK(sv)) {
-        sv = (SV*)SvRV(sv);
+        sv = MUTABLE_SV(SvRV(sv));
         if (SvOBJECT(sv))
             pkg = SvSTASH(sv);
     }
@@ -377,7 +414,7 @@ XS(XS_UNIVERSAL_can)
     if (pkg) {
        GV * const gv = gv_fetchmethod_autoload(pkg, name, FALSE);
         if (gv && isGV(gv))
-           rv = sv_2mortal(newRV((SV*)GvCV(gv)));
+           rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
     }
 
     ST(0) = rv;
@@ -416,7 +453,7 @@ XS(XS_UNIVERSAL_VERSION)
     PERL_UNUSED_ARG(cv);
 
     if (SvROK(ST(0))) {
-        sv = (SV*)SvRV(ST(0));
+        sv = MUTABLE_SV(SvRV(ST(0)));
         if (!SvOBJECT(sv))
             Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
         pkg = SvSTASH(sv);
@@ -436,7 +473,7 @@ XS(XS_UNIVERSAL_VERSION)
         undef = NULL;
     }
     else {
-        sv = (SV*)&PL_sv_undef;
+        sv = &PL_sv_undef;
         undef = "(undef)";
     }
 
@@ -462,7 +499,7 @@ XS(XS_UNIVERSAL_VERSION)
        }
 
        if ( vcmp( req, sv ) > 0 ) {
-           if ( hv_exists((HV*)SvRV(req), "qv", 2 ) ) {
+           if ( hv_exists(MUTABLE_HV(SvRV(req)), "qv", 2 ) ) {
                Perl_croak(aTHX_ "%s version %"SVf" required--"
                       "this is only version %"SVf"", HvNAME_get(pkg),
                       SVfARG(vnormal(req)),
@@ -504,7 +541,7 @@ XS(XS_version_new)
        if ( items == 1 || vs == &PL_sv_undef ) { /* no param or explicit undef */
            /* create empty object */
            vs = sv_newmortal();
-           sv_setpvn(vs,"",0);
+           sv_setpvs(vs,"");
        }
        else if ( items == 3 ) {
            vs = sv_newmortal();
@@ -677,7 +714,7 @@ XS(XS_version_is_alpha)
     SP -= items;
     if (sv_derived_from(ST(0), "version")) {
        SV * const lobj = ST(0);
-       if ( hv_exists((HV*)SvRV(lobj), "alpha", 5 ) )
+       if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
            XSRETURN_YES;
        else
            XSRETURN_NO;
@@ -884,7 +921,7 @@ XS(XS_Internals_hv_clear_placehold)
     if (items != 1)
        croak_xs_usage(cv, "hv");
     else {
-       HV * const hv = (HV *) SvRV(ST(0));
+       HV * const hv = MUTABLE_HV(SvRV(ST(0)));
        hv_clear_placeholders(hv);
        XSRETURN(0);
     }
@@ -949,11 +986,11 @@ XS(XS_PerlIO_get_layers)
        }
 
        sv = POPs;
-       gv = (GV*)sv;
+       gv = MUTABLE_GV(sv);
 
        if (!isGV(sv)) {
             if (SvROK(sv) && isGV(SvRV(sv)))
-                 gv = (GV*)SvRV(sv);
+                 gv = MUTABLE_GV(SvRV(sv));
             else if (SvPOKp(sv))
                  gv = gv_fetchsv(sv, 0, SVt_PVIO);
        }
@@ -1052,7 +1089,7 @@ XS(XS_Internals_HvREHASH) /* Subject to change  */
     dXSARGS;
     PERL_UNUSED_ARG(cv);
     if (SvROK(ST(0))) {
-       const HV * const hv = (HV *) SvRV(ST(0));
+       const HV * const hv = (const HV *) SvRV(ST(0));
        if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
            if (HvREHASH(hv))
                XSRETURN_YES;
@@ -1179,7 +1216,7 @@ XS(XS_re_regnames)
     if (!ret)
         XSRETURN_UNDEF;
 
-    av = (AV*)SvRV(ret);
+    av = MUTABLE_AV(SvRV(ret));
     length = av_len(av);
 
     for (i = 0; i <= length; i++) {
@@ -1256,7 +1293,7 @@ XS(XS_re_regexp_pattern)
             /* Scalar, so use the string that Perl would return */
             /* return the pattern in (?msix:..) format */
 #if PERL_VERSION >= 11
-            pattern = sv_2mortal(newSVsv((SV*)re));
+            pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
 #else
             pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
                                     (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
@@ -1305,7 +1342,7 @@ XS(XS_Tie_Hash_NamedCapture_FETCH)
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(1), flags);
 
     SPAGAIN;
@@ -1332,14 +1369,14 @@ XS(XS_Tie_Hash_NamedCapture_STORE)
 
     if (!rx) {
         if (!PL_localizing)
-            Perl_croak(aTHX_ PL_no_modify);
+            Perl_croak(aTHX_ "%s", PL_no_modify);
         else
             XSRETURN_UNDEF;
     }
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     CALLREG_NAMED_BUFF_STORE(rx,ST(1), ST(2), flags);
 }
 
@@ -1354,11 +1391,11 @@ XS(XS_Tie_Hash_NamedCapture_DELETE)
        croak_xs_usage(cv, "$key, $flags");
 
     if (!rx)
-        Perl_croak(aTHX_ PL_no_modify);
+        Perl_croak(aTHX_ "%s", PL_no_modify);
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     CALLREG_NAMED_BUFF_DELETE(rx, ST(1), flags);
 }
 
@@ -1375,11 +1412,11 @@ XS(XS_Tie_Hash_NamedCapture_CLEAR)
     rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
 
     if (!rx)
-        Perl_croak(aTHX_ PL_no_modify);
+        Perl_croak(aTHX_ "%s", PL_no_modify);
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     CALLREG_NAMED_BUFF_CLEAR(rx, flags);
 }
 
@@ -1401,7 +1438,7 @@ XS(XS_Tie_Hash_NamedCapture_EXISTS)
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     ret = CALLREG_NAMED_BUFF_EXISTS(rx, ST(1), flags);
 
     SPAGAIN;
@@ -1429,7 +1466,7 @@ XS(XS_Tie_Hash_NamedCapture_FIRSTK)
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     ret = CALLREG_NAMED_BUFF_FIRSTKEY(rx, flags);
 
     SPAGAIN;
@@ -1461,7 +1498,7 @@ XS(XS_Tie_Hash_NamedCapture_NEXTK)
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     ret = CALLREG_NAMED_BUFF_NEXTKEY(rx, ST(1), flags);
 
     SPAGAIN;
@@ -1492,7 +1529,7 @@ XS(XS_Tie_Hash_NamedCapture_SCALAR)
 
     SP -= items;
 
-    flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+    flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
     ret = CALLREG_NAMED_BUFF_SCALAR(rx, flags);
 
     SPAGAIN;