From f4530bff2235e8d1f2ed9bcbfa4d3843edc6d3aa Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Tue, 1 Oct 2024 09:22:09 +1000 Subject: [PATCH] =?UTF-8?q?Revert=20"Revert=20"[perl=20#89544]=20Non-eval?= =?UTF-8?q?=20closures=20don=E2=80=99t=20need=20CvOUTSIDE""?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 386907f061c1812ecaa5f3c88d9f729828408097. Reinstates the behaviour of CV outside references from 5.38, fixing #22547 Breaks #19370 --- cv.h | 6 +++++- dump.c | 1 + ext/Devel-Peek/t/Peek.t | 8 ++++---- lib/B/Deparse.t | 1 + pad.c | 4 +++- t/op/closure.t | 3 +-- t/op/eval.t | 1 + 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/cv.h b/cv.h index 5a5c90ffab4bf..6b8f6486c7dda 100644 --- a/cv.h +++ b/cv.h @@ -147,7 +147,7 @@ See L. #endif #define CVf_DYNFILE 0x1000 /* The filename is malloced */ #define CVf_AUTOLOAD 0x2000 /* SvPVX contains AUTOLOADed sub name */ -/* 0x4000 previously CVf_HASEVAL */ +#define CVf_HASEVAL 0x4000 /* contains string eval */ #define CVf_NAMED 0x8000 /* Has a name HEK */ #define CVf_LEXICAL 0x10000 /* Omit package from name */ #define CVf_ANONCONST 0x20000 /* :const - create anonconst op */ @@ -232,6 +232,10 @@ See L. #define CvAUTOLOAD_on(cv) (CvFLAGS(cv) |= CVf_AUTOLOAD) #define CvAUTOLOAD_off(cv) (CvFLAGS(cv) &= ~CVf_AUTOLOAD) +#define CvHASEVAL(cv) (CvFLAGS(cv) & CVf_HASEVAL) +#define CvHASEVAL_on(cv) (CvFLAGS(cv) |= CVf_HASEVAL) +#define CvHASEVAL_off(cv) (CvFLAGS(cv) &= ~CVf_HASEVAL) + #define CvNAMED(cv) (CvFLAGS(cv) & CVf_NAMED) #define CvNAMED_on(cv) (CvFLAGS(cv) |= CVf_NAMED) #define CvNAMED_off(cv) (CvFLAGS(cv) &= ~CVf_NAMED) diff --git a/dump.c b/dump.c index cdbbb0e2819d1..5eea86c37630c 100644 --- a/dump.c +++ b/dump.c @@ -1899,6 +1899,7 @@ const struct flag_to_name cv_flags_names[] = { {CVf_CVGV_RC, "CVGV_RC,"}, {CVf_DYNFILE, "DYNFILE,"}, {CVf_AUTOLOAD, "AUTOLOAD,"}, + {CVf_HASEVAL, "HASEVAL,"}, {CVf_SLABBED, "SLABBED,"}, {CVf_NAMED, "NAMED,"}, {CVf_LEXICAL, "LEXICAL,"}, diff --git a/ext/Devel-Peek/t/Peek.t b/ext/Devel-Peek/t/Peek.t index d6f1f21e68a55..80dd0b151f7b8 100644 --- a/ext/Devel-Peek/t/Peek.t +++ b/ext/Devel-Peek/t/Peek.t @@ -364,8 +364,8 @@ do_test('reference to named subroutine without prototype', RV = $ADDR SV = PVCV\\($ADDR\\) at $ADDR REFCNT = (3|4) - FLAGS = \\((?:HASEVAL,)?(?:NAMED)?\\) # $] < 5.015 || !thr - FLAGS = \\(DYNFILE(?:,HASEVAL)?(?:,NAMED)?\\) # $] >= 5.015 && thr + FLAGS = \\((?:HASEVAL(?:,NAMED)?)?\\) # $] < 5.015 || !thr + FLAGS = \\(DYNFILE(?:,HASEVAL(?:,NAMED)?)?\\) # $] >= 5.015 && thr COMP_STASH = $ADDR\\t"main" START = $ADDR ===> \\d+ ROOT = $ADDR @@ -375,8 +375,8 @@ do_test('reference to named subroutine without prototype', DEPTH = 1(?: MUTEXP = $ADDR OWNER = $ADDR)? - FLAGS = 0x(?:[c84]00)?0 # $] < 5.015 || !thr - FLAGS = 0x[cd1459]000 # $] >= 5.015 && thr + FLAGS = 0x(?:[c4]00)?0 # $] < 5.015 || !thr + FLAGS = 0x[cd145]000 # $] >= 5.015 && thr OUTSIDE_SEQ = \\d+ PADLIST = $ADDR PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\) diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t index d5e5ae9e0a3c8..291d03e70b4be 100644 --- a/lib/B/Deparse.t +++ b/lib/B/Deparse.t @@ -2150,6 +2150,7 @@ my sub g { sub f { } } #### +# TODO only partially fixed # lexical state subroutine with outer declaration and inner definition # CONTEXT use feature 'lexical_subs', 'state'; no warnings 'experimental::lexical_subs'; (); diff --git a/pad.c b/pad.c index 9b943b1158e49..765c702456d7f 100644 --- a/pad.c +++ b/pad.c @@ -1684,6 +1684,7 @@ Perl_pad_tidy(pTHX_ padtidy_type type) "Pad clone on cv=0x%" UVxf "\n", PTR2UV(cv))); CvCLONE_on(cv); } + CvHASEVAL_on(cv); } } @@ -1975,7 +1976,8 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned, PL_compcv = cv; if (newcv) SAVEFREESV(cv); /* in case of fatal warnings */ - CvOUTSIDE(cv) = CvREFCNT_inc_simple(outside); + if (CvHASEVAL(cv)) + CvOUTSIDE(cv) = CvREFCNT_inc_simple(outside); SAVESPTR(PL_comppad_name); PL_comppad_name = protopad_name; diff --git a/t/op/closure.t b/t/op/closure.t index be7da997b7c07..c92e6456d98ba 100644 --- a/t/op/closure.t +++ b/t/op/closure.t @@ -687,7 +687,7 @@ $r = \$x isnt($s[0], $s[1], "cloneable with //ee"); } -# [perl #89544] aka [GH #11286] +# [perl #89544] { sub trace::DESTROY { push @trace::trace, "destroyed"; @@ -711,7 +711,6 @@ $r = \$x }; my $inner = $outer2->(); - local $TODO = "we need outside links for debugger behaviour"; is "@trace::trace", "destroyed", 'closures only close over named variables, not entire subs'; } diff --git a/t/op/eval.t b/t/op/eval.t index 079aef2ed2179..78fc646098238 100644 --- a/t/op/eval.t +++ b/t/op/eval.t @@ -379,6 +379,7 @@ our $x = 1; is(db6(), 4); # [GH #19370] + local $TODO = "outside not available when needed"; my sub d6 { DB::db3(); }