{
Label frameLabel= labels.get(i);
mv.visitLabel(restoreLabels[i]);
MethodInsnNode mnode= nodes.get(i);
Frame frame= analyzer.getFrames()[canalyzer.getIndex(mnode)];
// for each local variable store the value in locals popping it from the stack!
// locals
int lsize= frame.getLocals();
for (int j= lsize - 1; j >= 0; j--)
{
BasicValue value= (BasicValue) frame.getLocal(j);
if (isNull(value))
{
mv.visitInsn(ACONST_NULL);
mv.visitVarInsn(ASTORE, j);
}
else if (value == BasicValue.UNINITIALIZED_VALUE)
{
// TODO ??
}
else if (value == BasicValue.RETURNADDRESS_VALUE)
{
// TODO ??
}
else
{
mv.visitVarInsn(ALOAD, stackRecorderVar);
Type type= value.getType();
if (value.isReference())
{
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object", "()Ljava/lang/Object;", false);
Type t= value.getType();
String desc= t.getDescriptor();
if (desc.charAt(0) == '[')
{
mv.visitTypeInsn(CHECKCAST, desc);
}
else
{
mv.visitTypeInsn(CHECKCAST, t.getInternalName());
}
mv.visitVarInsn(ASTORE, j);
}
else
{
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type), "()" + type.getDescriptor(), false);
mv.visitVarInsn(type.getOpcode(ISTORE), j);
}
}
}
if (frame instanceof MonitoringFrame)
{
int[] monitoredLocals= ((MonitoringFrame) frame).getMonitored();
// System.out.println(System.identityHashCode(frame)+" AMonitored locals "+monitoredLocals.length);
for (int monitoredLocal : monitoredLocals)
{
// System.out.println(System.identityHashCode(frame)+" AMonitored local "+monitoredLocals[j]);
mv.visitVarInsn(ALOAD, monitoredLocal);
mv.visitInsn(MONITORENTER);
}
}
// stack
int argSize= Type.getArgumentTypes(mnode.desc).length;
int ownerSize= mnode.getOpcode() == INVOKESTATIC ? 0 : 1; // TODO
int initSize= mnode.name.equals("<init>") ? 2 : 0;
int ssize= frame.getStackSize();
for (int j= 0; j < ssize - argSize - ownerSize - initSize; j++)
{
BasicValue value= (BasicValue) frame.getStack(j);
if (isNull(value))
{
mv.visitInsn(ACONST_NULL);
}
else if (value == BasicValue.UNINITIALIZED_VALUE)
{
// TODO ??
}
else if (value == BasicValue.RETURNADDRESS_VALUE)
{
// TODO ??
}
else if (value.isReference())
{
mv.visitVarInsn(ALOAD, stackRecorderVar);
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object", "()Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());
}
else
{
Type type= value.getType();
mv.visitVarInsn(ALOAD, stackRecorderVar);
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type), "()" + type.getDescriptor(), false);
}
}
boolean hasMethodRef= false;
if (mnode.getOpcode() != INVOKESTATIC)
{
// Load the object whose method we are calling
BasicValue value= ((BasicValue) frame.getStack(ssize - argSize - 1));
if (isNull(value))
{
// If user code causes NPE, then we keep this behavior: load null to get NPE at runtime
mv.visitInsn(ACONST_NULL);
}