private void prepareLeftOperand( BooleanOperator operation, Class<?> type, Class<?> leftType, Class<?> rightType, Label shortcutEvaluation) { if (leftType.isPrimitive()) { if (type != null) { castOrCoercePrimitive(LEFT_OPERAND, leftType, type); } return; } Label notNullLabel = jitLeftIsNull( type == null || leftType == type ? jitNullSafeOperationStart() : jitNullSafeCoercion(leftType, type)); if (operation.isEquality() && !rightType.isPrimitive()) { // if (left == null) return right == null checkNullEquality(); } else { // if (left == null) return false mv.visitInsn(ICONST_0); } mv.visitJumpInsn(GOTO, shortcutEvaluation); mv.visitLabel(notNullLabel); }
private void jitObjectBinary( SingleCondition singleCondition, Expression left, Expression right, Class<?> type) { Class<?> leftType = isDeclarationExpression(left) ? convertFromPrimitiveType(left.getType()) : left.getType(); Class<?> rightType = isDeclarationExpression(right) ? convertFromPrimitiveType(right.getType()) : right.getType(); jitExpression(left, type != null ? type : leftType); if (isDeclarationExpression(left) && left.getType().isPrimitive()) { castFromPrimitive(left.getType()); } store(LEFT_OPERAND, leftType); jitExpression(right, type != null ? type : rightType); if (isDeclarationExpression(right) && right.getType().isPrimitive()) { castFromPrimitive(right.getType()); } store(RIGHT_OPERAND, rightType); Label shortcutEvaluation = new Label(); BooleanOperator operation = singleCondition.getOperation(); prepareLeftOperand(operation, type, leftType, rightType, shortcutEvaluation); prepareRightOperand(right, type, rightType, shortcutEvaluation); load(LEFT_OPERAND); load(RIGHT_OPERAND); switch (operation) { case CONTAINS: invokeStatic( EvaluatorHelper.class, "contains", boolean.class, Object.class, rightType.isPrimitive() ? rightType : Object.class); break; case MATCHES: invokeVirtual(type, "matches", boolean.class, String.class); break; case SOUNDSLIKE: invokeStatic( EvaluatorHelper.class, "soundslike", boolean.class, String.class, String.class); break; default: if (operation.isEquality()) { if (type.isInterface()) { invokeInterface(type, "equals", boolean.class, Object.class); } else { invokeVirtual(type, "equals", boolean.class, Object.class); } if (operation == BooleanOperator.NE) { singleCondition.toggleNegation(); } } else { if (type.isInterface()) { invokeInterface( type, "compareTo", int.class, type == Comparable.class ? Object.class : type); } else { invokeVirtual(type, "compareTo", int.class, type); } mv.visitInsn(ICONST_0); jitPrimitiveOperation(operation, int.class); } } mv.visitLabel(shortcutEvaluation); }