SV ** itervar;
#endif
SV * itersave;
+ union {
/* (from inspection of source code) for a .. range of strings this is the
current string. */
- SV * iterlval;
+ SV * iterlval;
+ /* (from inspection of source code) for a .. range of numbers this is the
+ maximum value. */
+ IV itermax;
+ } lval_max_u;
union {
/* (from inspection of source code) for a foreach loop this is the array
being iterated over. For a .. range of numbers it's the current value.
IV itermin;
} ary_min_u;
IV iterix;
- /* (from inspection of source code) for a .. range of numbers this is the
- maximum value. */
- IV itermax;
};
-/* It might be possible to squeeze this structure further. As best I can tell
- itermax and iterlval are never used at the same time, so it might be possible
- to make them into a union. However, I'm not confident that there are enough
- flag bits/NULLable pointers in this structure alone to encode which is
- active. There is, however, U8 of space free in struct block, which could be
- used. Right now it may not be worth squeezing this structure further, as it's
- the largest part of struct block, and currently struct block is 64 bytes on
- an ILP32 system, which will give good cache alignment.
-*/
#ifdef USE_ITHREADS
# define CxITERVAR(c) \
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
PUSHLOOP_OP_NEXT; \
- cx->blk_loop.iterlval = NULL; \
+ cx->blk_loop.lval_max_u.iterlval = NULL; \
cx->blk_loop.ary_min_u.iterary = NULL; \
CX_ITERDATA_SET(cx,NULL);
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
PUSHLOOP_OP_NEXT; \
- cx->blk_loop.iterlval = NULL; \
+ cx->blk_loop.lval_max_u.iterlval = NULL; \
cx->blk_loop.ary_min_u.iterary = NULL; \
cx->blk_loop.iterix = -1; \
CX_ITERDATA_SET(cx,dat);
#define POPLOOP(cx) \
- if (CxTYPE(cx) == CXt_LOOP_LAZYIV) \
- assert(!cx->blk_loop.iterlval); \
- SvREFCNT_dec(cx->blk_loop.iterlval); \
+ if (CxTYPE(cx) != CXt_LOOP_LAZYIV) \
+ SvREFCNT_dec(cx->blk_loop.lval_max_u.iterlval); \
if (CxITERVAR(cx)) { \
if (SvPADMY(cx->blk_loop.itersave)) { \
SV ** const s_v_p = CxITERVAR(cx); \
#endif
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.iterix = SvIV(sv);
- cx->blk_loop.itermax = SvIV(right);
+ cx->blk_loop.lval_max_u.itermax = SvIV(right);
#ifdef DEBUGGING
/* for correct -Dstv display */
cx->blk_oldsp = sp - PL_stack_base;
#endif
}
else {
- cx->blk_loop.iterlval = newSVsv(sv);
- (void) SvPV_force_nolen(cx->blk_loop.iterlval);
+ cx->blk_loop.lval_max_u.iterlval = newSVsv(sv);
+ (void) SvPV_force_nolen(cx->blk_loop.lval_max_u.iterlval);
(void) SvPV_nolen_const(right);
}
}
else if (PL_op->op_private & OPpITER_REVERSED) {
- cx->blk_loop.itermax = 0xDEADBEEF;
cx->blk_loop.iterix = AvFILL(cx->blk_loop.ary_min_u.iterary) + 1;
}
/* iterate ($min .. $max) */
if (CxTYPE(cx) != CXt_LOOP_LAZYIV) {
/* string increment */
- register SV* cur = cx->blk_loop.iterlval;
+ register SV* cur = cx->blk_loop.lval_max_u.iterlval;
STRLEN maxlen = 0;
const char *max =
SvOK((SV*)av) ?
RETPUSHNO;
}
/* integer increment */
- assert(!cx->blk_loop.iterlval);
- if (cx->blk_loop.iterix > cx->blk_loop.itermax)
+ if (cx->blk_loop.iterix > cx->blk_loop.lval_max_u.itermax)
RETPUSHNO;
/* don't risk potential race */
/* Handle end of range at IV_MAX */
if ((cx->blk_loop.iterix == IV_MIN) &&
- (cx->blk_loop.itermax == IV_MAX))
+ (cx->blk_loop.lval_max_u.itermax == IV_MAX))
{
cx->blk_loop.iterix++;
- cx->blk_loop.itermax++;
+ cx->blk_loop.lval_max_u.itermax++;
}
RETPUSHYES;
else
sv = &PL_sv_undef;
if (av != PL_curstack && sv == &PL_sv_undef) {
- SV *lv = cx->blk_loop.iterlval;
+ SV *lv = cx->blk_loop.lval_max_u.iterlval;
if (lv && SvREFCNT(lv) > 1) {
SvREFCNT_dec(lv);
lv = NULL;
if (lv)
SvREFCNT_dec(LvTARG(lv));
else {
- lv = cx->blk_loop.iterlval = newSV_type(SVt_PVLV);
+ lv = cx->blk_loop.lval_max_u.iterlval = newSV_type(SVt_PVLV);
LvTYPE(lv) = 'y';
sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
}
PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%"UVxf"\n",
PTR2UV(cx->blk_loop.itersave));
PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERLVAL = 0x%"UVxf"\n",
- PTR2UV(cx->blk_loop.iterlval));
+ PTR2UV(cx->blk_loop.lval_max_u.iterlval));
break;
case CXt_SUBST:
ncx->blk_loop.oldcomppad);
ncx->blk_loop.itersave = sv_dup_inc(ncx->blk_loop.itersave,
param);
- ncx->blk_loop.iterlval = sv_dup_inc(ncx->blk_loop.iterlval,
- param);
+ if (CxTYPE(ncx) != CXt_LOOP_LAZYIV)
+ ncx->blk_loop.lval_max_u.iterlval
+ = sv_dup_inc(ncx->blk_loop.lval_max_u.iterlval, param);
break;
case CXt_FORMAT:
ncx->blk_format.cv = cv_dup(ncx->blk_format.cv, param);