summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index df28463295..5489d9c8d0 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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