diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-03 17:07:28 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-27 11:30:21 +0100 |
commit | 5a6c28370397ad3d5c138df5778833dc4b11c3be (patch) | |
tree | 220b9b186bb82e9ed21290c3f93130b906e3ba27 | |
parent | 0283ad960acb937e9387b3323f1f7852c2adb0fa (diff) | |
download | perl-5a6c28370397ad3d5c138df5778833dc4b11c3be.tar.gz |
add PL_sv_zero
it's like PL_sv_no, except that its string value is "0" rather than "".
It can be used for example where pp function wants to push a zero return
value on the stack. The next commit will start to use it.
Also update the SvIMMORTAL() to be more efficient: it now checks whether
the SV's address is in a range rather than individually checking against
&PL_sv_undef, &PL_sv_no etc.
-rw-r--r-- | dump.c | 15 | ||||
-rw-r--r-- | embedvar.h | 1 | ||||
-rw-r--r-- | globvar.sym | 1 | ||||
-rw-r--r-- | intrpvar.h | 8 | ||||
-rw-r--r-- | perl.c | 5 | ||||
-rw-r--r-- | perl.h | 2 | ||||
-rw-r--r-- | sv.c | 13 | ||||
-rw-r--r-- | sv.h | 2 |
8 files changed, 45 insertions, 2 deletions
@@ -369,7 +369,9 @@ Perl_sv_peek(pTHX_ SV *sv) sv_catpv(t, "WILD"); goto finish; } - else if (sv == &PL_sv_undef || sv == &PL_sv_no || sv == &PL_sv_yes || sv == &PL_sv_placeholder) { + else if ( sv == &PL_sv_undef || sv == &PL_sv_no || sv == &PL_sv_yes + || sv == &PL_sv_zero || sv == &PL_sv_placeholder) + { if (sv == &PL_sv_undef) { sv_catpv(t, "SV_UNDEF"); if (!(SvFLAGS(sv) & (SVf_OK|SVf_OOK|SVs_OBJECT| @@ -398,6 +400,17 @@ Perl_sv_peek(pTHX_ SV *sv) SvNVX(sv) == 1.0) goto finish; } + else if (sv == &PL_sv_zero) { + sv_catpv(t, "SV_ZERO"); + if (!(SvFLAGS(sv) & (SVf_ROK|SVf_OOK|SVs_OBJECT| + SVs_GMG|SVs_SMG|SVs_RMG)) && + !(~SvFLAGS(sv) & (SVf_POK|SVf_NOK|SVf_READONLY| + SVp_POK|SVp_NOK)) && + SvCUR(sv) == 1 && + SvPVX_const(sv) && *SvPVX_const(sv) == '0' && + SvNVX(sv) == 0.0) + goto finish; + } else { sv_catpv(t, "SV_PLACEHOLDER"); if (!(SvFLAGS(sv) & (SVf_OK|SVf_OOK|SVs_OBJECT| diff --git a/embedvar.h b/embedvar.h index 1e3f9a2ed9..4b945f26ab 100644 --- a/embedvar.h +++ b/embedvar.h @@ -322,6 +322,7 @@ #define PL_sv_serial (vTHX->Isv_serial) #define PL_sv_undef (vTHX->Isv_undef) #define PL_sv_yes (vTHX->Isv_yes) +#define PL_sv_zero (vTHX->Isv_zero) #define PL_sys_intern (vTHX->Isys_intern) #define PL_taint_warn (vTHX->Itaint_warn) #define PL_tainted (vTHX->Itainted) diff --git a/globvar.sym b/globvar.sym index c82dc8f1c8..a91d520306 100644 --- a/globvar.sym +++ b/globvar.sym @@ -3,6 +3,7 @@ # *** Usual globals initialized at runtime should be added in *var*.h. PL_No +PL_Zero PL_Yes PL_bincompat_options PL_bitcount diff --git a/intrpvar.h b/intrpvar.h index c6070eab43..e1c96f71e5 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -158,12 +158,20 @@ C<&PL_sv_no>. This is the C<true> SV. See C<L</PL_sv_no>>. Always refer to this as C<&PL_sv_yes>. +=for apidoc Amn|SV|PL_sv_zero +This readonly SV has a zero numeric value and a C<"0"> string value. It's +similar to C<L</PL_sv_no>> except for its string value. Can be used as a +cheap alternative to C<mXPUSHi(0)> for example. Always refer to this as +C<&PL_sv_zero>. Introduced in 5.28. + =cut */ PERLVAR(I, sv_undef, SV) PERLVAR(I, sv_no, SV) PERLVAR(I, sv_yes, SV) +PERLVAR(I, sv_zero, SV) + PERLVAR(I, padname_undef, PADNAME) PERLVAR(I, padname_const, PADNAME) PERLVAR(I, Sv, SV *) /* used to hold temporary values */ @@ -1287,6 +1287,11 @@ perl_destruct(pTHXx) SvANY(&PL_sv_no) = NULL; SvFLAGS(&PL_sv_no) = 0; + SvREFCNT(&PL_sv_zero) = 0; + sv_clear(&PL_sv_zero); + SvANY(&PL_sv_zero) = NULL; + SvFLAGS(&PL_sv_zero) = 0; + { int i; for (i=0; i<=2; i++) { @@ -4766,6 +4766,8 @@ EXTCONST char PL_Yes[] INIT("1"); EXTCONST char PL_No[] INIT(""); +EXTCONST char PL_Zero[] + INIT("0"); EXTCONST char PL_hexdigit[] INIT("0123456789abcdef0123456789ABCDEF"); @@ -15407,6 +15407,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, init_constants(); ptr_table_store(PL_ptr_table, &proto_perl->Isv_undef, &PL_sv_undef); ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no); + ptr_table_store(PL_ptr_table, &proto_perl->Isv_zero, &PL_sv_zero); ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes); ptr_table_store(PL_ptr_table, &proto_perl->Ipadname_const, &PL_padname_const); @@ -15914,6 +15915,12 @@ Perl_init_constants(pTHX) |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK |SVp_POK|SVf_POK; + SvANY(&PL_sv_zero) = new_XPVNV(); + SvREFCNT(&PL_sv_zero) = SvREFCNT_IMMORTAL; + SvFLAGS(&PL_sv_zero) = SVt_PVNV|SVf_READONLY|SVf_PROTECT + |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK + |SVp_POK|SVf_POK; + SvPV_set(&PL_sv_no, (char*)PL_No); SvCUR_set(&PL_sv_no, 0); SvLEN_set(&PL_sv_no, 0); @@ -15926,6 +15933,12 @@ Perl_init_constants(pTHX) SvIV_set(&PL_sv_yes, 1); SvNV_set(&PL_sv_yes, 1); + SvPV_set(&PL_sv_zero, (char*)PL_Zero); + SvCUR_set(&PL_sv_zero, 1); + SvLEN_set(&PL_sv_zero, 0); + SvIV_set(&PL_sv_zero, 0); + SvNV_set(&PL_sv_zero, 0); + PadnamePV(&PL_padname_const) = (char *)PL_No; } @@ -2087,7 +2087,7 @@ properly null terminated. Equivalent to sv_setpvs(""), but more efficient. #define SvPEEK(sv) "" #endif -#define SvIMMORTAL(sv) (SvREADONLY(sv) && ((sv)==&PL_sv_undef || (sv)==&PL_sv_yes || (sv)==&PL_sv_no || (sv)==&PL_sv_placeholder)) +#define SvIMMORTAL(sv) (SvREADONLY(sv) && ((sv)==&PL_sv_undef || (sv)==&PL_sv_yes || (sv)==&PL_sv_no || (sv)==&PL_sv_zero || (sv)==&PL_sv_placeholder)) #ifdef DEBUGGING /* exercise the immortal resurrection code in sv_free2() */ |