diff options
-rw-r--r-- | mg.c | 12 | ||||
-rw-r--r-- | scope.c | 17 | ||||
-rw-r--r-- | sv.c | 6 |
3 files changed, 15 insertions, 20 deletions
@@ -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; } } @@ -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; @@ -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); |