You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Correct EXTENDED_ARG handling on Python 3.6...
where it can appear several times and xdis may handle it as well. It possibly in other versions bug since EXTENDED_ARG is used so rarely there because it has such a high value 1<<16, it's hard to test and determine that.
This commit is contained in:
@@ -138,6 +138,13 @@ class Scanner3(Scanner):
|
|||||||
# FIXME: remove the above in favor of:
|
# FIXME: remove the above in favor of:
|
||||||
# self.varargs_ops = frozenset(self.opc.hasvargs)
|
# self.varargs_ops = frozenset(self.opc.hasvargs)
|
||||||
|
|
||||||
|
def extended_arg_val(self, val):
|
||||||
|
if self.version < 3.6:
|
||||||
|
return val * (1<<16)
|
||||||
|
else:
|
||||||
|
return val * (1<<8)
|
||||||
|
|
||||||
|
|
||||||
def ingest(self, co, classname=None, code_objects={}, show_asm=None):
|
def ingest(self, co, classname=None, code_objects={}, show_asm=None):
|
||||||
"""
|
"""
|
||||||
Pick out tokens from an uncompyle6 code object, and transform them,
|
Pick out tokens from an uncompyle6 code object, and transform them,
|
||||||
@@ -212,8 +219,25 @@ class Scanner3(Scanner):
|
|||||||
for i, inst in enumerate(bytecode):
|
for i, inst in enumerate(bytecode):
|
||||||
|
|
||||||
argval = inst.argval
|
argval = inst.argval
|
||||||
if isinstance(argval, int):
|
op = inst.opcode
|
||||||
argval += extended_arg
|
has_arg = op_has_argument(op, self.opc)
|
||||||
|
if has_arg:
|
||||||
|
if op == self.opc.EXTENDED_ARG:
|
||||||
|
extended_arg += self.extended_arg_val(argval)
|
||||||
|
|
||||||
|
# Normally we remove EXTENDED_ARG from the
|
||||||
|
# opcodes, but in the case of annotated functions
|
||||||
|
# can use the EXTENDED_ARG tuple to signal we have
|
||||||
|
# an annotated function.
|
||||||
|
if not bs[i+1].opname.startswith("MAKE_FUNCTION"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if isinstance(argval, int) and extended_arg:
|
||||||
|
min_extended= self.extended_arg_val(1)
|
||||||
|
if argval < min_extended:
|
||||||
|
argval += extended_arg
|
||||||
|
extended_arg = 0
|
||||||
|
|
||||||
if inst.offset in jump_targets:
|
if inst.offset in jump_targets:
|
||||||
jump_idx = 0
|
jump_idx = 0
|
||||||
# We want to process COME_FROMs to the same offset to be in *descending*
|
# We want to process COME_FROMs to the same offset to be in *descending*
|
||||||
@@ -252,23 +276,6 @@ class Scanner3(Scanner):
|
|||||||
|
|
||||||
pattr = inst.argrepr
|
pattr = inst.argrepr
|
||||||
opname = inst.opname
|
opname = inst.opname
|
||||||
op = inst.opcode
|
|
||||||
|
|
||||||
has_arg = op_has_argument(op, self.opc)
|
|
||||||
if has_arg:
|
|
||||||
extended_arg = 0
|
|
||||||
if op == self.opc.EXTENDED_ARG:
|
|
||||||
if self.version < 3.6:
|
|
||||||
extended_arg = argval * (1<<16)
|
|
||||||
else:
|
|
||||||
extended_arg = argval * (1<<8)
|
|
||||||
|
|
||||||
# Normally we remove EXTENDED_ARG from the
|
|
||||||
# opcodes, but in the case of annotated functions
|
|
||||||
# can use the EXTENDED_ARG tuple to signal we have
|
|
||||||
# an annotated function.
|
|
||||||
if not bs[i+1].opname.startswith("MAKE_FUNCTION"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if opname in ['LOAD_CONST']:
|
if opname in ['LOAD_CONST']:
|
||||||
const = argval
|
const = argval
|
||||||
|
Reference in New Issue
Block a user