You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Add COME_FROM_LOOP
Note: we have regressed in --verify and some tests, but I believe that's because we are producing more equivalant (if uglier) programs. That's a separate problem though.
This commit is contained in:
@@ -31,9 +31,11 @@ def test_grammar():
|
||||
assert expect_right_recursive == right_recursive
|
||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
||||
ignore_set = set(
|
||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM COME_FROM_EXCEPT
|
||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
|
||||
LAMBDA_MARKER RETURN_LAST
|
||||
"""
|
||||
JUMP_BACK CONTINUE RETURN_END_IF
|
||||
COME_FROM COME_FROM_EXCEPT COME_FROM_LOOP
|
||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
|
||||
LAMBDA_MARKER RETURN_LAST
|
||||
""".split())
|
||||
if 2.6 <= PYTHON_VERSION <= 2.7:
|
||||
opcode_set = set(s.opc.opname).union(ignore_set)
|
||||
|
@@ -9,8 +9,6 @@ def test_single_mode():
|
||||
'i = j % 4',
|
||||
'i = {}',
|
||||
'i = []',
|
||||
'while i < 1 or stop:\n i\n',
|
||||
'while i < 1 or stop:\n print%s\n' % ('(i)' if PYTHON3 else ' i'),
|
||||
'for i in range(10):\n i\n',
|
||||
'for i in range(10):\n for j in range(10):\n i + j\n',
|
||||
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
|
||||
|
@@ -36,15 +36,15 @@ check-3.3: check-bytecode
|
||||
|
||||
#: Run working tests from Python 3.4
|
||||
check-3.4: check-bytecode check-3.4-ok check-2.7-ok
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.4 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.5
|
||||
check-3.5: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.5 --weak-verify $(COMPILE)
|
||||
|
||||
#: Run working tests from Python 3.6
|
||||
check-3.6: check-bytecode
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --verify $(COMPILE)
|
||||
$(PYTHON) test_pythonlib.py --bytecode-3.6 --weak-verify $(COMPILE)
|
||||
|
||||
#: Check deparsing only, but from a different Python version
|
||||
check-disasm:
|
||||
|
Binary file not shown.
@@ -255,6 +255,7 @@ class Python3Parser(PythonParser):
|
||||
"""
|
||||
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts END_FINALLY COME_FROM
|
||||
|
||||
for_block ::= l_stmts_opt opt_come_from_loop JUMP_BACK
|
||||
for_block ::= l_stmts
|
||||
iflaststmtl ::= testexpr c_stmts_opt
|
||||
iflaststmt ::= testexpr c_stmts_opt34
|
||||
@@ -268,6 +269,9 @@ class Python3Parser(PythonParser):
|
||||
|
||||
come_froms ::= come_froms COME_FROM
|
||||
come_froms ::=
|
||||
|
||||
opt_come_from_loop ::= _come_from COME_FROM_LOOP
|
||||
opt_come_from_loop ::=
|
||||
"""
|
||||
|
||||
def p_jump3(self, args):
|
||||
@@ -298,15 +302,16 @@ class Python3Parser(PythonParser):
|
||||
stmt ::= whileTruestmt
|
||||
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite _come_from
|
||||
|
||||
forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK NOP _come_from
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK _come_from
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK NOP _come_from
|
||||
forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK opt_come_from_loop
|
||||
forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK NOP opt_come_from_loop
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK opt_come_from_loop
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK NOP opt_come_from_loop
|
||||
|
||||
# Python < 3.5 no POP BLOCK
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK _come_from
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK NOP _come_from
|
||||
whileTruestmt ::= SETUP_LOOP return_stmts _come_from
|
||||
while1stmt ::= SETUP_LOOP l_stmts _come_from JUMP_BACK _come_from
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK opt_come_from_loop
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK NOP opt_come_from_loop
|
||||
whileTruestmt ::= SETUP_LOOP return_stmts opt_come_from_loop
|
||||
while1stmt ::= SETUP_LOOP l_stmts _come_from JUMP_BACK opt_come_from_loop
|
||||
"""
|
||||
|
||||
def p_genexpr3(self, args):
|
||||
|
@@ -103,10 +103,12 @@ class Scanner3(Scanner):
|
||||
varargs_ops.add(self.opc.CALL_METHOD)
|
||||
self.varargs_ops = frozenset(varargs_ops)
|
||||
|
||||
self.setup_ops = frozenset([
|
||||
self.opc.SETUP_LOOP,
|
||||
self.opc.SETUP_EXCEPT, self.opc.SETUP_FINALLY,
|
||||
self.opc.SETUP_WITH])
|
||||
setup_ops = [self.opc.SETUP_LOOP, self.opc.SETUP_EXCEPT,
|
||||
self.opc.SETUP_FINALLY]
|
||||
|
||||
if self.version > 3.1:
|
||||
setup_ops.append(self.opc.SETUP_WITH)
|
||||
self.setup_ops = frozenset(setup_ops)
|
||||
|
||||
# Not really a set, but still clasification-like
|
||||
self.statement_opcode_sequences = [
|
||||
@@ -116,6 +118,9 @@ class Scanner3(Scanner):
|
||||
(self.opc.POP_JUMP_IF_TRUE, self.opc.JUMP_ABSOLUTE)]
|
||||
|
||||
|
||||
def opName(self, offset):
|
||||
return self.opc.opname[self.code[offset]]
|
||||
|
||||
def ingest(self, co, classname=None, code_objects={}, show_asm=None):
|
||||
"""
|
||||
Pick out tokens from an uncompyle6 code object, and transform them,
|
||||
@@ -193,13 +198,16 @@ class Scanner3(Scanner):
|
||||
jump_idx = 0
|
||||
for jump_offset in jump_targets[inst.offset]:
|
||||
come_from_name = 'COME_FROM'
|
||||
if (inst.offset in offset_action
|
||||
and offset_action[inst.offset].type == 'end'
|
||||
# Adjust the grammar and remove the below
|
||||
and offset_action[inst.offset].name in ['EXCEPT']
|
||||
):
|
||||
come_from_name = '%s_%s' % (
|
||||
(come_from_name, offset_action[inst.offset].name))
|
||||
if (inst.offset in offset_action):
|
||||
action = offset_action[inst.offset]
|
||||
if (action.type == 'end'
|
||||
# Adjust the grammar and remove the below
|
||||
and (self.opName(jump_offset)[len('SETUP_'):]
|
||||
== action.name)
|
||||
and action.name in ['EXCEPT', 'LOOP']):
|
||||
come_from_name = '%s_%s' % (
|
||||
(come_from_name, action.name))
|
||||
pass
|
||||
pass
|
||||
tokens.append(Token(come_from_name,
|
||||
None, repr(jump_offset),
|
||||
|
Reference in New Issue
Block a user