return compile(source, name, 'exec')
def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False,
- show_offsets=False, show_positions=False):
+ show_offsets=False, show_positions=False, show_jit=False):
"""Disassemble classes, methods, functions, and other compiled objects.
With no argument, disassemble the last traceback.
"""
if x is None:
distb(file=file, show_caches=show_caches, adaptive=adaptive,
- show_offsets=show_offsets, show_positions=show_positions)
+ show_offsets=show_offsets, show_positions=show_positions,
+ show_jit=show_jit)
return
# Extract functions from methods.
if hasattr(x, '__func__'):
if isinstance(x1, _have_code):
print("Disassembly of %s:" % name, file=file)
try:
- dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions)
+ dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive,
+ show_offsets=show_offsets, show_positions=show_positions, show_jit=show_jit)
except TypeError as msg:
print("Sorry:", msg, file=file)
print(file=file)
elif hasattr(x, 'co_code'): # Code object
- _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions)
+ _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive,
+ show_offsets=show_offsets, show_positions=show_positions, show_jit=show_jit)
elif isinstance(x, (bytes, bytearray)): # Raw bytecode
labels_map = _make_labels_map(x)
label_width = 4 + len(str(len(labels_map)))
arg_resolver = ArgResolver(labels_map=labels_map)
_disassemble_bytes(x, arg_resolver=arg_resolver, formatter=formatter)
elif isinstance(x, str): # Source code
- _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions)
+ _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive,
+ show_offsets=show_offsets, show_positions=show_positions, show_jit=show_jit)
else:
raise TypeError("don't know how to disassemble %s objects" %
type(x).__name__)
-def distb(tb=None, *, file=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False):
+def distb(tb=None, *, file=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False, show_jit=False):
"""Disassemble a traceback (default: last traceback)."""
if tb is None:
try:
except AttributeError:
raise RuntimeError("no last traceback to disassemble") from None
while tb.tb_next: tb = tb.tb_next
- disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions)
+ disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive,
+ show_offsets=show_offsets, show_positions=show_positions, show_jit=show_jit)
# The inspect module interrogates this dictionary to build its
# list of CO_* constants. It is also used by pretty_flags to
name = _all_opname[op]
return _all_opmap[deoptmap[name]] if name in deoptmap else op
-def _get_code_array(co, adaptive):
+def _get_code_array(co, adaptive, show_jit):
if adaptive:
code = co._co_code_adaptive
res = []
found = False
for i in range(0, len(code), 2):
op, arg = code[i], code[i+1]
- if op == ENTER_EXECUTOR:
+ if op == ENTER_EXECUTOR and not show_jit:
try:
ex = get_executor(co, i)
except (ValueError, RuntimeError):
argrepr = 'not in' if argval else 'in'
return argval, argrepr
-def get_instructions(x, *, first_line=None, show_caches=None, adaptive=False):
+def get_instructions(x, *, first_line=None, show_caches=None, adaptive=False, show_jit=False):
"""Iterator for the opcodes in methods, functions or code
Generates a series of Instruction named tuples giving the details of
names=co.co_names,
varname_from_oparg=co._varname_from_oparg,
labels_map=_make_labels_map(original_code))
- return _get_instructions_bytes(_get_code_array(co, adaptive),
+ return _get_instructions_bytes(_get_code_array(co, adaptive, show_jit),
linestarts=linestarts,
line_offset=line_offset,
co_positions=co.co_positions(),
positions = Positions(*next(co_positions, ()))
deop = _deoptop(op)
op = code[offset]
+ if op == ENTER_EXECUTOR:
+ arg = code[offset+1]
if arg_resolver:
argval, argrepr = arg_resolver.get_argval_argrepr(op, arg, offset)
def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False,
- show_offsets=False, show_positions=False):
+ show_offsets=False, show_positions=False, show_jit=False):
"""Disassemble a code object."""
linestarts = dict(findlinestarts(co))
exception_entries = _parse_exception_table(co)
names=co.co_names,
varname_from_oparg=co._varname_from_oparg,
labels_map=labels_map)
- _disassemble_bytes(_get_code_array(co, adaptive), lasti, linestarts,
+ _disassemble_bytes(_get_code_array(co, adaptive, show_jit), lasti, linestarts,
exception_entries=exception_entries, co_positions=co.co_positions(),
original_code=co.co_code, arg_resolver=arg_resolver, formatter=formatter)
-def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False):
- disassemble(co, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions)
+def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False, show_jit=False):
+ disassemble(co, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions, show_jit=show_jit)
if depth is None or depth > 0:
if depth is not None:
depth = depth - 1
print("Disassembly of %r:" % (x,), file=file)
_disassemble_recursive(
x, file=file, depth=depth, show_caches=show_caches,
- adaptive=adaptive, show_offsets=show_offsets, show_positions=show_positions
+ adaptive=adaptive, show_offsets=show_offsets,
+ show_positions=show_positions, show_jit=show_jit
)
Iterating over this yields the bytecode operations as Instruction instances.
"""
- def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False):
+ def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False, show_jit=False):
self.codeobj = co = _get_code_object(x)
if first_line is None:
self.first_line = co.co_firstlineno
self.adaptive = adaptive
self.show_offsets = show_offsets
self.show_positions = show_positions
+ self.show_jit = show_jit
def __iter__(self):
co = self.codeobj
names=co.co_names,
varname_from_oparg=co._varname_from_oparg,
labels_map=labels_map)
- return _get_instructions_bytes(_get_code_array(co, self.adaptive),
+ return _get_instructions_bytes(_get_code_array(co, self.adaptive, self.show_jit),
linestarts=self._linestarts,
line_offset=self._line_offset,
co_positions=co.co_positions(),
else:
offset = -1
with io.StringIO() as output:
- code = _get_code_array(co, self.adaptive)
+ code = _get_code_array(co, self.adaptive, self.show_jit)
offset_width = len(str(max(len(code) - 2, 9999))) if self.show_offsets else 0
if self.show_positions:
lineno_width = _get_positions_width(co)