コード例 #1
0
    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);
    }
コード例 #2
0
 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);
   }
 }
コード例 #3
0
    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);
      }
    }
コード例 #4
0
    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);
    }
コード例 #5
0
    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);
    }
コード例 #6
0
    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);
    }
コード例 #7
0
 private void jitUnary(SingleCondition singleCondition) {
   jitExpression(singleCondition.getLeft());
 }