let's handle invoke and array correctly

This commit is contained in:
金戟 2020-11-16 19:01:29 +08:00
parent f7dba2d33d
commit 809b1aa57f
2 changed files with 21 additions and 10 deletions

View File

@ -121,11 +121,21 @@ public class SourceClassHandler extends BaseClassHandler {
int stackLevel = ClassUtil.getParameterTypes(((MethodInsnNode)instructions[rangeEnd]).desc).size();
for (int i = rangeEnd - 1; i >= 0; i--) {
switch (instructions[i].getOpcode()) {
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESPECIAL:
stackLevel += ClassUtil.getParameterTypes(((MethodInsnNode)instructions[i]).desc).size();
if (((MethodInsnNode)instructions[i]).name.equals(ConstPool.CONSTRUCTOR)) {
// constructor implicitly eat 2 more stack and return 1 value
stackLevel++;
}
break;
case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE:
case Opcodes.INVOKEDYNAMIC:
// static and dynamic invoke implicitly return 1 value
stackLevel += (ClassUtil.getParameterTypes(((MethodInsnNode)instructions[i]).desc).size() - 1);
break;
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKEINTERFACE:
// virtual and interface invoke implicitly eat 1 more stack and return 1 more value, deuce
stackLevel += ClassUtil.getParameterTypes(((MethodInsnNode)instructions[i]).desc).size();
break;
case -1:
@ -179,6 +189,7 @@ public class SourceClassHandler extends BaseClassHandler {
mn.instructions.remove(instructions[end - 1]);
}
}
// method with @TestableMock will be modified as public access, so INVOKEVIRTUAL is used
mn.instructions.insertBefore(instructions[end], new MethodInsnNode(INVOKEVIRTUAL, testClassName,
substitutionMethod, addFirstParameter(method.desc, ClassUtil.fitCompanionClassName(ownerClass)), false));
mn.instructions.remove(instructions[end]);

View File

@ -51,14 +51,14 @@ public class BytecodeUtil {
put(FSTORE, -1);
put(DSTORE, -1);
put(ASTORE, -1);
put(IASTORE, -1);
put(LASTORE, -1);
put(FASTORE, -1);
put(DASTORE, -1);
put(AASTORE, -1);
put(BASTORE, -1);
put(CASTORE, -1);
put(SASTORE, -1);
put(IASTORE, -3);
put(LASTORE, -3);
put(FASTORE, -3);
put(DASTORE, -3);
put(AASTORE, -3);
put(BASTORE, -3);
put(CASTORE, -3);
put(SASTORE, -3);
put(POP, -1);
put(POP2, -2);
put(DUP, 1);