You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
EXTENDED_ARG handling...
get_target() wasn't taking into account EXTENDED_ARG before opcode. This is mostly relevant in Python 3.6 where the max size before needing EXTENDED_ARG has been reduced to 256, but theoretically possible in earlier versions.
This commit is contained in:
@@ -61,6 +61,8 @@ class Python36Parser(Python35Parser):
|
||||
continue_stmt ::= EXTENDED_ARG CONTINUE_LOOP
|
||||
|
||||
for_block ::= l_stmts_opt opt_come_from_loop jump_back
|
||||
cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
|
||||
EXTENDED_ARG JUMP_IF_FALSE_OR_POP cmp_list2 COME_FROM
|
||||
|
||||
|
||||
# 3.6 redoes how return_closure works
|
||||
|
@@ -27,6 +27,7 @@ from array import array
|
||||
|
||||
from uncompyle6.scanner import Scanner, op_has_argument
|
||||
from xdis.code import iscode
|
||||
from xdis.util import code2num
|
||||
from xdis.bytecode import Bytecode
|
||||
from uncompyle6.scanner import Token, parse_fn_counts
|
||||
|
||||
@@ -603,15 +604,27 @@ class Scanner3(Scanner):
|
||||
Get target offset for op located at given <offset>.
|
||||
"""
|
||||
op = self.code[offset]
|
||||
rel_offset = 0
|
||||
if self.version >= 3.6:
|
||||
target = self.code[offset+1]
|
||||
arg_offset = 1
|
||||
extended_arg_mult = 1 << 8
|
||||
if op in self.opc.hasjrel:
|
||||
target += offset + 2
|
||||
rel_offset = offset + 2
|
||||
else:
|
||||
target = self.code[offset+1] + self.code[offset+2] * 256
|
||||
arg_offset = 2
|
||||
extended_arg_mult = 1 << 16
|
||||
if op in self.opc.hasjrel:
|
||||
target += offset + 3
|
||||
|
||||
rel_offset = offset + 3
|
||||
pass
|
||||
pass
|
||||
target += rel_offset
|
||||
prev_offset = self.prev_op[offset]
|
||||
prev_op = code2num(self.code, prev_offset)
|
||||
if prev_op == self.opc.EXTENDED_ARG:
|
||||
target += (code2num(self.code, prev_offset + arg_offset) * extended_arg_mult)
|
||||
pass
|
||||
return target
|
||||
|
||||
def detect_control_flow(self, offset, targets):
|
||||
@@ -755,7 +768,7 @@ class Scanner3(Scanner):
|
||||
pre_rtarget = prev_op[rtarget]
|
||||
|
||||
# Is it an "and" inside an "if" or "while" block
|
||||
if op == self.opc.POP_JUMP_IF_FALSE:
|
||||
if op == self.opc.POP_JUMP_IF_FALSE and self.version < 3.6:
|
||||
|
||||
# Search for another POP_JUMP_IF_FALSE targetting the same op,
|
||||
# in current statement, starting from current offset, and filter
|
||||
|
Reference in New Issue
Block a user