From 44e1288e2fdb49f1a518bd39026571b0f0a27bf2 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 13 May 2019 22:59:24 -0400 Subject: [PATCH 1/4] Less dishonest COME_FROMs Addresses all of the problems seen in 3.7 datetime.py. However we limit COME_FROMs only to forward jumps, not back (which in the case of Python code right now means looping) jumps. --- uncompyle6/parsers/parse36.py | 4 ++++ uncompyle6/scanners/scanner3.py | 8 +++++++- uncompyle6/semantics/pysource.py | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index f87da84b3..96a6a3766 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -33,6 +33,10 @@ def p_36misc(self, args): """ sstmt ::= sstmt RETURN_LAST + cf_for_iter ::= _come_froms FOR_ITER + list_for ::= expr cf_for_iter store list_iter jb_or_c + genexpr_func ::= LOAD_FAST cf_for_iter store comp_iter JUMP_BACK + # 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index eec5f43cf..a9d8d8af7 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -811,7 +811,13 @@ def detect_control_flow(self, offset, targets, inst_index): self.fixed_jumps[offset] = fix or match[-1] return else: - self.fixed_jumps[offset] = match[-1] + if self.version < 3.6: + # FIXME: this is putting in COME_FROMs in the wrong place. + # Fix up grammar so we don't need to do this. + # See cf_for_iter use in parser36.py + self.fixed_jumps[offset] = match[-1] + else: + self.fixed_jumps[offset] = target return # op == POP_JUMP_IF_TRUE else: diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index f11f1fdaf..5be529880 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1433,7 +1433,7 @@ def print_super_classes3(self, node): assert node[n].kind.startswith('CALL_FUNCTION') if node[n].kind.startswith('CALL_FUNCTION_KW'): - # 3.6+ starts does this + # 3.6+ starts doing this kwargs = node[n-1].attr assert isinstance(kwargs, tuple) i = n - (len(kwargs)+1) From 46acb7474520007ed055c6351e448e38068761c9 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 14 May 2019 06:28:29 -0400 Subject: [PATCH 2/4] Only add forward-jumping COME_FROM in 3.6+ Is this a repeat commit? --- uncompyle6/parsers/parse36.py | 4 ---- uncompyle6/scanners/scanner3.py | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 96a6a3766..f87da84b3 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -33,10 +33,6 @@ def p_36misc(self, args): """ sstmt ::= sstmt RETURN_LAST - cf_for_iter ::= _come_froms FOR_ITER - list_for ::= expr cf_for_iter store list_iter jb_or_c - genexpr_func ::= LOAD_FAST cf_for_iter store comp_iter JUMP_BACK - # 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index a9d8d8af7..9eeabc7c8 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -816,7 +816,8 @@ def detect_control_flow(self, offset, targets, inst_index): # Fix up grammar so we don't need to do this. # See cf_for_iter use in parser36.py self.fixed_jumps[offset] = match[-1] - else: + elif target > offset: + # Right now we only add COME_FROMs in forward (not loop) jumps self.fixed_jumps[offset] = target return # op == POP_JUMP_IF_TRUE From 9db446d92874fa68b5614fa1e2f46f53b22fec9d Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 14 May 2019 07:26:18 -0400 Subject: [PATCH 3/4] Another 3.7 chained comparison rule --- uncompyle6/parsers/parse37.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 1d2baa7ee..269ed980a 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -88,6 +88,7 @@ def p_37misc(self, args): compare_chained37 ::= expr compare_chained1a_37 compare_chained37 ::= expr compare_chained1b_37 + compare_chained37_false ::= expr compare_chained1_false_37 compare_chained37_false ::= expr compare_chained2_false_37 @@ -103,12 +104,15 @@ def p_37misc(self, args): compare_chained2a_false_37 ELSE POP_TOP JUMP_BACK COME_FROM compare_chained2a_37 ::= expr COMPARE_OP POP_JUMP_IF_TRUE JUMP_FORWARD - compare_chained2a_false_37 ::= expr COMPARE_OP POP_JUMP_IF_FALSE JUMP_FORWARD + compare_chained2a_false_37 ::= expr COMPARE_OP POP_JUMP_IF_FALSE jf_cfs compare_chained2b_37 ::= expr COMPARE_OP come_from_opt POP_JUMP_IF_FALSE JUMP_FORWARD ELSE + compare_chained2b_37 ::= expr COMPARE_OP come_from_opt POP_JUMP_IF_FALSE JUMP_FORWARD compare_chained2c_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP come_from_opt POP_JUMP_IF_FALSE compare_chained2a_false_37 ELSE + compare_chained2c_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP come_from_opt POP_JUMP_IF_FALSE + compare_chained2a_false_37 jf_cfs ::= JUMP_FORWARD come_froms ifelsestmt ::= testexpr c_stmts_opt jf_cfs else_suite opt_come_from_except From b62752eca13d9dd6389748eaa1324a0eb19f79ce Mon Sep 17 00:00:00 2001 From: x0ret Date: Tue, 14 May 2019 17:51:51 +0430 Subject: [PATCH 4/4] 2 more 3.7 chained comparison rule --- uncompyle6/parsers/parse37.py | 8 ++++++-- uncompyle6/semantics/customize37.py | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 269ed980a..73b92acec 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -88,6 +88,7 @@ def p_37misc(self, args): compare_chained37 ::= expr compare_chained1a_37 compare_chained37 ::= expr compare_chained1b_37 + compare_chained37 ::= expr compare_chained1c_37 compare_chained37_false ::= expr compare_chained1_false_37 compare_chained37_false ::= expr compare_chained2_false_37 @@ -97,13 +98,16 @@ def p_37misc(self, args): compare_chained2a_37 ELSE POP_TOP COME_FROM compare_chained1b_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP POP_JUMP_IF_FALSE compare_chained2b_37 POP_TOP JUMP_FORWARD COME_FROM + compare_chained1c_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP POP_JUMP_IF_FALSE + compare_chained2a_37 POP_TOP compare_chained1_false_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP POP_JUMP_IF_FALSE compare_chained2c_37 POP_TOP JUMP_FORWARD COME_FROM - compare_chained2_false_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP POP_JUMP_IF_FALSE + compare_chained2_false_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP POP_JUMP_IF_FALSE compare_chained2a_false_37 ELSE POP_TOP JUMP_BACK COME_FROM compare_chained2a_37 ::= expr COMPARE_OP POP_JUMP_IF_TRUE JUMP_FORWARD + compare_chained2a_37 ::= expr COMPARE_OP POP_JUMP_IF_TRUE JUMP_BACK compare_chained2a_false_37 ::= expr COMPARE_OP POP_JUMP_IF_FALSE jf_cfs compare_chained2b_37 ::= expr COMPARE_OP come_from_opt POP_JUMP_IF_FALSE JUMP_FORWARD ELSE @@ -114,7 +118,7 @@ def p_37misc(self, args): compare_chained2c_37 ::= expr DUP_TOP ROT_THREE COMPARE_OP come_from_opt POP_JUMP_IF_FALSE compare_chained2a_false_37 - jf_cfs ::= JUMP_FORWARD come_froms + jf_cfs ::= JUMP_FORWARD _come_froms ifelsestmt ::= testexpr c_stmts_opt jf_cfs else_suite opt_come_from_except jmp_false37 ::= POP_JUMP_IF_FALSE COME_FROM diff --git a/uncompyle6/semantics/customize37.py b/uncompyle6/semantics/customize37.py index 71d84dc44..7d97d4a13 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -51,6 +51,9 @@ def customize_for_version37(self, version): 'compare_chained1b_37': ( ' %[3]{pattr.replace("-", " ")} %p %p', (0, 19), (-4, 19)), + 'compare_chained1c_37': ( + ' %[3]{pattr.replace("-", " ")} %p %p', + (0, 19), (-2, 19)), 'compare_chained2a_37': ( '%[1]{pattr.replace("-", " ")} %p', (0, 19) ),