Upgrade to PathTools 3.08
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index c838a6d..9bd3ab1 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -534,7 +534,7 @@ Perl_sv_free_arenas(pTHX)
            svanext = (SV*) SvANY(svanext);
 
        if (!SvFAKE(sva))
-           Safefree((void *)sva);
+           Safefree(sva);
     }
 
     for (arena = PL_xnv_arenaroot; arena; arena = arenanext) {
@@ -1173,19 +1173,19 @@ S_more_xpv(pTHX)
 STATIC void
 S_more_xpviv(pTHX)
 {
-    XPVIV* xpviv;
-    XPVIV* xpvivend;
-    New(714, xpviv, PERL_ARENA_SIZE/sizeof(XPVIV), XPVIV);
-    *((XPVIV**)xpviv) = PL_xpviv_arenaroot;
+    xpviv_allocated* xpviv;
+    xpviv_allocated* xpvivend;
+    New(713, xpviv, PERL_ARENA_SIZE/sizeof(xpviv_allocated), xpviv_allocated);
+    *((xpviv_allocated**)xpviv) = PL_xpviv_arenaroot;
     PL_xpviv_arenaroot = xpviv;
 
-    xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(XPVIV) - 1];
+    xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(xpviv_allocated) - 1];
     PL_xpviv_root = ++xpviv;
     while (xpviv < xpvivend) {
-       *((XPVIV**)xpviv) = xpviv + 1;
+       *((xpviv_allocated**)xpviv) = xpviv + 1;
        xpviv++;
     }
-    *((XPVIV**)xpviv) = 0;
+    *((xpviv_allocated**)xpviv) = 0;
 }
 
 /* allocate another arena's worth of struct xpvnv */
@@ -1417,14 +1417,20 @@ S_del_xpv(pTHX_ XPV *p)
 STATIC XPVIV*
 S_new_xpviv(pTHX)
 {
-    XPVIV* xpviv;
+    xpviv_allocated* xpviv;
     LOCK_SV_MUTEX;
     if (!PL_xpviv_root)
        S_more_xpviv(aTHX);
     xpviv = PL_xpviv_root;
-    PL_xpviv_root = *(XPVIV**)xpviv;
+    PL_xpviv_root = *(xpviv_allocated**)xpviv;
     UNLOCK_SV_MUTEX;
-    return xpviv;
+    /* If xpviv_allocated is the same structure as XPVIV then the two OFFSETs
+       sum to zero, and the pointer is unchanged. If the allocated structure
+       is smaller (no initial IV actually allocated) then the net effect is
+       to subtract the size of the IV from the pointer, to return a new pointer
+       as if an initial IV were actually allocated.  */
+    return (XPVIV*)((char*)xpviv - STRUCT_OFFSET(XPVIV, xpv_cur)
+                 + STRUCT_OFFSET(xpviv_allocated, xpv_cur));
 }
 
 /* return a struct xpviv to the free list */
@@ -1432,9 +1438,12 @@ S_new_xpviv(pTHX)
 STATIC void
 S_del_xpviv(pTHX_ XPVIV *p)
 {
+    xpviv_allocated* xpviv
+       = (xpviv_allocated*)((char*)(p) + STRUCT_OFFSET(XPVIV, xpv_cur)
+                          - STRUCT_OFFSET(xpviv_allocated, xpv_cur));
     LOCK_SV_MUTEX;
-    *(XPVIV**)p = PL_xpviv_root;
-    PL_xpviv_root = p;
+    *(xpviv_allocated**)xpviv = PL_xpviv_root;
+    PL_xpviv_root = xpviv;
     UNLOCK_SV_MUTEX;
 }
 
@@ -1870,7 +1879,6 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
            AvMAX(sv)   = -1;
            AvFILLp(sv) = -1;
            AvALLOC(sv) = 0;
-           AvARYLEN(sv)= 0;
            AvREAL_only(sv);
        }
        /* to here.  */
@@ -4941,7 +4949,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
     if (SvREADONLY(sv)) {
        if (SvFAKE(sv)) {
            char *pvx = SvPVX(sv);
-           int is_utf8 = SvUTF8(sv);
+           const int is_utf8 = SvUTF8(sv);
            STRLEN len = SvCUR(sv);
             U32 hash   = SvUVX(sv);
            SvFAKE_off(sv);
@@ -5445,6 +5453,7 @@ Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 nam
     case PERL_MAGIC_vec:
        vtable = &PL_vtbl_vec;
        break;
+    case PERL_MAGIC_arylen_p:
     case PERL_MAGIC_rhash:
     case PERL_MAGIC_symtab:
     case PERL_MAGIC_vstring:
@@ -10877,7 +10886,6 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        SvLEN_set(dstr, SvLEN(sstr));
        SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
        SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
-       AvARYLEN((AV*)dstr) = sv_dup_inc(AvARYLEN((AV*)sstr), param);
        if (AvARRAY((AV*)sstr)) {
            SV **dst_ary, **src_ary;
            SSize_t items = AvFILLp((AV*)sstr) + 1;
@@ -11211,6 +11219,9 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
     void (*dptr) (void*);
     void (*dxptr) (pTHX_ void*);
     OP *o;
+    /* Unions for circumventing strict ANSI C89 casting rules. */
+    union { void *vptr; void (*dptr)(void*); } u1, u2;
+    union { void *vptr; void (*dxptr)(pTHX_ void*); } u3, u4;
 
     Newz(54, nss, max, ANY);
 
@@ -11382,13 +11393,17 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);  /* XXX quite arbitrary */
            dptr = POPDPTR(ss,ix);
-           TOPDPTR(nss,ix) = (void (*)(void*))any_dup((void *)dptr, proto_perl);
+           u1.dptr = dptr;
+           u2.vptr = any_dup(u1.vptr, proto_perl);
+           TOPDPTR(nss,ix) = u2.dptr;
            break;
        case SAVEt_DESTRUCTOR_X:
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);  /* XXX quite arbitrary */
            dxptr = POPDXPTR(ss,ix);
-           TOPDXPTR(nss,ix) = (void (*)(pTHX_ void*))any_dup((void *)dxptr, proto_perl);
+           u3.dxptr = dxptr;
+           u4.vptr = any_dup(u3.vptr, proto_perl);;
+           TOPDXPTR(nss,ix) = u4.dxptr;
            break;
        case SAVEt_REGCONTEXT:
        case SAVEt_ALLOC: