diff options
author | David Mitchell <davem@iabyn.com> | 2010-09-08 16:53:10 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-09-08 16:53:10 +0100 |
commit | f83b46a0147ba6f476add85d17f61a7e7fb00f21 (patch) | |
tree | 0dcc25c8bf4f78496319fc13634d851282f3a960 /cop.h | |
parent | aafca5257dfefe4cf2a531c79cadea21a566f9c3 (diff) | |
download | perl-f83b46a0147ba6f476add85d17f61a7e7fb00f21.tar.gz |
bad things happened with for $x (...) { *x = *y }
fix for [perl #21469]:
since the GP may be pulled from under us and freed, coredumps and strange
things can happen.
Fix this by storing a pointer to the GV in the loop block, rather than a
pointer to the GvSV slot. The ITHREADS variant already stores GV rather
than than &GvSV; extend this to non-threaded builds too.
Also, for both threaded and non-threaded, it used to push &GvSV on the
save stack. Fix this by introducing a new save type, SAVEt_GVSV.
This behaves similarly to SAVEt_SV, but without magic get/set.
This means that
for $package_var (...)
is now close in behaviour to
local $package_var = ...
(except for the magic bit).
Diffstat (limited to 'cop.h')
-rw-r--r-- | cop.h | 14 |
1 files changed, 9 insertions, 5 deletions
@@ -469,15 +469,19 @@ struct block_loop { }; #ifdef USE_ITHREADS -# define CxITERVAR(c) \ +# define CxITERVAR_PADSV(c) \ + &CX_CURPAD_SV( (c)->blk_loop.itervar_u, (c)->blk_loop.my_op->op_targ) +#else +# define CxITERVAR_PADSV(c) ((c)->blk_loop.itervar_u.svp) +#endif + +#define CxITERVAR(c) \ ((c)->blk_loop.itervar_u.oldcomppad \ ? (CxPADLOOP(c) \ - ? &CX_CURPAD_SV( (c)->blk_loop.itervar_u, (c)->blk_loop.my_op->op_targ) \ + ? CxITERVAR_PADSV(c) \ : &GvSV((c)->blk_loop.itervar_u.gv)) \ : (SV**)NULL) -#else -# define CxITERVAR(c) ((c)->blk_loop.itervar_u.svp) -#endif + #define CxLABEL(c) (0 + CopLABEL((c)->blk_oldcop)) #define CxHASARGS(c) (((c)->cx_type & CXp_HASARGS) == CXp_HASARGS) #define CxLVAL(c) (0 + (c)->blk_u16) |