예제 #1
0
 /** @apilevel internal */
 private TypeDecl sourceType_compute() {
   TypeDecl left = getDest().type();
   TypeDecl right = getSource().type();
   if (!left.isString() && !right.isString()) return super.sourceType();
   if (left.isVoid() || right.isVoid()) return unknownType();
   return left.isString() ? left : right;
 }
예제 #2
0
 /** @apilevel internal */
 private TypeDecl binaryNumericPromotedType_compute() {
   TypeDecl leftType = left().type();
   TypeDecl rightType = right().type();
   if (leftType.isString()) return leftType;
   if (rightType.isString()) return rightType;
   if (leftType.isNumericType() && rightType.isNumericType())
     return leftType.binaryNumericPromotion(rightType);
   if (leftType.isBoolean() && rightType.isBoolean()) return leftType;
   return unknownType();
 }
예제 #3
0
  /**
   * @ast method
   * @aspect Expressions
   * @declaredat
   *     /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/Expressions.jrag:84
   */
  public soot.Value eval(Body b) {
    TypeDecl dest = getDest().type();
    TypeDecl source = getSource().type();
    if (dest.isString()) {

      Value lvalue = getDest().eval(b);

      Value v = asImmediate(b, lvalue);

      // new StringBuffer(left)
      Local local =
          b.newTemp(b.newNewExpr(lookupType("java.lang", "StringBuffer").sootRef(), this));
      b.setLine(this);
      b.add(
          b.newInvokeStmt(
              b.newSpecialInvokeExpr(
                  local,
                  Scene.v()
                      .getMethod("<java.lang.StringBuffer: void <init>(java.lang.String)>")
                      .makeRef(),
                  v,
                  this),
              this));

      // append right
      Local rightResult =
          b.newTemp(
              b.newVirtualInvokeExpr(
                  local,
                  lookupType("java.lang", "StringBuffer")
                      .methodWithArgs("append", new TypeDecl[] {source.stringPromotion()})
                      .sootRef(),
                  asImmediate(b, getSource().eval(b)),
                  this));

      // toString
      Local result =
          b.newTemp(
              b.newVirtualInvokeExpr(
                  rightResult,
                  Scene.v()
                      .getMethod("<java.lang.StringBuffer: java.lang.String toString()>")
                      .makeRef(),
                  this));

      Value v2 = lvalue instanceof Local ? lvalue : (Value) lvalue.clone();
      getDest().emitStore(b, v2, result, this);
      return result;
    } else {
      return super.eval(b);
    }
  }
예제 #4
0
  // string addition assign expression
  public void createBCode(CodeGeneration gen) {
    TypeDecl dest = getDest().type();
    TypeDecl source = getSource().type();
    if (dest.isString()) {
      getDest().createAssignLoadDest(gen);

      // new StringBuffer()
      TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer");
      String classname = stringBuffer.constantPoolName();
      String desc;
      int index;
      TypeDecl argumentType;
      stringBuffer.emitNew(gen); // new StringBuffer
      gen.emitDup(); // dup
      desc = "()V";
      index = gen.constantPool().addMethodref(classname, "<init>", desc);
      gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer()

      gen.emitSwap();

      // append
      argumentType = dest.stringPromotion();
      desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor();
      index = gen.constantPool().addMethodref(classname, "append", desc);
      gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize())
          .add2(index); // StringBuffer.append

      getSource().createBCode(gen);

      // typed append
      argumentType = source.stringPromotion();
      desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor();
      index = gen.constantPool().addMethodref(classname, "append", desc);
      gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize())
          .add2(index); // StringBuffer.append

      // toString
      desc = "()" + type().typeDescriptor();
      index = gen.constantPool().addMethodref(classname, "toString", desc);
      gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString

      if (needsPush()) {
        getDest().createPushAssignmentResult(gen);
      }
      getDest().emitStore(gen);
    } else {
      super.createBCode(gen);
    }
  }