summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-13 09:40:49 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:23 +0100
commit7b394f128b8d5e84ca0e485c98c8f135baf53b4f (patch)
tree6ec042ce94e3b7cd546fe53ea53394cf5fd010d0 /pp.c
parenta247dbb235b6ada82425a663c4ebd4f426e4947f (diff)
downloadperl-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.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/pp.c b/pp.c
index 24326b8d63..20fd474b2e 100644
--- a/pp.c
+++ b/pp.c
@@ -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);