This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add IP probe for ip_mreq
[perl5.git] / universal.c
index 563761e..a7c480f 100644 (file)
@@ -164,6 +164,8 @@ Perl_sv_derived_from_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len,
     }
     else {
         stash = gv_stashsv(sv, 0);
+        if (!stash)
+            stash = gv_stashpv("UNIVERSAL", 0);
     }
 
     return stash ? isa_lookup(stash, name, len, flags) : FALSE;
@@ -356,8 +358,8 @@ XS(XS_UNIVERSAL_can)
 
     SvGETMAGIC(sv);
 
-    if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
-               || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
+    if (!SvOK(sv) || !(SvROK(sv) || SvNIOK(sv) || (SvPOK(sv) && SvCUR(sv))
+       || (SvGMAGICAL(sv) && (SvNIOKp(sv) || (SvPOKp(sv) && SvCUR(sv))))))
        XSRETURN_UNDEF;
 
     rv = &PL_sv_undef;
@@ -369,6 +371,8 @@ XS(XS_UNIVERSAL_can)
     }
     else {
         pkg = gv_stashsv(sv, 0);
+        if (!pkg)
+            pkg = gv_stashpv("UNIVERSAL", 0);
     }
 
     if (pkg) {
@@ -425,7 +429,7 @@ XS(XS_UNIVERSAL_VERSION)
         SV * const nsv = sv_newmortal();
         sv_setsv(nsv, sv);
         sv = nsv;
-       if ( !sv_derived_from(sv, "version") || !SvROK(sv))
+       if ( !sv_isobject(sv) || !sv_derived_from(sv, "version"))
            upg_version(sv, FALSE);
 
         undef = NULL;
@@ -452,7 +456,7 @@ XS(XS_UNIVERSAL_VERSION)
             }
        }
 
-       if ( !sv_derived_from(req, "version") || !SvROK(req)) {
+       if ( !sv_isobject(req) || !sv_derived_from(req, "version")) {
            /* req may very well be R/O, so create a new object */
            req = sv_2mortal( new_version(req) );
        }
@@ -538,7 +542,7 @@ XS(XS_version_stringify)
      {
          SV *  lobj = ST(0);
 
-         if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+         if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
               lobj = SvRV(lobj);
          }
          else
@@ -561,7 +565,7 @@ XS(XS_version_numify)
      {
          SV *  lobj = ST(0);
 
-         if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+         if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
               lobj = SvRV(lobj);
          }
          else
@@ -584,7 +588,7 @@ XS(XS_version_normal)
      {
          SV *  lobj = ST(0);
 
-         if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+         if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
               lobj = SvRV(lobj);
          }
          else
@@ -607,7 +611,7 @@ XS(XS_version_vcmp)
      {
          SV *  lobj = ST(0);
 
-         if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+         if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
               lobj = SvRV(lobj);
          }
          else
@@ -619,7 +623,7 @@ XS(XS_version_vcmp)
               SV * robj = ST(1);
               const IV  swap = (IV)SvIV(ST(2));
 
-              if ( ! sv_derived_from(robj, "version") || !SvROK(robj) )
+              if ( !sv_isobject(robj) || !sv_derived_from(robj, "version") )
               {
                    robj = new_version(SvOK(robj) ? robj : newSVpvs_flags("0", SVs_TEMP));
                    sv_2mortal(robj);
@@ -650,9 +654,15 @@ XS(XS_version_boolean)
     if (items < 1)
        croak_xs_usage(cv, "lobj, ...");
     SP -= items;
-    if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+    if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
        SV * const lobj = SvRV(ST(0));
-       SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
+       SV * const rs =
+           newSViv( vcmp(lobj,
+                         sv_2mortal(new_version(
+                                       sv_2mortal(newSVpvs("0"))
+                                   ))
+                        )
+                  );
        mPUSHs(rs);
        PUTBACK;
        return;
@@ -667,7 +677,7 @@ XS(XS_version_noop)
     dXSARGS;
     if (items < 1)
        croak_xs_usage(cv, "lobj, ...");
-    if (sv_derived_from(ST(0), "version") && SvROK(ST(0)))
+    if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version"))
        Perl_croak(aTHX_ "operation not supported with version object");
     else
        Perl_croak(aTHX_ "lobj is not of type version");
@@ -683,7 +693,7 @@ XS(XS_version_is_alpha)
     if (items != 1)
        croak_xs_usage(cv, "lobj");
     SP -= items;
-    if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+    if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
        SV * const lobj = ST(0);
        if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
            XSRETURN_YES;
@@ -745,7 +755,7 @@ XS(XS_version_is_qv)
     if (items != 1)
        croak_xs_usage(cv, "lobj");
     SP -= items;
-    if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+    if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
        SV * const lobj = ST(0);
        if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "qv", 2 ) )
            XSRETURN_YES;
@@ -812,7 +822,7 @@ XS(XS_utf8_decode)
     else {
        SV * const sv = ST(0);
        bool RETVAL;
-       if (SvIsCOW(sv)) sv_force_normal(sv);
+       SvPV_force_nolen(sv);
        RETVAL = sv_utf8_decode(sv);
        ST(0) = boolSV(RETVAL);
     }
@@ -1004,14 +1014,10 @@ XS(XS_PerlIO_get_layers)
        }
 
        sv = POPs;
-       gv = MUTABLE_GV(sv);
+       gv = MAYBE_DEREF_GV(sv);
 
-       if (!isGV(sv)) {
-            if (SvROK(sv) && isGV(SvRV(sv)))
-                 gv = MUTABLE_GV(SvRV(sv));
-            else if (SvPOKp(sv))
-                 gv = gv_fetchsv(sv, 0, SVt_PVIO);
-       }
+       if (!gv && !SvROK(sv))
+           gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO);
 
        if (gv && (io = GvIO(gv))) {
             AV* const av = PerlIO_get_layers(aTHX_ input ?
@@ -1367,6 +1373,15 @@ struct xsub_details details[] = {
     {"version::vcmp", XS_version_vcmp, NULL},
     {"version::(bool", XS_version_boolean, NULL},
     {"version::boolean", XS_version_boolean, NULL},
+    {"version::(+", XS_version_noop, NULL},
+    {"version::(-", XS_version_noop, NULL},
+    {"version::(*", XS_version_noop, NULL},
+    {"version::(/", XS_version_noop, NULL},
+    {"version::(+=", XS_version_noop, NULL},
+    {"version::(-=", XS_version_noop, NULL},
+    {"version::(*=", XS_version_noop, NULL},
+    {"version::(/=", XS_version_noop, NULL},
+    {"version::(abs", XS_version_noop, NULL},
     {"version::(nomethod", XS_version_noop, NULL},
     {"version::noop", XS_version_noop, NULL},
     {"version::is_alpha", XS_version_is_alpha, NULL},
@@ -1408,9 +1423,6 @@ Perl_boot_core_UNIVERSAL(pTHX)
        newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
     } while (++xsub < end);
 
-    /* register the overloading (type 'A') magic */
-    PL_amagic_generation++;
-
     /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t  */
     {
        CV * const cv =
@@ -1425,8 +1437,8 @@ Perl_boot_core_UNIVERSAL(pTHX)
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
  * End:
  *
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
  */