summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2006-12-13 01:47:34 +0000
committerDave Mitchell <davem@fdisolutions.com>2006-12-13 01:47:34 +0000
commit670f3923755f0c152f1bbc2d0a205d2d07284748 (patch)
treed42b438c68d76a9ee818a4a30085cc0f2d3793a0 /op.c
parent30994c59813138744bd35d43a2330cafe5893149 (diff)
downloadperl-670f3923755f0c152f1bbc2d0a205d2d07284748.tar.gz
fix parser leaks caused by croaking while shifting or reducing
e.g. these no longer leak: eval q[my $x; local $x] while 1; eval q[$s = sub <> {}] while 1; p4raw-id: //depot/perl@29543
Diffstat (limited to 'op.c')
-rw-r--r--op.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/op.c b/op.c
index ab84ef143d..1a3baa34c5 100644
--- a/op.c
+++ b/op.c
@@ -287,6 +287,11 @@ Perl_op_free(pTHX_ OP *o)
if (!o || o->op_static)
return;
+ if (o->op_latefreed) {
+ if (o->op_latefree)
+ return;
+ goto do_free;
+ }
type = o->op_type;
if (o->op_private & OPpREFCOUNTED) {
@@ -327,6 +332,11 @@ Perl_op_free(pTHX_ OP *o)
cop_free((COP*)o);
op_clear(o);
+ if (o->op_latefree) {
+ o->op_latefreed = 1;
+ return;
+ }
+ do_free:
FreeOp(o);
#ifdef DEBUG_LEAKING_SCALARS
if (PL_op == o)
@@ -2712,6 +2722,8 @@ Perl_newOP(pTHX_ I32 type, I32 flags)
o->op_type = (OPCODE)type;
o->op_ppaddr = PL_ppaddr[type];
o->op_flags = (U8)flags;
+ o->op_latefree = 0;
+ o->op_latefreed = 0;
o->op_next = o;
o->op_private = (U8)(0 | (flags >> 8));