summaryrefslogtreecommitdiff
path: root/Lib/dis.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/dis.py')
-rw-r--r--Lib/dis.py49
1 files changed, 26 insertions, 23 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index f7e3c7f8d7..59886f1e37 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -163,6 +163,15 @@ def show_code(co, *, file=None):
_Instruction = collections.namedtuple("_Instruction",
"opname opcode arg argval argrepr offset starts_line is_jump_target")
+_Instruction.opname.__doc__ = "Human readable name for operation"
+_Instruction.opcode.__doc__ = "Numeric code for operation"
+_Instruction.arg.__doc__ = "Numeric argument to operation (if any), otherwise None"
+_Instruction.argval.__doc__ = "Resolved arg value (if known), otherwise same as arg"
+_Instruction.argrepr.__doc__ = "Human readable description of operation argument"
+_Instruction.offset.__doc__ = "Start index of operation within bytecode sequence"
+_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None"
+_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False"
+
class Instruction(_Instruction):
"""Details for a bytecode operation
@@ -276,7 +285,6 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
"""
labels = findlabels(code)
starts_line = None
- free = None
for offset, op, arg in _unpack_opargs(code):
if linestarts is not None:
starts_line = linestarts.get(offset, None)
@@ -296,7 +304,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
elif op in hasname:
argval, argrepr = _get_name_info(arg, names)
elif op in hasjrel:
- argval = offset + 3 + arg
+ argval = offset + 2 + arg
argrepr = "to " + repr(argval)
elif op in haslocal:
argval, argrepr = _get_name_info(arg, varnames)
@@ -343,23 +351,15 @@ def _disassemble_str(source, *, file=None):
disco = disassemble # XXX For backwards compatibility
def _unpack_opargs(code):
- # enumerate() is not an option, since we sometimes process
- # multiple elements on a single pass through the loop
extended_arg = 0
- n = len(code)
- i = 0
- while i < n:
+ for i in range(0, len(code), 2):
op = code[i]
- offset = i
- i = i+1
- arg = None
if op >= HAVE_ARGUMENT:
- arg = code[i] + code[i+1]*256 + extended_arg
- extended_arg = 0
- i = i+2
- if op == EXTENDED_ARG:
- extended_arg = arg*65536
- yield (offset, op, arg)
+ arg = code[i+1] | extended_arg
+ extended_arg = (arg << 8) if op == EXTENDED_ARG else 0
+ else:
+ arg = None
+ yield (i, op, arg)
def findlabels(code):
"""Detect all offsets in a byte code which are jump targets.
@@ -370,14 +370,14 @@ def findlabels(code):
labels = []
for offset, op, arg in _unpack_opargs(code):
if arg is not None:
- label = -1
if op in hasjrel:
- label = offset + 3 + arg
+ label = offset + 2 + arg
elif op in hasjabs:
label = arg
- if label >= 0:
- if label not in labels:
- labels.append(label)
+ else:
+ continue
+ if label not in labels:
+ labels.append(label)
return labels
def findlinestarts(code):
@@ -386,8 +386,8 @@ def findlinestarts(code):
Generate pairs (offset, lineno) as described in Python/compile.c.
"""
- byte_increments = list(code.co_lnotab[0::2])
- line_increments = list(code.co_lnotab[1::2])
+ byte_increments = code.co_lnotab[0::2]
+ line_increments = code.co_lnotab[1::2]
lastlineno = None
lineno = code.co_firstlineno
@@ -398,6 +398,9 @@ def findlinestarts(code):
yield (addr, lineno)
lastlineno = lineno
addr += byte_incr
+ if line_incr >= 0x80:
+ # line_increments is an array of 8-bit signed integers
+ line_incr -= 0x100
lineno += line_incr
if lineno != lastlineno:
yield (addr, lineno)