summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cop.h2
-rw-r--r--op.c12
-rw-r--r--pp_ctl.c3
-rwxr-xr-xt/op/misc.t12
4 files changed, 26 insertions, 3 deletions
diff --git a/cop.h b/cop.h
index 6c6820b3a1..8d8126bfbc 100644
--- a/cop.h
+++ b/cop.h
@@ -156,6 +156,7 @@ struct block_eval {
SV * old_namesv;
OP * old_eval_root;
SV * cur_text;
+ CV * cv;
};
#define PUSHEVAL(cx,n,fgv) \
@@ -165,6 +166,7 @@ struct block_eval {
cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : Nullsv); \
cx->blk_eval.old_eval_root = PL_eval_root; \
cx->blk_eval.cur_text = PL_linestr; \
+ cx->blk_eval.cv = Nullcv; /* set by doeval(), as applicable */ \
} STMT_END
#define POPEVAL(cx) \
diff --git a/op.c b/op.c
index 34fb48a82d..18745183ef 100644
--- a/op.c
+++ b/op.c
@@ -346,15 +346,22 @@ S_pad_findlex(pTHX_ char *name, PADOFFSET newoff, U32 seq, CV* startcv,
switch (CxTYPE(cx)) {
default:
if (i == 0 && saweval) {
- seq = cxstack[saweval].blk_oldcop->cop_seq;
return pad_findlex(name, newoff, seq, PL_main_cv, -1, saweval, 0);
}
break;
case CXt_EVAL:
switch (cx->blk_eval.old_op_type) {
case OP_ENTEREVAL:
- if (CxREALEVAL(cx))
+ if (CxREALEVAL(cx)) {
+ PADOFFSET off;
saweval = i;
+ seq = cxstack[i].blk_oldcop->cop_seq;
+ startcv = cxstack[i].blk_eval.cv;
+ off = pad_findlex(name, newoff, seq, startcv, i-1,
+ saweval, 0);
+ if (off) /* continue looking if not found here */
+ return off;
+ }
break;
case OP_DOFILE:
case OP_REQUIRE:
@@ -371,7 +378,6 @@ S_pad_findlex(pTHX_ char *name, PADOFFSET newoff, U32 seq, CV* startcv,
saweval = i; /* so we know where we were called from */
continue;
}
- seq = cxstack[saweval].blk_oldcop->cop_seq;
return pad_findlex(name, newoff, seq, cv, i-1, saweval,FINDLEX_NOSEARCH);
}
}
diff --git a/pp_ctl.c b/pp_ctl.c
index a161372794..046c6661f2 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2832,6 +2832,9 @@ S_doeval(pTHX_ int gimme, OP** startop)
PL_compcv = (CV*)NEWSV(1104,0);
sv_upgrade((SV *)PL_compcv, SVt_PVCV);
CvEVAL_on(PL_compcv);
+ assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
+ cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
+
#ifdef USE_THREADS
CvOWNER(PL_compcv) = 0;
New(666, CvMUTEXP(PL_compcv), 1, perl_mutex);
diff --git a/t/op/misc.t b/t/op/misc.t
index 8e67b6144b..881f99dc18 100755
--- a/t/op/misc.t
+++ b/t/op/misc.t
@@ -587,6 +587,18 @@ EXPECT
ok 1
ok 2
########
+# lexicals outside an eval"" should be visible inside subroutine definitions
+# within it
+eval <<'EOT'; die $@ if $@;
+{
+ my $X = "ok\n";
+ eval 'sub Y { print $X }'; die $@ if $@;
+ Y();
+}
+EOT
+EXPECT
+ok
+########
# This test is here instead of pragma/locale.t because
# the bug depends on in the internal state of the locale
# settings and pragma/locale messes up that state pretty badly.