Skip to content

Commit

Permalink
Store PL_prevailing_version in the frozen hinthash around a string-ev…
Browse files Browse the repository at this point in the history
…al op

We need to save the value of PL_prevailing_version at the time the eval
op was compiled, so it can be put in place during the running code.

Ideally we'd do something more robust, like change the OP_ENTERVAL op
class into UNOP_AUX, so that the aux vector can store additional
information like the version number and perhaps the frozen hints hash.

In practice it is far too close to the 5.40 release to contemplate such
a change now, so this is a less intrusive but hackier change to achieve
the same aim.

See also
  #22121
  • Loading branch information
leonerd committed Apr 26, 2024
1 parent 7a2df06 commit db010e6
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 0 deletions.
3 changes: 3 additions & 0 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -12416,6 +12416,8 @@ Perl_ck_eval(pTHX_ OP *o)
PERL_ARGS_ASSERT_CK_EVAL;

PL_hints |= HINT_BLOCK_SCOPE;
if(PL_prevailing_version != 0)
PL_hints |= HINT_LOCALIZE_HH;
if (o->op_flags & OPf_KIDS) {
SVOP * const kid = cSVOPx(cUNOPo->op_first);
assert(kid);
Expand Down Expand Up @@ -12457,6 +12459,7 @@ Perl_ck_eval(pTHX_ OP *o)
&& !(o->op_private & OPpEVAL_COPHH) && GvHV(PL_hintgv)) {
/* Store a copy of %^H that pp_entereval can pick up. */
HV *hh = hv_copy_hints_hv(GvHV(PL_hintgv));
hv_stores(hh, "CORE/prevailing_version", newSVuv(PL_prevailing_version));
OP *hhop;
hhop = newSVOP(OP_HINTSEVAL, 0, MUTABLE_SV(hh));
/* append hhop to only child */
Expand Down
6 changes: 6 additions & 0 deletions pp_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4062,6 +4062,7 @@ S_doeval_compile(pTHX_ U8 gimme, CV* outside, U32 seq, HV *hh)
else {
PL_hints = saveop->op_private & OPpEVAL_COPHH
? oldcurcop->cop_hints : (U32)saveop->op_targ;
PL_prevailing_version = 0; /* we might change this below */

/* making 'use re eval' not be in scope when compiling the
* qr/mabye_has_runtime_code_block/ ensures that we don't get
Expand All @@ -4076,6 +4077,11 @@ S_doeval_compile(pTHX_ U8 gimme, CV* outside, U32 seq, HV *hh)
SvREFCNT_dec(GvHV(PL_hintgv));
GvHV(PL_hintgv) = hh;
FETCHFEATUREBITSHH(hh);
SV *versv, **svp;
if((svp = hv_fetchs(hh, "CORE/prevailing_version", 0)) && (versv = *svp) && SvOK(versv)) {
SAVEI16(PL_prevailing_version);
PL_prevailing_version = SvUV(versv);
}
}
}
SAVECOMPILEWARNINGS();
Expand Down
2 changes: 2 additions & 0 deletions t/lib/test_22121.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eval "use v5.14;";
1;
6 changes: 6 additions & 0 deletions t/lib/warnings/op
Original file line number Diff line number Diff line change
Expand Up @@ -2180,3 +2180,9 @@ use v5.12;
use v5.12;
# expect no warning because same version
EXPECT
########
# GH #22121
use v5.20;
use test_22121;
# expect no warning because different scope
EXPECT

0 comments on commit db010e6

Please sign in to comment.