diff --git a/test/bytecode_2.7/03_if_vs_and.pyc b/test/bytecode_2.7/03_if_vs_and.pyc new file mode 100644 index 00000000..f699eeff Binary files /dev/null and b/test/bytecode_2.7/03_if_vs_and.pyc differ diff --git a/test/bytecode_2.7/05_while_if_return.pyc-notyet b/test/bytecode_2.7/05_while_if_return.pyc similarity index 100% rename from test/bytecode_2.7/05_while_if_return.pyc-notyet rename to test/bytecode_2.7/05_while_if_return.pyc diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index c19d365b..75b7822e 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -130,6 +130,10 @@ class Python27Parser(Python2Parser): whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK else_suitel COME_FROM + return_stmts ::= _stmts return_stmt + return_stmt ::= return + + ifstmt ::= testexpr return_stmts COME_FROM ifstmt ::= testexpr return_if_stmts COME_FROM ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index bcf23021..25b1c9cb 100644 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -958,17 +958,32 @@ class Scanner2(Scanner): 'end': end_offset}) elif code_pre_rtarget == self.opc.RETURN_VALUE: if self.version == 2.7 or pre_rtarget not in self.ignore_if: - # 10 is exception-match. If there is an exception match in the - # compare, then this is an exception clause not an if-then clause + # Below, 10 is exception-match. If there is an exception + # match in the compare, then this is an exception + # clause not an if-then clause if (self.code[self.prev[offset]] != self.opc.COMPARE_OP or self.code[self.prev[offset]+1] != 10): self.structs.append({'type': 'if-then', 'start': start, 'end': rtarget}) self.thens[start] = rtarget - if self.version == 2.7 or code[pre_rtarget+1] != self.opc.JUMP_FORWARD: + if (self.version == 2.7 or + code[pre_rtarget+1] != self.opc.JUMP_FORWARD): + # The below is a big hack until we get + # better control flow analysis: disallow + # END_IF if the instruction before the + # END_IF instruction happens to be a jump + # target. In this case, probably what's + # gone on is that we messed up on the + # END_IF location and it should be the + # instruction before. self.fixed_jumps[offset] = rtarget - self.return_end_ifs.add(pre_rtarget) + if (self.version == 2.7 and + self.insts[self.offset2inst_index[pre[pre_rtarget]]].is_jump_target): + self.return_end_ifs.add(pre[pre_rtarget]) + pass + else: + self.return_end_ifs.add(pre_rtarget) pass pass pass