diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-13 09:40:49 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-27 11:30:23 +0100 |
commit | 7b394f128b8d5e84ca0e485c98c8f135baf53b4f (patch) | |
tree | 6ec042ce94e3b7cd546fe53ea53394cf5fd010d0 /pp.c | |
parent | a247dbb235b6ada82425a663c4ebd4f426e4947f (diff) | |
download | perl-7b394f128b8d5e84ca0e485c98c8f135baf53b4f.tar.gz |
add boolean context support to several ops
For some ops which return integer values and which have a reasonable
likelihood of being used in a boolean context, set the OPpTRUEBOOL
flag on the op as appropriate, and at runtime return &PL_sv_yes /
&PL_sv_zero rather than an integer value.
This is especially beneficial where the op doesn't have a targ, so has
to create a mortal SV to return the integer value.
Similarly, its a win where it may be expensive to calculate an integer
return value, such as pos() or length() converting between byte and char
offset.
Ops done:
OP_SUBST
OP_AASSIGN
OP_POS
OP_LENGTH
OP_GREPWHILE
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 22 |
1 files changed, 18 insertions, 4 deletions
@@ -466,11 +466,15 @@ PP(pp_pos) else { const MAGIC * const mg = mg_find_mglob(sv); if (mg && mg->mg_len != -1) { - dTARGET; STRLEN i = mg->mg_len; - if (mg->mg_flags & MGf_BYTES && DO_UTF8(sv)) - i = sv_pos_b2u_flags(sv, i, SV_GMAGIC|SV_CONST_RETURN); - SETu(i); + if (PL_op->op_private & OPpTRUEBOOL) + SETs(i ? &PL_sv_yes : &PL_sv_zero); + else { + dTARGET; + if (mg->mg_flags & MGf_BYTES && DO_UTF8(sv)) + i = sv_pos_b2u_flags(sv, i, SV_GMAGIC|SV_CONST_RETURN); + SETu(i); + } return NORMAL; } SETs(&PL_sv_undef); @@ -3258,6 +3262,11 @@ PP(pp_length) if (!IN_BYTES) { /* reread to avoid using an C auto/register */ if ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == SVf_POK) goto simple_pv; + if ( SvPOK(sv) && (PL_op->op_private & OPpTRUEBOOL)) { + /* no need to convert from bytes to chars */ + len = SvCUR(sv); + goto return_bool; + } len = sv_len_utf8_nomg(sv); } else { @@ -3265,6 +3274,11 @@ PP(pp_length) if (SvPOK_nog(sv)) { simple_pv: len = SvCUR(sv); + if (PL_op->op_private & OPpTRUEBOOL) { + return_bool: + SETs(len ? &PL_sv_yes : &PL_sv_zero); + return NORMAL; + } } else { (void)sv_2pv_flags(sv, &len, 0|SV_CONST_RETURN); |