You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Python 3.0 doesn't have POP_JUMP ops...
In some ways Python 3.0 code generation is more like Python 2.6 (and before) than it is Python 2.7 or 3.0.
This commit is contained in:
@@ -5,19 +5,24 @@ spark grammar differences over Python 3.1 for Python 3.0.
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from uncompyle6.parser import PythonParserSingle
|
from uncompyle6.parser import PythonParserSingle
|
||||||
from uncompyle6.parsers.parse31 import Python31Parser
|
from uncompyle6.parsers.parse3 import Python3Parser
|
||||||
|
|
||||||
class Python30Parser(Python31Parser):
|
class Python30Parser(Python3Parser):
|
||||||
|
|
||||||
def p_30(self, args):
|
def p_30(self, args):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Store locals is only in Python 3.0 to 3.3
|
# Store locals is only in Python 3.0 to 3.3
|
||||||
stmt ::= store_locals
|
stmt ::= store_locals
|
||||||
store_locals ::= LOAD_FAST STORE_LOCALS
|
store_locals ::= LOAD_FAST STORE_LOCALS
|
||||||
|
|
||||||
jmp_true ::= JUMP_IF_TRUE_OR_POP POP_TOP
|
|
||||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD POP_TOP COME_FROM
|
# In many ways Python 3.0 code generation is more like Python 2.6 than
|
||||||
|
# it is 2.7 or 3.1. So we have a number of 2.6ish (and before) rules below
|
||||||
|
|
||||||
|
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM
|
||||||
|
jmp_true ::= JUMP_IF_TRUE POP_TOP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Python31ParserSingle(Python31Parser, PythonParserSingle):
|
class Python30ParserSingle(Python30Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
@@ -91,18 +91,35 @@ class Scanner3(Scanner):
|
|||||||
self.opc.JUMP_ABSOLUTE, self.opc.UNPACK_EX
|
self.opc.JUMP_ABSOLUTE, self.opc.UNPACK_EX
|
||||||
])
|
])
|
||||||
|
|
||||||
self.jump_if_pop = frozenset([self.opc.JUMP_IF_FALSE_OR_POP,
|
if self.version > 3.0:
|
||||||
self.opc.JUMP_IF_TRUE_OR_POP])
|
self.jump_if_pop = frozenset([self.opc.JUMP_IF_FALSE_OR_POP,
|
||||||
|
self.opc.JUMP_IF_TRUE_OR_POP])
|
||||||
|
|
||||||
self.pop_jump_if_pop = frozenset([self.opc.JUMP_IF_FALSE_OR_POP,
|
self.pop_jump_if_pop = frozenset([self.opc.JUMP_IF_FALSE_OR_POP,
|
||||||
self.opc.JUMP_IF_TRUE_OR_POP,
|
self.opc.JUMP_IF_TRUE_OR_POP,
|
||||||
self.opc.POP_JUMP_IF_TRUE,
|
self.opc.POP_JUMP_IF_TRUE,
|
||||||
self.opc.POP_JUMP_IF_FALSE])
|
self.opc.POP_JUMP_IF_FALSE])
|
||||||
|
# Not really a set, but still clasification-like
|
||||||
|
self.statement_opcode_sequences = [
|
||||||
|
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_FORWARD),
|
||||||
|
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_ABSOLUTE),
|
||||||
|
(self.opc.POP_JUMP_IF_TRUE, self.opc.JUMP_FORWARD),
|
||||||
|
(self.opc.POP_JUMP_IF_TRUE, self.opc.JUMP_ABSOLUTE)]
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.jump_if_pop = frozenset([])
|
||||||
|
self.pop_jump_if_pop = frozenset([])
|
||||||
|
# Not really a set, but still clasification-like
|
||||||
|
self.statement_opcode_sequences = [
|
||||||
|
(self.opc.JUMP_FORWARD,),
|
||||||
|
(self.opc.JUMP_ABSOLUTE,),
|
||||||
|
(self.opc.JUMP_FORWARD,),
|
||||||
|
(self.opc.JUMP_ABSOLUTE,)]
|
||||||
|
|
||||||
# Opcodes that take a variable number of arguments
|
# Opcodes that take a variable number of arguments
|
||||||
# (expr's)
|
# (expr's)
|
||||||
varargs_ops = set([
|
varargs_ops = set([
|
||||||
self.opc.BUILD_LIST, self.opc.BUILD_TUPLE,
|
self.opc.BUILD_LIST, self.opc.BUILD_TUPLE,
|
||||||
self.opc.BUILD_SET, self.opc.BUILD_SLICE,
|
self.opc.BUILD_SET, self.opc.BUILD_SLICE,
|
||||||
self.opc.BUILD_MAP, self.opc.UNPACK_SEQUENCE,
|
self.opc.BUILD_MAP, self.opc.UNPACK_SEQUENCE,
|
||||||
self.opc.RAISE_VARARGS])
|
self.opc.RAISE_VARARGS])
|
||||||
@@ -111,13 +128,6 @@ class Scanner3(Scanner):
|
|||||||
varargs_ops.add(self.opc.CALL_METHOD)
|
varargs_ops.add(self.opc.CALL_METHOD)
|
||||||
self.varargs_ops = frozenset(varargs_ops)
|
self.varargs_ops = frozenset(varargs_ops)
|
||||||
|
|
||||||
# Not really a set, but still clasification-like
|
|
||||||
self.statement_opcode_sequences = [
|
|
||||||
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_FORWARD),
|
|
||||||
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_ABSOLUTE),
|
|
||||||
(self.opc.POP_JUMP_IF_TRUE, self.opc.JUMP_FORWARD),
|
|
||||||
(self.opc.POP_JUMP_IF_TRUE, self.opc.JUMP_ABSOLUTE)]
|
|
||||||
|
|
||||||
|
|
||||||
def opName(self, offset):
|
def opName(self, offset):
|
||||||
return self.opc.opname[self.code[offset]]
|
return self.opc.opname[self.code[offset]]
|
||||||
@@ -139,7 +149,7 @@ class Scanner3(Scanner):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
show_asm = self.show_asm if not show_asm else show_asm
|
show_asm = self.show_asm if not show_asm else show_asm
|
||||||
# show_asm = 'after'
|
# show_asm = 'before'
|
||||||
if show_asm in ('both', 'before'):
|
if show_asm in ('both', 'before'):
|
||||||
bytecode = Bytecode(co, self.opc)
|
bytecode = Bytecode(co, self.opc)
|
||||||
for instr in bytecode.get_instructions(co):
|
for instr in bytecode.get_instructions(co):
|
||||||
|
@@ -16,7 +16,7 @@ from uncompyle6.scanners.scanner3 import Scanner3
|
|||||||
class Scanner30(Scanner3):
|
class Scanner30(Scanner3):
|
||||||
|
|
||||||
def __init__(self, show_asm=None, is_pypy=False):
|
def __init__(self, show_asm=None, is_pypy=False):
|
||||||
Scanner3.__init__(self, 3.1, show_asm, is_pypy)
|
Scanner3.__init__(self, 3.0, show_asm, is_pypy)
|
||||||
return
|
return
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user