This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Move the function to set $^X to its own file
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index 41f9d17..8ef01c9 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -41,8 +41,6 @@
 # include <stdint.h>
 #endif
 
-#define FCALL *f
-
 #ifdef __Lynx__
 /* Missing proto on LynxOS */
   char *gconvert(double, int, int,  char *);
@@ -419,7 +417,7 @@ S_visit(pTHX_ SVFUNC_t f, const U32 flags, const U32 mask)
                    && (sv->sv_flags & mask) == flags
                    && SvREFCNT(sv))
            {
-               (FCALL)(aTHX_ sv);
+               (*f)(aTHX_ sv);
                ++visited;
            }
        }
@@ -1479,13 +1477,6 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
 
     PERL_ARGS_ASSERT_SV_GROW;
 
-#ifdef HAS_64K_LIMIT
-    if (newlen >= 0x10000) {
-       PerlIO_printf(Perl_debug_log,
-                     "Allocation too large: %"UVxf"\n", (UV)newlen);
-       my_exit(1);
-    }
-#endif /* HAS_64K_LIMIT */
     if (SvROK(sv))
        sv_unref(sv);
     if (SvTYPE(sv) < SVt_PV) {
@@ -1497,10 +1488,6 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
        s = SvPVX_mutable(sv);
        if (newlen > SvLEN(sv))
            newlen += 10 * (newlen - SvCUR(sv)); /* avoid copy each time */
-#ifdef HAS_64K_LIMIT
-       if (newlen >= 0x10000)
-           newlen = 0xFFFF;
-#endif
     }
     else
     {
@@ -2998,10 +2985,6 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            RESTORE_ERRNO;
            while (*s) s++;
        }
-#ifdef hcx
-       if (s[-1] == '.')
-           *--s = '\0';
-#endif
     }
     else if (isGV_with_GP(sv)) {
        GV *const gv = MUTABLE_GV(sv);
@@ -3169,12 +3152,13 @@ contain SV_GMAGIC, then it does an mg_get() first.
 */
 
 bool
-Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags)
+Perl_sv_2bool_flags(pTHX_ SV *sv, I32 flags)
 {
     dVAR;
 
     PERL_ARGS_ASSERT_SV_2BOOL_FLAGS;
 
+    restart:
     if(flags & SV_GMAGIC) SvGETMAGIC(sv);
 
     if (!SvOK(sv))
@@ -3182,8 +3166,30 @@ Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags)
     if (SvROK(sv)) {
        if (SvAMAGIC(sv)) {
            SV * const tmpsv = AMG_CALLunary(sv, bool__amg);
-           if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv))))
-               return cBOOL(SvTRUE(tmpsv));
+           if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv)))) {
+                bool svb;
+                sv = tmpsv;
+                if(SvGMAGICAL(sv)) {
+                    flags = SV_GMAGIC;
+                    goto restart; /* call sv_2bool */
+                }
+                /* expanded SvTRUE_common(sv, (flags = 0, goto restart)) */
+                else if(!SvOK(sv)) {
+                    svb = 0;
+                }
+                else if(SvPOK(sv)) {
+                    svb = SvPVXtrue(sv);
+                }
+                else if((SvFLAGS(sv) & (SVf_IOK|SVf_NOK))) {
+                    svb = (SvIOK(sv) && SvIVX(sv) != 0)
+                        || (SvNOK(sv) && SvNVX(sv) != 0.0);
+                }
+                else {
+                    flags = 0;
+                    goto restart; /* call sv_2bool_nomg */
+                }
+                return cBOOL(svb);
+            }
        }
        return SvRV(sv) != 0;
     }
@@ -5696,12 +5702,10 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv)
     if (SvTYPE(tsv) == SVt_PVHV) {
        svp = (SV**)Perl_hv_backreferences_p(aTHX_ MUTABLE_HV(tsv));
     } else {
-       if (! ((mg =
-           (SvMAGICAL(tsv) ? mg_find(tsv, PERL_MAGIC_backref) : NULL))))
-       {
-           sv_magic(tsv, NULL, PERL_MAGIC_backref, NULL, 0);
-           mg = mg_find(tsv, PERL_MAGIC_backref);
-       }
+        if (SvMAGICAL(tsv))
+            mg = mg_find(tsv, PERL_MAGIC_backref);
+       if (!mg)
+            mg = sv_magicext(tsv, NULL, PERL_MAGIC_backref, &PL_vtbl_backref, NULL, 0);
        svp = &(mg->mg_obj);
     }
 
@@ -5711,32 +5715,32 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv)
        || (*svp && SvTYPE(*svp) != SVt_PVAV)
     ) {
        /* create array */
+       if (mg)
+           mg->mg_flags |= MGf_REFCOUNTED;
        av = newAV();
        AvREAL_off(av);
-       SvREFCNT_inc_simple_void(av);
+       SvREFCNT_inc_simple_void_NN(av);
        /* av now has a refcnt of 2; see discussion above */
+       av_extend(av, *svp ? 2 : 1);
        if (*svp) {
            /* move single existing backref to the array */
-           av_extend(av, 1);
            AvARRAY(av)[++AvFILLp(av)] = *svp; /* av_push() */
        }
        *svp = (SV*)av;
-       if (mg)
-           mg->mg_flags |= MGf_REFCOUNTED;
     }
