Like in #310, I am running against a JUMP_ABSOLUTE error with a piece of bytecode written in Python 2.7, using uncompyle6 3.9.0a1 (source code from GitHub, current master branch):
Code
```python
class Test():
elements = []
def test(self):
for element in Test.elements:
if element.a:
if element.b:
pass
else:
continue
if element.c:
print Hello
```
If pass is replaced with print Foo, the error changes to the line of LOAD_FAST associated to element of element.c.
It seems jumps pointers cache doesn't like this level of embedding inside condition blocks: if I move the instructions to a higher level, the problem vanishes.
For instance, this code is fine:
Code
```python
class Test():
elements = []
def test(self):
for element in Test.elements:
if element.a:
pass
else:
continue
if element.c:
print Hello
```
Description
Like in #310, I am running against a
JUMP_ABSOLUTE
error with a piece of bytecode written in Python 2.7, using uncompyle6 3.9.0a1 (source code from GitHub, current master branch):How to Reproduce
Code
```python class Test(): elements = [] def test(self): for element in Test.elements: if element.a: if element.b: pass else: continue if element.c: print Hello ```Output Given
Output
```console # uncompyle6 version 3.9.0a1 # Python bytecode version base 2.7 (62211) # Decompiled from: Python 3.9.2 (default, Feb 28 2021, 17:03:44) # [GCC 10.2.1 20210110] # Embedded file name: ./test.3.py # Compiled at: 2022-09-20 22:47:05 -- Stacks of completed symbols: START ::= |- stmts . _come_froms ::= \e__come_froms . COME_FROM _ifstmts_jump ::= \e_c_stmts_opt . JUMP_FORWARD come_froms _ifstmts_jump ::= \e_c_stmts_opt JUMP_FORWARD . come_froms _ifstmts_jump ::= c_stmts_opt . JUMP_FORWARD come_froms _stmts ::= _stmts . stmt _stmts ::= stmt . and ::= expr . JUMP_IF_FALSE_OR_POP expr COME_FROM and ::= expr . jmp_false expr \e_come_from_opt and ::= expr . jmp_false expr come_from_opt and ::= expr jmp_false . expr \e_come_from_opt and ::= expr jmp_false . expr come_from_opt and ::= expr jmp_false expr . come_from_opt and ::= expr jmp_false expr \e_come_from_opt . and ::= expr jmp_false expr come_from_opt . assert ::= assert_expr . jmp_true LOAD_ASSERT RAISE_VARARGS_1 assert2 ::= assert_expr . jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1 assert_expr ::= assert_expr_and . assert_expr ::= expr . assert_expr_and ::= assert_expr . jmp_false expr assert_expr_and ::= assert_expr jmp_false . expr assert_expr_and ::= assert_expr jmp_false expr . assert_expr_or ::= assert_expr . jmp_true expr assign ::= expr . DUP_TOP designList assign ::= expr . store assign2 ::= expr . expr ROT_TWO store store assign3 ::= expr . expr expr ROT_THREE ROT_TWO store store store attribute ::= expr . GET_ITER attribute ::= expr . LOAD_ATTR attribute ::= expr GET_ITER . attribute ::= expr LOAD_ATTR . aug_assign1 ::= expr . expr inplace_op ROT_FOUR STORE_SLICE+3 aug_assign1 ::= expr . expr inplace_op ROT_THREE STORE_SLICE+1 aug_assign1 ::= expr . expr inplace_op ROT_THREE STORE_SLICE+2 aug_assign1 ::= expr . expr inplace_op ROT_THREE STORE_SUBSCR aug_assign1 ::= expr . expr inplace_op ROT_TWO STORE_SLICE+0 aug_assign1 ::= expr . expr inplace_op store aug_assign2 ::= expr . DUP_TOP LOAD_ATTR expr inplace_op ROT_TWO STORE_ATTR bin_op ::= expr . expr binary_operator c_stmts ::= _stmts . c_stmts ::= _stmts . lastc_stmt c_stmts_opt ::= c_stmts . call ::= expr . CALL_FUNCTION_0 call_stmt ::= expr . POP_TOP classdefdeco1 ::= expr . classdefdeco1 CALL_FUNCTION_1 classdefdeco1 ::= expr . classdefdeco2 CALL_FUNCTION_1 come_from_opt ::= COME_FROM . come_froms ::= COME_FROM . come_froms ::= come_froms . COME_FROM compare_chained ::= expr . compare_chained1 ROT_TWO POP_TOP \e__come_froms compare_chained ::= expr . compare_chained1 ROT_TWO POP_TOP _come_froms compare_single ::= expr . expr COMPARE_OP continue ::= CONTINUE . continues ::= _stmts . lastl_stmt continue continues ::= _stmts lastl_stmt . continue continues ::= continue . delete ::= expr . DELETE_ATTR delete_subscript ::= expr . expr DELETE_SUBSCR else_suite ::= suite_stmts . expr ::= LOAD_FAST . expr ::= LOAD_GLOBAL . expr ::= and . expr ::= attribute . expr ::= get_iter . expr_jitop ::= expr . JUMP_IF_TRUE_OR_POP expr_jt ::= expr . jmp_true for ::= SETUP_LOOP . expr for_iter store for_block POP_BLOCK \e__come_froms for ::= SETUP_LOOP . expr for_iter store for_block POP_BLOCK _come_froms for ::= SETUP_LOOP expr . for_iter store for_block POP_BLOCK \e__come_froms for ::= SETUP_LOOP expr . for_iter store for_block POP_BLOCK _come_froms for ::= SETUP_LOOP expr for_iter . store for_block POP_BLOCK \e__come_froms for ::= SETUP_LOOP expr for_iter . store for_block POP_BLOCK _come_froms for ::= SETUP_LOOP expr for_iter store . for_block POP_BLOCK \e__come_froms for ::= SETUP_LOOP expr for_iter store . for_block POP_BLOCK _come_froms for_block ::= \e_l_stmts_opt . JUMP_BACK for_block ::= \e_l_stmts_opt . _come_froms JUMP_BACK for_block ::= \e_l_stmts_opt \e__come_froms . JUMP_BACK for_block ::= l_stmts_opt . JUMP_BACK for_block ::= l_stmts_opt . _come_froms JUMP_BACK for_block ::= l_stmts_opt \e__come_froms . JUMP_BACK for_iter ::= GET_ITER . COME_FROM FOR_ITER for_iter ::= GET_ITER . FOR_ITER for_iter ::= GET_ITER FOR_ITER . forelsestmt ::= SETUP_LOOP . expr for_iter store for_block POP_BLOCK else_suite \e__come_froms forelsestmt ::= SETUP_LOOP . expr for_iter store for_block POP_BLOCK else_suite _come_froms forelsestmt ::= SETUP_LOOP expr . for_iter store for_block POP_BLOCK else_suite \e__come_froms forelsestmt ::= SETUP_LOOP expr . for_iter store for_block POP_BLOCK else_suite _come_froms forelsestmt ::= SETUP_LOOP expr for_iter . store for_block POP_BLOCK else_suite \e__come_froms forelsestmt ::= SETUP_LOOP expr for_iter . store for_block POP_BLOCK else_suite _come_froms forelsestmt ::= SETUP_LOOP expr for_iter store . for_block POP_BLOCK else_suite \e__come_froms forelsestmt ::= SETUP_LOOP expr for_iter store . for_block POP_BLOCK else_suite _come_froms genexpr_func ::= LOAD_FAST . FOR_ITER store comp_iter JUMP_BACK get_iter ::= expr . GET_ITER get_iter ::= expr GET_ITER . if_exp ::= expr . jmp_false expr JUMP_ABSOLUTE expr if_exp ::= expr . jmp_false expr JUMP_FORWARD expr COME_FROM if_exp ::= expr jmp_false . expr JUMP_ABSOLUTE expr if_exp ::= expr jmp_false . expr JUMP_FORWARD expr COME_FROM if_exp ::= expr jmp_false expr . JUMP_ABSOLUTE expr if_exp ::= expr jmp_false expr . JUMP_FORWARD expr COME_FROM if_exp_lambda ::= expr . jmp_false expr return_if_lambda return_stmt_lambda LAMBDA_MARKER if_exp_lambda ::= expr jmp_false . expr return_if_lambda return_stmt_lambda LAMBDA_MARKER if_exp_lambda ::= expr jmp_false expr . return_if_lambda return_stmt_lambda LAMBDA_MARKER if_exp_not ::= expr . jmp_true expr _jump expr COME_FROM if_exp_not_lambda ::= expr . jmp_true expr return_if_lambda return_stmt_lambda LAMBDA_MARKER if_exp_true ::= expr . JUMP_FORWARD expr COME_FROM ifelsestmt ::= testexpr . c_stmts_opt JUMP_FORWARD else_suite come_froms ifelsestmt ::= testexpr \e_c_stmts_opt . JUMP_FORWARD else_suite come_froms ifelsestmt ::= testexpr \e_c_stmts_opt JUMP_FORWARD . else_suite come_froms ifelsestmt ::= testexpr \e_c_stmts_opt JUMP_FORWARD else_suite . come_froms ifelsestmt ::= testexpr \e_c_stmts_opt JUMP_FORWARD else_suite come_froms . ifelsestmt ::= testexpr c_stmts_opt . JUMP_FORWARD else_suite come_froms ifelsestmtl ::= testexpr . c_stmts_opt CONTINUE else_suitel ifelsestmtl ::= testexpr . c_stmts_opt JUMP_BACK else_suitel ifelsestmtl ::= testexpr \e_c_stmts_opt . CONTINUE else_suitel ifelsestmtl ::= testexpr \e_c_stmts_opt . JUMP_BACK else_suitel ifelsestmtl ::= testexpr c_stmts_opt . CONTINUE else_suitel ifelsestmtl ::= testexpr c_stmts_opt . JUMP_BACK else_suitel ifelsestmtr ::= testexpr . return_if_stmts COME_FROM returns iflaststmtl ::= testexpr . c_stmts iflaststmtl ::= testexpr . c_stmts_opt JUMP_BACK iflaststmtl ::= testexpr \e_c_stmts_opt . JUMP_BACK iflaststmtl ::= testexpr c_stmts . iflaststmtl ::= testexpr c_stmts_opt . JUMP_BACK ifstmt ::= testexpr . _ifstmts_jump ifstmt ::= testexpr . return_if_stmts COME_FROM ifstmt ::= testexpr . return_stmts COME_FROM jmp_false ::= POP_JUMP_IF_FALSE . l_stmts ::= _stmts . l_stmts ::= _stmts . lastl_stmt l_stmts ::= _stmts lastl_stmt . l_stmts_opt ::= l_stmts . lastl_stmt ::= iflaststmtl . mkfuncdeco ::= expr . mkfuncdeco CALL_FUNCTION_1 mkfuncdeco ::= expr . mkfuncdeco0 CALL_FUNCTION_1 print_items_nl_stmt ::= expr . PRINT_ITEM \e_print_items_opt PRINT_NEWLINE_CONT print_items_nl_stmt ::= expr . PRINT_ITEM print_items_opt PRINT_NEWLINE_CONT print_items_nl_stmt ::= expr PRINT_ITEM . print_items_opt PRINT_NEWLINE_CONT print_items_nl_stmt ::= expr PRINT_ITEM \e_print_items_opt . PRINT_NEWLINE_CONT print_items_nl_stmt ::= expr PRINT_ITEM \e_print_items_opt PRINT_NEWLINE_CONT . print_items_stmt ::= expr . PRINT_ITEM \e_print_items_opt print_items_stmt ::= expr . PRINT_ITEM print_items_opt print_items_stmt ::= expr PRINT_ITEM . print_items_opt print_items_stmt ::= expr PRINT_ITEM \e_print_items_opt . print_nl_to ::= expr . PRINT_NEWLINE_TO print_to ::= expr . print_to_items POP_TOP print_to_nl ::= expr . print_to_items PRINT_NEWLINE_TO raise_stmt1 ::= expr . RAISE_VARARGS_1 raise_stmt2 ::= expr . expr RAISE_VARARGS_2 raise_stmt3 ::= expr . expr expr RAISE_VARARGS_3 ret_and ::= expr . JUMP_IF_FALSE_OR_POP return_expr_or_cond COME_FROM ret_or ::= expr . JUMP_IF_TRUE_OR_POP return_expr_or_cond COME_FROM return ::= return_expr . RETURN_VALUE return_expr ::= expr . return_expr_lambda ::= return_expr . RETURN_VALUE_LAMBDA return_expr_lambda ::= return_expr . RETURN_VALUE_LAMBDA LAMBDA_MARKER return_if_stmt ::= return_expr . RETURN_END_IF return_if_stmts ::= _stmts . return_if_stmt return_stmts ::= _stmts . return_stmt returns ::= _stmts . return slice0 ::= expr . DUP_TOP SLICE+0 slice0 ::= expr . SLICE+0 slice1 ::= expr . expr DUP_TOPX_2 SLICE+1 slice1 ::= expr . expr SLICE+1 slice2 ::= expr . expr DUP_TOPX_2 SLICE+2 slice2 ::= expr . expr SLICE+2 slice3 ::= expr . expr expr DUP_TOPX_3 SLICE+3 slice3 ::= expr . expr expr SLICE+3 stmt ::= continue . stmt ::= ifelsestmt . stmt ::= print_items_nl_stmt . stmt ::= print_items_stmt . store ::= STORE_FAST . subscript ::= expr . expr BINARY_SUBSCR subscript2 ::= expr . expr DUP_TOPX_2 BINARY_SUBSCR suite_stmts ::= _stmts . suite_stmts ::= continues . testexpr ::= testfalse . testfalse ::= expr . jmp_false testfalse ::= expr jmp_false . testtrue ::= expr . jmp_true unary_convert ::= expr . UNARY_CONVERT unary_not ::= expr . UNARY_NOT unary_op ::= expr . unary_operator while1elsestmt ::= SETUP_LOOP . l_stmts JUMP_BACK POP_BLOCK else_suitel COME_FROM while1elsestmt ::= SETUP_LOOP . l_stmts JUMP_BACK else_suitel COME_FROM while1stmt ::= SETUP_LOOP . l_stmts_opt CONTINUE COME_FROM while1stmt ::= SETUP_LOOP . l_stmts_opt JUMP_BACK COME_FROM while1stmt ::= SETUP_LOOP . l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM while1stmt ::= SETUP_LOOP . returns COME_FROM while1stmt ::= SETUP_LOOP . returns pb_come_from while1stmt ::= SETUP_LOOP \e_l_stmts_opt . CONTINUE COME_FROM while1stmt ::= SETUP_LOOP \e_l_stmts_opt . JUMP_BACK COME_FROM while1stmt ::= SETUP_LOOP \e_l_stmts_opt . JUMP_BACK POP_BLOCK COME_FROM whileelsestmt ::= SETUP_LOOP . testexpr \e_l_stmts_opt JUMP_BACK POP_BLOCK else_suitel COME_FROM whileelsestmt ::= SETUP_LOOP . testexpr l_stmts_opt JUMP_BACK POP_BLOCK else_suitel COME_FROM whilestmt ::= SETUP_LOOP . testexpr \e_l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK \e__come_froms whilestmt ::= SETUP_LOOP . testexpr \e_l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK _come_froms whilestmt ::= SETUP_LOOP . testexpr \e_l_stmts_opt JUMP_BACK POP_BLOCK \e__come_froms whilestmt ::= SETUP_LOOP . testexpr \e_l_stmts_opt JUMP_BACK POP_BLOCK _come_froms whilestmt ::= SETUP_LOOP . testexpr l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK \e__come_froms whilestmt ::= SETUP_LOOP . testexpr l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK _come_froms whilestmt ::= SETUP_LOOP . testexpr l_stmts_opt JUMP_BACK POP_BLOCK \e__come_froms whilestmt ::= SETUP_LOOP . testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms whilestmt ::= SETUP_LOOP . testexpr returns \e__come_froms POP_BLOCK COME_FROM whilestmt ::= SETUP_LOOP . testexpr returns _come_froms POP_BLOCK COME_FROM with ::= expr . SETUP_WITH POP_TOP \e_suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY with ::= expr . SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY withasstmt ::= expr . SETUP_WITH store \e_suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY withasstmt ::= expr . SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY yield ::= expr . YIELD_VALUE Instruction context: L. 11 49 LOAD_GLOBAL 5 'Hello' 52 PRINT_ITEM 53 PRINT_NEWLINE_CONT -> 54 JUMP_ABSOLUTE 60 'to 60' 57 JUMP_BACK 10 'to 10' 60 JUMP_BACK 10 'to 10' 63 POP_BLOCK class Test: elements = [] def test--- This code section failed: --- L. 4 0 SETUP_LOOP 61 'to 64' 3 LOAD_GLOBAL 0 'Test' 6 LOAD_ATTR 1 'elements' 9 GET_ITER 10 FOR_ITER 50 'to 63' 13 STORE_FAST 1 'element' L. 5 16 LOAD_FAST 1 'element' 19 LOAD_ATTR 2 'a' 22 POP_JUMP_IF_FALSE 10 'to 10' L. 6 25 LOAD_FAST 1 'element' 28 LOAD_ATTR 3 'b' 31_0 COME_FROM 22 '22' 31 POP_JUMP_IF_FALSE 10 'to 10' L. 7 34 JUMP_FORWARD 3 'to 40' L. 9 37 CONTINUE 10 'to 10' 40_0 COME_FROM 34 '34' L. 10 40 LOAD_FAST 1 'element' 43 LOAD_ATTR 4 'c' 46 POP_JUMP_IF_FALSE 60 'to 60' L. 11 49 LOAD_GLOBAL 5 'Hello' 52 PRINT_ITEM 53 PRINT_NEWLINE_CONT 54 JUMP_ABSOLUTE 60 'to 60' 57 JUMP_BACK 10 'to 10' 60 JUMP_BACK 10 'to 10' 63 POP_BLOCK 64_0 COME_FROM 0 '0' Parse error at or near `JUMP_ABSOLUTE' instruction at offset 54 # file test.3.pyc # Deparsing stopped due to parse error ```Additional information
If
pass
is replaced withprint Foo
, the error changes to the line ofLOAD_FAST
associated toelement
ofelement.c
. It seems jumps pointers cache doesn't like this level of embedding inside condition blocks: if I move the instructions to a higher level, the problem vanishes. For instance, this code is fine:Code
```python class Test(): elements = [] def test(self): for element in Test.elements: if element.a: pass else: continue if element.c: print Hello ```which disassembles in:
Disassembly
``` 4: 0 SETUP_LOOP (to 52) 3 LOAD_GLOBAL (Test) 6 LOAD_ATTR (elements) 9 GET_ITER >> 10 FOR_ITER (to 51) 13 STORE_FAST (element) 5: 16 LOAD_FAST (element) 19 LOAD_ATTR (a) 22 POP_JUMP_IF_FALSE (to 10) 6: 25 JUMP_FORWARD (to 31) 8: 28 JUMP_ABSOLUTE (to 10) 9: >> 31 LOAD_FAST (element) 34 LOAD_ATTR (c) 37 POP_JUMP_IF_FALSE (to 10) 10: 40 LOAD_GLOBAL (Hello) 43 PRINT_ITEM 44 PRINT_NEWLINE 45 JUMP_ABSOLUTE (to 10) 48 JUMP_ABSOLUTE (to 10) >> 51 POP_BLOCK >> 52 LOAD_CONST (None) 55 RETURN_VALUE ```