public void emitShrinkedInitMethod(InstrumentClass cv, int splitPos, Frame f, FrameInfo fi, MethodInsnNode invokedInitInsn)
throws InternalError {
String desc = buildShrinkedInitMethodDesc(mn.desc);
String[] exps = MethodDatabase.toStringArray(mn.exceptions);
MethodVisitor cmv = cv.makeOutMV(mn.access, "<init>", desc, null, exps);
cmv.visitCode();
for (int i = 0; i < splitPos -1; i++) {
mn.instructions.get(i).accept(cmv);
}
if (invokedInitInsn != null) {
if (db.checkMethodSuspendType(invokedInitInsn.owner, ClassEntry.key(invokedInitInsn.name, invokedInitInsn.desc), false, false) == MethodDatabase.SUSPEND_NORMAL) {
Type[] tps = Type.getArgumentTypes(invokedInitInsn.desc);
Type[] ntps = new Type[tps.length + 1];
System.arraycopy(tps, 0, ntps, 0, tps.length);
ntps[tps.length] = Type.getType(CheckInstrumentationVisitor.EXCEPTION_DESC);
cmv.visitInsn(Opcodes.ACONST_NULL);
cmv.visitMethodInsn(invokedInitInsn.getOpcode(), invokedInitInsn.owner,invokedInitInsn.name, Type.getMethodDescriptor(Type.VOID_TYPE, ntps));
}else {
invokedInitInsn.accept(cmv);
}
}
cmv.visitMethodInsn(Opcodes.INVOKESTATIC, CSTACK_NAME, "getStack", "()L"+CSTACK_NAME+";");
cmv.visitVarInsn(Opcodes.ASTORE, lvarCStack);
cmv.visitVarInsn(Opcodes.ALOAD,lvarCStack);
emitConst(cmv, fi.numSlots);
cmv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CSTACK_NAME, "incRefsAndReserveSpace", "(I)V");
for (int i = f.getStackSize(); i-->0 ;) {
BasicValue v = (BasicValue) f.getStack(i);
if(!isOmitted(v)) {
if(!isNullType(v)) {
int slotIdx = fi.stackSlotIndices[i];
assert slotIdx >= 0 && slotIdx < fi.numSlots;
emitStoreValue(cmv, v, lvarCStack, slotIdx);
} else {
db.trace("NULL stack entry: type=%s size=%d", v.getType(), v.getSize());
cmv.visitInsn(Opcodes.POP);
}
}
}
for(int i=firstLocal; i < f.getLocals() ; i++) {
BasicValue v = (BasicValue) f.getLocal(i);
if(!isNullType(v)) {
cmv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), i);
int slotIdx = fi.localSlotIndices[i];
assert slotIdx >= 0 && slotIdx < fi.numSlots;
emitStoreValue(cmv, v, lvarCStack, slotIdx);
}
}
if(mn.localVariables != null) {
for(LocalVariableNode var : mn.localVariables) {
if (invokedInitInsn != null) {
if (mn.instructions.indexOf(var.start) <= splitPos) {
var.accept(cmv);
}
}else if (var.start.getPrevious() == null) {
var.accept(cmv);
}
}
}
cmv.visitInsn(Opcodes.RETURN);
cmv.visitMaxs(mn.maxStack+3, mn.maxLocals+3);
cmv.visitEnd();
}