As Perl_get_arena() is dealing with sizes, use size_t rather than int,
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index 2d4fc39..ac5eeb0 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -443,7 +443,8 @@ static void
 do_clean_objs(pTHX_ SV *ref)
 {
     dVAR;
-    if (SvROK(ref)) {
+    assert (SvROK(ref));
+    {
        SV * const target = SvRV(ref);
        if (SvOBJECT(target)) {
            DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "), sv_dump(ref)));
@@ -469,7 +470,9 @@ static void
 do_clean_named_objs(pTHX_ SV *sv)
 {
     dVAR;
-    if (SvTYPE(sv) == SVt_PVGV && isGV_with_GP(sv) && GvGP(sv)) {
+    assert(SvTYPE(sv) == SVt_PVGV);
+    assert(isGV_with_GP(sv));
+    if (GvGP(sv)) {
        if ((
 #ifdef PERL_DONT_CREATE_GVSV
             GvSV(sv) &&
@@ -504,7 +507,7 @@ Perl_sv_clean_objs(pTHX)
     visit(do_clean_objs, SVf_ROK, SVf_ROK);
 #ifndef DISABLE_DESTRUCTOR_KLUDGE
     /* some barnacles may yet remain, clinging to typeglobs */
-    visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK);
+    visit(do_clean_named_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
 #endif
     PL_in_clean_objs = FALSE;
 }
@@ -676,7 +679,7 @@ Perl_sv_free_arenas(pTHX)
    TBD: export properly for hv.c: S_more_he().
 */
 void*
-Perl_get_arena(pTHX_ int arena_size)
+Perl_get_arena(pTHX_ size_t arena_size)
 {
     dVAR;
     struct arena_desc* adesc;
@@ -701,7 +704,7 @@ Perl_get_arena(pTHX_ int arena_size)
     adesc = &((*aroot)->set[curr]);
     assert(!adesc->arena);
     
-    Newxz(adesc->arena, arena_size, char);
+    Newx(adesc->arena, arena_size, char);
     adesc->size = arena_size;
     DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %d\n", 
                          curr, (void*)adesc->arena, arena_size));
@@ -1033,10 +1036,6 @@ static const struct body_details bodies_by_type[] = {
 #define new_NOARENAZ(details) \
        my_safecalloc((details)->body_size + (details)->offset)
 
-#if defined(DEBUGGING) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
-static bool done_sanity_check;
-#endif
-
 STATIC void *
 S_more_bodies (pTHX_ svtype sv_type)
 {
@@ -1046,10 +1045,9 @@ S_more_bodies (pTHX_ svtype sv_type)
     const size_t body_size = bdp->body_size;
     char *start;
     const char *end;
-
-    assert(bdp->arena_size);
-
 #if defined(DEBUGGING) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
+    static bool done_sanity_check;
+
     /* PERL_GLOBAL_STRUCT_PRIVATE cannot coexist with global
      * variables like done_sanity_check. */
     if (!done_sanity_check) {
@@ -1062,6 +1060,8 @@ S_more_bodies (pTHX_ svtype sv_type)
     }
 #endif
 
+    assert(bdp->arena_size);
+
     start = (char*) Perl_get_arena(aTHX_ bdp->arena_size);
 
     end = start + bdp->arena_size - body_size;
@@ -3457,6 +3457,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
        break;
 
        /* case SVt_BIND: */
+    case SVt_PVLV:
     case SVt_PVGV:
        if (isGV_with_GP(sstr) && dtype <= SVt_PVGV) {
            glob_assign_glob(dstr, sstr, dtype);
@@ -3466,7 +3467,6 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
        /*FALLTHROUGH*/
 
     case SVt_PVMG:
-    case SVt_PVLV:
        if (SvGMAGICAL(sstr) && (flags & SV_GMAGIC)) {
            mg_get(sstr);
            if (SvTYPE(sstr) != stype) {
@@ -3705,7 +3705,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
            SvNV_set(dstr, SvNVX(sstr));
        }
        if (sflags & SVp_IOK) {
-           SvRELEASE_IVX(dstr);
+           SvOOK_off(dstr);
            SvIV_set(dstr, SvIVX(sstr));
            /* Must do this otherwise some other overloaded use of 0x80000000
               gets confused. I guess SVpbm_VALID */
@@ -4010,9 +4010,9 @@ Perl_sv_usepvn_flags(pTHX_ SV *sv, char *ptr, STRLEN len, U32 flags)
    (which it can do by means other than releasing copy-on-write Svs)
    or by changing the other copy-on-write SVs in the loop.  */
 STATIC void
-S_sv_release_COW(pTHX_ register SV *sv, const char *pvx, STRLEN len, SV *after)
+S_sv_release_COW(pTHX_ register SV *sv, const char *pvx, SV *after)
 {
-    if (len) { /* this SV was SvIsCOW_normal(sv) */
+    { /* this SV was SvIsCOW_normal(sv) */
          /* we need to find the SV pointing to us.  */
         SV *current = SV_COW_NEXT_SV(after);
 
@@ -4036,19 +4036,8 @@ S_sv_release_COW(pTHX_ register SV *sv, const char *pvx, STRLEN len, SV *after)
             /* Make the SV before us point to the SV after us.  */
             SV_COW_NEXT_SV_SET(current, after);
         }
-    } else {
-        unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
     }
 }
-
-int
-Perl_sv_release_IVX(pTHX_ register SV *sv)
-{
-    if (SvIsCOW(sv))
-        sv_force_normal_flags(sv, 0);
-    SvOOK_off(sv);
-    return 0;
-}
 #endif
 /*
 =for apidoc sv_force_normal_flags
@@ -4077,7 +4066,11 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
            const char * const pvx = SvPVX_const(sv);
            const STRLEN len = SvLEN(sv);
            const STRLEN cur = SvCUR(sv);
-           SV * const next = SV_COW_NEXT_SV(sv);   /* next COW sv in the loop. */
+           /* next COW sv in the loop.  If len is 0 then this is a shared-hash
+              key scalar, so we mustn't attempt to call SV_COW_NEXT_SV(), as
+              we'll fail an assertion.  */
+           SV * const next = len ? SV_COW_NEXT_SV(sv) : 0;
+
             if (DEBUG_C_TEST) {
                 PerlIO_printf(Perl_debug_log,
                               "Copy on write: Force normal %ld\n",
@@ -4098,7 +4091,11 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
                 SvCUR_set(sv, cur);
                 *SvEND(sv) = '\0';
             }
-            sv_release_COW(sv, pvx, len, next);
+           if (len) {
+               sv_release_COW(sv, pvx, next);
+           } else {
+               unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
+           }
             if (DEBUG_C_TEST) {
                 sv_dump(sv);
             }
@@ -5158,7 +5155,6 @@ Perl_sv_clear(pTHX_ register SV *sv)
        }
        else if (LvTYPE(sv) != 't') /* unless tie: unrefcnted fake SV**  */
            SvREFCNT_dec(LvTARG(sv));
-       goto freescalar;
     case SVt_PVGV:
        if (isGV_with_GP(sv)) {
            gp_free((GV*)sv);
@@ -5196,8 +5192,12 @@ Perl_sv_clear(pTHX_ register SV *sv)
                     PerlIO_printf(Perl_debug_log, "Copy on write: clear\n");
                     sv_dump(sv);
                 }
-                sv_release_COW(sv, SvPVX_const(sv), SvLEN(sv),
-                              SV_COW_NEXT_SV(sv));
+               if (SvLEN(sv)) {
+                   sv_release_COW(sv, SvPVX_const(sv), SV_COW_NEXT_SV(sv));
+               } else {
+                   unshare_hek(SvSHARED_HEK_FROM_PV(SvPVX_const(sv)));
+               }
+
                 /* And drop it here.  */
                 SvFAKE_off(sv);
             } else if (SvLEN(sv)) {
@@ -10045,20 +10045,16 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
                    LvTARG(dstr) = (SV*)he_dup((HE*)LvTARG(dstr), 0, param);
                else
                    LvTARG(dstr) = sv_dup_inc(LvTARG(dstr), param);
-               break;
            case SVt_PVGV:
                if(isGV_with_GP(sstr)) {
                    if (GvNAME_HEK(dstr))
                        GvNAME_HEK(dstr) = hek_dup(GvNAME_HEK(dstr), param);
-               }
-
-               /* Don't call sv_add_backref here as it's going to be created
-                  as part of the magic cloning of the symbol table.  */
-               if(!SvVALID(dstr))
-                   GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param);
-               if(isGV_with_GP(sstr)) {
+                   /* Don't call sv_add_backref here as it's going to be
+                      created as part of the magic cloning of the symbol
+                      table.  */
                    /* Danger Will Robinson - GvGP(dstr) isn't initialised
                       at the point of this comment.  */
+                   GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param);
                    GvGP(dstr)  = gp_dup(GvGP(sstr), param);
                    (void)GpREFCNT_inc(GvGP(dstr));
                } else