Add a PL_prevailing_version interpreter var

Save/restore PL_prevailing_version at SAVEHINTS time

Have PL_prevailing_version track the applied use VERSION currently in scope
This commit is contained in:
Paul "LeoNerd" Evans 2022-02-05 02:05:56 +00:00 committed by Paul Evans
parent 573a2c7380
commit 78efaf0398
5 changed files with 41 additions and 2 deletions

1
embedvar.h generated
View File

@ -233,6 +233,7 @@
#define PL_phase (vTHX->Iphase)
#define PL_pidstatus (vTHX->Ipidstatus)
#define PL_preambleav (vTHX->Ipreambleav)
#define PL_prevailing_version (vTHX->Iprevailing_version)
#define PL_profiledata (vTHX->Iprofiledata)
#define PL_psig_name (vTHX->Ipsig_name)
#define PL_psig_pend (vTHX->Ipsig_pend)

View File

@ -1029,6 +1029,12 @@ PERLVAR(I, wcrtomb_ps, mbstate_t)
PERLVARA(I, mem_log, 1 + 1 + TYPE_DIGITS(UV) + 1 + 3 + 1, char)
#endif
/* The most recently seen `use VERSION` declaration, encoded in a single
* U16 as (major << 8) | minor. We do this rather than store an entire SV
* version object so we can fit the U16 into the uv of a SAVEHINTS and not
* have to worry about SV refcounts during scope enter/exit. */
PERLVAR(I, prevailing_version, U16)
/* If you are adding a U8 or U16, check to see if there are 'Space' comments
* above on where there are gaps which currently will be structure padding. */

30
op.c
View File

@ -8842,6 +8842,32 @@ Perl_package_version( pTHX_ OP *v )
op_free(v);
}
/* grrrr */
static U16 S_extract_shortver(pTHX_ SV *sv)
{
SV *rv;
if(!SvRV(sv) || !SvOBJECT(rv = SvRV(sv)) || !sv_derived_from(sv, "version"))
return 0;
AV *av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(rv), "version", 0)));
U16 shortver = 0;
IV major = av_count(av) > 0 ? SvIV(*av_fetch(av, 0, false)) : 0;
if(major > 255)
shortver |= 255 << 8;
else
shortver |= major << 8;
IV minor = av_count(av) > 1 ? SvIV(*av_fetch(av, 1, false)) : 0;
if(minor > 255)
shortver |= 255;
else
shortver |= minor;
return shortver;
}
void
Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
{
@ -8926,6 +8952,8 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
use_version = sv_2mortal(new_version(use_version));
S_enable_feature_bundle(aTHX_ use_version);
U16 shortver = S_extract_shortver(aTHX_ use_version);
/* If a version >= 5.11.0 is requested, strictures are on by default! */
if (vcmp(use_version,
sv_2mortal(upg_version(newSVnv(5.011000), FALSE))) >= 0) {
@ -8948,6 +8976,8 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
if (!(PL_hints & HINT_EXPLICIT_STRICT_VARS))
PL_hints &= ~HINT_STRICT_VARS;
}
PL_prevailing_version = shortver;
}
/* The "did you use incorrect case?" warning used to be here.

View File

@ -3539,6 +3539,7 @@ S_doeval_compile(pTHX_ U8 gimme, CV* outside, U32 seq, HV *hh)
SAVEHINTS();
if (clear_hints) {
PL_hints = HINTS_DEFAULT;
PL_prevailing_version = 0;
hv_clear(GvHV(PL_hintgv));
CLEARFEATUREBITS();
}

View File

@ -699,14 +699,14 @@ Perl_save_hints(pTHX)
SS_ADD_INT(PL_hints);
SS_ADD_PTR(save_cophh);
SS_ADD_PTR(oldhh);
SS_ADD_UV(SAVEt_HINTS_HH);
SS_ADD_UV(SAVEt_HINTS_HH | (PL_prevailing_version << 8));
SS_ADD_END(4);
}
GvHV(PL_hintgv) = NULL; /* in case copying dies */
GvHV(PL_hintgv) = hv_copy_hints_hv(oldhh);
SAVEFEATUREBITS();
} else {
save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS);
save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS | (PL_prevailing_version << 8));
}
}
@ -1380,6 +1380,7 @@ Perl_leave_scope(pTHX_ I32 base)
cophh_free(CopHINTHASH_get(&PL_compiling));
CopHINTHASH_set(&PL_compiling, (COPHH*)a1.any_ptr);
*(I32*)&PL_hints = a0.any_i32;
PL_prevailing_version = (U16)(uv >> 8);
if (type == SAVEt_HINTS_HH) {
SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
GvHV(PL_hintgv) = MUTABLE_HV(a2.any_ptr);