private void jitStringConcat(Expression left, Expression right) { invokeConstructor(StringBuilder.class); jitExpression(left, String.class); invokeVirtual(StringBuilder.class, "append", StringBuilder.class, left.getType()); jitExpression(right, String.class); invokeVirtual(StringBuilder.class, "append", StringBuilder.class, right.getType()); invokeVirtual(StringBuilder.class, "toString", String.class); }
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 ensureNotNullArgs(Expression exp, Label nullArg) { if (exp instanceof FixedExpression) { if (((FixedExpression) exp).canBeNull()) { mv.visitJumpInsn(GOTO, nullArg); } } else if (exp instanceof EvaluatedExpression) { if (!exp.getType().isPrimitive()) { jitEvaluatedExpression((EvaluatedExpression) exp, true, Object.class); mv.visitJumpInsn(IFNULL, nullArg); } } else if (exp instanceof VariableExpression) { if (!exp.getType().isPrimitive()) { jitVariableExpression((VariableExpression) exp); mv.visitJumpInsn(IFNULL, nullArg); } } else if (exp instanceof AritmeticExpression) { ensureNotNullInAritmeticExpression((AritmeticExpression) exp, nullArg); } }
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 Class<?> jitExpression(Expression exp, Class<?> requiredClass) { if (exp instanceof FixedExpression) { push(((FixedExpression) exp).getValue(), requiredClass); return exp.getType(); } else if (exp instanceof EvaluatedExpression) { return jitEvaluatedExpression((EvaluatedExpression) exp, true, Object.class); } else if (exp instanceof VariableExpression) { return jitVariableExpression((VariableExpression) exp); } else if (exp instanceof AritmeticExpression) { return jitAritmeticExpression((AritmeticExpression) exp); } else if (exp instanceof ArrayCreationExpression) { return jitArrayCreationExpression((ArrayCreationExpression) exp); } else if (exp instanceof CastExpression) { return jitCastExpression((CastExpression) exp); } else { throw new RuntimeException("Unknown expression: " + exp); } }
private void jitExpressionToPrimitiveType(Expression expression, Class<?> primitiveType) { jitExpression(expression, primitiveType); if (!isFixed(expression)) { cast(expression.getType(), primitiveType); } }
private Class<?> jitExpression(Expression exp) { return jitExpression(exp, exp.getType()); }
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 castExpressionResultToPrimitive(Expression expression, Class<?> type) { if (!isFixed(expression)) { cast(expression.getType(), type); } }