mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-02-20 05:02:26 +00:00
Start handling Pyton 2.4 bytecodes
This commit is contained in:
parent
7fdb4d3e68
commit
62e60817f6
@ -37,7 +37,7 @@ entry_points={
|
||||
]}
|
||||
ftp_url = None
|
||||
install_requires = ['spark-parser >= 1.4.0',
|
||||
'xdis >= 1.1.4']
|
||||
'xdis >= 1.1.5']
|
||||
license = 'MIT'
|
||||
mailing_list = 'python-debugger@googlegroups.com'
|
||||
modname = 'uncompyle6'
|
||||
|
@ -43,7 +43,7 @@ check-disasm:
|
||||
|
||||
#: Check deparsing bytecode 2.x only
|
||||
check-bytecode-2:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.3 --bytecode-2.5 --bytecode-2.6 --bytecode-2.7
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.3 --bytecode-2.4 --bytecode-2.5 --bytecode-2.6 --bytecode-2.7
|
||||
|
||||
#: Check deparsing bytecode 3.x only
|
||||
check-bytecode-3:
|
||||
@ -57,6 +57,10 @@ check-bytecode: check-bytecode-3
|
||||
check-bytecode-2.3:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.3
|
||||
|
||||
#: Check deparsing Python 2.4
|
||||
check-bytecode-2.4:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.4
|
||||
|
||||
#: Check deparsing Python 2.5
|
||||
check-bytecode-2.5:
|
||||
$(PYTHON) test_pythonlib.py --bytecode-2.5
|
||||
|
@ -2,12 +2,12 @@
|
||||
""" Trivial helper program to bytecompile and run an uncompile
|
||||
"""
|
||||
import os, sys, py_compile
|
||||
assert len(sys.argv) == 2
|
||||
path = sys.argv[1]
|
||||
short = os.path.basename(path)
|
||||
assert len(sys.argv) >= 2
|
||||
version = sys.version[0:3]
|
||||
cfile = "bytecode_%s/%s" % (version, short) + 'c'
|
||||
print("byte-compiling %s to %s" % (path, cfile))
|
||||
py_compile.compile(path, cfile)
|
||||
if sys.version >= (2, 6, 0):
|
||||
os.system("../bin/uncompyle6 -a -t %s" % cfile)
|
||||
for path in sys.argv[1:]:
|
||||
short = os.path.basename(path)
|
||||
cfile = "bytecode_%s/%s" % (version, short) + 'c'
|
||||
print("byte-compiling %s to %s" % (path, cfile))
|
||||
py_compile.compile(path, cfile)
|
||||
if sys.version >= (2, 6, 0):
|
||||
os.system("../bin/uncompyle6 -a -t %s" % cfile)
|
||||
|
BIN
test/bytecode_2.4/03_if_elif.pyc
Normal file
BIN
test/bytecode_2.4/03_if_elif.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.4/04_raise.pyc
Normal file
BIN
test/bytecode_2.4/04_raise.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7/03_if_elif.pyc
Normal file
BIN
test/bytecode_2.7/03_if_elif.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7/04_raise.pyc
Normal file
BIN
test/bytecode_2.7/04_raise.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7/04_withas.pyc
Normal file
BIN
test/bytecode_2.7/04_withas.pyc
Normal file
Binary file not shown.
@ -27,7 +27,8 @@ from fnmatch import fnmatch
|
||||
|
||||
#----- configure this for your needs
|
||||
|
||||
TEST_VERSIONS=('2.3.7', '2.5.6', '2.6.9', '2.7.10', '2.7.11', '3.2.6', '3.3.5', '3.4.2', '3.5.1')
|
||||
TEST_VERSIONS=('2.3.7', '2.4.6', '2.5.6', '2.6.9', '2.7.10', '2.7.11',
|
||||
'3.2.6', '3.3.5', '3.4.2', '3.5.1')
|
||||
|
||||
target_base = '/tmp/py-dis/'
|
||||
lib_prefix = os.path.join(os.environ['HOME'], '.pyenv/versions')
|
||||
|
@ -78,7 +78,7 @@ for vers in (2.7, 3.4, 3.5):
|
||||
test_options[key] = (os.path.join(src_dir, pythonlib), PYOC, key, vers)
|
||||
pass
|
||||
|
||||
for vers in (2.3, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5):
|
||||
for vers in (2.3, 2.4, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5):
|
||||
bytecode = "bytecode_%s" % vers
|
||||
key = "bytecode-%s" % vers
|
||||
test_options[key] = (bytecode, PYC, bytecode, vers)
|
||||
|
@ -591,6 +591,12 @@ def get_python_parser(version, debug_parser, compile_mode='exec'):
|
||||
p = parse23.Python23Parser(debug_parser)
|
||||
else:
|
||||
p = parse23.Python23ParserSingle(debug_parser)
|
||||
elif version == 2.4:
|
||||
import uncompyle6.parsers.parse24 as parse24
|
||||
if compile_mode == 'exec':
|
||||
p = parse24.Python24Parser(debug_parser)
|
||||
else:
|
||||
p = parse24.Python24ParserSingle(debug_parser)
|
||||
elif version == 2.5:
|
||||
import uncompyle6.parsers.parse25 as parse25
|
||||
if compile_mode == 'exec':
|
||||
|
28
uncompyle6/parsers/parse24.py
Normal file
28
uncompyle6/parsers/parse24.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2016 Rocky Bernstein
|
||||
"""
|
||||
spark grammar differences over Python2.5 for Python 2.4.
|
||||
"""
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
from uncompyle6.parsers.parse25 import Python25Parser
|
||||
|
||||
class Python24Parser(Python25Parser):
|
||||
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
|
||||
super(Python24Parser, self).__init__(debug_parser)
|
||||
self.customized = {}
|
||||
|
||||
def p_misc24(self, args):
|
||||
'''
|
||||
# 2.5+ has two LOAD_CONSTs, one for the number '.'s in a relative import
|
||||
importstmt ::= LOAD_CONST filler import_as
|
||||
importfrom ::= LOAD_CONST filler IMPORT_NAME importlist2 POP_TOP
|
||||
'''
|
||||
|
||||
class Python24ParserSingle(Python25Parser, PythonParserSingle):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Check grammar
|
||||
p = Python24Parser()
|
||||
p.checkGrammar()
|
@ -1,6 +1,6 @@
|
||||
# Copyright (c) 2016 Rocky Bernstein
|
||||
"""
|
||||
spark grammar differences over Python2.6 for Python 2.6.
|
||||
spark grammar differences over Python2.6 for Python 2.5.
|
||||
"""
|
||||
|
||||
from uncompyle6.parser import PythonParserSingle
|
||||
@ -41,5 +41,5 @@ class Python25ParserSingle(Python26Parser, PythonParserSingle):
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Check grammar
|
||||
p = Python26Parser()
|
||||
p = Python25Parser()
|
||||
p.checkGrammar()
|
||||
|
@ -26,7 +26,7 @@ if PYTHON3:
|
||||
# Need to work out Python 2.3. ord's in PYTHON3
|
||||
PYTHON_VERSIONS = (2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5)
|
||||
else:
|
||||
PYTHON_VERSIONS = (2.3, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5)
|
||||
PYTHON_VERSIONS = (2.3, 2.4, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5)
|
||||
|
||||
# FIXME: DRY
|
||||
if PYTHON3:
|
||||
|
68
uncompyle6/scanners/scanner24.py
Executable file
68
uncompyle6/scanners/scanner24.py
Executable file
@ -0,0 +1,68 @@
|
||||
# Copyright (c) 2016 by Rocky Bernstein
|
||||
"""
|
||||
Python 2.4 bytecode scanner/deparser
|
||||
|
||||
This overlaps Python's 2.4's dis module, but it can be run from
|
||||
Python 3 and other versions of Python. Also, we save token
|
||||
information for later use in deparsing.
|
||||
"""
|
||||
|
||||
import uncompyle6.scanners.scanner25 as scan
|
||||
import uncompyle6.scanners.scanner2 as scan2
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_24
|
||||
JUMP_OPs = opcode_24.JUMP_OPs
|
||||
|
||||
# We base this off of 2.6 instead of the other way around
|
||||
# because we cleaned things up this way.
|
||||
# The history is that 2.7 support is the cleanest,
|
||||
# then from that we got 2.6 and so on.
|
||||
class Scanner24(scan.Scanner25):
|
||||
def __init__(self, show_asm):
|
||||
scan2.Scanner2.__init__(self, 2.4, show_asm)
|
||||
self.stmt_opcodes = frozenset([
|
||||
self.opc.SETUP_LOOP, self.opc.BREAK_LOOP,
|
||||
self.opc.SETUP_FINALLY, self.opc.END_FINALLY,
|
||||
self.opc.SETUP_EXCEPT, self.opc.POP_BLOCK,
|
||||
self.opc.STORE_FAST, self.opc.DELETE_FAST,
|
||||
self.opc.STORE_DEREF, self.opc.STORE_GLOBAL,
|
||||
self.opc.DELETE_GLOBAL, self.opc.STORE_NAME,
|
||||
self.opc.DELETE_NAME, self.opc.STORE_ATTR,
|
||||
self.opc.DELETE_ATTR, self.opc.STORE_SUBSCR,
|
||||
self.opc.DELETE_SUBSCR, self.opc.RETURN_VALUE,
|
||||
self.opc.RAISE_VARARGS, self.opc.POP_TOP,
|
||||
self.opc.PRINT_EXPR, self.opc.PRINT_ITEM,
|
||||
self.opc.PRINT_NEWLINE, self.opc.PRINT_ITEM_TO,
|
||||
self.opc.PRINT_NEWLINE_TO, self.opc.CONTINUE_LOOP,
|
||||
self.opc.JUMP_ABSOLUTE, self.opc.EXEC_STMT,
|
||||
])
|
||||
|
||||
# "setup" opcodes
|
||||
self.setup_ops = frozenset([
|
||||
self.opc.SETUP_EXCEPT, self.opc.SETUP_FINALLY,
|
||||
])
|
||||
|
||||
# opcodes with expect a variable number pushed values whose
|
||||
# count is in the opcode. For parsing we generally change the
|
||||
# opcode name to include that number.
|
||||
self.varargs_ops = frozenset([
|
||||
self.opc.BUILD_LIST, self.opc.BUILD_TUPLE,
|
||||
self.opc.BUILD_SLICE, self.opc.UNPACK_SEQUENCE,
|
||||
self.opc.MAKE_FUNCTION, self.opc.CALL_FUNCTION,
|
||||
self.opc.MAKE_CLOSURE, self.opc.CALL_FUNCTION_VAR,
|
||||
self.opc.CALL_FUNCTION_KW, self.opc.CALL_FUNCTION_VAR_KW,
|
||||
self.opc.DUP_TOPX, self.opc.RAISE_VARARGS])
|
||||
|
||||
# opcodes that store values into a variable
|
||||
self.designator_ops = frozenset([
|
||||
self.opc.STORE_FAST, self.opc.STORE_NAME,
|
||||
self.opc.STORE_GLOBAL, self.opc.STORE_DEREF, self.opc.STORE_ATTR,
|
||||
self.opc.STORE_SLICE_0, self.opc.STORE_SLICE_1, self.opc.STORE_SLICE_2,
|
||||
self.opc.STORE_SLICE_3, self.opc.STORE_SUBSCR, self.opc.UNPACK_SEQUENCE,
|
||||
self.opc.JA
|
||||
])
|
||||
# Python 2.7 has POP_JUMP_IF_{TRUE,FALSE}_OR_POP but < 2.7 doesn't
|
||||
# Add an empty set make processing more uniform.
|
||||
self.pop_jump_if_or_pop = frozenset([])
|
||||
return
|
@ -1,7 +1,4 @@
|
||||
# Copyright (c) 2015-2016 by Rocky Bernstein
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
"""
|
||||
Python 2.5 bytecode scanner/deparser
|
||||
|
||||
@ -10,7 +7,6 @@ Python 3 and other versions of Python. Also, we save token
|
||||
information for later use in deparsing.
|
||||
"""
|
||||
|
||||
from xdis.opcodes.opcode_25 import *
|
||||
import uncompyle6.scanners.scanner26 as scan
|
||||
import uncompyle6.scanners.scanner2 as scan2
|
||||
|
||||
|
@ -961,8 +961,9 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
n_import_as_cont = n_import_as
|
||||
|
||||
def n_importfrom(self, node):
|
||||
if node[0].pattr > 0:
|
||||
node[2].pattr = '.'*node[0].pattr+node[2].pattr
|
||||
relative_path_index = 0
|
||||
if self.version >= 2.5 and node[relative_path_index].pattr > 0:
|
||||
node[2].pattr = '.'*node[relative_path_index].pattr + node[2].pattr
|
||||
self.default(node)
|
||||
|
||||
n_importstar = n_importfrom
|
||||
|
Loading…
x
Reference in New Issue
Block a user