diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 40c61c29..824db86a 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -66,6 +66,12 @@ class Scanner(object): # FIXME: This weird Python2 behavior is not Python3 self.resetTokenClass() + def opname_for_offset(self, offset): + return self.opc.opname[self.code[offset]] + + def op_name(self, op): + return self.opc.opname[op] + def is_jump_forward(self, offset): """ Return True if the code at offset is some sort of jump forward. diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index 0c69b7f8..1c9ae442 100644 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -164,7 +164,7 @@ class Scanner2(scan.Scanner): # continue # last_offset = jump_offset come_from_name = 'COME_FROM' - op_name = self.opc.opname[self.code[jump_offset]] + op_name = self.opname_for_offset(jump_offset) if op_name.startswith('SETUP_') and self.version == 2.7: come_from_type = op_name[len('SETUP_'):] if come_from_type not in ('LOOP', 'EXCEPT'): @@ -178,7 +178,7 @@ class Scanner2(scan.Scanner): pass op = self.code[offset] - op_name = self.opc.opname[op] + op_name = self.op_name(op) oparg = None; pattr = None has_arg = op_has_argument(op, self.opc) @@ -406,7 +406,7 @@ class Scanner2(scan.Scanner): while code[j] == self.opc.JUMP_ABSOLUTE: j = self.prev[j] if (self.version >= 2.3 and - self.opc.opname[code[j]] == 'LIST_APPEND'): # list comprehension + self.opname_for_offset(j) == 'LIST_APPEND'): # list comprehension stmts.remove(s) continue elif code[s] == self.opc.POP_TOP: @@ -844,7 +844,7 @@ class Scanner2(scan.Scanner): # is a jump to a SETUP_LOOP target. next_offset = target + self.op_size(self.code[target]) next_op = self.code[next_offset] - if self.opc.opname[next_op] == 'JUMP_FORWARD': + if self.op_name(next_op) == 'JUMP_FORWARD': jump_target = self.get_target(next_offset, next_op) if jump_target in self.setup_loops: self.structs.append({'type': 'while-loop', @@ -882,12 +882,12 @@ class Scanner2(scan.Scanner): # 39_0 COME_FROM 3 # 40 ... - if self.opc.opname[code[jump_if_offset]].startswith('JUMP_IF'): + if self.opname_for_offset(jump_if_offset).startswith('JUMP_IF'): jump_if_target = code[jump_if_offset+1] - if self.opc.opname[code[jump_if_target + jump_if_offset + 3]] == 'POP_TOP': + if self.opname_for_offset(jump_if_target + jump_if_offset + 3) == 'POP_TOP': jump_inst = jump_if_target + jump_if_offset jump_offset = code[jump_inst+1] - jump_op = self.opc.opname[code[jump_inst]] + jump_op = self.opname_for_offset(jump_inst) if (jump_op == 'JUMP_FORWARD' and jump_offset == 1): self.structs.append({'type': 'if-then', 'start': start-3, @@ -922,7 +922,7 @@ class Scanner2(scan.Scanner): # 256 if if_then_maybe and jump_op == 'JUMP_ABSOLUTE': jump_target = self.get_target(jump_inst, code[jump_inst]) - if self.opc.opname[code[end]] == 'JUMP_FORWARD': + if self.opname_for_offset(end) == 'JUMP_FORWARD': end_target = self.get_target(end, code[end]) if jump_target == end_target: self.structs.append(if_then_maybe) @@ -991,7 +991,7 @@ class Scanner2(scan.Scanner): oparg = self.get_argument(offset) if label is None: - if op in self.opc.hasjrel and self.opc.opname[op] != 'FOR_ITER': + if op in self.opc.hasjrel and self.op_name(op) != 'FOR_ITER': # if (op in self.opc.hasjrel and # (self.version < 2.0 or op != self.opc.FOR_ITER)): label = offset + 3 + oparg diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index a74a041b..60b6ee19 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -133,9 +133,6 @@ class Scanner3(Scanner): # FIXME: remove the above in favor of: # self.varargs_ops = frozenset(self.opc.hasvargs) - def opName(self, offset): - return self.opc.opname[self.code[offset]] - def ingest(self, co, classname=None, code_objects={}, show_asm=None): """ Pick out tokens from an uncompyle6 code object, and transform them, @@ -219,7 +216,7 @@ class Scanner3(Scanner): # "loop" tag last so the grammar rule matches that properly. for jump_offset in sorted(jump_targets[inst.offset], reverse=True): come_from_name = 'COME_FROM' - opname = self.opName(jump_offset) + opname = self.opname_for_offset(jump_offset) if opname.startswith('SETUP_'): come_from_type = opname[len('SETUP_'):] come_from_name = 'COME_FROM_%s' % come_from_type @@ -902,6 +899,14 @@ class Scanner3(Scanner): target = self.get_target(offset) end = self.restrict_to_parent(target, parent) self.fixed_jumps[offset] = end + elif op == self.opc.POP_EXCEPT: + if self.version <= 3.5: + next_offset = offset+1 + else: + next_offset = offset+2 + target = self.get_target(next_offset) + if target > next_offset: + self.fixed_jumps[next_offset] = target elif op == self.opc.SETUP_FINALLY: target = self.get_target(offset) end = self.restrict_to_parent(target, parent) diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index e699477d..31488128 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -331,18 +331,22 @@ def cmp_code_objects(version, is_pypy, code_obj1, code_obj2, raise CmpErrorCode(name, tokens1[i1].offset, tokens1[i1], tokens2[i2], tokens1, tokens2) elif tokens1[i1].type in JUMP_OPs and tokens1[i1].pattr != tokens2[i2].pattr: - dest1 = int(tokens1[i1].pattr) - dest2 = int(tokens2[i2].pattr) if tokens1[i1].type == 'JUMP_BACK': + dest1 = int(tokens1[i1].pattr) + dest2 = int(tokens2[i2].pattr) if offset_map[dest1] != dest2: raise CmpErrorCode(name, tokens1[i1].offset, tokens1[i1], tokens2[i2], tokens1, tokens2) else: # import pdb; pdb.set_trace() - if dest1 in check_jumps: - check_jumps[dest1].append((i1, i2, dest2)) - else: - check_jumps[dest1] = [(i1, i2, dest2)] + try: + dest1 = int(tokens1[i1].pattr) + if dest1 in check_jumps: + check_jumps[dest1].append((i1, i2, dest2)) + else: + check_jumps[dest1] = [(i1, i2, dest2)] + except: + pass i1 += 1 i2 += 1