You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Fix 3.5+ bug in if's with pass bodies
Fixes #104 in a somewhat hacky way.
This commit is contained in:
@@ -66,6 +66,9 @@ def test_if_in_for():
|
|||||||
scan.build_lines_data(code)
|
scan.build_lines_data(code)
|
||||||
scan.build_prev_op()
|
scan.build_prev_op()
|
||||||
scan.insts = list(bytecode)
|
scan.insts = list(bytecode)
|
||||||
|
scan.offset2inst_index = {}
|
||||||
|
for i, inst in enumerate(scan.insts):
|
||||||
|
scan.offset2inst_index[inst.offset] = i
|
||||||
fjt = scan.find_jump_targets(False)
|
fjt = scan.find_jump_targets(False)
|
||||||
assert {69: [66], 63: [18]} == fjt
|
assert {69: [66], 63: [18]} == fjt
|
||||||
assert scan.structs == \
|
assert scan.structs == \
|
||||||
|
BIN
test/bytecode_3.5/05_empty_ifs.pyc
Normal file
BIN
test/bytecode_3.5/05_empty_ifs.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6/05_empty_ifs.pyc
Normal file
BIN
test/bytecode_3.6/05_empty_ifs.pyc
Normal file
Binary file not shown.
9
test/simple_source/bug35/05_empty_ifs.py
Normal file
9
test/simple_source/bug35/05_empty_ifs.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Issue 104 seen in Python 3.5
|
||||||
|
# Since we have empty statement bodies the if's can get confused
|
||||||
|
# with "and/or". There is a lot of flakiness in control flow here,
|
||||||
|
# and this needs to be straightened out in a more uniform way
|
||||||
|
if __file__:
|
||||||
|
if __name__:
|
||||||
|
pass
|
||||||
|
elif __import__:
|
||||||
|
pass
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015-2017 by Rocky Bernstein
|
# Copyright (c) 2015-2018 by Rocky Bernstein
|
||||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
"""
|
"""
|
||||||
@@ -767,18 +767,25 @@ class Scanner3(Scanner):
|
|||||||
# not myself? If so, it's part of a larger conditional.
|
# not myself? If so, it's part of a larger conditional.
|
||||||
# rocky: if we have a conditional jump to the next instruction, then
|
# rocky: if we have a conditional jump to the next instruction, then
|
||||||
# possibly I am "skipping over" a "pass" or null statement.
|
# possibly I am "skipping over" a "pass" or null statement.
|
||||||
|
pretarget = self.insts[self.offset2inst_index[prev_op[target]]]
|
||||||
|
|
||||||
if ((code[prev_op[target]] in self.pop_jump_if_pop) and
|
if (pretarget.opcode in self.pop_jump_if_pop and
|
||||||
(target > offset) and prev_op[target] != offset):
|
(target > offset) and pretarget.offset != offset):
|
||||||
# FIXME: this is not accurate The commented out below
|
|
||||||
# is what it should be. However grammar rules right now
|
# FIXME: hack upon hack...
|
||||||
# assume the incorrect offsets.
|
# In some cases the pretarget can be a jump to the next instruction
|
||||||
# self.fixed_jumps[offset] = target
|
# and these aren't and/or's either. We limit to 3.5+ since we experienced there
|
||||||
self.fixed_jumps[offset] = prev_op[target]
|
# but it might be earlier versions, or might be a general principle.
|
||||||
self.structs.append({'type': 'and/or',
|
if self.version < 3.5 or pretarget.argval != target:
|
||||||
'start': start,
|
# FIXME: this is not accurate The commented out below
|
||||||
'end': prev_op[target]})
|
# is what it should be. However grammar rules right now
|
||||||
return
|
# assume the incorrect offsets.
|
||||||
|
# self.fixed_jumps[offset] = target
|
||||||
|
self.fixed_jumps[offset] = pretarget.offset
|
||||||
|
self.structs.append({'type': 'and/or',
|
||||||
|
'start': start,
|
||||||
|
'end': pretarget.offset})
|
||||||
|
return
|
||||||
|
|
||||||
# The opcode *two* instructions before the target jump offset is important
|
# The opcode *two* instructions before the target jump offset is important
|
||||||
# in making a determination of what we have. Save that.
|
# in making a determination of what we have. Save that.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 3.6 bytecode decompiler scanner
|
Python 3.6 bytecode decompiler scanner
|
||||||
|
|
||||||
@@ -13,8 +13,6 @@ from __future__ import print_function
|
|||||||
|
|
||||||
from uncompyle6.scanners.scanner3 import Scanner3
|
from uncompyle6.scanners.scanner3 import Scanner3
|
||||||
|
|
||||||
import xdis
|
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPS from here
|
# bytecode verification, verify(), uses JUMP_OPS from here
|
||||||
from xdis.opcodes import opcode_36 as opc
|
from xdis.opcodes import opcode_36 as opc
|
||||||
JUMP_OPS = opc.JUMP_OPS
|
JUMP_OPS = opc.JUMP_OPS
|
||||||
|
Reference in New Issue
Block a user