-    else
+    else {
        av = MUTABLE_AV(*svp);
-
-    if (!av) {
-       /* optimisation: store single backref directly in HvAUX or mg_obj */
-       *svp = sv;
-       return;
+        if (!av) {
+            /* optimisation: store single backref directly in HvAUX or mg_obj */
+            *svp = sv;
+            return;
+        }
+        assert(SvTYPE(av) == SVt_PVAV);
+        if (AvFILLp(av) >= AvMAX(av)) {
+            av_extend(av, AvFILLp(av)+1);
+        }
     }
     /* push new backref */
-    assert(SvTYPE(av) == SVt_PVAV);
-    if (AvFILLp(av) >= AvMAX(av)) {
-        av_extend(av, AvFILLp(av)+1);
-    }
     AvARRAY(av)[++AvFILLp(av)] = sv; /* av_push() */
 }
 
@@ -6297,8 +6301,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                    if (PL_stashcache) {
                     DEBUG_o(Perl_deb(aTHX_ "sv_clear clearing PL_stashcache for '%"SVf"'\n",
                                      sv));
-                       (void)hv_delete(PL_stashcache, name,
-                           HvNAMEUTF8((HV*)sv) ? -HvNAMELEN_get((HV*)sv) : HvNAMELEN_get((HV*)sv), G_DISCARD);
+                       (void)hv_deletehek(PL_stashcache,
+                                          HvNAME_HEK((HV*)sv), G_DISCARD);
                     }
                    hv_name_set((HV*)sv, NULL, 0, 0);
                }
@@ -13561,9 +13565,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PerlIO_clone(aTHX_ proto_perl, param);
 #endif
 
-    PL_envgv           = gv_dup(proto_perl->Ienvgv, param);
-    PL_incgv           = gv_dup(proto_perl->Iincgv, param);
-    PL_hintgv          = gv_dup(proto_perl->Ihintgv, param);
+    PL_envgv           = gv_dup_inc(proto_perl->Ienvgv, param);
+    PL_incgv           = gv_dup_inc(proto_perl->Iincgv, param);
+    PL_hintgv          = gv_dup_inc(proto_perl->Ihintgv, param);
     PL_origfilename    = SAVEPV(proto_perl->Iorigfilename);
     PL_diehook         = sv_dup_inc(proto_perl->Idiehook, param);
     PL_warnhook                = sv_dup_inc(proto_perl->Iwarnhook, param);
@@ -13605,20 +13609,20 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_stdingv         = gv_dup(proto_perl->Istdingv, param);
     PL_stderrgv                = gv_dup(proto_perl->Istderrgv, param);
     PL_defgv           = gv_dup(proto_perl->Idefgv, param);
-    PL_argvgv          = gv_dup(proto_perl->Iargvgv, param);
+    PL_argvgv          = gv_dup_inc(proto_perl->Iargvgv, param);
     PL_argvoutgv       = gv_dup(proto_perl->Iargvoutgv, param);
     PL_argvout_stack   = av_dup_inc(proto_perl->Iargvout_stack, param);
 
     /* shortcuts to regexp stuff */
-    PL_replgv          = gv_dup(proto_perl->Ireplgv, param);
+    PL_replgv          = gv_dup_inc(proto_perl->Ireplgv, param);
 
     /* shortcuts to misc objects */
     PL_errgv           = gv_dup(proto_perl->Ierrgv, param);
 
     /* shortcuts to debugging objects */
-    PL_DBgv            = gv_dup(proto_perl->IDBgv, param);
-    PL_DBline          = gv_dup(proto_perl->IDBline, param);
-    PL_DBsub           = gv_dup(proto_perl->IDBsub, param);
+    PL_DBgv            = gv_dup_inc(proto_perl->IDBgv, param);
+    PL_DBline          = gv_dup_inc(proto_perl->IDBline, param);
+    PL_DBsub           = gv_dup_inc(proto_perl->IDBsub, param);
     PL_DBsingle                = sv_dup(proto_perl->IDBsingle, param);
     PL_DBtrace         = sv_dup(proto_perl->IDBtrace, param);
     PL_DBsignal                = sv_dup(proto_perl->IDBsignal, param);
@@ -13727,8 +13731,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 #endif /* !USE_LOCALE_NUMERIC */
 
     /* Unicode inversion lists */
-    PL_ASCII           = sv_dup_inc(proto_perl->IASCII, param);
     PL_Latin1          = sv_dup_inc(proto_perl->ILatin1, param);
+    PL_UpperLatin1     = sv_dup_inc(proto_perl->IUpperLatin1, param);
     PL_AboveLatin1     = sv_dup_inc(proto_perl->IAboveLatin1, param);
 
     PL_NonL1NonFinalFold = sv_dup_inc(proto_perl->INonL1NonFinalFold, param);
@@ -13841,8 +13845,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_errors          = sv_dup_inc(proto_perl->Ierrors, param);
 
     PL_sortcop         = (OP*)any_dup(proto_perl->Isortcop, proto_perl);
-    PL_firstgv         = gv_dup(proto_perl->Ifirstgv, param);
-    PL_secondgv                = gv_dup(proto_perl->Isecondgv, param);
+    PL_firstgv         = gv_dup_inc(proto_perl->Ifirstgv, param);
+    PL_secondgv                = gv_dup_inc(proto_perl->Isecondgv, param);
 
     PL_stashcache       = newHV();