You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Grammar improvement
This commit is contained in:
@@ -18,7 +18,7 @@ hashes get pretty-printed.
|
|||||||
a tool called 'decompyle'. This tool has been vastly improved by
|
a tool called 'decompyle'. This tool has been vastly improved by
|
||||||
Hartmut Goebel `http://www.crazy-compilers.com/`_
|
Hartmut Goebel `http://www.crazy-compilers.com/`_
|
||||||
|
|
||||||
### Additional note (3 July 2004, Ben Burton):
|
# Additional note (3 July 2004, Ben Burton):
|
||||||
|
|
||||||
This software is no longer available from the original website. It has
|
This software is no longer available from the original website. It has
|
||||||
now become a commercial decompilation service, with no software
|
now become a commercial decompilation service, with no software
|
||||||
@@ -28,7 +28,7 @@ Any developers seeking to make alterations or enhancements to this code
|
|||||||
should therefore consider these debian packages an appropriate starting
|
should therefore consider these debian packages an appropriate starting
|
||||||
point.
|
point.
|
||||||
|
|
||||||
### Additional note (5 June 2012):
|
# Additional note (5 June 2012):
|
||||||
|
|
||||||
The decompilation of python bytecode 2.5 & 2.6 is based on the work of
|
The decompilation of python bytecode 2.5 & 2.6 is based on the work of
|
||||||
Eloi Vanderbeken. bytecode is translated to a pseudo 2.7 python bytecode
|
Eloi Vanderbeken. bytecode is translated to a pseudo 2.7 python bytecode
|
||||||
@@ -86,9 +86,9 @@ http://www.python.org/doc/current/inst/inst.html
|
|||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
uncompyle2 -h prints short usage
|
./uncompyle2.py -h prints usage
|
||||||
uncompyle2 --help prints long usage
|
|
||||||
|
|
||||||
|
./test_pythonlib.py test files and python library
|
||||||
|
|
||||||
Known Bugs/Restrictions
|
Known Bugs/Restrictions
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@@ -231,9 +231,7 @@ class Parser(GenericASTBuilder):
|
|||||||
importlist2 ::= importlist2 import_as
|
importlist2 ::= importlist2 import_as
|
||||||
importlist2 ::= import_as
|
importlist2 ::= import_as
|
||||||
import_as ::= IMPORT_NAME designator
|
import_as ::= IMPORT_NAME designator
|
||||||
import_as ::= IMPORT_NAME LOAD_ATTR designator
|
import_as ::= IMPORT_NAME load_attrs designator
|
||||||
import_as ::= IMPORT_NAME LOAD_ATTR LOAD_ATTR designator
|
|
||||||
import_as ::= IMPORT_NAME LOAD_ATTR LOAD_ATTR LOAD_ATTR designator
|
|
||||||
import_as ::= IMPORT_FROM designator
|
import_as ::= IMPORT_FROM designator
|
||||||
|
|
||||||
importstmt ::= LOAD_CONST LOAD_CONST import_as
|
importstmt ::= LOAD_CONST LOAD_CONST import_as
|
||||||
@@ -247,10 +245,11 @@ class Parser(GenericASTBuilder):
|
|||||||
imports_cont ::= import_cont
|
imports_cont ::= import_cont
|
||||||
import_cont ::= LOAD_CONST LOAD_CONST import_as_cont
|
import_cont ::= LOAD_CONST LOAD_CONST import_as_cont
|
||||||
import_as_cont ::= IMPORT_NAME_CONT designator
|
import_as_cont ::= IMPORT_NAME_CONT designator
|
||||||
import_as_cont ::= IMPORT_NAME_CONT LOAD_ATTR designator
|
import_as_cont ::= IMPORT_NAME_CONT load_attrs designator
|
||||||
import_as_cont ::= IMPORT_NAME_CONT LOAD_ATTR LOAD_ATTR designator
|
|
||||||
import_as_cont ::= IMPORT_NAME_CONT LOAD_ATTR LOAD_ATTR LOAD_ATTR designator
|
|
||||||
import_as_cont ::= IMPORT_FROM designator
|
import_as_cont ::= IMPORT_FROM designator
|
||||||
|
|
||||||
|
load_attrs ::= LOAD_ATTR
|
||||||
|
load_attrs ::= load_attrs LOAD_ATTR
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def p_grammar(self, args):
|
def p_grammar(self, args):
|
||||||
@@ -331,13 +330,13 @@ class Parser(GenericASTBuilder):
|
|||||||
call_stmt ::= expr POP_TOP
|
call_stmt ::= expr POP_TOP
|
||||||
|
|
||||||
stmt ::= return_stmt
|
stmt ::= return_stmt
|
||||||
return_stmt ::= expr RETURN_VALUE
|
return_stmt ::= ret_expr RETURN_VALUE
|
||||||
return_stmts ::= return_stmt
|
return_stmts ::= return_stmt
|
||||||
return_stmts ::= _stmts return_stmt
|
return_stmts ::= _stmts return_stmt
|
||||||
|
|
||||||
return_if_stmts ::= return_if_stmt
|
return_if_stmts ::= return_if_stmt
|
||||||
return_if_stmts ::= _stmts return_if_stmt
|
return_if_stmts ::= _stmts return_if_stmt
|
||||||
return_if_stmt ::= expr RETURN_END_IF
|
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||||
|
|
||||||
stmt ::= break_stmt
|
stmt ::= break_stmt
|
||||||
break_stmt ::= BREAK_LOOP
|
break_stmt ::= BREAK_LOOP
|
||||||
@@ -349,9 +348,15 @@ class Parser(GenericASTBuilder):
|
|||||||
continue_stmts ::= lastl_stmt continue_stmt
|
continue_stmts ::= lastl_stmt continue_stmt
|
||||||
continue_stmts ::= continue_stmt
|
continue_stmts ::= continue_stmt
|
||||||
|
|
||||||
stmt ::= raise_stmt
|
stmt ::= raise_stmt0
|
||||||
raise_stmt ::= exprlist RAISE_VARARGS
|
stmt ::= raise_stmt1
|
||||||
raise_stmt ::= nullexprlist RAISE_VARARGS
|
stmt ::= raise_stmt2
|
||||||
|
stmt ::= raise_stmt3
|
||||||
|
|
||||||
|
raise_stmt0 ::= RAISE_VARARGS_0
|
||||||
|
raise_stmt1 ::= expr RAISE_VARARGS_1
|
||||||
|
raise_stmt2 ::= expr expr RAISE_VARARGS_2
|
||||||
|
raise_stmt3 ::= expr expr expr RAISE_VARARGS_3
|
||||||
|
|
||||||
stmt ::= exec_stmt
|
stmt ::= exec_stmt
|
||||||
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
||||||
@@ -406,24 +411,14 @@ class Parser(GenericASTBuilder):
|
|||||||
jmp_false ::= JUMP_IF_FALSE
|
jmp_false ::= JUMP_IF_FALSE
|
||||||
jmp_true ::= POP_JUMP_IF_TRUE
|
jmp_true ::= POP_JUMP_IF_TRUE
|
||||||
jmp_true ::= JUMP_IF_TRUE
|
jmp_true ::= JUMP_IF_TRUE
|
||||||
|
|
||||||
multi_come_from ::= multi_come_from COME_FROM
|
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
||||||
multi_come_from ::=
|
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
|
||||||
assert_end ::= multi_come_from POP_TOP
|
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_2
|
||||||
assert_end ::=
|
|
||||||
|
assert_expr ::= expr
|
||||||
assert ::= assert_expr jmp_true
|
|
||||||
LOAD_ASSERT RAISE_VARARGS assert_end
|
|
||||||
assert2 ::= assert_expr jmp_true
|
|
||||||
LOAD_ASSERT expr RAISE_VARARGS assert_end
|
|
||||||
assert ::= assert_expr jmp_true
|
|
||||||
LOAD_GLOBAL RAISE_VARARGS assert_end
|
|
||||||
assert2 ::= assert_expr jmp_true
|
|
||||||
LOAD_GLOBAL expr RAISE_VARARGS assert_end
|
|
||||||
|
|
||||||
assert_expr ::= assert_expr_or
|
assert_expr ::= assert_expr_or
|
||||||
assert_expr ::= assert_expr_and
|
assert_expr ::= assert_expr_and
|
||||||
assert_expr ::= expr
|
|
||||||
assert_expr_or ::= assert_expr jmp_true expr
|
assert_expr_or ::= assert_expr jmp_true expr
|
||||||
assert_expr_and ::= assert_expr jmp_false expr
|
assert_expr_and ::= assert_expr jmp_false expr
|
||||||
|
|
||||||
@@ -477,7 +472,7 @@ class Parser(GenericASTBuilder):
|
|||||||
except_suite ::= c_stmts_opt JUMP_FORWARD
|
except_suite ::= c_stmts_opt JUMP_FORWARD
|
||||||
except_suite ::= c_stmts_opt jmp_abs
|
except_suite ::= c_stmts_opt jmp_abs
|
||||||
except_suite ::= return_stmts
|
except_suite ::= return_stmts
|
||||||
|
|
||||||
except_cond1 ::= DUP_TOP expr COMPARE_OP
|
except_cond1 ::= DUP_TOP expr COMPARE_OP
|
||||||
jmp_false POP_TOP POP_TOP POP_TOP
|
jmp_false POP_TOP POP_TOP POP_TOP
|
||||||
|
|
||||||
@@ -638,12 +633,24 @@ class Parser(GenericASTBuilder):
|
|||||||
conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr
|
conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr
|
||||||
expr ::= conditionalnot
|
expr ::= conditionalnot
|
||||||
conditionalnot ::= expr jmp_true expr _jump expr COME_FROM
|
conditionalnot ::= expr jmp_true expr _jump expr COME_FROM
|
||||||
|
|
||||||
|
ret_expr ::= expr
|
||||||
|
ret_expr ::= ret_and
|
||||||
|
ret_expr ::= ret_or
|
||||||
|
|
||||||
|
ret_expr_or_cond ::= ret_expr
|
||||||
|
ret_expr_or_cond ::= ret_cond
|
||||||
|
ret_expr_or_cond ::= ret_cond_not
|
||||||
|
|
||||||
|
ret_and ::= expr jmp_false ret_expr_or_cond COME_FROM
|
||||||
|
ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM
|
||||||
|
ret_cond ::= expr jmp_false expr RETURN_END_IF ret_expr_or_cond
|
||||||
|
ret_cond_not ::= expr jmp_true expr RETURN_END_IF ret_expr_or_cond
|
||||||
|
|
||||||
stmt ::= return_lambda
|
stmt ::= return_lambda
|
||||||
stmt ::= conditional_lambda
|
stmt ::= conditional_lambda
|
||||||
stmt ::= conditional_lambda2
|
|
||||||
|
|
||||||
return_lambda ::= expr RETURN_VALUE LAMBDA_MARKER
|
return_lambda ::= ret_expr RETURN_VALUE LAMBDA_MARKER
|
||||||
conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER
|
conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER
|
||||||
|
|
||||||
cmp ::= cmp_list
|
cmp ::= cmp_list
|
||||||
@@ -744,7 +751,7 @@ def parse(tokens, customize):
|
|||||||
rule = 'unpack ::= ' + k + ' designator'*v
|
rule = 'unpack ::= ' + k + ' designator'*v
|
||||||
elif op == 'UNPACK_LIST':
|
elif op == 'UNPACK_LIST':
|
||||||
rule = 'unpack_list ::= ' + k + ' designator'*v
|
rule = 'unpack_list ::= ' + k + ' designator'*v
|
||||||
elif op == 'DUP_TOPX':
|
elif op in ('DUP_TOPX', 'RAISE_VARARGS'):
|
||||||
# no need to add a rule
|
# no need to add a rule
|
||||||
continue
|
continue
|
||||||
#rule = 'dup_topx ::= ' + 'expr '*v + k
|
#rule = 'dup_topx ::= ' + 'expr '*v + k
|
||||||
|
@@ -93,8 +93,8 @@ class Scanner(object):
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
def get_argument(self, pos):
|
def get_argument(self, pos):
|
||||||
target = self.code[pos+1] + self.code[pos+2] * 256
|
arg = self.code[pos+1] + self.code[pos+2] * 256
|
||||||
return target
|
return arg
|
||||||
|
|
||||||
def print_bytecode(self):
|
def print_bytecode(self):
|
||||||
for i in self.op_range(0, len(self.code)):
|
for i in self.op_range(0, len(self.code)):
|
||||||
|
@@ -62,7 +62,7 @@ class Scanner25(scan.Scanner):
|
|||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
if self.op_hasArgument(op):
|
if self.op_hasArgument(op):
|
||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
j = 0
|
j = 0
|
||||||
linestarts = self.linestarts
|
linestarts = self.linestarts
|
||||||
self.lines = []
|
self.lines = []
|
||||||
@@ -78,6 +78,13 @@ class Scanner25(scan.Scanner):
|
|||||||
while j < codelen:
|
while j < codelen:
|
||||||
self.lines.append(linetuple(prev_line_no, codelen))
|
self.lines.append(linetuple(prev_line_no, codelen))
|
||||||
j+=1
|
j+=1
|
||||||
|
|
||||||
|
self.load_asserts = set()
|
||||||
|
for i in self.op_range(0, codelen):
|
||||||
|
if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL:
|
||||||
|
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||||
|
self.load_asserts.add(i+3)
|
||||||
|
|
||||||
# self.lines contains (block,addrLastInstr)
|
# self.lines contains (block,addrLastInstr)
|
||||||
cf = self.find_jump_targets(self.code)
|
cf = self.find_jump_targets(self.code)
|
||||||
# contains (code, [addrRefToCode])
|
# contains (code, [addrRefToCode])
|
||||||
@@ -163,7 +170,7 @@ class Scanner25(scan.Scanner):
|
|||||||
UNPACK_SEQUENCE,
|
UNPACK_SEQUENCE,
|
||||||
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
||||||
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
||||||
CALL_FUNCTION_VAR_KW, DUP_TOPX,
|
CALL_FUNCTION_VAR_KW, DUP_TOPX, RAISE_VARARGS
|
||||||
):
|
):
|
||||||
# CE - Hack for >= 2.5
|
# CE - Hack for >= 2.5
|
||||||
# Now all values loaded via LOAD_CLOSURE are packed into
|
# Now all values loaded via LOAD_CLOSURE are packed into
|
||||||
@@ -185,11 +192,8 @@ class Scanner25(scan.Scanner):
|
|||||||
op_name = 'JUMP_BACK'
|
op_name = 'JUMP_BACK'
|
||||||
|
|
||||||
elif op == LOAD_GLOBAL:
|
elif op == LOAD_GLOBAL:
|
||||||
try:
|
if offset in self.load_asserts:
|
||||||
if pattr == 'AssertionError' and rv and rv[-1] == 'JUMP_IF_TRUE':
|
op_name = 'LOAD_ASSERT'
|
||||||
op_name = 'LOAD_ASSERT'
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
elif op == RETURN_VALUE:
|
elif op == RETURN_VALUE:
|
||||||
if offset in self.return_end_ifs:
|
if offset in self.return_end_ifs:
|
||||||
op_name = 'RETURN_END_IF'
|
op_name = 'RETURN_END_IF'
|
||||||
@@ -573,6 +577,7 @@ class Scanner25(scan.Scanner):
|
|||||||
if except_match:
|
if except_match:
|
||||||
jmp = self.prev[self.get_target(except_match)]
|
jmp = self.prev[self.get_target(except_match)]
|
||||||
self.ignore_if.add(except_match)
|
self.ignore_if.add(except_match)
|
||||||
|
self.not_continue.add(jmp)
|
||||||
return jmp
|
return jmp
|
||||||
|
|
||||||
count_END_FINALLY = 0
|
count_END_FINALLY = 0
|
||||||
@@ -584,6 +589,7 @@ class Scanner25(scan.Scanner):
|
|||||||
if self.code[self.prev[i]] == NOP:
|
if self.code[self.prev[i]] == NOP:
|
||||||
i = self.prev[i]
|
i = self.prev[i]
|
||||||
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
||||||
|
self.not_continue.add(self.prev[i])
|
||||||
return self.prev[i]
|
return self.prev[i]
|
||||||
count_END_FINALLY += 1
|
count_END_FINALLY += 1
|
||||||
elif op in (SETUP_EXCEPT, SETUP_FINALLY):
|
elif op in (SETUP_EXCEPT, SETUP_FINALLY):
|
||||||
@@ -784,6 +790,11 @@ class Scanner25(scan.Scanner):
|
|||||||
self.fixed_jumps[pos] = match[-1]
|
self.fixed_jumps[pos] = match[-1]
|
||||||
return
|
return
|
||||||
else: # op == PJIT
|
else: # op == PJIT
|
||||||
|
if (pos+3) in self.load_asserts:
|
||||||
|
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||||
|
return
|
||||||
|
self.load_asserts.remove(pos+3)
|
||||||
|
|
||||||
next = self.next_stmt[pos]
|
next = self.next_stmt[pos]
|
||||||
if pre[next] == pos:
|
if pre[next] == pos:
|
||||||
pass
|
pass
|
||||||
|
@@ -79,6 +79,13 @@ class Scanner26(scan.Scanner):
|
|||||||
self.lines.append(linetuple(prev_line_no, codelen))
|
self.lines.append(linetuple(prev_line_no, codelen))
|
||||||
j+=1
|
j+=1
|
||||||
# self.lines contains (block,addrLastInstr)
|
# self.lines contains (block,addrLastInstr)
|
||||||
|
|
||||||
|
self.load_asserts = set()
|
||||||
|
for i in self.op_range(0, codelen):
|
||||||
|
if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL:
|
||||||
|
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||||
|
self.load_asserts.add(i+3)
|
||||||
|
|
||||||
cf = self.find_jump_targets(self.code)
|
cf = self.find_jump_targets(self.code)
|
||||||
# contains (code, [addrRefToCode])
|
# contains (code, [addrRefToCode])
|
||||||
|
|
||||||
@@ -164,7 +171,7 @@ class Scanner26(scan.Scanner):
|
|||||||
UNPACK_SEQUENCE,
|
UNPACK_SEQUENCE,
|
||||||
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
||||||
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
||||||
CALL_FUNCTION_VAR_KW, DUP_TOPX,
|
CALL_FUNCTION_VAR_KW, DUP_TOPX, RAISE_VARARGS
|
||||||
):
|
):
|
||||||
# CE - Hack for >= 2.5
|
# CE - Hack for >= 2.5
|
||||||
# Now all values loaded via LOAD_CLOSURE are packed into
|
# Now all values loaded via LOAD_CLOSURE are packed into
|
||||||
@@ -186,11 +193,8 @@ class Scanner26(scan.Scanner):
|
|||||||
op_name = 'JUMP_BACK'
|
op_name = 'JUMP_BACK'
|
||||||
|
|
||||||
elif op == LOAD_GLOBAL:
|
elif op == LOAD_GLOBAL:
|
||||||
try:
|
if offset in self.load_asserts:
|
||||||
if pattr == 'AssertionError' and rv and rv[-1] == 'JUMP_IF_TRUE':
|
op_name = 'LOAD_ASSERT'
|
||||||
op_name = 'LOAD_ASSERT'
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
elif op == RETURN_VALUE:
|
elif op == RETURN_VALUE:
|
||||||
if offset in self.return_end_ifs:
|
if offset in self.return_end_ifs:
|
||||||
op_name = 'RETURN_END_IF'
|
op_name = 'RETURN_END_IF'
|
||||||
@@ -569,6 +573,7 @@ class Scanner26(scan.Scanner):
|
|||||||
if except_match:
|
if except_match:
|
||||||
jmp = self.prev[self.get_target(except_match)]
|
jmp = self.prev[self.get_target(except_match)]
|
||||||
self.ignore_if.add(except_match)
|
self.ignore_if.add(except_match)
|
||||||
|
self.not_continue.add(jmp)
|
||||||
return jmp
|
return jmp
|
||||||
|
|
||||||
count_END_FINALLY = 0
|
count_END_FINALLY = 0
|
||||||
@@ -580,6 +585,7 @@ class Scanner26(scan.Scanner):
|
|||||||
if self.code[self.prev[i]] == NOP:
|
if self.code[self.prev[i]] == NOP:
|
||||||
i = self.prev[i]
|
i = self.prev[i]
|
||||||
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
||||||
|
self.not_continue.add(self.prev[i])
|
||||||
return self.prev[i]
|
return self.prev[i]
|
||||||
count_END_FINALLY += 1
|
count_END_FINALLY += 1
|
||||||
elif op in (SETUP_EXCEPT, SETUP_FINALLY):
|
elif op in (SETUP_EXCEPT, SETUP_FINALLY):
|
||||||
@@ -783,6 +789,11 @@ class Scanner26(scan.Scanner):
|
|||||||
self.fixed_jumps[pos] = match[-1]
|
self.fixed_jumps[pos] = match[-1]
|
||||||
return
|
return
|
||||||
else: # op == PJIT
|
else: # op == PJIT
|
||||||
|
if (pos+3) in self.load_asserts:
|
||||||
|
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||||
|
return
|
||||||
|
self.load_asserts.remove(pos+3)
|
||||||
|
|
||||||
next = self.next_stmt[pos]
|
next = self.next_stmt[pos]
|
||||||
if pre[next] == pos:
|
if pre[next] == pos:
|
||||||
pass
|
pass
|
||||||
|
@@ -56,8 +56,6 @@ class Scanner27(scan.Scanner):
|
|||||||
self.lines.append(linetuple(prev_line_no, n))
|
self.lines.append(linetuple(prev_line_no, n))
|
||||||
j+=1
|
j+=1
|
||||||
# self.lines contains (block,addrLastInstr)
|
# self.lines contains (block,addrLastInstr)
|
||||||
cf = self.find_jump_targets(code)
|
|
||||||
# contains (code, [addrRefToCode])
|
|
||||||
if classname:
|
if classname:
|
||||||
classname = '_' + classname.lstrip('_') + '__'
|
classname = '_' + classname.lstrip('_') + '__'
|
||||||
def unmangle(name):
|
def unmangle(name):
|
||||||
@@ -73,6 +71,14 @@ class Scanner27(scan.Scanner):
|
|||||||
names = co.co_names
|
names = co.co_names
|
||||||
varnames = co.co_varnames
|
varnames = co.co_varnames
|
||||||
|
|
||||||
|
self.load_asserts = set()
|
||||||
|
for i in self.op_range(0, n):
|
||||||
|
if code[i] == PJIT and code[i+3] == LOAD_GLOBAL:
|
||||||
|
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||||
|
self.load_asserts.add(i+3)
|
||||||
|
|
||||||
|
cf = self.find_jump_targets(code)
|
||||||
|
# contains (code, [addrRefToCode])
|
||||||
last_stmt = self.next_stmt[0]
|
last_stmt = self.next_stmt[0]
|
||||||
i = self.next_stmt[last_stmt]
|
i = self.next_stmt[last_stmt]
|
||||||
replace = {}
|
replace = {}
|
||||||
@@ -108,7 +114,7 @@ class Scanner27(scan.Scanner):
|
|||||||
op_name = opname[op]
|
op_name = opname[op]
|
||||||
oparg = None; pattr = None
|
oparg = None; pattr = None
|
||||||
if op >= HAVE_ARGUMENT:
|
if op >= HAVE_ARGUMENT:
|
||||||
oparg = code[offset+1] + code[offset+2] * 256 + extended_arg
|
oparg = self.get_argument(offset) + extended_arg
|
||||||
extended_arg = 0
|
extended_arg = 0
|
||||||
if op == EXTENDED_ARG:
|
if op == EXTENDED_ARG:
|
||||||
extended_arg = oparg * 65536L
|
extended_arg = oparg * 65536L
|
||||||
@@ -151,7 +157,7 @@ class Scanner27(scan.Scanner):
|
|||||||
UNPACK_SEQUENCE,
|
UNPACK_SEQUENCE,
|
||||||
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
MAKE_FUNCTION, CALL_FUNCTION, MAKE_CLOSURE,
|
||||||
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
CALL_FUNCTION_VAR, CALL_FUNCTION_KW,
|
||||||
CALL_FUNCTION_VAR_KW, DUP_TOPX,
|
CALL_FUNCTION_VAR_KW, DUP_TOPX, RAISE_VARARGS
|
||||||
):
|
):
|
||||||
# CE - Hack for >= 2.5
|
# CE - Hack for >= 2.5
|
||||||
# Now all values loaded via LOAD_CLOSURE are packed into
|
# Now all values loaded via LOAD_CLOSURE are packed into
|
||||||
@@ -173,11 +179,8 @@ class Scanner27(scan.Scanner):
|
|||||||
op_name = 'JUMP_BACK'
|
op_name = 'JUMP_BACK'
|
||||||
|
|
||||||
elif op == LOAD_GLOBAL:
|
elif op == LOAD_GLOBAL:
|
||||||
try:
|
if offset in self.load_asserts:
|
||||||
if pattr == 'AssertionError' and rv and rv[-1] == 'POP_JUMP_IF_TRUE':
|
op_name = 'LOAD_ASSERT'
|
||||||
op_name = 'LOAD_ASSERT'
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
elif op == RETURN_VALUE:
|
elif op == RETURN_VALUE:
|
||||||
if offset in self.return_end_ifs:
|
if offset in self.return_end_ifs:
|
||||||
op_name = 'RETURN_END_IF'
|
op_name = 'RETURN_END_IF'
|
||||||
@@ -299,6 +302,7 @@ class Scanner27(scan.Scanner):
|
|||||||
if except_match:
|
if except_match:
|
||||||
jmp = self.prev[self.get_target(except_match)]
|
jmp = self.prev[self.get_target(except_match)]
|
||||||
self.ignore_if.add(except_match)
|
self.ignore_if.add(except_match)
|
||||||
|
self.not_continue.add(jmp)
|
||||||
return jmp
|
return jmp
|
||||||
|
|
||||||
count_END_FINALLY = 0
|
count_END_FINALLY = 0
|
||||||
@@ -308,6 +312,7 @@ class Scanner27(scan.Scanner):
|
|||||||
if op == END_FINALLY:
|
if op == END_FINALLY:
|
||||||
if count_END_FINALLY == count_SETUP_:
|
if count_END_FINALLY == count_SETUP_:
|
||||||
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
assert self.code[self.prev[i]] in (JA, JF, RETURN_VALUE)
|
||||||
|
self.not_continue.add(self.prev[i])
|
||||||
return self.prev[i]
|
return self.prev[i]
|
||||||
count_END_FINALLY += 1
|
count_END_FINALLY += 1
|
||||||
elif op in (SETUP_EXCEPT, SETUP_WITH, SETUP_FINALLY):
|
elif op in (SETUP_EXCEPT, SETUP_WITH, SETUP_FINALLY):
|
||||||
@@ -503,6 +508,11 @@ class Scanner27(scan.Scanner):
|
|||||||
self.fixed_jumps[pos] = match[-1]
|
self.fixed_jumps[pos] = match[-1]
|
||||||
return
|
return
|
||||||
else: # op == PJIT
|
else: # op == PJIT
|
||||||
|
if (pos+3) in self.load_asserts:
|
||||||
|
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||||
|
return
|
||||||
|
self.load_asserts.remove(pos+3)
|
||||||
|
|
||||||
next = self.next_stmt[pos]
|
next = self.next_stmt[pos]
|
||||||
if pre[next] == pos:
|
if pre[next] == pos:
|
||||||
pass
|
pass
|
||||||
@@ -511,19 +521,30 @@ class Scanner27(scan.Scanner):
|
|||||||
if code[next] == JF or target != rtarget or code[pre[pre[rtarget]]] not in (JA, RETURN_VALUE):
|
if code[next] == JF or target != rtarget or code[pre[pre[rtarget]]] not in (JA, RETURN_VALUE):
|
||||||
self.fixed_jumps[pos] = pre[next]
|
self.fixed_jumps[pos] = pre[next]
|
||||||
return
|
return
|
||||||
elif code[next] == JA and code[target] in (JA, JF) \
|
elif code[next] == JA and code[target] in (JA, JF):
|
||||||
and self.get_target(target) == self.get_target(next):
|
next_target = self.get_target(next)
|
||||||
self.fixed_jumps[pos] = pre[next]
|
if self.get_target(target) == next_target:
|
||||||
return
|
self.fixed_jumps[pos] = pre[next]
|
||||||
|
return
|
||||||
|
elif code[next_target] in (JA, JF) and self.get_target(next_target) == self.get_target(target):
|
||||||
|
self.fixed_jumps[pos] = pre[next]
|
||||||
|
return
|
||||||
|
|
||||||
#don't add a struct for a while test, it's already taken care of
|
#don't add a struct for a while test, it's already taken care of
|
||||||
if pos in self.ignore_if:
|
if pos in self.ignore_if:
|
||||||
return
|
return
|
||||||
|
|
||||||
if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \
|
if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \
|
||||||
and pre[rtarget] != pos and pre[pre[rtarget]] != pos \
|
and pre[rtarget] != pos and pre[pre[rtarget]] != pos:
|
||||||
and not (code[rtarget] == JA and code[rtarget+3] == POP_BLOCK and code[pre[pre[rtarget]]] != JA):
|
if code[rtarget] == JA and code[rtarget+3] == POP_BLOCK:
|
||||||
rtarget = pre[rtarget]
|
if code[pre[pre[rtarget]]] != JA:
|
||||||
|
pass
|
||||||
|
elif self.get_target(pre[pre[rtarget]]) != target:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
rtarget = pre[rtarget]
|
||||||
|
else:
|
||||||
|
rtarget = pre[rtarget]
|
||||||
#does the if jump just beyond a jump op, then this is probably an if statement
|
#does the if jump just beyond a jump op, then this is probably an if statement
|
||||||
if code[pre[rtarget]] in (JA, JF):
|
if code[pre[rtarget]] in (JA, JF):
|
||||||
if_end = self.get_target(pre[rtarget])
|
if_end = self.get_target(pre[rtarget])
|
||||||
@@ -552,15 +573,7 @@ class Scanner27(scan.Scanner):
|
|||||||
|
|
||||||
elif op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
elif op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
||||||
target = self.get_target(pos, op)
|
target = self.get_target(pos, op)
|
||||||
if target > pos:
|
self.fixed_jumps[pos] = self.restrict_to_parent(target, parent)
|
||||||
unop_target = self.last_instr(pos, target, JF, target)
|
|
||||||
if unop_target and code[unop_target+3] != ROT_TWO:
|
|
||||||
self.fixed_jumps[pos] = unop_target
|
|
||||||
else:
|
|
||||||
self.fixed_jumps[pos] = self.restrict_to_parent(target, parent)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_jump_targets(self, code):
|
def find_jump_targets(self, code):
|
||||||
'''
|
'''
|
||||||
|
@@ -54,7 +54,7 @@ minint = -sys.maxint-1
|
|||||||
# the end of functions).
|
# the end of functions).
|
||||||
|
|
||||||
RETURN_LOCALS = AST('return_stmt',
|
RETURN_LOCALS = AST('return_stmt',
|
||||||
[ AST('expr', [ Token('LOAD_LOCALS') ]),
|
[ AST('ret_expr', [AST('expr', [ Token('LOAD_LOCALS') ])]),
|
||||||
Token('RETURN_VALUE')])
|
Token('RETURN_VALUE')])
|
||||||
|
|
||||||
|
|
||||||
@@ -199,13 +199,15 @@ TABLE_DIRECT = {
|
|||||||
# 'dup_topx': ( '%c', 0),
|
# 'dup_topx': ( '%c', 0),
|
||||||
'designList': ( '%c = %c', 0, -1 ),
|
'designList': ( '%c = %c', 0, -1 ),
|
||||||
'and': ( '%c and %c', 0, 2 ),
|
'and': ( '%c and %c', 0, 2 ),
|
||||||
|
'ret_and': ( '%c and %c', 0, 2 ),
|
||||||
'and2': ( '%c', 3 ),
|
'and2': ( '%c', 3 ),
|
||||||
'or': ( '%c or %c', 0, 2 ),
|
'or': ( '%c or %c', 0, 2 ),
|
||||||
|
'ret_or': ( '%c or %c', 0, 2 ),
|
||||||
'conditional': ( '%p if %p else %p', (2,27), (0,27), (4,27)),
|
'conditional': ( '%p if %p else %p', (2,27), (0,27), (4,27)),
|
||||||
'conditionaland': ( '%p if %p and %p else %p', (4,27), (0,24), (2,24), (6,27)),
|
'ret_cond': ( '%p if %p else %p', (2,27), (0,27), (4,27)),
|
||||||
'conditionalnot': ( '%p if not %p else %p', (2,27), (0,22), (4,27)),
|
'conditionalnot': ( '%p if not %p else %p', (2,27), (0,22), (4,27)),
|
||||||
|
'ret_cond_not': ( '%p if not %p else %p', (2,27), (0,22), (4,27)),
|
||||||
'conditional_lambda': ( '(%c if %c else %c)', 2, 0, 3),
|
'conditional_lambda': ( '(%c if %c else %c)', 2, 0, 3),
|
||||||
'conditional_lambda2': ( '(%c if %p and %p else %c)', 4, (0,24), (2,24), 5),
|
|
||||||
'return_lambda': ('%c', 0),
|
'return_lambda': ('%c', 0),
|
||||||
'compare': ( '%p %[-1]{pattr} %p', (0,19), (1,19) ),
|
'compare': ( '%p %[-1]{pattr} %p', (0,19), (1,19) ),
|
||||||
'cmp_list': ( '%p %p', (0,20), (1,19)),
|
'cmp_list': ( '%p %p', (0,20), (1,19)),
|
||||||
@@ -237,8 +239,11 @@ TABLE_DIRECT = {
|
|||||||
'call_stmt': ( '%|%p\n', (0,200)),
|
'call_stmt': ( '%|%p\n', (0,200)),
|
||||||
'break_stmt': ( '%|break\n', ),
|
'break_stmt': ( '%|break\n', ),
|
||||||
'continue_stmt': ( '%|continue\n', ),
|
'continue_stmt': ( '%|continue\n', ),
|
||||||
'jcontinue_stmt': ( '%|continue\n', ),
|
|
||||||
'raise_stmt': ( '%|raise %[0]C\n', (0,sys.maxint,', ') ),
|
'raise_stmt0': ( '%|raise\n', ),
|
||||||
|
'raise_stmt1': ( '%|raise %c\n', 0),
|
||||||
|
'raise_stmt2': ( '%|raise %c, %c\n', 0, 1),
|
||||||
|
'raise_stmt3': ( '%|raise %c, %c, %c\n', 0, 1, 2),
|
||||||
# 'yield': ( 'yield %c', 0),
|
# 'yield': ( 'yield %c', 0),
|
||||||
# 'return_stmt': ( '%|return %c\n', 0),
|
# 'return_stmt': ( '%|return %c\n', 0),
|
||||||
|
|
||||||
@@ -365,12 +370,15 @@ PRECEDENCE = {
|
|||||||
'unary_not': 22,
|
'unary_not': 22,
|
||||||
|
|
||||||
'and': 24,
|
'and': 24,
|
||||||
|
'ret_and': 24,
|
||||||
|
|
||||||
'or': 26,
|
'or': 26,
|
||||||
|
'ret_or': 26,
|
||||||
|
|
||||||
'conditional': 28,
|
'conditional': 28,
|
||||||
'conditionaland': 28,
|
|
||||||
'conditionalnot': 28,
|
'conditionalnot': 28,
|
||||||
|
'ret_cond': 28,
|
||||||
|
'ret_cond_not': 28,
|
||||||
|
|
||||||
'_mklambda': 30,
|
'_mklambda': 30,
|
||||||
'yield': 101
|
'yield': 101
|
||||||
@@ -593,7 +601,7 @@ class Walker(GenericASTTraversal, object):
|
|||||||
self.prune()
|
self.prune()
|
||||||
else:
|
else:
|
||||||
self.write(self.indent, 'return')
|
self.write(self.indent, 'return')
|
||||||
if self.return_none or node != AST('return_stmt', [NONE, Token('RETURN_VALUE')]):
|
if self.return_none or node != AST('return_stmt', [AST('ret_expr', [NONE]), Token('RETURN_VALUE')]):
|
||||||
self.write(' ')
|
self.write(' ')
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.print_()
|
self.print_()
|
||||||
@@ -605,7 +613,7 @@ class Walker(GenericASTTraversal, object):
|
|||||||
self.prune()
|
self.prune()
|
||||||
else:
|
else:
|
||||||
self.write(self.indent, 'return')
|
self.write(self.indent, 'return')
|
||||||
if self.return_none or node != AST('return_if_stmt', [NONE, Token('RETURN_END_IF')]):
|
if self.return_none or node != AST('return_stmt', [AST('ret_expr', [NONE]), Token('RETURN_END_IF')]):
|
||||||
self.write(' ')
|
self.write(' ')
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.print_()
|
self.print_()
|
||||||
@@ -667,7 +675,15 @@ class Walker(GenericASTTraversal, object):
|
|||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
|
def n_ret_expr(self, node):
|
||||||
|
if len(node) == 1 and node[0] == 'expr':
|
||||||
|
self.n_expr(node[0])
|
||||||
|
else:
|
||||||
|
self.n_expr(node)
|
||||||
|
|
||||||
|
n_ret_expr_or_cond = n_expr
|
||||||
|
|
||||||
def n_binary_expr(self, node):
|
def n_binary_expr(self, node):
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(' ')
|
self.write(' ')
|
||||||
@@ -1073,6 +1089,11 @@ class Walker(GenericASTTraversal, object):
|
|||||||
n[0].type = 'unpack_w_parens'
|
n[0].type = 'unpack_w_parens'
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
|
def n_except_cond2(self, node):
|
||||||
|
if node[5][0] == 'unpack':
|
||||||
|
node[5][0].type = 'unpack_w_parens'
|
||||||
|
self.default(node)
|
||||||
|
|
||||||
def engine(self, entry, startnode):
|
def engine(self, entry, startnode):
|
||||||
#self.print_("-----")
|
#self.print_("-----")
|
||||||
#self.print_(str(startnode.__dict__))
|
#self.print_(str(startnode.__dict__))
|
||||||
|
Reference in New Issue
Block a user