private Expression operationWithConstantValue(
      BinaryExpression binExp,
      java.lang.Class expectedClass,
      Expression constantExp,
      boolean constantOnLeft,
      boolean operationWithSideEffect) {
    Expression exp;
    if (operationWithSideEffect) {
      MethodAccess call = new MethodAccess();
      call.expression = new This();
      exp = call;
    } else {
      exp = new IdExpression();
    }
    exp.type = constantExp.type;
    if (constantOnLeft) {
      binExp.right = exp;
      binExp.left = constantExp;
    } else {
      binExp.left = exp;
      binExp.right = constantExp;
    }
    if (null == expectedClass) expectedClass = MethodAccess.class;

    return expressionSimplificationTester(binExp, expectedClass, constantExp.type, 0, false);
  }
Example #2
0
 public void positionStmtsAfterEnumInitStmts(List<Statement> staticFieldStatements) {
   MethodNode method = getOrAddStaticConstructorNode();
   Statement statement = method.getCode();
   if (statement instanceof BlockStatement) {
     BlockStatement block = (BlockStatement) statement;
     // add given statements for explicitly declared static fields just after enum-special fields
     // are found - the $VALUES binary expression marks the end of such fields.
     List<Statement> blockStatements = block.getStatements();
     ListIterator<Statement> litr = blockStatements.listIterator();
     while (litr.hasNext()) {
       Statement stmt = litr.next();
       if (stmt instanceof ExpressionStatement
           && ((ExpressionStatement) stmt).getExpression() instanceof BinaryExpression) {
         BinaryExpression bExp = (BinaryExpression) ((ExpressionStatement) stmt).getExpression();
         if (bExp.getLeftExpression() instanceof FieldExpression) {
           FieldExpression fExp = (FieldExpression) bExp.getLeftExpression();
           if (fExp.getFieldName().equals("$VALUES")) {
             for (Statement tmpStmt : staticFieldStatements) {
               litr.add(tmpStmt);
             }
           }
         }
       }
     }
   }
 }
Example #3
0
 @Override
 public Void visitBinaryExpression(BinaryExpression node) {
   visit(node.getLeftOperand());
   writer.print(' ');
   writer.print(node.getOperator().getLexeme());
   writer.print(' ');
   visit(node.getRightOperand());
   return null;
 }
 public void generateOptimizedStringConcatenationCreation(
     BlockScope blockScope, CodeStream codeStream, int typeID) {
   // keep implementation in sync with BinaryExpression
   // #generateOptimizedStringConcatenationCreation
   if (this.referencesTable == null) {
     super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
   } else {
     if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
         && ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)
         && this.constant == Constant.NotAConstant) {
       int pc = codeStream.position;
       BinaryExpression cursor = this.referencesTable[this.arity - 1];
       // silence warnings
       int restart = 0;
       for (restart = this.arity - 1; restart >= 0; restart--) {
         if (((((cursor = this.referencesTable[restart]).bits & ASTNode.OperatorMASK)
                     >> ASTNode.OperatorSHIFT)
                 == OperatorIds.PLUS)
             && ((cursor.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
           if (cursor.constant != Constant.NotAConstant) {
             codeStream.newStringContatenation(); // new: java.lang.StringBuffer
             codeStream.dup();
             codeStream.ldc(cursor.constant.stringValue());
             codeStream.invokeStringConcatenationStringConstructor();
             // invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
             break;
           }
         } else {
           cursor.generateOptimizedStringConcatenationCreation(
               blockScope, codeStream, cursor.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
           break;
         }
       }
       restart++;
       if (restart == 0) { // reached the leftmost expression
         cursor.left.generateOptimizedStringConcatenationCreation(
             blockScope, codeStream, cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
       }
       int pcAux;
       for (int i = restart; i < this.arity; i++) {
         codeStream.recordPositionsFrom(pc, (cursor = this.referencesTable[i]).left.sourceStart);
         pcAux = codeStream.position;
         cursor.right.generateOptimizedStringConcatenation(
             blockScope, codeStream, cursor.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
         codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart);
       }
       codeStream.recordPositionsFrom(pc, this.left.sourceStart);
       pc = codeStream.position;
       this.right.generateOptimizedStringConcatenation(
           blockScope, codeStream, this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
       codeStream.recordPositionsFrom(pc, this.right.sourceStart);
     } else {
       super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
     }
   }
 }
 public void traverse(ASTVisitor visitor, BlockScope scope) {
   if (this.referencesTable == null) {
     super.traverse(visitor, scope);
   } else {
     if (visitor.visit(this, scope)) {
       int restart;
       for (restart = this.arity - 1; restart >= 0; restart--) {
         if (!visitor.visit(this.referencesTable[restart], scope)) {
           visitor.endVisit(this.referencesTable[restart], scope);
           break;
         }
       }
       restart++;
       // restart now points to the deepest BE for which
       // visit returned true, if any
       if (restart == 0) {
         this.referencesTable[0].left.traverse(visitor, scope);
       }
       for (int i = restart, end = this.arity; i < end; i++) {
         this.referencesTable[i].right.traverse(visitor, scope);
         visitor.endVisit(this.referencesTable[i], scope);
       }
       this.right.traverse(visitor, scope);
     }
     visitor.endVisit(this, scope);
   }
 }
  /** Boolean operator code generation Optimized operations are: == and != */
  public void generateOptimizedBoolean(
      BlockScope currentScope,
      CodeStream codeStream,
      BranchLabel trueLabel,
      BranchLabel falseLabel,
      boolean valueRequired) {

    if (this.constant != Constant.NotAConstant) {
      super.generateOptimizedBoolean(
          currentScope, codeStream, trueLabel, falseLabel, valueRequired);
      return;
    }
    if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
      if ((this.left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
        generateOptimizedBooleanEqual(
            currentScope, codeStream, trueLabel, falseLabel, valueRequired);
      } else {
        generateOptimizedNonBooleanEqual(
            currentScope, codeStream, trueLabel, falseLabel, valueRequired);
      }
    } else {
      if ((this.left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
        generateOptimizedBooleanEqual(
            currentScope, codeStream, falseLabel, trueLabel, valueRequired);
      } else {
        generateOptimizedNonBooleanEqual(
            currentScope, codeStream, falseLabel, trueLabel, valueRequired);
      }
    }
  }
Example #7
0
  /** Log mutated line */
  public void visit(BinaryExpression p) throws ParseTreeException {
    if (isSameObject(p, original)) {
      BinaryExpression mutant_exp;
      mutant_exp = (BinaryExpression) original.makeRecursiveCopy();
      mutant_exp.setOperator(mutant_op);
      super.visit(mutant_exp);

      String operator = mutant_exp.operatorString();
      out.print(" " + operator + " ");
      // -----------------------------------------------------------
      mutated_line = line_num;
      String log_str = p.operatorString() + " => " + operator;
      writeLog(removeNewline(log_str));
      // -------------------------------------------------------------

      mutant_exp = null;
    } else {
      super.visit(p);
    }
  }
    private Runnable replaceWith(final BinaryExpression newExpr) {
      final Mapper<?, ?> root = Mappers.getRoot(myMapper);

      BinaryExpression oldExpr = myMapper.getSource();
      oldExpr.replaceWith(newExpr);

      Expression left = oldExpr.left.get();
      if (left != null) {
        left.removeFromParent();
      }
      Expression right = oldExpr.right.get();
      if (right != null) {
        right.removeFromParent();
      }

      newExpr.left.set(left);
      newExpr.right.set(right);

      new ExprBinOpTransformer().balanceOnOperationChange(newExpr).parent().get();

      return CellActions.toEnd(
          ((BinaryExpressionMapper) root.getDescendantMapper(newExpr)).getTarget().sign);
    }
Example #9
0
  // Parses a binary expression
  private void parse(BinaryExpression be) {
    BinaryOperator bop = be.getOperator();
    SimpleExpression lhs = new SimpleExpression(be.getLHS());
    SimpleExpression rhs = new SimpleExpression(be.getRHS());
    contains_side_effect |= (lhs.contains_side_effect || rhs.contains_side_effect);

    if (bop == BinaryOperator.SUBTRACT) {
      sop = ADD;
      SimpleExpression new_rhs = new SimpleExpression(MUL);
      new_rhs.add(getInt(-1));
      new_rhs.add(rhs);
      add(lhs);
      add(new_rhs);
    } else {
      sop = cop.indexOf(bop);
      if (sop == -1) {
        sop = TREE;
        expr = be;
      }
      add(lhs);
      add(rhs);
    }
  }
 @Override
 public void visitBinaryExpression(BinaryExpression be) {
   super.visitBinaryExpression(be);
   switch (be.getOperation().getType()) {
     case Types.EQUAL: // = assignment
     case Types.BITWISE_AND_EQUAL:
     case Types.BITWISE_OR_EQUAL:
     case Types.BITWISE_XOR_EQUAL:
     case Types.PLUS_EQUAL:
     case Types.MINUS_EQUAL:
     case Types.MULTIPLY_EQUAL:
     case Types.DIVIDE_EQUAL:
     case Types.INTDIV_EQUAL:
     case Types.MOD_EQUAL:
     case Types.POWER_EQUAL:
     case Types.LEFT_SHIFT_EQUAL:
     case Types.RIGHT_SHIFT_EQUAL:
     case Types.RIGHT_SHIFT_UNSIGNED_EQUAL:
       checkFinalFieldAccess(be.getLeftExpression());
       break;
     default:
       break;
   }
 }
Example #11
0
  /**
   * Attempts to parse a syntactic assignment expression from token stream. If parsing fails the
   * stream is reset to its initial position.
   *
   * @param tokens source token stream
   * @return Expression object or null if tokens don't form a valid expression
   */
  public static Expression parse(TokenStream tokens) {
    Position pos = tokens.getPosition();
    tokens.pushMark();
    Expression expr = BinaryExpression.parse(tokens);

    if (expr != null) {
      tokens.pushMark();
      Expression right = null;
      String op = tokens.read().toString();
      if (assignmentOperators.containsKey(op)) right = AssignmentExpression.parse(tokens);

      tokens.popMark(right == null);
      if (right != null) expr = new AssignmentExpression(op, expr, right, pos);
    }

    tokens.popMark(expr == null);
    return expr;
  }
 protected Expression transformBinaryExpression(BinaryExpression be) {
   int type = be.getOperation().getType();
   boolean oldInLeftExpression;
   Expression right = transform(be.getRightExpression());
   be.setRightExpression(right);
   Expression left;
   if (type == Types.EQUAL && be.getLeftExpression() instanceof VariableExpression) {
     oldInLeftExpression = inLeftExpression;
     inLeftExpression = true;
     left = transform(be.getLeftExpression());
     inLeftExpression = oldInLeftExpression;
     if (left instanceof StaticMethodCallExpression) {
       StaticMethodCallExpression smce = (StaticMethodCallExpression) left;
       StaticMethodCallExpression result =
           new StaticMethodCallExpression(smce.getOwnerType(), smce.getMethod(), right);
       setSourcePosition(result, be);
       return result;
     }
   } else {
     left = transform(be.getLeftExpression());
   }
   be.setLeftExpression(left);
   return be;
 }
 public void visit(BinaryExpression entity) {
   wGetVisitor1().visit(entity.getLeftExpr());
   wGetVisitor1().visit(entity.getOperator());
   wGetVisitor1().visit(entity.getRightExpr());
 }
 Expression transformMethodCallExpression(final MethodCallExpression expr) {
   Expression objectExpression = expr.getObjectExpression();
   if (expr.isSafe()) {
     MethodCallExpression notSafe =
         new MethodCallExpression(objectExpression, expr.getMethod(), expr.getArguments());
     notSafe.copyNodeMetaData(expr);
     notSafe.setSpreadSafe(expr.isSpreadSafe());
     notSafe.setSourcePosition(expr);
     notSafe.setMethodTarget(expr.getMethodTarget());
     TernaryExpression texpr =
         new TernaryExpression(
             new BooleanExpression(
                 new BinaryExpression(
                     objectExpression,
                     Token.newSymbol(
                         "!=",
                         objectExpression.getLineNumber(),
                         objectExpression.getColumnNumber()),
                     ConstantExpression.NULL)),
             notSafe,
             ConstantExpression.NULL);
     return staticCompilationTransformer.transform(texpr);
   }
   ClassNode type =
       staticCompilationTransformer
           .getTypeChooser()
           .resolveType(objectExpression, staticCompilationTransformer.getClassNode());
   if (type != null && type.isArray()) {
     String method = expr.getMethodAsString();
     ClassNode componentType = type.getComponentType();
     if ("getAt".equals(method)) {
       Expression arguments = expr.getArguments();
       if (arguments instanceof TupleExpression) {
         List<Expression> argList = ((TupleExpression) arguments).getExpressions();
         if (argList.size() == 1) {
           Expression indexExpr = argList.get(0);
           ClassNode argType =
               staticCompilationTransformer
                   .getTypeChooser()
                   .resolveType(indexExpr, staticCompilationTransformer.getClassNode());
           ClassNode indexType = ClassHelper.getWrapper(argType);
           if (componentType.isEnum() && ClassHelper.Number_TYPE == indexType) {
             // workaround for generated code in enums which use .next() returning a Number
             indexType = ClassHelper.Integer_TYPE;
           }
           if (argType != null && ClassHelper.Integer_TYPE == indexType) {
             BinaryExpression binaryExpression =
                 new BinaryExpression(
                     objectExpression,
                     Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()),
                     indexExpr);
             binaryExpression.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
             return staticCompilationTransformer.transform(binaryExpression);
           }
         }
       }
     }
     if ("putAt".equals(method)) {
       Expression arguments = expr.getArguments();
       if (arguments instanceof TupleExpression) {
         List<Expression> argList = ((TupleExpression) arguments).getExpressions();
         if (argList.size() == 2) {
           Expression indexExpr = argList.get(0);
           Expression objExpr = argList.get(1);
           ClassNode argType =
               staticCompilationTransformer
                   .getTypeChooser()
                   .resolveType(indexExpr, staticCompilationTransformer.getClassNode());
           if (argType != null && ClassHelper.Integer_TYPE == ClassHelper.getWrapper(argType)) {
             BinaryExpression arrayGet =
                 new BinaryExpression(
                     objectExpression,
                     Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()),
                     indexExpr);
             arrayGet.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
             BinaryExpression assignment =
                 new BinaryExpression(
                     arrayGet,
                     Token.newSymbol("=", objExpr.getLineNumber(), objExpr.getColumnNumber()),
                     objExpr);
             return staticCompilationTransformer.transform(assignment);
           }
         }
       }
     }
   }
   return staticCompilationTransformer.superTransform(expr);
 }
  /** Boolean operator code generation Optimized operations are: || */
  public void generateOptimizedBoolean(
      BlockScope currentScope,
      CodeStream codeStream,
      BranchLabel trueLabel,
      BranchLabel falseLabel,
      boolean valueRequired) {
    if (this.constant != Constant.NotAConstant) {
      super.generateOptimizedBoolean(
          currentScope, codeStream, trueLabel, falseLabel, valueRequired);
      return;
    }

    // <expr> || false --> <expr>
    Constant cst = this.right.constant;
    if (cst != Constant.NotAConstant && cst.booleanValue() == false) {
      int pc = codeStream.position;
      this.left.generateOptimizedBoolean(
          currentScope, codeStream, trueLabel, falseLabel, valueRequired);
      if (this.mergedInitStateIndex != -1) {
        codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
      }
      codeStream.recordPositionsFrom(pc, this.sourceStart);
      return;
    }

    cst = this.left.optimizedBooleanConstant();
    boolean leftIsConst = cst != Constant.NotAConstant;
    boolean leftIsTrue = leftIsConst && cst.booleanValue() == true;

    cst = this.right.optimizedBooleanConstant();
    boolean rightIsConst = cst != Constant.NotAConstant;
    boolean rightIsTrue = rightIsConst && cst.booleanValue() == true;

    // default case
    generateOperands:
    {
      if (falseLabel == null) {
        if (trueLabel != null) {
          // implicit falling through the FALSE case
          this.left.generateOptimizedBoolean(
              currentScope, codeStream, trueLabel, null, !leftIsConst);
          // need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
          if (leftIsTrue) {
            if (valueRequired) codeStream.goto_(trueLabel);
            codeStream.recordPositionsFrom(codeStream.position, this.left.sourceEnd);
            break generateOperands; // no need to generate right operand
          }
          if (this.rightInitStateIndex != -1) {
            codeStream.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
          }
          this.right.generateOptimizedBoolean(
              currentScope, codeStream, trueLabel, null, valueRequired && !rightIsConst);
          if (valueRequired && rightIsTrue) {
            codeStream.goto_(trueLabel);
            codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
          }
        }
      } else {
        // implicit falling through the TRUE case
        if (trueLabel == null) {
          BranchLabel internalTrueLabel = new BranchLabel(codeStream);
          this.left.generateOptimizedBoolean(
              currentScope, codeStream, internalTrueLabel, null, !leftIsConst);
          // need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
          if (leftIsTrue) {
            internalTrueLabel.place();
            break generateOperands; // no need to generate right operand
          }
          if (this.rightInitStateIndex != -1) {
            codeStream.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
          }
          this.right.generateOptimizedBoolean(
              currentScope, codeStream, null, falseLabel, valueRequired && !rightIsConst);
          int pc = codeStream.position;
          if (valueRequired && rightIsConst && !rightIsTrue) {
            codeStream.goto_(falseLabel);
            codeStream.recordPositionsFrom(pc, this.sourceEnd);
          }
          internalTrueLabel.place();
        } else {
          // no implicit fall through TRUE/FALSE --> should never occur
        }
      }
    }
    if (this.mergedInitStateIndex != -1) {
      codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
    }
  }
Example #16
0
 public void visitBinaryExpression(BinaryExpression binaryExpression) throws Exception {
   binaryExpression.getLeftExpression().accept(this);
   binaryExpression.getRightExpression().accept(this);
 }
Example #17
0
 @SuppressWarnings("unchecked")
 @Override
 public Function<Object[], ?> visit(BinaryExpression e) {
   final Function<Object[], ?> first = e.getFirst().accept(this);
   final Function<Object[], ?> second = e.getSecond().accept(this);
   switch (e.getExpressionType()) {
     case ExpressionType.Add:
       return normalize(
           add((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.BitwiseAnd:
       return normalize(
           bitwiseAnd((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LogicalAnd:
       return normalize(
           and((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second));
     case ExpressionType.ArrayIndex:
       return t -> Array.get(first.apply(t), (Integer) second.apply(t));
       // return new Function<Object, Object[]>() {
       // // @Override
       // public Object invoke(Object[] t) throws Throwable {
       // return Array.get(first.invoke(t), (Integer) second
       // .invoke(t));
       // }
       // };
       // case ExpressionType.Coalesce:
       // return coalesce((Function<?, Object[]>) first,
       // (Function<?, Object[]>) second);
     case ExpressionType.Conditional:
       return iif((Function<Object[], Boolean>) e.getOperator().accept(this), first, second);
     case ExpressionType.Divide:
       return normalize(
           divide((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Equal:
       return normalize(equal(first, second));
     case ExpressionType.ExclusiveOr:
       return normalize(
           xor((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.GreaterThan:
       return normalize(
           greaterThan((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.GreaterThanOrEqual:
       return normalize(
           greaterThanOrEqual(
               (Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LeftShift:
       return normalize(
           shiftLeft((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LessThan:
       return normalize(
           lessThan((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LessThanOrEqual:
       return normalize(
           lessThanOrEqual(
               (Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Modulo:
       return normalize(
           modulo((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Multiply:
       return normalize(
           multiply((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.NotEqual:
       return normalize(equal(first, second).negate());
     case ExpressionType.BitwiseOr:
       return normalize(
           bitwiseOr((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LogicalOr:
       return normalize(
           or((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second));
       // case ExpressionType.Power:
       // return power((Function<Number, Object[]>) first,
       // (Function<Number, Object[]>) second);
     case ExpressionType.RightShift:
       return normalize(
           shiftRight((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Subtract:
       return normalize(
           subtract((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.InstanceOf:
       return normalize(instanceOf(first, (Class<?>) second.apply(null)));
     default:
       throw new IllegalArgumentException(ExpressionType.toString(e.getExpressionType()));
   }
 }
Example #18
0
  @Override
  public Object visitBinaryExpression(BinaryExpression binaryExpression, Object arg)
      throws Exception {
    MethodVisitor mv = ((InheritedAttributes) arg).mv;

    Kind op = binaryExpression.op.kind;

    binaryExpression.setType(binaryExpression.expression0.getType());

    switch (op) {
      case PLUS:
        if (binaryExpression.expression0.getType().equalsIgnoreCase(intType)
            || binaryExpression.expression0.getType().equalsIgnoreCase(booleanType)) {
          binaryExpression.expression0.visit(this, arg);
          binaryExpression.expression1.visit(this, arg);
          mv.visitInsn(IADD);

        } else if (binaryExpression.expression0.getType().equalsIgnoreCase(stringType)) {
          mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
          mv.visitInsn(DUP);
          binaryExpression.expression0.visit(this, arg);
          mv.visitMethodInsn(
              INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
          binaryExpression.expression1.visit(this, arg);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/lang/StringBuilder",
              "append",
              "(Ljava/lang/String;)Ljava/lang/StringBuilder;",
              false);
          mv.visitMethodInsn(
              INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
        }
        break;

      case MINUS:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitInsn(ISUB);
        break;

      case TIMES:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitInsn(IMUL);
        break;

      case DIV:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitInsn(IDIV);
        break;

      case LSHIFT:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);

        mv.visitInsn(ISHL);
        break;

      case RSHIFT:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitInsn(ISHR);
        break;

      case BAR:
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitInsn(IOR);
        break;

      case AND:
        binaryExpression.expression0.visit(this, arg);
        Label l1 = new Label();
        mv.visitJumpInsn(IFEQ, l1);
        binaryExpression.expression1.visit(this, arg);
        mv.visitJumpInsn(IFEQ, l1);
        mv.visitInsn(ICONST_1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(l2);
        break;

      case EQUAL:
        Label falseLabel = new Label();
        Label end = new Label();
        if (binaryExpression.expression0.getType().equalsIgnoreCase(intType)
            || binaryExpression.expression0.getType().equalsIgnoreCase(booleanType)) {
          binaryExpression.expression0.visit(this, arg);
          binaryExpression.expression1.visit(this, arg);
          mv.visitJumpInsn(IF_ICMPNE, falseLabel);

          mv.visitInsn(ICONST_1);

          mv.visitJumpInsn(GOTO, end);
          mv.visitLabel(falseLabel);
          mv.visitInsn(ICONST_0);
          mv.visitLabel(end);
        } else {

          binaryExpression.expression0.visit(this, arg);
          binaryExpression.expression1.visit(this, arg);
          mv.visitMethodInsn(
              INVOKEVIRTUAL, "java/lang/String", "compareTo", "(Ljava/lang/String;)I", false);

          mv.visitJumpInsn(IFNE, falseLabel);

          mv.visitInsn(ICONST_1);

          mv.visitJumpInsn(GOTO, end);

          mv.visitLabel(falseLabel);
          mv.visitInsn(ICONST_0);

          mv.visitLabel(end);
        }
        binaryExpression.setType(booleanType);
        break;

      case NOTEQUAL:
        falseLabel = new Label();
        end = new Label();
        if (binaryExpression.expression0.getType().equalsIgnoreCase(intType)
            || binaryExpression.expression0.getType().equalsIgnoreCase(booleanType)) {
          binaryExpression.expression0.visit(this, arg);
          binaryExpression.expression1.visit(this, arg);
          mv.visitJumpInsn(IF_ICMPEQ, falseLabel);

          mv.visitInsn(ICONST_1);

          mv.visitJumpInsn(GOTO, end);
          mv.visitLabel(falseLabel);
          mv.visitInsn(ICONST_0);
          mv.visitLabel(end);
        } else {

          binaryExpression.expression0.visit(this, arg);
          binaryExpression.expression1.visit(this, arg);
          mv.visitMethodInsn(
              INVOKEVIRTUAL, "java/lang/String", "compareTo", "(Ljava/lang/String;)I", false);

          mv.visitJumpInsn(IFEQ, falseLabel);

          mv.visitInsn(ICONST_1);

          mv.visitJumpInsn(GOTO, end);

          mv.visitLabel(falseLabel);
          mv.visitInsn(ICONST_0);

          mv.visitLabel(end);
        }
        binaryExpression.setType(booleanType);
        break;

      case LT:
        falseLabel = new Label();
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitJumpInsn(IF_ICMPGE, falseLabel);

        mv.visitInsn(ICONST_1);
        end = new Label();
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(falseLabel);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(end);
        binaryExpression.setType(booleanType);
        break;

      case GT:
        falseLabel = new Label();
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitJumpInsn(IF_ICMPLE, falseLabel);

        mv.visitInsn(ICONST_1);
        end = new Label();
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(falseLabel);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(end);
        binaryExpression.setType(booleanType);
        break;

      case LE:
        falseLabel = new Label();
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitJumpInsn(IF_ICMPGT, falseLabel);

        mv.visitInsn(ICONST_1);
        end = new Label();
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(falseLabel);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(end);
        binaryExpression.setType(booleanType);
        break;

      case GE:
        falseLabel = new Label();
        binaryExpression.expression0.visit(this, arg);
        binaryExpression.expression1.visit(this, arg);
        mv.visitJumpInsn(IF_ICMPLT, falseLabel);

        mv.visitInsn(ICONST_1);
        end = new Label();
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(falseLabel);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(end);
        binaryExpression.setType(booleanType);
        break;
    }

    return binaryExpression.getType();
    // throw new UnsupportedOperationException("code generation not yet implemented");
  }
 public void visitBinaryExpression(BinaryExpression expression) {
   expression.getLeftExpression().visit(this);
   expression.getRightExpression().visit(this);
 }
Example #20
0
 /** Normalization for points-to analysis. */
 private static Expression normalize(Expression arg, Symbol param) {
   Expression ret = arg.clone(); // default behavior.
   // Converts array accesses to address-of expressions.
   if (ret instanceof ArrayAccess) {
     ArrayAccess array = (ArrayAccess) ret;
     // Normalize the array name.
     Expression name = normalize(array.getArrayName(), null);
     Symbol base = SymbolTools.getSymbolOf(name);
     if (base != null && param != null && SymbolTools.isPointerParameter(param)) {
       // case 1: the base symbol has an array specifier.
       // --> - keeps the array indices while adding trailing [0].
       //     - converts to address-of expression.
       //     - adds dereference operator if base is a formal parameter
       if (SymbolTools.isArray(base)) {
         // Adds a trailing subscript "[0]" intentionally.
         array.addIndex(new IntegerLiteral(0));
         ret = new UnaryExpression(UnaryOperator.ADDRESS_OF, ret);
         // Formal parameter is normalized: a[10] to (*a)[10].
         // This conversion is used only internally (not legal in C).
         if (SymbolTools.isPointerParameter(base)) {
           array
               .getArrayName()
               .swapWith(new UnaryExpression(UnaryOperator.DEREFERENCE, name.clone()));
         }
         // case 2: the base symbol does not have an array specifier.
         // --> just take the base object while converting a subscript
         // to a dereference.
       } else {
         ret = name;
         for (int i = 0; i < array.getNumIndices(); i++) {
           ret = new UnaryExpression(UnaryOperator.DEREFERENCE, ret.clone());
         }
       }
     } else { // just normalizes the array name.
       array.getArrayName().swapWith(name);
     }
     // Removes pointer access and adds trailing dummy index for pointer
     // type.
   } else if (ret instanceof AccessExpression) {
     AccessExpression access = (AccessExpression) ret;
     // POINTER_ACCESS to MEMBER_ACCESS
     if (access.getOperator() == AccessOperator.POINTER_ACCESS) {
       // Normalize the LHS.
       Expression lhs = normalize(access.getLHS(), null);
       ret =
           new AccessExpression(
               new UnaryExpression(UnaryOperator.DEREFERENCE, lhs.clone()),
               AccessOperator.MEMBER_ACCESS,
               access.getRHS().clone());
     }
     // Pointer type to address-of expression.
     if (param != null && SymbolTools.isPointerParameter(param)) {
       ret =
           new UnaryExpression(
               UnaryOperator.ADDRESS_OF, new ArrayAccess(ret.clone(), new IntegerLiteral(0)));
     }
     // Just normalize the expression child.
   } else if (ret instanceof UnaryExpression) {
     UnaryExpression ue = (UnaryExpression) ret;
     ue.setExpression(normalize(ue.getExpression(), null));
     // Tries to convert simple pointer arithmetic to array access.
   } else if (ret instanceof BinaryExpression) {
     BinaryExpression be = (BinaryExpression) ret;
     Expression lhs = normalize(be.getLHS(), null);
     Expression rhs = normalize(be.getRHS(), null);
     if (param != null
         && SymbolTools.isPointerParameter(param)
         && be.getOperator() == BinaryOperator.ADD) {
       if (isPointerArithmeticOperand(lhs, rhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(rhs.clone(), lhs.clone()));
       } else if (isPointerArithmeticOperand(rhs, lhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(lhs.clone(), rhs.clone()));
       }
     } else {
       ret = new BinaryExpression(lhs.clone(), be.getOperator(), rhs.clone());
     }
     // Type cast is discarded.
   } else if (ret instanceof Typecast) {
     ret = (Expression) ret.getChildren().get(0);
   }
   return ret;
 }
  public void generateOptimizedStringConcatenation(
      BlockScope blockScope, CodeStream codeStream, int typeID) {
    // keep implementation in sync with BinaryExpression and Expression
    // #generateOptimizedStringConcatenation
    if (this.referencesTable == null) {
      super.generateOptimizedStringConcatenation(blockScope, codeStream, typeID);
    } else {
      if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
          && ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
        if (this.constant != Constant.NotAConstant) {
          codeStream.generateConstant(this.constant, this.implicitConversion);
          codeStream.invokeStringConcatenationAppendForType(
              this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
        } else {
          BinaryExpression cursor = this.referencesTable[0];

          int restart = 0;
          //			int cursorTypeID;
          int pc = codeStream.position;
          for (restart = this.arity - 1; restart >= 0; restart--) {
            if ((cursor = this.referencesTable[restart]).constant != Constant.NotAConstant) {
              codeStream.generateConstant(cursor.constant, cursor.implicitConversion);
              codeStream.invokeStringConcatenationAppendForType(
                  cursor.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
              break;
            }
            // never happens for now - may reconsider if we decide to
            // cover more than string concatenation
            //				if (!((((cursor = this.referencesTable[restart]).bits &
            //						ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) ==
            //							OperatorIds.PLUS) &
            //						((cursorTypeID = cursor.bits & ASTNode.ReturnTypeIDMASK) ==
            //							TypeIds.T_JavaLangString)) {
            //					if (cursorTypeID == T_JavaLangString &&
            //							cursor.constant != Constant.NotAConstant &&
            //							cursor.constant.stringValue().length() == 0) {
            //						break; // optimize str + ""
            //					}
            //					cursor.generateCode(blockScope, codeStream, true);
            //					codeStream.invokeStringConcatenationAppendForType(
            //							cursorTypeID);
            //					break;
            //				}
          }
          restart++;
          if (restart == 0) { // reached the leftmost expression
            cursor.left.generateOptimizedStringConcatenation(
                blockScope, codeStream, cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
          }
          int pcAux;
          for (int i = restart; i < this.arity; i++) {
            codeStream.recordPositionsFrom(pc, (cursor = this.referencesTable[i]).left.sourceStart);
            pcAux = codeStream.position;
            cursor.right.generateOptimizedStringConcatenation(
                blockScope,
                codeStream,
                cursor.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
            codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart);
          }
          codeStream.recordPositionsFrom(pc, this.left.sourceStart);
          pc = codeStream.position;
          this.right.generateOptimizedStringConcatenation(
              blockScope, codeStream, this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
          codeStream.recordPositionsFrom(pc, this.right.sourceStart);
        }
      } else {
        super.generateOptimizedStringConcatenation(blockScope, codeStream, typeID);
      }
    }
  }
Example #22
0
 private void visitBinaryOperation(BinaryExpression be) {
   be.getLeftExpression().accept(this);
   be.getRightExpression().accept(this);
 }
Example #23
0
 @Override
 void XMLAttributes(final StringBuilder sb) {
   sb.append(" op=\"").append(BinaryExpression.encodeXML(ops.getStr(op))).append('"');
 }