Example #1
1
  public JDynamicInvokeExpr(
      SootMethodRef bootstrapMethodRef,
      List<Value> bootstrapArgs,
      SootMethodRef methodRef,
      List<Value> methodArgs) {
    if (!methodRef.getSignature().startsWith("<" + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME + ": "))
      throw new IllegalArgumentException(
          "Receiver type of JDynamicInvokeExpr must be "
              + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME
              + "!");
    if (!bootstrapMethodRef.returnType().equals(RefType.v("java.lang.invoke.CallSite"))) {
      throw new IllegalArgumentException(
          "Return type of bootstrap method must be java.lang.invoke.CallSite!");
    }

    this.bsmRef = bootstrapMethodRef;
    this.methodRef = methodRef;
    this.bsmArgBoxes = new ValueBox[bootstrapArgs.size()];
    this.argBoxes = new ValueBox[methodArgs.size()];

    for (int i = 0; i < bootstrapArgs.size(); i++) {
      // RoboVM note: Changed to handle InvokeExpr values in bootstrap args
      Value v = bootstrapArgs.get(i);
      if (v instanceof InvokeExpr) {
        this.bsmArgBoxes[i] = Jimple.v().newInvokeExprBox(v);
      } else {
        this.bsmArgBoxes[i] = Jimple.v().newImmediateBox(v);
      }
    }
    for (int i = 0; i < methodArgs.size(); i++) {
      this.argBoxes[i] = Jimple.v().newImmediateBox((Value) methodArgs.get(i));
    }
  }
Example #2
0
  public String toString() {
    StringBuffer buffer = new StringBuffer();

    buffer.append(Jimple.DYNAMICINVOKE);
    buffer.append(" \"");
    buffer.append(methodRef.name()); // quoted method name (can be any UTF8 string)
    buffer.append("\" <");
    buffer.append(
        SootMethod.getSubSignature(
            "" /* no method name here*/, methodRef.parameterTypes(), methodRef.returnType()));
    buffer.append(">(");

    for (int i = 0; i < argBoxes.length; i++) {
      if (i != 0) buffer.append(", ");

      buffer.append(argBoxes[i].getValue().toString());
    }

    buffer.append(") ");

    buffer.append(bsmRef.getSignature());
    buffer.append("(");
    for (int i = 0; i < bsmArgBoxes.length; i++) {
      if (i != 0) buffer.append(", ");

      buffer.append(bsmArgBoxes[i].getValue().toString());
    }
    buffer.append(")");

    return buffer.toString();
  }
  /** Dumps out the call chain in json format * */
  public void dump_json(PrintStream fp, String indent) {
    fp.printf("%s{ %s,\n", indent, json_field("type", type));
    fp.printf("%s  %s,\n", indent, json_field("link", link));
    String sig = method.getSignature();
    fp.printf("%s  %s,\n", indent, json_field("signature", sig));
    if (stmt != null) {
      SootMethodRef invoke = stmt.getInvokeExpr().getMethodRef();
      String invokeSig;
      try {
        SootMethod concrete = SootUtils.resolve(stmt.getInvokeExpr().getMethodRef());
        invokeSig = concrete.getSignature();
      } catch (CannotFindMethodException e1) {
        logger.debug("Cannot find concrete method for {} in SourceCallChainInfo.dump_json()", stmt);
        invokeSig = invoke.getSignature();
      }
      if (!invokeSig.equals(sig)) {
        fp.printf("%s  %s,\n", indent, json_field("source-signature", invokeSig));
      }
    }
    SourceLocationTag slt =
        (stmt == null) ? SootUtils.getMethodLocation(method) : getSourceLocation(stmt);
    if (slt != null) {
      fp.printf("%s  %s", indent, json_field("src-loc"));
      fp.printf(
          "{ %s, %s},\n", json_field("class", slt.getClz()), json_field("line", slt.getLine()));
    }
    fp.printf("%s  %s,\n", indent, json_field("syscalls", syscalls));
    fp.printf("%s  %s,\n", indent, json_field("calls", calls));

    if ((contents != null) && (contents.length > 0)) {
      fp.printf("%s  %s,\n", indent, json_field("score", score));
      fp.printf("%s  %s [\n", indent, json_field("contents"));
      String delim = "";
      for (SourceCallChainInfo cci : contents) {
        fp.print(delim);
        delim = ",\n";
        cci.dump_json(fp, indent + "  ");
      }
      fp.printf("\n%s]}", indent);
    } else {
      fp.printf("%s  %s\n", indent, json_field("score", score));
      fp.printf("%s}", indent);
    }
  }