From c3fdbe63198acdd08cb8c46ae0c75e0cb18d6707 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Mon, 17 Jul 2023 13:43:57 +0200 Subject: [PATCH 1/8] optimize: use array (assign entries from high index to low index) and Arrays.toList to remove the necessity of reversing the ArrayList after creation unify 2 ternary-ifs with equivalent condition to a single if invert inverted if condition --- .../bytecode/frontend/AsmMethodSource.java | 128 +++++++----------- 1 file changed, 47 insertions(+), 81 deletions(-) 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 067aa461843..855d9bb8bfe 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,38 +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.expr.JStaticInvokeExpr; +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.Modifier; +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; @@ -1229,59 +1197,60 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { MethodSignature methodSignature = javaIdentifierFactory.getMethodSignature(cls, insn.name, returnType, sigTypes); int nrArgs = sigTypes.size(); - final Operand[] args; - List argList = Collections.emptyList(); + final Operand[] operands; + Immediate[] argList; if (!isInstance) { - args = nrArgs == 0 ? null : new Operand[nrArgs]; - if (args != null) { - argList = new ArrayList<>(nrArgs); + if (nrArgs == 0) { + operands = null; + argList = new Immediate[0]; + } else { + operands = new Operand[nrArgs]; + argList = new Immediate[nrArgs]; } } else { - args = new Operand[nrArgs + 1]; - if (nrArgs != 0) { - argList = new ArrayList<>(nrArgs); + if (nrArgs == 0) { + operands = new Operand[1]; + argList = new Immediate[0]; + } else { + operands = new Operand[nrArgs + 1]; + argList = new Immediate[nrArgs]; } } - while (nrArgs-- != 0) { - args[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); - argList.add((Immediate) args[nrArgs].stackOrValue()); - } - if (argList.size() > 1) { - Collections.reverse(argList); + + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); } if (isInstance) { - args[args.length - 1] = operandStack.popLocal(); + operands[operands.length - 1] = operandStack.popLocal(); } AbstractInvokeExpr invoke; if (!isInstance) { invoke = Jimple.newStaticInvokeExpr(methodSignature, argList); } else { - Operand baseOperand = args[args.length - 1]; + Operand baseOperand = operands[operands.length - 1]; Local base = (Local) baseOperand.stackOrValue(); - AbstractInstanceInvokeExpr iinvoke; switch (op) { case INVOKESPECIAL: - iinvoke = Jimple.newSpecialInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, argList); break; case INVOKEVIRTUAL: - iinvoke = Jimple.newVirtualInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, argList); break; case INVOKEINTERFACE: - iinvoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, argList); break; default: throw new UnsupportedOperationException("Unknown invoke op:" + op); } - - invoke = iinvoke; baseOperand.addUsageInExpr(invoke); } - 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,10 +1261,10 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { Operand[] oprs; int nrArgs = types.size(); boolean isInstanceMethod = expr instanceof AbstractInstanceInvokeExpr; - if (!isInstanceMethod) { - oprs = nrArgs == 0 ? null : new Operand[nrArgs]; - } else { + if (isInstanceMethod) { oprs = new Operand[nrArgs + 1]; + } else { + oprs = nrArgs == 0 ? null : new Operand[nrArgs]; } if (oprs != null) { while (nrArgs-- != 0) { @@ -1346,31 +1315,28 @@ private void convertInvokeDynamicInsn(@Nonnull InvokeDynamicInsnNode insn) { // Generate parameters & returnType & parameterTypes List types = AsmUtil.toJimpleSignatureDesc(insn.desc); int nrArgs = types.size() - 1; - List parameterTypes = new ArrayList<>(nrArgs); - List methodArgs = new ArrayList<>(nrArgs); + 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--) { - parameterTypes.add(types.get(i)); + parameterTypes[i] = types.get(i); args[i] = operandStack.popImmediate(types.get(i)); - methodArgs.add((Immediate) args[i].stackOrValue()); - } - if (methodArgs.size() > 1) { - Collections.reverse(methodArgs); // Call stack is FIFO, Jimple is linear - Collections.reverse(parameterTypes); + 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 = - javaIdentifierFactory.getMethodSignature(bclass, insn.name, returnType, parameterTypes); + javaIdentifierFactory.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); } From 801bc94350facfdeb5b6a51a37e7af67f4705787 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Mon, 17 Jul 2023 13:54:45 +0200 Subject: [PATCH 2/8] deprecate methods: Jimple.new*Invoke(..., Immediate .. args) -> use the version with: List args as parameter instead --- sootup.core/src/main/java/sootup/core/jimple/Jimple.java | 4 ++++ .../sootup/java/bytecode/frontend/AsmMethodSource.java | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) 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 855d9bb8bfe..dc130d54afe 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 @@ -1226,20 +1226,20 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { } AbstractInvokeExpr invoke; if (!isInstance) { - invoke = Jimple.newStaticInvokeExpr(methodSignature, argList); + invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); } else { Operand baseOperand = operands[operands.length - 1]; Local base = (Local) baseOperand.stackOrValue(); switch (op) { case INVOKESPECIAL: - invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, Arrays.asList(argList)); break; case INVOKEVIRTUAL: - invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, Arrays.asList(argList)); break; case INVOKEINTERFACE: - invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, argList); + invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, Arrays.asList(argList)); break; default: throw new UnsupportedOperationException("Unknown invoke op:" + op); From 985ea7ea8c2c9297027c94bcc7f00245ce133ac8 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 11:49:59 +0200 Subject: [PATCH 3/8] fix missing import /merge leftover --- .../main/java/sootup/java/bytecode/frontend/AsmMethodSource.java | 1 + 1 file changed, 1 insertion(+) 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 7116d4c87ab..8e6b1899be5 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 @@ -49,6 +49,7 @@ import sootup.core.jimple.javabytecode.stmt.JSwitchStmt; 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; From 5e0f7d92d22a4e4608e22f8fa4d9bcaf53aef6b0 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 12:01:27 +0200 Subject: [PATCH 4/8] optimize: merge ifs; flip ! condition; remove unnecessary empty array init that will not be used if its empty --- .../bytecode/frontend/AsmMethodSource.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 8e6b1899be5..2e85f4d6fe9 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 @@ -1201,20 +1201,20 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { int nrArgs = sigTypes.size(); final Operand[] operands; Immediate[] argList; - if (!isInstance) { + if (isInstance) { if (nrArgs == 0) { - operands = null; - argList = new Immediate[0]; + operands = new Operand[1]; + argList = null; } else { - operands = new Operand[nrArgs]; + operands = new Operand[nrArgs + 1]; argList = new Immediate[nrArgs]; } } else { if (nrArgs == 0) { - operands = new Operand[1]; - argList = new Immediate[0]; + operands = null; + argList = null; } else { - operands = new Operand[nrArgs + 1]; + operands = new Operand[nrArgs]; argList = new Immediate[nrArgs]; } } @@ -1223,13 +1223,11 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); } - if (isInstance) { - operands[operands.length - 1] = operandStack.popLocal(); - } + AbstractInvokeExpr invoke; - if (!isInstance) { - invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); - } else { + if (isInstance) { + operands[operands.length - 1] = operandStack.popLocal(); // pop the return type + Operand baseOperand = operands[operands.length - 1]; Local base = (Local) baseOperand.stackOrValue(); @@ -1247,6 +1245,8 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { throw new UnsupportedOperationException("Unknown invoke op:" + op); } baseOperand.addUsageInExpr(invoke); + } else { + invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); } if (operands != null) { for (int i = 0; i < sigTypes.size(); i++) { From d163bcbb2576f3e4d254a803ac76d707581468c0 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 12:03:19 +0200 Subject: [PATCH 5/8] refactor: merge if --- .../bytecode/frontend/AsmMethodSource.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) 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 2e85f4d6fe9..0e0f8cb207f 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 @@ -1201,6 +1201,7 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { int nrArgs = sigTypes.size(); final Operand[] operands; Immediate[] argList; + AbstractInvokeExpr invoke; if (isInstance) { if (nrArgs == 0) { operands = new Operand[1]; @@ -1209,23 +1210,12 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { operands = new Operand[nrArgs + 1]; argList = new Immediate[nrArgs]; } - } else { - if (nrArgs == 0) { - operands = null; - argList = null; - } else { - operands = new Operand[nrArgs]; - argList = new Immediate[nrArgs]; - } - } - while (nrArgs-- > 0) { - operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); - argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); - } + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } - AbstractInvokeExpr invoke; - if (isInstance) { operands[operands.length - 1] = operandStack.popLocal(); // pop the return type Operand baseOperand = operands[operands.length - 1]; @@ -1245,9 +1235,24 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { throw new UnsupportedOperationException("Unknown invoke op:" + op); } baseOperand.addUsageInExpr(invoke); + } else { + if (nrArgs == 0) { + operands = null; + argList = null; + } else { + operands = new Operand[nrArgs]; + argList = new Immediate[nrArgs]; + } + + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } + invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); } + if (operands != null) { for (int i = 0; i < sigTypes.size(); i++) { operands[i].addUsageInExpr(invoke); From 29cc21089d221298aba81000479c0033fd9dc85b Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 12:10:21 +0200 Subject: [PATCH 6/8] refactor: reduce repeated condition checks to improve readability and 'performance' for the cost of 3 lines of code duplication --- .../bytecode/frontend/AsmMethodSource.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) 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 0e0f8cb207f..b3f5b9c9863 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 @@ -1200,20 +1200,21 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { identifierFactory.getMethodSignature(cls, insn.name, returnType, sigTypes); int nrArgs = sigTypes.size(); final Operand[] operands; - Immediate[] argList; AbstractInvokeExpr invoke; if (isInstance) { + final List args; if (nrArgs == 0) { operands = new Operand[1]; - argList = null; + args = Collections.emptyList(); } else { + Immediate[] argList = new Immediate[nrArgs]; operands = new Operand[nrArgs + 1]; - argList = new Immediate[nrArgs]; - } - while (nrArgs-- > 0) { - operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); - argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } + args = Arrays.asList(argList); } operands[operands.length - 1] = operandStack.popLocal(); // pop the return type @@ -1223,13 +1224,13 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { switch (op) { case INVOKESPECIAL: - invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, Arrays.asList(argList)); + invoke = Jimple.newSpecialInvokeExpr(base, methodSignature, args); break; case INVOKEVIRTUAL: - invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, Arrays.asList(argList)); + invoke = Jimple.newVirtualInvokeExpr(base, methodSignature, args); break; case INVOKEINTERFACE: - invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, Arrays.asList(argList)); + invoke = Jimple.newInterfaceInvokeExpr(base, methodSignature, args); break; default: throw new UnsupportedOperationException("Unknown invoke op:" + op); @@ -1239,18 +1240,20 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { } else { if (nrArgs == 0) { operands = null; - argList = null; + invoke = Jimple.newStaticInvokeExpr(methodSignature, Collections.emptyList()); + } else { + operands = new Operand[nrArgs]; - argList = new Immediate[nrArgs]; - } + Immediate[] argList = new Immediate[nrArgs]; - while (nrArgs-- > 0) { - operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); - argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); - } + while (nrArgs-- > 0) { + operands[nrArgs] = operandStack.popImmediate(sigTypes.get(nrArgs)); + argList[nrArgs] = (Immediate) operands[nrArgs].stackOrValue(); + } - invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); + invoke = Jimple.newStaticInvokeExpr(methodSignature, Arrays.asList(argList)); + } } if (operands != null) { From 4327ee1635b01bfb9295df8c7d88188efd14157e Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 12:17:56 +0200 Subject: [PATCH 7/8] same principle again --- .../bytecode/frontend/AsmMethodSource.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) 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 b3f5b9c9863..a81e866f5a9 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 @@ -1217,9 +1217,8 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { args = Arrays.asList(argList); } - operands[operands.length - 1] = operandStack.popLocal(); // pop the return type - - Operand baseOperand = operands[operands.length - 1]; + final Operand baseOperand = operandStack.popLocal(); + operands[operands.length - 1] = baseOperand; Local base = (Local) baseOperand.stackOrValue(); switch (op) { @@ -1270,25 +1269,27 @@ 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 = new Operand[nrArgs + 1]; - } else { - oprs = nrArgs == 0 ? null : new Operand[nrArgs]; - } - 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]; + while (nrArgs-- != 0) { + oprs[nrArgs] = operandStack.pop(types.get(nrArgs)); + } + frame.mergeIn(currentLineNumber, oprs); + } } returnType = expr.getMethodSignature().getType(); } + if (AsmUtil.isDWord(returnType)) { operandStack.pushDual(opr); } else if (returnType != VoidType.getInstance()) { From 5e7d9228e52c4b4a96116fb0a503e1fddd6f6efa Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 26 Oct 2023 13:24:16 +0200 Subject: [PATCH 8/8] we can dodowhile --- .../java/bytecode/frontend/AsmMethodSource.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) 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 a81e866f5a9..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 @@ -1246,10 +1246,11 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { operands = new Operand[nrArgs]; Immediate[] argList = new Immediate[nrArgs]; - while (nrArgs-- > 0) { + 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)); } @@ -1279,11 +1280,13 @@ private void convertMethodInsn(@Nonnull MethodInsnNode insn) { oprs[oprs.length - 1] = operandStack.pop(); frame.mergeIn(currentLineNumber, oprs); } else { - if (nrArgs != 0) { + if (nrArgs > 0) { oprs = new Operand[nrArgs]; - while (nrArgs-- != 0) { + do { + nrArgs--; oprs[nrArgs] = operandStack.pop(types.get(nrArgs)); - } + } while (nrArgs > 0); + frame.mergeIn(currentLineNumber, oprs); } }