For SAVEt_ALLOC, store the number of save stack entries used with the type.
Nicholas Clark [Sat, 20 Feb 2010 17:19:53 +0000 (17:19 +0000)]
mg.c
scope.c
sv.c

diff --git a/mg.c b/mg.c
index 59ead34..3c57026 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -3071,14 +3071,12 @@ S_restore_magic(pTHX_ const void *p)
      */
     if (PL_savestack_ix == mgs->mgs_ss_ix)
     {
-       UV type = SSPOPUV;
-       I32 popval;
-        assert(type == SAVEt_DESTRUCTOR_X);
+       UV popval = SSPOPUV;
+        assert(popval == SAVEt_DESTRUCTOR_X);
         PL_savestack_ix -= 2;
-       type = SSPOPUV;
-        assert(type == SAVEt_ALLOC);
-       popval = SSPOPINT;
-        PL_savestack_ix -= popval;
+       popval = SSPOPUV;
+        assert((popval & SAVE_MASK) == SAVEt_ALLOC);
+        PL_savestack_ix -= popval >> SAVE_TIGHT_SHIFT;
     }
 
 }
diff --git a/scope.c b/scope.c
index b2c2ee0..5b7b614 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -680,13 +680,17 @@ Perl_save_alloc(pTHX_ I32 size, I32 pad)
     dVAR;
     register const I32 start = pad + ((char*)&PL_savestack[PL_savestack_ix]
                                - (char*)PL_savestack);
-    register const I32 elems = 1 + ((size + pad - 1) / sizeof(*PL_savestack));
+    const UV elems = 1 + ((size + pad - 1) / sizeof(*PL_savestack));
+    const UV elems_shifted = elems << SAVE_TIGHT_SHIFT;
 
-    SSGROW(elems + 2);
+    if ((elems_shifted >> SAVE_TIGHT_SHIFT) != elems)
+       Perl_croak(aTHX_ "panic: save_alloc elems %"UVuf" out of range (%ld-%ld)",
+                  elems, size, pad);
+
+    SSGROW(elems + 1);
 
     PL_savestack_ix += elems;
-    SSPUSHINT(elems);
-    SSPUSHUV(SAVEt_ALLOC);
+    SSPUSHUV(SAVEt_ALLOC | elems_shifted);
     return start;
 }
 
@@ -932,11 +936,8 @@ Perl_leave_scope(pTHX_ I32 base)
            break;
        case SAVEt_REGCONTEXT:
            /* regexp must have croaked */
-           PL_savestack_ix -= uv >> SAVE_TIGHT_SHIFT;
-           break;
        case SAVEt_ALLOC:
-           i = SSPOPINT;
-           PL_savestack_ix -= i;       /* regexp must have croaked */
+           PL_savestack_ix -= uv >> SAVE_TIGHT_SHIFT;
            break;
        case SAVEt_STACK_POS:           /* Position on Perl stack */
            i = SSPOPINT;
diff --git a/sv.c b/sv.c
index 6fc3ac2..cdeb362 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -11660,12 +11660,8 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
                                                 proto_perl));
            break;
        case SAVEt_REGCONTEXT:
-           ix -= uv >> SAVE_TIGHT_SHIFT;
-           break;
        case SAVEt_ALLOC:
-           i = POPINT(ss,ix);
-           TOPINT(nss,ix) = i;
-           ix -= i;
+           ix -= uv >> SAVE_TIGHT_SHIFT;
            break;
        case SAVEt_AELEM:               /* array element */
            sv = (const SV *)POPPTR(ss,ix);