diff --git a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java index 35eda4a4ccb..02d91d3c563 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java +++ b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java @@ -349,6 +349,7 @@ public static JStaticInvokeExpr newStaticInvokeExpr( return new JStaticInvokeExpr(method, args); } + @Deprecated // use the version with List args instead public static JStaticInvokeExpr newStaticInvokeExpr(MethodSignature method, Immediate... args) { return newStaticInvokeExpr(method, Arrays.asList(args)); } @@ -374,6 +375,7 @@ public static JSpecialInvokeExpr newSpecialInvokeExpr( * Constructs a NewSpecialInvokeExpr(Local base, SootMethod method, List of Immediate) grammar * chunk. */ + @Deprecated // use the version with List args instead public static JSpecialInvokeExpr newSpecialInvokeExpr( Local base, MethodSignature method, Immediate... args) { return newSpecialInvokeExpr(base, method, Arrays.asList(args)); @@ -427,6 +429,7 @@ public static JVirtualInvokeExpr newVirtualInvokeExpr( * Constructs a NewVirtualInvokeExpr(Local base, SootMethod method, List of Immediate) grammar * chunk. */ + @Deprecated // use the version with List args instead public static JVirtualInvokeExpr newVirtualInvokeExpr( Local base, MethodSignature method, Immediate... args) { return newVirtualInvokeExpr(base, method, Arrays.asList(args)); @@ -454,6 +457,7 @@ public static JInterfaceInvokeExpr newInterfaceInvokeExpr( * Constructs a NewInterfaceInvokeExpr(Local base, SootMethod method, List of Immediate) grammar * chunk. */ + @Deprecated // use the version with List args instead public static JInterfaceInvokeExpr newInterfaceInvokeExpr( Local base, MethodSignature method, Immediate... args) { return newInterfaceInvokeExpr(base, method, Arrays.asList(args)); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java index 857b4d21349..7f1b861860f 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java @@ -21,25 +21,12 @@ * #L% */ -import static org.objectweb.asm.tree.AbstractInsnNode.FIELD_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.FRAME; -import static org.objectweb.asm.tree.AbstractInsnNode.IINC_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.INT_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.INVOKE_DYNAMIC_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.JUMP_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.LABEL; -import static org.objectweb.asm.tree.AbstractInsnNode.LDC_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.LINE; -import static org.objectweb.asm.tree.AbstractInsnNode.LOOKUPSWITCH_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.METHOD_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.MULTIANEWARRAY_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.TABLESWITCH_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.TYPE_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.VAR_INSN; +import static org.objectweb.asm.tree.AbstractInsnNode.*; import com.google.common.base.Suppliers; -import com.google.common.collect.*; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Table; import java.util.*; import java.util.Map.Entry; import java.util.function.BiFunction; @@ -55,37 +42,19 @@ import sootup.core.graph.MutableBlockStmtGraph; import sootup.core.jimple.Jimple; import sootup.core.jimple.basic.*; -import sootup.core.jimple.common.constant.DoubleConstant; -import sootup.core.jimple.common.constant.FloatConstant; -import sootup.core.jimple.common.constant.IntConstant; -import sootup.core.jimple.common.constant.LongConstant; -import sootup.core.jimple.common.constant.MethodHandle; -import sootup.core.jimple.common.constant.NullConstant; -import sootup.core.jimple.common.expr.AbstractBinopExpr; -import sootup.core.jimple.common.expr.AbstractConditionExpr; -import sootup.core.jimple.common.expr.AbstractInstanceInvokeExpr; -import sootup.core.jimple.common.expr.AbstractInvokeExpr; -import sootup.core.jimple.common.expr.AbstractUnopExpr; -import sootup.core.jimple.common.expr.Expr; -import sootup.core.jimple.common.expr.JAddExpr; -import sootup.core.jimple.common.expr.JCastExpr; -import sootup.core.jimple.common.expr.JDynamicInvokeExpr; -import sootup.core.jimple.common.expr.JInstanceOfExpr; -import sootup.core.jimple.common.expr.JNewArrayExpr; -import sootup.core.jimple.common.expr.JNewMultiArrayExpr; +import sootup.core.jimple.common.constant.*; +import sootup.core.jimple.common.expr.*; import sootup.core.jimple.common.ref.*; import sootup.core.jimple.common.stmt.*; import sootup.core.jimple.javabytecode.stmt.JSwitchStmt; -import sootup.core.model.*; +import sootup.core.model.Body; +import sootup.core.model.FullPosition; +import sootup.core.model.MethodModifier; +import sootup.core.model.Position; import sootup.core.signatures.FieldSignature; import sootup.core.signatures.MethodSignature; import sootup.core.transform.BodyInterceptor; -import sootup.core.types.ArrayType; -import sootup.core.types.ClassType; -import sootup.core.types.PrimitiveType; -import sootup.core.types.Type; -import sootup.core.types.UnknownType; -import sootup.core.types.VoidType; +import sootup.core.types.*; import sootup.core.views.View; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.jimple.basic.JavaLocal; @@ -1230,59 +1199,68 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { MethodSignature methodSignature = identifierFactory.getMethodSignature(cls, insn.name, returnType, sigTypes); int nrArgs = sigTypes.size(); - final Operand[] args; - List argList = Collections.emptyList(); - if (!isInstance) { - args = nrArgs == 0 ? null : new Operand[nrArgs]; - if (args != null) { - argList = new ArrayList<>(nrArgs); - } - } else { - args = new Operand[nrArgs + 1]; - if (nrArgs != 0) { - argList = new ArrayList<>(nrArgs); - } - } - while (nrArgs-- != 0) { - args[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); - argList.add((Immediate) args[nrArgs].stackOrValue()); - } - if (argList.size() > 1) { - Collections.reverse(argList); - } - if (isInstance) { - args[args.length - 1] = operandStack.popLocal(); - } + final Operand[] operands; AbstractInvokeExpr invoke; - if (!isInstance) { - invoke = Jimple.newStaticInvokeExpr(methodSignature, argList); - } else { - Operand baseOperand = args[args.length - 1]; + if (isInstance) { + final List args; + if (nrArgs == 0) { + operands = new Operand[1]; + args = Collections.emptyList(); + } else { + Immediate[] argList = new Immediate[nrArgs]; + operands = new Operand[nrArgs + 1]; + + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } + args = Arrays.asList(argList); + } + + final Operand baseOperand = operandStack.popLocal(); + operands[operands.length - 1] = baseOperand; Local base = (Local) baseOperand.stackOrValue(); - AbstractInstanceInvokeExpr iinvoke; switch (op) { case INVOKESPECIAL: - iinvoke = Jimple.newSpecialInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, args); break; case INVOKEVIRTUAL: - iinvoke = Jimple.newVirtualInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, args); break; case INVOKEINTERFACE: - iinvoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, args); break; default: throw new UnsupportedOperationException("Unknown invoke op:" + op); } - - invoke = iinvoke; baseOperand.addUsageInExpr(invoke); + + } else { + if (nrArgs == 0) { + operands = null; + invoke = Jimple.newStaticInvokeExpr(methodSignature, Collections.emptyList()); + + } else { + + operands = new Operand[nrArgs]; + Immediate[] argList = new Immediate[nrArgs]; + + do { + nrArgs--; + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } while (nrArgs > 0); + + invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); + } } - if (args != null) { + + if (operands != null) { for (int i = 0; i < sigTypes.size(); i++) { - args[i].addUsageInExpr(invoke); + operands[i].addUsageInExpr(invoke); } - frame.setIn(args); + frame.setIn(operands); } opr = new Operand(insn, invoke, this); frame.setOut(opr); @@ -1292,25 +1270,29 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { List types = expr.getMethodSignature().getParameterTypes(); Operand[] oprs; int nrArgs = types.size(); - // TODO: check equivalent to isInstance? + assert (isInstance); // TODO: check equivalent to isInstance? boolean isInstanceMethod = expr instanceof AbstractInstanceInvokeExpr; - if (!isInstanceMethod) { - oprs = nrArgs == 0 ? null : new Operand[nrArgs]; - } else { + if (isInstanceMethod) { oprs = new Operand[nrArgs + 1]; - } - if (oprs != null) { while (nrArgs-- != 0) { oprs[nrArgs] = operandStack.pop(types.get(nrArgs)); } - if (isInstanceMethod) { - oprs[oprs.length - 1] = operandStack.pop(); - } - + oprs[oprs.length - 1] = operandStack.pop(); frame.mergeIn(currentLineNumber, oprs); + } else { + if (nrArgs > 0) { + oprs = new Operand[nrArgs]; + do { + nrArgs--; + oprs[nrArgs] = operandStack.pop(types.get(nrArgs)); + } while (nrArgs > 0); + + frame.mergeIn(currentLineNumber, oprs); + } } returnType = expr.getMethodSignature().getType(); } + if (AsmUtil.isDWord(returnType)) { operandStack.pushDual(opr); } else if (returnType != VoidType.getInstance()) { @@ -1346,33 +1328,29 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) { // Generate parameters & returnType & parameterTypes List types = AsmUtil.toJimpleSignatureDesc(insn.desc); - int nrArgs = types.size() - 1; // don't handle the return type here - List parameterTypes = new ArrayList<>(nrArgs); - List methodArgs = new ArrayList<>(nrArgs); + int nrArgs = types.size() - 1; + Type[] parameterTypes = new Type[nrArgs]; + Immediate[] methodArgs = new Immediate[nrArgs]; Operand[] args = new Operand[nrArgs]; // Beware: Call stack is FIFO, Jimple is linear for (int i = nrArgs - 1; i >= 0; i--) { - final Type type = types.get(i); - parameterTypes.add(type); - args[i] = operandStack.popImmediate(type); - methodArgs.add((Immediate) args[i].stackOrValue()); - } - if (methodArgs.size() > 1) { - Collections.reverse(methodArgs); // Call stack is FIFO, Jimple is linear - Collections.reverse(parameterTypes); + parameterTypes[i] = types.get(i); + args[i] = operandStack.popImmediate(types.get(i)); + methodArgs[i] = (Immediate) args[i].stackOrValue(); } returnType = types.get(types.size() - 1); // we always model invokeDynamic method refs as static method references // of methods on the type SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME MethodSignature methodSig = - identifierFactory.getMethodSignature(bclass, insn.name, returnType, parameterTypes); + identifierFactory.getMethodSignature( + bclass, insn.name, returnType, Arrays.asList(parameterTypes)); JDynamicInvokeExpr indy = Jimple.newDynamicInvokeExpr( - bsmMethodRef, bsmMethodArgs, methodSig, insn.bsm.getTag(), methodArgs); + bsmMethodRef, bsmMethodArgs, methodSig, insn.bsm.getTag(), Arrays.asList(methodArgs)); for (int i = 0; i < types.size() - 1; i++) { args[i].addUsageInExpr(indy); }