summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-01-04 23:50:14 +0000
committerDavid Mitchell <davem@iabyn.com>2017-01-06 16:28:27 +0000
commit9d692a7f83cf8fe36c59aaa07bca533887350e9b (patch)
treeb1aef56bc9c2aaa3447cafca50bf5cae4f7bee3e /op.c
parent2ee1faad3521a3f4af605ff9c9242b912259f946 (diff)
downloadperl-9d692a7f83cf8fe36c59aaa07bca533887350e9b.tar.gz
add xor, grep, flip, flop to boolean cxt detection
The code that detects whether certain ops (currently just PADHV and RV2HV) are called in boolean context only recognises a few ops as providing boolean context: NOT, OR, DOR, AND, COND_EXPR. This commit expands this by adding GREPWHILE, FLIP, FLOP, XOR too (in the case of XOR it only applies to the RHS arg - the LHS is not simple to detect). This means that in something like @AofH_nonempty = grep %$_, @AofH the test for each hash being non-empty will now be done in boolean rather than full scalar context, so may be faster. Similarly (although less excitingly) these hash key counts are also boolean now: %hash .. $other; $other .. %hash; $other xor %hash; (I basically did a grep for 'SvTRUE' in pp*.c to see what other ops might be imposing boolean context.) Since this has been added to the general boolean context detection mechanism, it will also apply for any future ops with are 'booleanised'.
Diffstat (limited to 'op.c')
-rw-r--r--op.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/op.c b/op.c
index 5966d538d5..1636993628 100644
--- a/op.c
+++ b/op.c
@@ -13406,9 +13406,22 @@ S_check_for_bool_cxt(pTHX_ OP*o, U8 bool_flag, U8 maybe_flag)
case OP_SCALAR:
break;
- /* these two never leave the original value on the stack */
+ /* these two consume the stack argument in the scalar case,
+ * and treat it as a boolean in the non linenumber case */
+ case OP_FLIP:
+ case OP_FLOP:
+ if ( ((lop->op_flags & OPf_WANT) == OPf_WANT_LIST)
+ || (lop->op_private & OPpFLIP_LINENUM))
+ {
+ lop = NULL;
+ break;
+ }
+ /* FALLTHROUGH */
+ /* these never leave the original value on the stack */
case OP_NOT:
+ case OP_XOR:
case OP_COND_EXPR:
+ case OP_GREPWHILE:
/* AND may leave its original arg on the stack, but only if it's
* false. As long as o returns a value which is both false
* and usable in scalar context, it's safe.
@@ -13438,6 +13451,7 @@ S_check_for_bool_cxt(pTHX_ OP*o, U8 bool_flag, U8 maybe_flag)
default:
lop = NULL;
+ break;
}
if (lop)