Skip to content

Commit

Permalink
no force boolean context for some defined-or ops
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Nov 20, 2024
1 parent c88e713 commit 402db74
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 20 deletions.
38 changes: 23 additions & 15 deletions Cover.xs
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,9 @@ static void set_conditional(pTHX_ OP *op, int cond, int value) {

static void add_conditional(pTHX_ OP *op, int cond) {
SV **count = av_fetch(get_conditional_array(aTHX_ op), cond, 1);
int c = SvTRUE(*count) ? SvIV(*count) + 1 : 1;
int true_ish = (op->op_type == OP_DOR || op->op_type == OP_DORASSIGN)
? SvOK(*count) : SvTRUE(*count);
int c = true_ish ? SvIV(*count) + 1 : 1;
sv_setiv(*count, c);
NDEB(D(L, "Adding %d conditional making %d at %p\n", cond, c, op));
}
Expand Down Expand Up @@ -586,14 +588,16 @@ static void add_condition(pTHX_ SV *cond_ref, int value) {
for (; i <= av_len(conds); i++) {
OP *op = INT2PTR(OP *, SvIV(*av_fetch(conds, i, 0)));
SV **count = av_fetch(get_conditional_array(aTHX_ op), 0, 1);
int type = SvTRUE(*count) ? SvIV(*count) : 0;
int true_ish = (op->op_type == OP_DOR || op->op_type == OP_DORASSIGN)
? SvOK(*count) : SvTRUE(*count);
int type = true_ish ? SvIV(*count) : 0;
sv_setiv(*count, 0);

/* Check if we have come from an xor with a true first op */
if (final) value = 1;
if (type == 1) value += 2;

NDEB(D(L, "Found %p: %d, %d\n", op, type, value));
NDEB(D(L, "Found %p (trueish=%d): %d, %d\n", op, true_ish, type, value));
add_conditional(aTHX_ op, value);
}

Expand Down Expand Up @@ -706,11 +710,15 @@ static OP *get_condition(pTHX) {

if (pc && SvROK(*pc)) {
dSP;
int true_ish;
NDEB(D(L, "get_condition from %p, %p: %p (%s)\n",
PL_op, (void *)PL_op->op_targ, pc, hex_key(get_key(PL_op))));
/* dump_conditions(aTHX); */
NDEB(svdump(Pending_conditionals));
add_condition(aTHX_ *pc, SvTRUE(TOPs) ? 2 : 1);
true_ish = (PL_op->op_type == OP_DOR || PL_op->op_type == OP_DORASSIGN)
? SvOK(TOPs) : SvTRUE(TOPs);
NDEB(D(L, " get_condition true_ish=%d\n", true_ish));
add_condition(aTHX_ *pc, true_ish ? 2 : 1);
} else {
PDEB(D(L, "All is lost, I know not where to go from %p, %p: %p (%s)\n",
PL_op, (void *)PL_op->op_targ, pc, hex_key(get_key(PL_op))));
Expand Down Expand Up @@ -802,26 +810,26 @@ static void cover_logop(pTHX) {
} else {
dSP;

int left_val = SvTRUE(TOPs);
int left_val_def = SvOK(TOPs);
int leftval_true_ish = (PL_op->op_type == OP_DOR || PL_op->op_type == OP_DORASSIGN)
? SvOK(TOPs) : SvTRUE(TOPs);
/* We don't count X= as void context because we care about the value
* of the RHS */
int void_context = GIMME_V == G_VOID &&
PL_op->op_type != OP_DORASSIGN &&
PL_op->op_type != OP_ANDASSIGN &&
PL_op->op_type != OP_ORASSIGN;
NDEB(D(L, "left_val: %d, void_context: %d at %p\n",
left_val, void_context, PL_op));
NDEB(D(L, "leftval_true_ish: %d, void_context: %d at %p\n",
leftval_true_ish, void_context, PL_op));
NDEB(op_dump(PL_op));

set_conditional(aTHX_ PL_op, 5, void_context);

if ((PL_op->op_type == OP_AND && left_val) ||
(PL_op->op_type == OP_ANDASSIGN && left_val) ||
(PL_op->op_type == OP_OR && !left_val) ||
(PL_op->op_type == OP_ORASSIGN && !left_val) ||
(PL_op->op_type == OP_DOR && !left_val_def) ||
(PL_op->op_type == OP_DORASSIGN && !left_val_def) ||
if ((PL_op->op_type == OP_AND && leftval_true_ish) ||
(PL_op->op_type == OP_ANDASSIGN && leftval_true_ish) ||
(PL_op->op_type == OP_OR && !leftval_true_ish) ||
(PL_op->op_type == OP_ORASSIGN && !leftval_true_ish) ||
(PL_op->op_type == OP_DOR && !leftval_true_ish) ||
(PL_op->op_type == OP_DORASSIGN && !leftval_true_ish) ||
(PL_op->op_type == OP_XOR)) {
/* no short circuit */

Expand Down Expand Up @@ -852,7 +860,7 @@ static void cover_logop(pTHX) {
*cond;
OP *next;

if (PL_op->op_type == OP_XOR && left_val) {
if (PL_op->op_type == OP_XOR && leftval_true_ish) {
/*
* This is an xor. It does not short circuit. We
* have just executed the first op. When we get to
Expand Down
21 changes: 17 additions & 4 deletions test_output/cover/overload_bool.5.012000
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Reading database from ...
------------------- ------ ------ ------ ------ ------
File stmt bran cond sub total
------------------- ------ ------ ------ ------ ------
tests/overload_bool 55.5 50.0 n/a 25.0 46.6
Total 55.5 50.0 n/a 25.0 46.6
tests/overload_bool 63.6 50.0 50.0 25.0 52.6
Total 63.6 50.0 50.0 25.0 52.6
------------------- ------ ------ ------ ------ ------


Expand All @@ -30,7 +30,7 @@ line err stmt bran cond sub code
10 package Foo;
11 use overload
12 *** *0 *0 '""' => sub { shift->render},
13 1 1 bool => sub { die; 1 };
13 1 1 bool => sub { die "I was used as a bool and shouldn't be\n"; 1 };
*** 1 *0
1
*** *0
Expand All @@ -43,7 +43,10 @@ line err stmt bran cond sub code
19 1 my $foo = 1;
20 *** 1 * 50 bless {}, 'Foo' if $foo;
21
22 1;
22 1 my $boolobj = bless {}, 'Foo';
23 *** 1 * 50 $boolobj //= 5;
24
25 1;


Branches
Expand All @@ -54,6 +57,16 @@ line err % true false branch
20 *** 50 1 0 if $foo


Conditions
----------

or 2 conditions

line err % l !l expr
----- --- ------ ------ ------ ----
23 *** 50 1 0 $boolobj //= 5


Covered Subroutines
-------------------

Expand Down
5 changes: 4 additions & 1 deletion tests/overload_bool
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
package Foo;
use overload
'""' => sub { shift->render},
bool => sub { die; 1 };
bool => sub { die "I was used as a bool and shouldn't be\n"; 1 };

sub render {
"foo";
Expand All @@ -19,4 +19,7 @@ sub render {
my $foo = 1;
bless {}, 'Foo' if $foo;

my $boolobj = bless {}, 'Foo';
$boolobj //= 5;

1;

0 comments on commit 402db74

Please sign in to comment.