{
SV *targ = cx->sb_targ;
- if (DO_UTF8(dstr) && !SvUTF8(targ))
- sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
- else
- sv_catpvn(dstr, s, cx->sb_strend - s);
+ assert(cx->sb_strend >= s);
+ if(cx->sb_strend > s) {
+ if (DO_UTF8(dstr) && !SvUTF8(targ))
+ sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
+ else
+ sv_catpvn(dstr, s, cx->sb_strend - s);
+ }
cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
#ifdef PERL_COPY_ON_WRITE
#define RANGE_IS_NUMERIC(left,right) ( \
SvNIOKp(left) || (SvOK(left) && !SvPOKp(left)) || \
SvNIOKp(right) || (SvOK(right) && !SvPOKp(right)) || \
- (((!SvOK(left) && SvOK(right)) || (looks_like_number(left) && \
- SvPOKp(left) && *SvPVX(left) != '0')) && looks_like_number(right)))
+ (((!SvOK(left) && SvOK(right)) || ((!SvOK(left) || \
+ looks_like_number(left)) && SvPOKp(left) && *SvPVX(left) != '0')) \
+ && (!SvOK(right) || looks_like_number(right))))
PP(pp_flop)
{
if (GIMME == G_ARRAY) {
dPOPPOPssrl;
- register I32 i, j;
+ register IV i, j;
register SV *sv;
- I32 max;
+ IV max;
if (SvGMAGICAL(left))
mg_get(left);
mg_get(right);
if (RANGE_IS_NUMERIC(left,right)) {
- if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
+ if ((SvOK(left) && SvNV(left) < IV_MIN) ||
+ (SvOK(right) && SvNV(right) > IV_MAX))
DIE(aTHX_ "Range iterator outside integer range");
i = SvIV(left);
max = SvIV(right);
cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
dPOPss;
- if (RANGE_IS_NUMERIC(sv,(SV*)cx->blk_loop.iterary)) {
- if (SvNV(sv) < IV_MIN ||
- SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
+ SV *right = (SV*)cx->blk_loop.iterary;
+ if (RANGE_IS_NUMERIC(sv,right)) {
+ if ((SvOK(sv) && SvNV(sv) < IV_MIN) ||
+ (SvOK(right) && SvNV(right) >= IV_MAX))
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.iterix = SvIV(sv);
- cx->blk_loop.itermax = SvIV((SV*)cx->blk_loop.iterary);
+ cx->blk_loop.itermax = SvIV(right);
}
else {
STRLEN n_a;
cx->blk_loop.iterlval = newSVsv(sv);
- SvPV_force(cx->blk_loop.iterlval,n_a);
+ (void) SvPV_force(cx->blk_loop.iterlval,n_a);
+ (void) SvPV(right,n_a);
}
}
+ else if (PL_op->op_private & OPpITER_REVERSED) {
+ cx->blk_loop.itermax = -1;
+ cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary);
+
+ }
}
else {
cx->blk_loop.iterary = PL_curstack;
AvFILLp(PL_curstack) = SP - PL_stack_base;
- cx->blk_loop.iterix = MARK - PL_stack_base;
+ if (PL_op->op_private & OPpITER_REVERSED) {
+ cx->blk_loop.itermax = MARK - PL_stack_base;
+ cx->blk_loop.iterix = cx->blk_oldsp;
+ }
+ else {
+ cx->blk_loop.iterix = MARK - PL_stack_base;
+ }
}
RETURN;
else {
if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
sub_crush_depth(cv);
- pad_push(padlist, CvDEPTH(cv), cx->blk_sub.hasargs);
+ pad_push(padlist, CvDEPTH(cv), 1);
}
PAD_SET_CUR(padlist, CvDEPTH(cv));
if (cx->blk_sub.hasargs)
If db_seqp is non_null, skip CVs that are in the DB package and populate
*db_seqp with the cop sequence number at the point that the DB:: code was
entered. (allows debuggers to eval in the scope of the breakpoint rather
-than in in the scope of the debuger itself).
+than in in the scope of the debugger itself).
=cut
*/