*/
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;
}
}
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;
}
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;
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);