diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 824db86a..67ab4dbf 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -226,6 +226,9 @@ class Scanner(object): yield start start += self.op_size(self.code[start]) + def next_offset(self, op, offset): + return offset + self.op_size(op) + def op_size(self, op): """ Return size of operator with its arguments diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index e347bb6b..3f0f751c 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -135,9 +135,6 @@ class Scanner3(Scanner): # FIXME: remove the above in favor of: # self.varargs_ops = frozenset(self.opc.hasvargs) - def next_offset(self, op, offset): - return offset + self.op_size(op) - def ingest(self, co, classname=None, code_objects={}, show_asm=None): """ Pick out tokens from an uncompyle6 code object, and transform them, diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index b97c61b8..8f294182 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -519,6 +519,25 @@ class SourceWalker(GenericASTTraversal, object): node == AST('return_stmt', [AST('ret_expr', [NONE]), Token('RETURN_VALUE')])) + def n_continue_stmt(self, node): + if node[0] == 'CONTINUE': + t = node[0] + if not t.linestart: + # Artificially-added "continue" statements derived from JUMP_ABSOLUTE + # don't have line numbers associated with them. + # If this is a CONTINUE is to the same target as a JUMP_ABSOLUTE following it, + # then the "continue" can be suppressed. + op, offset = t.op, t.offset + next_offset = self.scanner.next_offset(op, offset) + scanner = self.scanner + code = scanner.code + next_inst = code[next_offset] + if (scanner.opc.opname[next_inst] == 'JUMP_ABSOLUTE' + and t.pattr == code[next_offset+1]): + # Suppress "continue" + self.prune() + self.default(node) + def n_return_stmt(self, node): if self.params['isLambda']: self.preorder(node[0])