From: Nicholas Clark Date: Sat, 26 Jan 2008 16:03:03 +0000 (+0000) Subject: As itersave points to the initial CxITERVAR(), and the state of X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d28d780685cbd952928da9c691e2b5bae129457a;p=p5sagit%2Fp5-mst-13.2.git As itersave points to the initial CxITERVAR(), and the state of SvPADMY() does not change over the duration of the scope, we can perform conditional actions at loop push time. For the non-pad case, a reference to the initial CxITERVAR() is already held on the scope stack thanks to SAVEGENERICSV(*svp); in pp_enteriter. So there is no need to save another reference to it in itersave - it's not going away. p4raw-id: //depot/perl@33076 --- diff --git a/cop.h b/cop.h index 359abd6..ca9dae2 100644 --- a/cop.h +++ b/cop.h @@ -469,14 +469,15 @@ struct block_loop { : (SV**)NULL) # define CX_ITERDATA_SET(cx,idata) \ CX_CURPAD_SAVE(cx->blk_loop); \ - if ((cx->blk_loop.iterdata = (idata))) \ + if ((cx->blk_loop.iterdata = (idata)) && SvPADMY(*CxITERVAR(cx))) \ cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \ else \ cx->blk_loop.itersave = NULL; #else # define CxITERVAR(c) ((c)->blk_loop.itervar) # define CX_ITERDATA_SET(cx,ivar) \ - if ((cx->blk_loop.itervar = (SV**)(ivar))) \ + if ((cx->blk_loop.itervar = (SV**)(ivar)) \ + && SvPADMY(*CxITERVAR(cx))) \ cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \ else \ cx->blk_loop.itersave = NULL; @@ -515,14 +516,10 @@ struct block_loop { SvREFCNT_dec(cx->blk_loop.state_u.lazysv.end); \ } \ if (cx->blk_loop.itersave) { \ - if (SvPADMY(cx->blk_loop.itersave)) { \ - SV ** const s_v_p = CxITERVAR(cx); \ - sv_2mortal(*s_v_p); \ - *s_v_p = cx->blk_loop.itersave; \ - } \ - else { \ - SvREFCNT_dec(cx->blk_loop.itersave); \ - } \ + SV ** const s_v_p = CxITERVAR(cx); \ + assert(SvPADMY(cx->blk_loop.itersave)); \ + sv_2mortal(*s_v_p); \ + *s_v_p = cx->blk_loop.itersave; \ } \ if (CxTYPE(cx) == CXt_LOOP_FOR) \ SvREFCNT_dec(cx->blk_loop.state_u.ary.ary);