codec-jvm
codec-jvm copied to clipboard
StackMapTable error: bad offset
Following is the code:
stack1Class :: ClassFile
stack1Class =
mkClassFile
java8
[]
"Stack1"
Nothing
[]
[]
[ mkMethodDef
"Stack1"
[Public, Static]
"main"
[arr . obj $ "java/lang/String"]
void $
fold
[ iconst jint 3
, gstore jint 1
, gload jint 1
, iconst jint 2
, if_icmpne
(fold $
[ getstatic systemOut
, bipush jint 42
, invokevirtual printlnI
, vreturn
])
(fold $
[ getstatic systemOut
, bipush jint 43
, invokevirtual printlnI
, vreturn
])
]
]
where
systemOut = mkFieldRef "java/lang/System" "out" (obj "java/io/PrintStream")
printlnI = mkMethodRef "java/io/PrintStream" "println" [prim JInt] void
On execution of the class file it generates, it will give this error:
@sibi::jane { ~/github/codec-jvm }-> java Stack1
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: StackMapTable error: bad offset
Exception Details:
Location:
Stack1.main([Ljava/lang/String;)V @0: iconst_3
Reason:
Invalid stackmap specification.
Current Frame:
bci: @25
flags: { }
locals: { '[Ljava/lang/String;', integer }
stack: { }
Bytecode:
0x0000000: 063c 1b05 a000 0cb2 0007 102b b600 0fb1
0x0000010: b200 0710 2ab6 000f b1
Stackmap Table:
append_frame(@16,Integer)
same_frame(@25)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
This is the bytecode generated for the main method (which to my naive eyes appear valid):
Code:
stack=2, locals=2, args_size=1
0: iconst_3
1: istore_1
2: iload_1
3: iconst_2
4: if_icmpne 16
7: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
10: bipush 43
12: invokevirtual #15 // Method java/io/PrintStream.println:(I)V
15: return
16: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
19: bipush 42
21: invokevirtual #15 // Method java/io/PrintStream.println:(I)V
24: return
Replace return in bci 15 with a goto solves the problem. But I think the above instruction should also work.