From 597d51951e26596a17ffc55bb97b97545ad9ef0d Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 23 Jan 2017 02:32:09 -0500 Subject: [PATCH] Improve Python 2.6 & 2.7 verification --- uncompyle6/scanners/scanner2.py | 12 ++++++------ uncompyle6/scanners/scanner26.py | 28 ++++++++++++++++++---------- uncompyle6/verify.py | 10 ++++++++-- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index 34c0ee36..e508178e 100644 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -159,7 +159,6 @@ class Scanner2(scan.Scanner): # we sort them). That way, specific COME_FROM tags will match up # properly. For example, a "loop" with an "if" nested in it should have the # "loop" tag last so the grammar rule matches that properly. - # last_offset = -1 for jump_offset in sorted(jump_targets[offset], reverse=True): # if jump_offset == last_offset: # continue @@ -265,13 +264,14 @@ class Scanner2(scan.Scanner): # rule for that. target = self.get_target(offset) if target <= offset: + op_name = 'JUMP_BACK' if (offset in self.stmts and self.code[offset+3] not in (self.opc.END_FINALLY, - self.opc.POP_BLOCK) - and offset not in self.not_continue): - op_name = 'CONTINUE' - else: - op_name = 'JUMP_BACK' + self.opc.POP_BLOCK)): + if ((offset in self.linestartoffsets and + self.code[self.prev[offset]] == self.opc.JUMP_ABSOLUTE) + or offset not in self.not_continue): + op_name = 'CONTINUE' elif op == self.opc.LOAD_GLOBAL: if offset in self.load_asserts: diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index 9562e056..f649e739 100755 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -158,12 +158,15 @@ class Scanner26(scan.Scanner2): # we sort them). That way, specific COME_FROM tags will match up # properly. For example, a "loop" with an "if" nested in it should have the # "loop" tag last so the grammar rule matches that properly. + last_jump_offset = -1 for jump_offset in sorted(jump_targets[offset], reverse=True): - tokens.append(Token( - 'COME_FROM', None, repr(jump_offset), - offset="%s_%d" % (offset, jump_idx), - has_arg = True)) - jump_idx += 1 + if jump_offset != last_jump_offset: + tokens.append(Token( + 'COME_FROM', None, repr(jump_offset), + offset="%s_%d" % (offset, jump_idx), + has_arg = True)) + jump_idx += 1 + last_jump_offset = jump_offset elif offset in self.thens: tokens.append(Token( 'THEN', None, self.thens[offset], @@ -242,16 +245,21 @@ class Scanner26(scan.Scanner2): # boundaries The continue-type jumps help us get # "continue" statements with would otherwise be turned # into a "pass" statement because JUMPs are sometimes - # ignored in rules as just boundary overhead. + # ignored in rules as just boundary overhead. In + # comprehensions we might sometimes classify JUMP_BACK + # as CONTINUE, but that's okay since we add a grammar + # rule for that. target = self.get_target(offset) if target <= offset: + op_name = 'JUMP_BACK' if (offset in self.stmts and self.code[offset+3] not in (self.opc.END_FINALLY, - self.opc.POP_BLOCK) - and offset not in self.not_continue): - op_name = 'CONTINUE' + self.opc.POP_BLOCK)): + if ((offset in self.linestartoffsets and + tokens[-1].type == 'JUMP_BACK') + or offset not in self.not_continue): + op_name = 'CONTINUE' else: - op_name = 'JUMP_BACK' # FIXME: this is a hack to catch stuff like: # if x: continue # the "continue" is not on a new line. diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index 3a652b88..e699477d 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -318,8 +318,14 @@ def cmp_code_objects(version, is_pypy, code_obj1, code_obj2, elif tokens1[i1].type == 'LOAD_NAME' and tokens2[i2].type == 'LOAD_CONST' \ and tokens1[i1].pattr == 'None' and tokens2[i2].pattr is None: pass - elif tokens1[i1].type == 'RETURN_VALUE' and \ - tokens2[i2].type == 'RETURN_END_IF': + elif tokens1[i1].type == 'LOAD_GLOBAL' and tokens2[i2].type == 'LOAD_NAME' \ + and tokens1[i1].pattr == tokens2[i2].pattr: + pass + elif (tokens1[i1].type == 'RETURN_VALUE' and + tokens2[i2].type == 'RETURN_END_IF'): + pass + elif (tokens1[i1].type == 'BUILD_TUPLE_0' and + tokens2[i2].pattr == ()): pass else: raise CmpErrorCode(name, tokens1[i1].offset, tokens1[i1],