diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1999-10-09 00:41:02 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1999-10-09 00:41:02 +0000 |
commit | b0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9 (patch) | |
tree | a7de3bee889a19e08ea369636a8e8b53b0bacb28 /pp_hot.c | |
parent | a8bba7fac320f0a7f553e9a133cddd65ef2a66c7 (diff) | |
download | perl-b0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9.tar.gz |
POPSUB() gave up the refcount to the CV before LEAVE had a chance to
clear entries in the CV's pad, leading to coredumps when CV had no
other references to it; this is a slightly edited version of the
patch suggested by Russel O'Connor <roconnor@world.std.com>
p4raw-id: //depot/perl@4321
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 24 |
1 files changed, 18 insertions, 6 deletions
@@ -1914,6 +1914,7 @@ PP(pp_leavesub) PMOP *newpm; I32 gimme; register PERL_CONTEXT *cx; + SV *sv; POPBLOCK(cx,newpm); @@ -1951,10 +1952,11 @@ PP(pp_leavesub) } PUTBACK; - POPSUB(cx); /* Stack values are safe: release CV and @_ ... */ + POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ LEAVE; + LEAVESUB(sv); return pop_return(); } @@ -1968,6 +1970,7 @@ PP(pp_leavesublv) PMOP *newpm; I32 gimme; register PERL_CONTEXT *cx; + SV *sv; POPBLOCK(cx,newpm); @@ -2005,8 +2008,10 @@ PP(pp_leavesublv) * the refcounts so the caller gets a live guy. Cannot set * TEMP, so sv_2mortal is out of question. */ if (!CvLVALUE(cx->blk_sub.cv)) { - POPSUB(cx); + POPSUB(cx,sv); PL_curpm = newpm; + LEAVE; + LEAVESUB(sv); DIE(aTHX_ "Can't modify non-lvalue subroutine call"); } if (gimme == G_SCALAR) { @@ -2014,8 +2019,10 @@ PP(pp_leavesublv) EXTEND_MORTAL(1); if (MARK == SP) { if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { - POPSUB(cx); + POPSUB(cx,sv); PL_curpm = newpm; + LEAVE; + LEAVESUB(sv); DIE(aTHX_ "Can't return a %s from lvalue subroutine", SvREADONLY(TOPs) ? "readonly value" : "temporary"); } @@ -2026,8 +2033,10 @@ PP(pp_leavesublv) } } else { /* Should not happen? */ - POPSUB(cx); + POPSUB(cx,sv); PL_curpm = newpm; + LEAVE; + LEAVESUB(sv); DIE(aTHX_ "%s returned from lvalue subroutine in scalar context", (MARK > SP ? "Empty array" : "Array")); } @@ -2039,8 +2048,10 @@ PP(pp_leavesublv) if (SvFLAGS(*mark) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { /* Might be flattened array after $#array = */ PUTBACK; - POPSUB(cx); + POPSUB(cx,sv); PL_curpm = newpm; + LEAVE; + LEAVESUB(sv); DIE(aTHX_ "Can't return %s from lvalue subroutine", (*mark != &PL_sv_undef) ? (SvREADONLY(TOPs) @@ -2093,10 +2104,11 @@ PP(pp_leavesublv) } PUTBACK; - POPSUB(cx); /* Stack values are safe: release CV and @_ ... */ + POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ LEAVE; + LEAVESUB(sv); return pop_return(); } |