diff options
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 39 |
1 files changed, 37 insertions, 2 deletions
@@ -1852,7 +1852,7 @@ PP(pp_goto) mark++; } } - if (perldb && curstash != debstash) { + if (PERLDB_SUB && curstash != debstash) { /* * We do not care about using sv to call CV; * it's for informational purposes only. @@ -1940,6 +1940,11 @@ PP(pp_goto) OP *oldop = op; for (ix = 1; enterops[ix]; ix++) { op = enterops[ix]; + /* Eventually we may want to stack the needed arguments + * for each op. For now, we punt on the hard ones. */ + if (op->op_type == OP_ENTERITER) + DIE("Can't \"goto\" into the middle of a foreach loop", + label); (*op->op_ppaddr)(); } op = oldop; @@ -2205,7 +2210,7 @@ int gimme; DEBUG_x(dump_eval()); /* Register with debugger: */ - if (perldb && saveop->op_type == OP_REQUIRE) { + if (PERLDB_INTER && saveop->op_type == OP_REQUIRE) { CV *cv = perl_get_cv("DB::postponed", FALSE); if (cv) { dSP; @@ -2461,6 +2466,36 @@ PP(pp_leaveeval) } curpm = newpm; /* Don't pop $1 et al till now */ + /* + * Closures mentioned at top level of eval cannot be referenced + * again, and their presence indirectly causes a memory leak. + * (Note that the fact that compcv and friends are still set here + * is, AFAIK, an accident.) --Chip + */ + if (AvFILL(comppad_name) >= 0) { + SV **svp = AvARRAY(comppad_name); + I32 ix; + for (ix = AvFILL(comppad_name); ix >= 0; ix--) { + SV *sv = svp[ix]; + if (sv && sv != &sv_undef && *SvPVX(sv) == '&') { + SvREFCNT_dec(sv); + svp[ix] = &sv_undef; + + sv = curpad[ix]; + if (CvCLONE(sv)) { + SvREFCNT_dec(CvOUTSIDE(sv)); + CvOUTSIDE(sv) = Nullcv; + } + else { + SvREFCNT_dec(sv); + sv = NEWSV(0,0); + SvPADTMP_on(sv); + curpad[ix] = sv; + } + } + } + } + #ifdef DEBUGGING assert(CvDEPTH(compcv) == 1); #endif |