private void jitInstanceof(SingleCondition singleCondition) { Class<?> value = (Class<?>) ((FixedExpression) singleCondition.getRight()).getValue(); String internalClassName = internalName(value); Expression left = singleCondition.getLeft(); Class<?> leftType = isDeclarationExpression(left) ? convertFromPrimitiveType(left.getType()) : left.getType(); jitExpression(left, leftType); mv.visitTypeInsn(INSTANCEOF, internalClassName); }
private void jitSingleCondition(SingleCondition singleCondition) { if (singleCondition.isBinary()) { switch (singleCondition.getOperation()) { case MATCHES: jitMatches(singleCondition); break; case INSTANCEOF: jitInstanceof(singleCondition); break; default: jitBinary(singleCondition); } } else { jitUnary(singleCondition); } }
private void jitBinary(SingleCondition singleCondition) { Expression left = singleCondition.getLeft(); Expression right = singleCondition.getRight(); Class<?> commonType = singleCondition.getOperation().needsSameType() ? findCommonClass( left.getType(), !left.canBeNull(), right.getType(), !right.canBeNull()) : null; if (commonType == Object.class && singleCondition.getOperation().isComparison()) { commonType = Comparable.class; } if (commonType != null && commonType.isPrimitive()) { jitPrimitiveBinary(singleCondition, left, right, commonType); } else { jitObjectBinary(singleCondition, left, right, commonType); } }
private void jitPrimitiveBinary( SingleCondition singleCondition, Expression left, Expression right, Class<?> type) { if (isFixed(right) && right.canBeNull()) { // a primitive cannot be null mv.visitInsn(singleCondition.getOperation() == BooleanOperator.NE ? ICONST_1 : ICONST_0); return; } Label nullArg = new Label(); ensureNotNullArgs(left, right, nullArg); jitExpression(left, type); castExpressionResultToPrimitive(left, type); jitExpression(right, type); castExpressionResultToPrimitive(right, type); jitPrimitiveOperation(singleCondition.getOperation(), type); Label nonNullArg = new Label(); mv.visitJumpInsn(GOTO, nonNullArg); mv.visitLabel(nullArg); mv.visitInsn(ICONST_0); mv.visitLabel(nonNullArg); }
private void jitMatches(SingleCondition singleCondition) { if (!(singleCondition.getRight() instanceof FixedExpression)) { jitBinary(singleCondition); return; } final String matchingString = ((FixedExpression) singleCondition.getRight()).getValue().toString(); final String patternVariableName = getUniqueName("pattern"); getClassGenerator() .addStaticField(ACC_PRIVATE | ACC_FINAL, patternVariableName, Pattern.class, null); getClassGenerator() .addStaticInitBlock( new ClassGenerator.MethodBody() { @Override public void body(MethodVisitor mv) { mv.visitLdcInsn(matchingString); invokeStatic(Pattern.class, "compile", Pattern.class, String.class); putStaticField(patternVariableName, Pattern.class); } }); jitExpression(singleCondition.getLeft(), String.class); store(LEFT_OPERAND, singleCondition.getLeft().getType()); Label notNullLabel = jitLeftIsNull( singleCondition.getLeft().getType() == String.class ? jitNullSafeOperationStart() : jitNullSafeCoercion(singleCondition.getLeft().getType(), String.class)); mv.visitInsn(ICONST_0); Label nullEvaluation = new Label(); mv.visitJumpInsn(GOTO, nullEvaluation); mv.visitLabel(notNullLabel); getStaticField(patternVariableName, Pattern.class); load(LEFT_OPERAND); invokeVirtual(Pattern.class, "matcher", Matcher.class, CharSequence.class); invokeVirtual(Matcher.class, "matches", boolean.class); mv.visitLabel(nullEvaluation); }
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); }
private void jitUnary(SingleCondition singleCondition) { jitExpression(singleCondition.getLeft()); }