Expression statement inside a loop throws incompatible stack heights AnalyzerException
patiences opened this issue · comments
Python program:
for i in range(10):
"abc" == "def"
Exception from ASM:
org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 67: Incompatible stack heights
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source)
at org.objectweb.asm.util.CheckClassAdapter.verify(Unknown Source)
at org.objectweb.asm.util.CheckClassAdapter.verify(Unknown Source)
at org.objectweb.asm.util.CheckClassAdapter.main(Unknown Source)
Caused by: org.objectweb.asm.tree.analysis.AnalyzerException: Incompatible stack heights
at org.objectweb.asm.tree.analysis.Frame.merge(Unknown Source)
at org.objectweb.asm.tree.analysis.Analyzer.merge(Unknown Source)
... 4 more
module$import()V
00000 example . . . : : ACONST_NULL
00001 example . . . : Lnull; : ASTORE 1
00002 example Lnull; . . : : ACONST_NULL
00003 example Lnull; . . : Lnull; : ASTORE 2
00004 example Lnull; Lnull; . : : ACONST_NULL
00005 example Lnull; Lnull; . : Lnull; : ASTORE 3
00006 example Lnull; Lnull; Lnull; : : GETSTATIC python/sys.modules : Lorg/python/types/Dict;
00007 example Lnull; Lnull; Lnull; : Dict : NEW org/python/types/Str
00008 example Lnull; Lnull; Lnull; : Dict Str : DUP
00009 example Lnull; Lnull; Lnull; : Dict Str Str : LDC "example"
00010 example Lnull; Lnull; Lnull; : Dict Str Str String : INVOKESPECIAL org/python/types/Str.<init> (Ljava/lang/String;)V
00011 example Lnull; Lnull; Lnull; : Dict Str : INVOKEINTERFACE org/python/Object.__getitem__ (Lorg/python/Object;)Lorg/python/Object;
00012 example Lnull; Lnull; Lnull; : Object : CHECKCAST org/python/types/Module
00013 example Lnull; Lnull; Lnull; : Module : ASTORE 1
00014 example Module Lnull; Lnull; : : ALOAD 1
00015 example Module Lnull; Lnull; : Module : LDC "range"
00016 example Module Lnull; Lnull; : Module String : INVOKEINTERFACE org/python/Object.__getattribute__ (Ljava/lang/String;)Lorg/python/Object;
00017 example Module Lnull; Lnull; : Object : CHECKCAST org/python/Callable
00018 example Module Lnull; Lnull; : Callable : ICONST_1
00019 example Module Lnull; Lnull; : Callable I : ANEWARRAY org/python/Object
00020 example Module Lnull; Lnull; : Callable Object : DUP
00021 example Module Lnull; Lnull; : Callable Object Object : ICONST_0
00022 example Module Lnull; Lnull; : Callable Object Object I : LDC 10
00023 example Module Lnull; Lnull; : Callable Object Object I J : INVOKESTATIC org/python/types/Int.getInt (J)Lorg/python/types/Int;
00024 example Module Lnull; Lnull; : Callable Object Object I Int : AASTORE
00025 example Module Lnull; Lnull; : Callable Object : NEW java/util/HashMap
00026 example Module Lnull; Lnull; : Callable Object HashMap : DUP
00027 example Module Lnull; Lnull; : Callable Object HashMap HashMap : INVOKESPECIAL java/util/HashMap.<init> ()V
00028 example Module Lnull; Lnull; : Callable Object HashMap : INVOKEINTERFACE org/python/Callable.invoke ([Lorg/python/Object;Ljava/util/Map;)Lorg/python/Object;
00029 example Module Lnull; Lnull; : Object : INVOKEINTERFACE org/python/Object.__iter__ ()Lorg/python/Object;
00030 example Module Lnull; Lnull; : Object : ICONST_1
00031 example Module Lnull; Lnull; : Object I : ISTORE 2
00032 example Module I Lnull; : Object : ASTORE 3
00033 example Module I Object : : ALOAD 1
00034 example Module I Object : Module : ALOAD 3
00035 example Module I Object : Module Object : LDC "#for-iter-10d8fbf28"
00036 example Module I Object : Module Object String : SWAP
00037 example Module I Object : Module String Object : INVOKEINTERFACE org/python/Object.__setattr__ (Ljava/lang/String;Lorg/python/Object;)V
00038 example Module I Object : : L0
00039 example Module I Object : : ALOAD 1
00040 example Module I Object : Module : LDC "#for-iter-10d8fbf28"
00041 example Module I Object : Module String : INVOKEINTERFACE org/python/Object.__getattribute__ (Ljava/lang/String;)Lorg/python/Object;
00042 example Module I Object : Object : INVOKEINTERFACE org/python/Object.__next__ ()Lorg/python/Object;
00043 example Module I Object : Object : L1
00044 example Module I Object : Object : GOTO L2
00045 example Module I Object : StopIteration : L3
00046 example Module I Object : StopIteration : POP
00047 example Module I Object : : GOTO L4
00048 example Module I Object : Object : L2
00049 example Module I Object : Object : ASTORE 3
00050 example Module I Object : : ALOAD 1
00051 example Module I Object : Module : ALOAD 3
00052 example Module I Object : Module Object : LDC "i"
00053 example Module I Object : Module Object String : SWAP
00054 example Module I Object : Module String Object : INVOKEINTERFACE org/python/Object.__setattr__ (Ljava/lang/String;Lorg/python/Object;)V
00055 example Module I Object : : NEW org/python/types/Str
00056 example Module I Object : Str : DUP
00057 example Module I Object : Str Str : LDC "abc"
00058 example Module I Object : Str Str String : INVOKESPECIAL org/python/types/Str.<init> (Ljava/lang/String;)V
00059 example Module I Object : Str : NEW org/python/types/Str
00060 example Module I Object : Str Str : DUP
00061 example Module I Object : Str Str Str : LDC "def"
00062 example Module I Object : Str Str Str String : INVOKESPECIAL org/python/types/Str.<init> (Ljava/lang/String;)V
00063 example Module I Object : Str Str : LDC "=="
00064 example Module I Object : Str Str String : LDC "__eq__"
00065 example Module I Object : Str Str String String : LDC "__eq__"
00066 example Module I Object : Str Str String String String : INVOKESTATIC org/python/types/Object.__cmp__ (Lorg/python/Object;Lorg/python/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/python/Object;
00067 example Module I Object : Object : GOTO L0
00068 example Module I Object : : L4
00069 example Module I Object : : ALOAD 1
00070 example Module I Object : Module : LDC "#for-iter-10d8fbf28"
00071 example Module I Object : Module String : INVOKEINTERFACE org/python/Object.__delattr__ (Ljava/lang/String;)V
00072 example Module I Object : : RETURN
TRYCATCHBLOCK L0 L1 L3 org/python/exceptions/StopIteration
@freakboy3742 The bug I mentioned to you yesterday seems to be related to this issue as well. It appears that not only for for-loop, expression statement in while-loop and try-catch suite will throw the same incompatible stack heights
error.
My gut feeling tells me that it has to do with this part of code in visit_Expr
:
# If the expression is a call, we need to ignore
# any return value from the function.
if isinstance(node.value, (ast.Call, ast.Attribute, ast.Str)):
self.context.add_opcodes(
JavaOpcodes.POP()
)
I removed the isinstance
check from the condition so it will always pop the expression off the stack and after that no more incompatible stack heights
error 😄 .
I'm currently running local test suite to see if this fix introduces any regression and submit a PR if all is well.
Merged, so closing! Thanks @BPYap!