From 815ae2c5cdee3abb7441aef21ca7a34149faade3 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 6 Jul 2020 18:38:14 -0400 Subject: [PATCH] for/else detection for older 2.x Pythons --- .../bytecode_2.4_run/01_for_else_try_else.pyc | Bin 0 -> 546 bytes uncompyle6/parsers/parse26.py | 31 +++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 test/bytecode_2.4_run/01_for_else_try_else.pyc diff --git a/test/bytecode_2.4_run/01_for_else_try_else.pyc b/test/bytecode_2.4_run/01_for_else_try_else.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50f2fbe1ec26bb5eb7164df4bc3849e10a9c9ae8 GIT binary patch literal 546 zcmZutO-sW-5S>ZdrY+Tj;H3wtw}2nD=v_s7W_R8s|JrD-K0}ql&r_lA8HF1XWB~Vs2p>ccG(r}^J7EY<0n8#mAHWI$ zS*eRs`A2DpQvIW3HR#7p9<@VoJ29>^v*p+h^A1s`r=x>(qSI$njCWI{mVkooT~N4V zg4cam0$e_H;0;NbLV-E zkzzs&63%000)CH}Gx=<)l`H2q)!oPWxOdV$>Zws_m7Y4Syj=)6oGm=tb?LC+scwq^ zFoGI}*rJGnYEVJLRU>oRixGq3V6FU0xm%WyM%h6QOU*~5DwUO~QVCz=Hwn(2)7G1^ dxU#miF^>{)y;mZCfrV3Mu1-+HMyri&{01wiQ=|X@ literal 0 HcmV?d00001 diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 938e3b18..ac2a08e8 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -93,8 +93,8 @@ class Python26Parser(Python2Parser): cf_jb_cf_pop ::= _come_froms JUMP_BACK come_froms POP_TOP - bp_come_from ::= POP_BLOCK COME_FROM - jb_pb_come_from ::= JUMP_BACK bp_come_from + pb_come_from ::= POP_BLOCK COME_FROM + jb_pb_come_from ::= JUMP_BACK pb_come_from _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM @@ -148,7 +148,7 @@ class Python26Parser(Python2Parser): while1stmt ::= SETUP_LOOP l_stmts_opt CONTINUE _come_froms whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_froms - whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop bp_come_from + whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop pb_come_from whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop POP_BLOCK whilestmt ::= SETUP_LOOP testexpr returns POP_BLOCK COME_FROM @@ -412,11 +412,22 @@ class Python26Parser(Python2Parser): # for t in range(first, last): # print(tokens[t]) # print("=" * 30) - # FIXME: Figure out why this doesn't work on - # bytecode-1.4/anydbm.pyc - if self.version == 1.4: - return False - return tokens[last-1].off2int() > tokens[first].attr + + # If the SETUP_LOOP jumps to the tokens[last] then + # this is a "for" not a "for else". + + # However, in Python 2.2 and before there is a SET_LINENO + # instruction which might have gotten removed. So we need + # to account for that. bytecode-1.4/anydbm.pyc exhibits + # this behavior. + + # Also we need to use the setup_loop instruction (not opcode) + # since the operand can be a relative offset rather than + # an absolute offset. + setup_inst = self.insts[self.offset2inst_index[tokens[first].offset]] + if self.version <= 2.2 and tokens[last] == "COME_FROM": + last += 1 + return tokens[last-1].off2int() > setup_inst.argval elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")): for i in range(last-1, last-4, -1): t = tokens[i] @@ -434,10 +445,6 @@ class Python26Parser(Python2Parser): ja_attr = ast[4].attr return tokens[last].offset != ja_attr elif lhs == 'try_except': - # FIXME: Figure out why this doesn't work on - # bytecode-1.4/anydbm.pyc - if self.version == 1.4: - return False # We need to distingush try_except from tryelsestmt and we do that # by checking the jump before the END_FINALLY # If we have: