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 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):
|
||||
"""
|
||||
|
||||
# Store locals is only in Python 3.0 to 3.3
|
||||
stmt ::= 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
|
||||
|
@@ -91,6 +91,7 @@ class Scanner3(Scanner):
|
||||
self.opc.JUMP_ABSOLUTE, self.opc.UNPACK_EX
|
||||
])
|
||||
|
||||
if self.version > 3.0:
|
||||
self.jump_if_pop = frozenset([self.opc.JUMP_IF_FALSE_OR_POP,
|
||||
self.opc.JUMP_IF_TRUE_OR_POP])
|
||||
|
||||
@@ -98,6 +99,22 @@ class Scanner3(Scanner):
|
||||
self.opc.JUMP_IF_TRUE_OR_POP,
|
||||
self.opc.POP_JUMP_IF_TRUE,
|
||||
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
|
||||
# (expr's)
|
||||
@@ -111,13 +128,6 @@ class Scanner3(Scanner):
|
||||
varargs_ops.add(self.opc.CALL_METHOD)
|
||||
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):
|
||||
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 = 'after'
|
||||
# show_asm = 'before'
|
||||
if show_asm in ('both', 'before'):
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
for instr in bytecode.get_instructions(co):
|
||||
|
@@ -16,7 +16,7 @@ from uncompyle6.scanners.scanner3 import Scanner3
|
||||
class Scanner30(Scanner3):
|
||||
|
||||
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
|
||||
pass
|
||||
|
||||
|
Reference in New Issue
Block a user