diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-04-11 20:25:04 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-05-19 08:55:56 +0100 |
commit | 523a0f0c39e20d3c9a00a9efa8a965d0cf7ed035 (patch) | |
tree | cbc254864a93286b62f144eb9d6f7748c6982941 /op.c | |
parent | 8ae73bce341cb300ba81a3680bab34352ff2c2ba (diff) | |
download | perl-523a0f0c39e20d3c9a00a9efa8a965d0cf7ed035.tar.gz |
In S_fold_constants() under MAD, need to copy the SV representing the result.
For the non-MAD case (the historical default), it was fine to use pad_swipe()
(which doesn't adjust any part of the OS), because the OS was freed soon after.
However, the MAD code doesn't free the OS, hence as-was, without this change,
the OS still thought that it owned the pad slot, and much jollity resulted as
two different parts of the code fought over whichever SV had the bad luck to
next be billeted there.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -2683,8 +2683,16 @@ S_fold_constants(pTHX_ register OP *o) case 0: CALLRUNOPS(aTHX); sv = *(PL_stack_sp--); - if (o->op_targ && sv == PAD_SV(o->op_targ)) /* grab pad temp? */ + if (o->op_targ && sv == PAD_SV(o->op_targ)) { /* grab pad temp? */ +#ifdef PERL_MAD + /* Can't simply swipe the SV from the pad, because that relies on + the op being freed "real soon now". Under MAD, this doesn't + happen (see the #ifdef below). */ + sv = newSVsv(sv); +#else pad_swipe(o->op_targ, FALSE); +#endif + } else if (SvTEMP(sv)) { /* grab mortal temp? */ SvREFCNT_inc_simple_void(sv); SvTEMP_off(sv); |