summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mg.c12
-rw-r--r--scope.c17
-rw-r--r--sv.c6
3 files changed, 15 insertions, 20 deletions
diff --git a/mg.c b/mg.c
index 59ead344d0..3c5702669f 100644
--- 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 b2c2ee0f64..5b7b614243 100644
--- 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 6fc3ac2a78..cdeb362fd3 100644
--- 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);