From 05db6194ec89f54d6c36858683ef17d9e974512f Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 23 Apr 2019 05:14:29 -0400 Subject: [PATCH] Use up right 3.x opcodes in jump detection... A small but pervasive, and I guess important change. More correct COME_FROMs are now coming out. A number of grammar changes then in 3.0, 3.5, and 3.8 --- uncompyle6/parsers/parse30.py | 25 +++++++++++++------------ uncompyle6/parsers/parse35.py | 4 ++-- uncompyle6/parsers/parse38.py | 9 ++++++--- uncompyle6/scanners/scanner3.py | 4 ++-- uncompyle6/semantics/customize38.py | 4 ++++ uncompyle6/semantics/pysource.py | 2 +- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/uncompyle6/parsers/parse30.py b/uncompyle6/parsers/parse30.py index 8d1365bc..327849a0 100644 --- a/uncompyle6/parsers/parse30.py +++ b/uncompyle6/parsers/parse30.py @@ -12,8 +12,8 @@ class Python30Parser(Python31Parser): def p_30(self, args): """ - assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 POP_TOP - return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP + assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 COME_FROM POP_TOP + return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM POP_TOP compare_chained2 ::= expr COMPARE_OP RETURN_END_IF_LAMBDA # FIXME: combine with parse3.2 @@ -28,10 +28,10 @@ class Python30Parser(Python31Parser): # instructions _ifstmts_jump ::= c_stmts JUMP_FORWARD _come_froms POP_TOP COME_FROM - _ifstmts_jump ::= c_stmts POP_TOP + _ifstmts_jump ::= c_stmts COME_FROM POP_TOP # Used to keep index order the same in semantic actions - jb_pop_top ::= JUMP_BACK POP_TOP + jb_pop_top ::= JUMP_BACK COME_FROM POP_TOP while1stmt ::= SETUP_LOOP l_stmts COME_FROM_LOOP whileelsestmt ::= SETUP_LOOP testexpr l_stmts @@ -45,7 +45,7 @@ class Python30Parser(Python31Parser): ifelsestmtl ::= testexpr c_stmts_opt jb_pop_top else_suitel iflaststmtl ::= testexpr c_stmts_opt jb_pop_top - iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE POP_TOP + iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE COME_FROM POP_TOP withasstmt ::= expr setupwithas store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_FINALLY @@ -78,17 +78,18 @@ class Python30Parser(Python31Parser): # JUMP_IF_TRUE POP_TOP as a replacement comp_if ::= expr jmp_false comp_iter - comp_if ::= expr jmp_false comp_iter JUMP_BACK POP_TOP - comp_if_not ::= expr jmp_true comp_iter JUMP_BACK POP_TOP + comp_if ::= expr jmp_false comp_iter JUMP_BACK COME_FROM POP_TOP + comp_if_not ::= expr jmp_true comp_iter JUMP_BACK COME_FROM POP_TOP comp_iter ::= expr expr SET_ADD comp_iter ::= expr expr LIST_APPEND - jump_forward_else ::= JUMP_FORWARD POP_TOP - jump_absolute_else ::= JUMP_ABSOLUTE POP_TOP + jump_forward_else ::= JUMP_FORWARD COME_FROM POP_TOP + jump_absolute_else ::= JUMP_ABSOLUTE COME_FROM POP_TOP except_suite ::= c_stmts POP_EXCEPT jump_except POP_TOP except_suite_finalize ::= SETUP_FINALLY c_stmts_opt except_var_finalize END_FINALLY - _jump POP_TOP - jump_except ::= JUMP_FORWARD POP_TOP + _jump COME_FROM POP_TOP + jump_except ::= JUMP_FORWARD COME_FROM POP_TOP + jump_except ::= JUMP_ABSOLUTE COME_FROM POP_TOP or ::= expr jmp_false expr jmp_true expr or ::= expr jmp_true expr @@ -110,7 +111,7 @@ class Python30Parser(Python31Parser): return_if_stmt ::= ret_expr RETURN_END_IF POP_TOP and ::= expr jmp_false expr come_from_opt whilestmt ::= SETUP_LOOP testexpr l_stmts_opt come_from_opt - JUMP_BACK POP_TOP POP_BLOCK COME_FROM_LOOP + JUMP_BACK COME_FROM POP_TOP POP_BLOCK COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK COME_FROM_LOOP diff --git a/uncompyle6/parsers/parse35.py b/uncompyle6/parsers/parse35.py index d7c66781..c6f8ccec 100644 --- a/uncompyle6/parsers/parse35.py +++ b/uncompyle6/parsers/parse35.py @@ -167,7 +167,7 @@ class Python35Parser(Python34Parser): async_with_stmt ::= expr BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST + POP_BLOCK LOAD_CONST COME_FROM_ASYNC_WITH WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_FINISH END_FINALLY @@ -177,7 +177,7 @@ class Python35Parser(Python34Parser): async_with_as_stmt ::= expr BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH store suite_stmts_opt - POP_BLOCK LOAD_CONST + POP_BLOCK LOAD_CONST COME_FROM_ASYNC_WITH WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_FINISH END_FINALLY diff --git a/uncompyle6/parsers/parse38.py b/uncompyle6/parsers/parse38.py index 7a8398e0..f6a2c0d5 100644 --- a/uncompyle6/parsers/parse38.py +++ b/uncompyle6/parsers/parse38.py @@ -73,7 +73,7 @@ class Python38Parser(Python37Parser): SETUP_ASYNC_WITH POP_TOP suite_stmts POP_TOP POP_BLOCK - BEGIN_FINALLY + BEGIN_FINALLY COME_FROM_ASYNC_WITH WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_FINISH END_FINALLY @@ -82,7 +82,7 @@ class Python38Parser(Python37Parser): SETUP_ASYNC_WITH store suite_stmts POP_TOP POP_BLOCK - BEGIN_FINALLY + BEGIN_FINALLY COME_FROM_ASYNC_WITH WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM WITH_CLEANUP_FINISH END_FINALLY @@ -124,8 +124,11 @@ class Python38Parser(Python37Parser): try_except_ret38 ::= SETUP_FINALLY expr POP_BLOCK RETURN_VALUE except_ret38a + # Note: there is a suite_stmts_opt which seems + # to be bookkeeping which is not expressed in source code except_ret38 ::= SETUP_FINALLY expr ROT_FOUR POP_BLOCK POP_EXCEPT - CALL_FINALLY RETURN_VALUE COME_FROM_FINALLY + CALL_FINALLY RETURN_VALUE COME_FROM + COME_FROM_FINALLY suite_stmts_opt END_FINALLY except_ret38a ::= COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP expr ROT_FOUR diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 8da10a2d..9e24bdd8 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -502,9 +502,9 @@ class Scanner3(Scanner): next_offset = xdis.next_offset(op, self.opc, offset) if label is None: - if op in op3.hasjrel and op != self.opc.FOR_ITER: + if op in self.opc.hasjrel and op != self.opc.FOR_ITER: label = next_offset + oparg - elif op in op3.hasjabs: + elif op in self.opc.hasjabs: if op in self.jump_if_pop: if oparg > offset: label = oparg diff --git a/uncompyle6/semantics/customize38.py b/uncompyle6/semantics/customize38.py index 472851d6..aa46e396 100644 --- a/uncompyle6/semantics/customize38.py +++ b/uncompyle6/semantics/customize38.py @@ -54,7 +54,11 @@ def customize_for_version38(self, version): 'except_ret38a': ( 'return %c', (4, 'expr') ), + + # Note: there is a suite_stmts_opt which seems + # to be bookkeeping which is not expressed in source code 'except_ret38': ( '%|return %c\n', (1, 'expr') ), + 'for38': ( '%|for %c in %c:\n%+%c%-\n\n', (2, 'store'), diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 144032e5..6f9e22e2 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1081,7 +1081,7 @@ class SourceWalker(GenericASTTraversal, object): n = (k[3], k[1]) pass elif k == 'comp_iter': - n = k[1] + n = k[0] pass pass else: