From 4a79082872a8be1d228887464830955654a1629c Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 8 May 2016 10:22:29 -0400 Subject: [PATCH] Fix 3.5 if..pass bug Update HISTORY.MD to include Dan Pascu. Some minor doc corrections --- HISTORY.md | 7 +++- test/bytecode_3.5/10_if_pass.pyc | Bin 0 -> 794 bytes test/simple_source/branching/10_if_pass.py | 23 +++++++++++++ uncompyle6/scanners/scanner26.py | 2 +- uncompyle6/scanners/scanner27.py | 2 +- uncompyle6/scanners/scanner3.py | 36 +++++++++++++++------ uncompyle6/scanners/scanner35.py | 10 +++--- 7 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 test/bytecode_3.5/10_if_pass.pyc create mode 100644 test/simple_source/branching/10_if_pass.py diff --git a/HISTORY.md b/HISTORY.md index 59c90c7b..9672a1db 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -36,7 +36,7 @@ first subsequent public release announcement that I can find is From the CHANGES file found in [the tarball for that release](http://old-releases.ubuntu.com/ubuntu/pool/universe/d/decompyle2.2/decompyle2.2_2.2beta1.orig.tar.gz), it appears that Hartmut did most of the work to get this code to -accept the full Python language. He added precidence to the table +accept the full Python language. He added precedence to the table specifiers, support for multiple versions of Python, the pretty-printing of docstrings, lists, and hashes. He also wrote test and verification routines of deparsed bytecode, and used this in an extensive set of tests that he also wrote. He could verify against the entire Python library. @@ -55,6 +55,11 @@ it doesn't look like he's done anything compiler-wise since SPARK). So I hope people will use the crazy-compilers service. I wish them the success that his good work deserves. +Also looking at code I see Dan Pascu did a bit of work around 2005 on +the Python scanner, parser, and marshaling routines. For example I +see a bit code to massage disassembly output to make it more amenable +for deparsing. 2005 would put his work around the Python 2.4 releases. + Next we get to ["uncompyle" and PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and the era of git repositories. In contrast to decompyle, this now runs diff --git a/test/bytecode_3.5/10_if_pass.pyc b/test/bytecode_3.5/10_if_pass.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7adab0545708d707cc9917e4e0066a2ef74e03f2 GIT binary patch literal 794 zcmZuvPm9zr6n{xNf1O!H*#*HvE+Pf#=uKo<1P^+e%N&GWLTysFY}*-=l)+*4G~%BR z;Ro<5_3Fv5;K}z=R!1;2kC)`V-=Cys^ZB%Xy?FDD1N?xaAuxY|(>=nV@ncW{)C^Jv z?3L!A1$@M90S68#E+bgQgP&LoG3$giMNaw6K=>Z+0VW0r1wp9~6HZ8}Ah1;&byHQX z^Q@SIeB#bS;O zV)yK&HJLXula1L*UFKdEYb*Vwk$G#aX*}jwq94nw(b5{<+D4W>`J;z)khXiI=RSrn z0EZw6DbU%~1nem#tC%gnLo7O`I#Ft$4uUznqtVue)RM1X4;}e6%B@?Qo5fq3HTh-P zyjwhdqRK*TGUt-bhwh};rL?JxH~KEo4>16nuo>GWf3GgdgGWW~lJmgiE|P!SQ5G+? zB_ruPl-vNvgD!HWD$-%!kxs%ffm!0S6AGj}W_CpR7(;jKi1Y+E+!O=wA!<8~ZnNFl z|Me~L)yGOTS#6ZU_gD2=w|E( offset): + # Does this jump to right after another cond jump that is + # not myself? If so, it's part of a larger conditional. + # rocky: if we have a conditional jump to the next instruction, then + # possibly I am "skipping over" a "pass" or null statement. + if ((code[prev_op[target]] in + (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP, + POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE)) and + (target > offset) and prev_op[target] != offset): self.fixed_jumps[offset] = prev_op[target] self.structs.append({'type': 'and/or', 'start': start, 'end': prev_op[target]}) return + # Is it an and inside if block if op == POP_JUMP_IF_FALSE: # Search for other POP_JUMP_IF_FALSE targetting the same op, diff --git a/uncompyle6/scanners/scanner35.py b/uncompyle6/scanners/scanner35.py index a8182cf6..469c31cb 100644 --- a/uncompyle6/scanners/scanner35.py +++ b/uncompyle6/scanners/scanner35.py @@ -37,9 +37,6 @@ class Scanner35(scan3.Scanner3): self.build_lines_data(co) self.build_prev_op() - # Get jump targets - # Format: {target offset: [jump offsets]} - jump_targets = self.find_jump_targets() bytecode = dis35.Bytecode(co) # self.lines contains (block,addrLastInstr) @@ -61,12 +58,17 @@ class Scanner35(scan3.Scanner3): n = len(bs) for i in range(n): inst = bs[i] - if inst.opname == 'POP_JUMP_IF_TRUE' and i+1 < n: + + if inst.opname == 'POP_JUMP_IF_TRUE' and i+1 < n: next_inst = bs[i+1] if (next_inst.opname == 'LOAD_GLOBAL' and next_inst.argval == 'AssertionError'): self.load_asserts.add(next_inst.offset) + # Get jump targets + # Format: {target offset: [jump offsets]} + jump_targets = self.find_jump_targets() + for inst in bytecode: if inst.offset in jump_targets: jump_idx = 0