I'm trying to generate a simple conditional Jump instruction. Here is the class:
public static Class<?> getKlass2(){
String className = "TestClass";
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classWriter.visit(V1_8, ACC_PUBLIC, className, null, getInternalName(Object.class), null);
MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC + ACC_STATIC, "m", "()Z",null, null);
Label trueLable = new Label();
Label afterFalseLable = new Label();
mv.visitFieldInsn(GETSTATIC, getInternalName(Boolean.class), "TRUE", "Ljava/lang/Boolean;");
mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(Boolean.class), "booleanValue", "()Z", false);
mv.visitJumpInsn(IFEQ, trueLable);
mv.visitInsn(ICONST_1);
mv.visitJumpInsn(GOTO, afterFalseLable);
mv.visitLabel(trueLable);
mv.visitInsn(ICONST_0);
mv.visitFrame(F_APPEND, 0, null, 0, null);
mv.visitLabel(afterFalseLable);
mv.visitInsn(IRETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
//converting classWriter.toByteArray() to Class<?> instance
}
When loading the class I got the following error:
Expecting a stackmap frame at branch target 13
Exception Details:
Location:
TestClass.m()Z @6: ifeq
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: b200 0cb6 000f 9900 0704 a700 0403 ac
Stackmap Table:
same_frame_extended(@14)
But the code of the class seems ok to me:
public class TestClass {
public static boolean m();
Code:
0: getstatic #12 // Field java/lang/Boolean.TRUE:Ljava/lang/Boolean;
3: invokevirtual #15 // Method java/lang/Boolean.booleanValue:()Z
6: ifeq 13
9: iconst_1
10: goto 14
13: iconst_0
14: ireturn
}
So I tried to add a frame by hand:
mv.visitFrame(F_APPEND, 0, new Object[]{ }, 0, new Object[]{ });
But it also failed with the same exception. Do they expect to recreate a frame with the same operand stack? But this seems non-sense since I cannot get a direct access to opearand stack from Java code.
What did I do wrong?
Aucun commentaire:
Enregistrer un commentaire