/**
* Short circuit binary operations.
*/
@Override
public void endVisit(JBinaryOperation x, Context ctx) {
JBinaryOperator op = x.getOp();
JExpression lhs = x.getLhs();
JExpression rhs = x.getRhs();
if ((lhs instanceof JValueLiteral) && (rhs instanceof JValueLiteral)) {
if (evalOpOnLiterals(op, (JValueLiteral) lhs, (JValueLiteral) rhs, ctx)) {
return;
}
}
switch (op) {
case AND:
shortCircuitAnd(lhs, rhs, ctx);
break;
case OR:
shortCircuitOr(lhs, rhs, ctx);
break;
case BIT_XOR:
simplifyXor(lhs, rhs, ctx);
break;
case EQ:
// simplify: null == null -> true
if (lhs.getType() == program.getTypeNull()
&& rhs.getType() == program.getTypeNull() && !x.hasSideEffects()) {
ctx.replaceMe(program.getLiteralBoolean(true));
return;
}
simplifyEq(lhs, rhs, ctx, false);
break;
case NEQ:
// simplify: null != null -> false
if (lhs.getType() == program.getTypeNull()
&& rhs.getType() == program.getTypeNull() && !x.hasSideEffects()) {
ctx.replaceMe(program.getLiteralBoolean(false));
return;
}
simplifyEq(lhs, rhs, ctx, true);
break;
case ADD:
simplifyAdd(lhs, rhs, ctx, x.getType());
break;
case CONCAT:
evalConcat(lhs, rhs, ctx);
break;
case SUB:
simplifySub(lhs, rhs, ctx, x.getType());
break;
case MUL:
simplifyMul(lhs, rhs, ctx, x.getType());
break;
case DIV:
simplifyDiv(lhs, rhs, ctx, x.getType());
break;
case SHL:
case SHR:
case SHRU:
if (isLiteralZero(rhs)) {
ctx.replaceMe(lhs);
}
break;
default:
if (op.isAssignment()) {
lvalues.remove(lhs);
}
break;
}
}