Skip to content

Commit

Permalink
no force boolean context for defined-or ops
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Nov 19, 2024
1 parent 723b601 commit 5c3354f
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 42 deletions.
53 changes: 38 additions & 15 deletions Cover.xs
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,13 @@ 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;
#if PERL_VERSION > 8
bool true_ish = (op->op_type == OP_DOR || op->op_type == OP_DORASSIGN)
? SvOK(*count) : SvTRUE(*count);
#else
bool true_ish = SvTRUE(*count);
#endif
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 @@ -594,14 +600,20 @@ 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;
#if PERL_VERSION > 8
bool true_ish = (op->op_type == OP_DOR || op->op_type == OP_DORASSIGN)
? SvOK(*count) : SvTRUE(*count);
#else
bool true_ish = SvTRUE(*count);
#endif
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?1:0, type, value));
add_conditional(aTHX_ op, value);
}

Expand Down Expand Up @@ -718,7 +730,15 @@ static OP *get_condition(pTHX) {
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);
bool true_ish;
#if PERL_VERSION > 8
true_ish = (PL_op->op_type == OP_DOR || PL_op->op_type == OP_DORASSIGN)
? SvOK(TOPs) : SvTRUE(TOPs);
#else
true_ish = SvTRUE(TOPs);
#endif
NDEB(D(L, " get_condition true_ish=%d\n", true_ish?1:0));
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 @@ -810,9 +830,12 @@ static void cover_logop(pTHX) {
} else {
dSP;

int left_val = SvTRUE(TOPs);
int leftval_true_ish;
#if PERL_VERSION > 8
int left_val_def = SvOK(TOPs);
leftval_true_ish = (PL_op->op_type == OP_DOR || PL_op->op_type == OP_DORASSIGN)
? SvOK(TOPs) : SvTRUE(TOPs);
#else
leftval_true_ish = SvTRUE(TOPs);
#endif
/* We don't count X= as void context because we care about the value
* of the RHS */
Expand All @@ -822,19 +845,19 @@ static void cover_logop(pTHX) {
#endif
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) ||
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) ||
#if PERL_VERSION > 8
(PL_op->op_type == OP_DOR && !left_val_def) ||
(PL_op->op_type == OP_DORASSIGN && !left_val_def) ||
(PL_op->op_type == OP_DOR && !leftval_true_ish) ||
(PL_op->op_type == OP_DORASSIGN && !leftval_true_ish) ||
#endif
(PL_op->op_type == OP_XOR)) {
/* no short circuit */
Expand Down Expand Up @@ -866,7 +889,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
40 changes: 20 additions & 20 deletions test_output/cover/cond_or.5.012000
Original file line number Diff line number Diff line change
Expand Up @@ -249,26 +249,26 @@ or 2 conditions

line err % l !l expr
----- --- ------ ------ ------ ----
16 *** 50 11 0 $$x[18] //= undef
17 *** 50 11 0 $$x[18] //= 0
18 *** 50 11 0 $$x[18] //= 0
19 *** 50 11 0 $$x[18] //= 1
20 *** 50 11 0 $$x[18] //= 1
22 100 10 1 $$x[19] //= 1
23 *** 50 11 0 $$x[19] //= 1
24 *** 50 11 0 $$x[19] //= 0
25 *** 50 11 0 $$x[19] //= undef
26 *** 50 11 0 $$x[19] //= 1
28 *** 50 0 11 $$x[21] // undef
29 *** 50 0 11 $$x[21] // 0
30 *** 50 0 11 $$x[21] // 0
31 *** 50 0 11 $$x[21] // 1
32 *** 50 0 11 $$x[21] // 1
34 100 10 1 $$x[22] // undef
35 100 10 1 $$x[22] // 0
36 *** 50 11 0 $$x[22] // 0
37 *** 50 11 0 $$x[22] // 1
38 *** 50 11 0 $$x[22] // 1
16 *** 50 1 0 $$x[18] //= undef
17 *** 50 1 0 $$x[18] //= 0
18 *** 50 1 0 $$x[18] //= 0
19 *** 50 1 0 $$x[18] //= 1
20 *** 50 1 0 $$x[18] //= 1
22 100 1 1 $$x[19] //= 1
23 *** 50 1 0 $$x[19] //= 1
24 *** 50 1 0 $$x[19] //= 0
25 *** 50 1 0 $$x[19] //= undef
26 *** 50 1 0 $$x[19] //= 1
28 *** 50 0 1 $$x[21] // undef
29 *** 50 0 1 $$x[21] // 0
30 *** 50 0 1 $$x[21] // 0
31 *** 50 0 1 $$x[21] // 1
32 *** 50 0 1 $$x[21] // 1
34 100 1 1 $$x[22] // undef
35 100 1 1 $$x[22] // 0
36 *** 50 1 0 $$x[22] // 0
37 *** 50 1 0 $$x[22] // 1
38 *** 50 1 0 $$x[22] // 1


Covered Subroutines
Expand Down
Loading

0 comments on commit 5c3354f

Please sign in to comment.