Skip to content

Commit

Permalink
pythongh-112720: make it easier to subclass and modify dis.ArgResolve…
Browse files Browse the repository at this point in the history
…r's jump arg resolution
  • Loading branch information
iritkatriel committed Feb 16, 2024
1 parent f92857a commit 7bff89d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
30 changes: 19 additions & 11 deletions Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,20 @@ def __init__(self, co_consts=None, names=None, varname_from_oparg=None, labels_m
self.varname_from_oparg = varname_from_oparg
self.labels_map = labels_map or {}

def offset_from_jump_arg(self, op, arg, offset):
deop = _deoptop(op)
if deop in hasjabs:
return arg * 2
elif deop in hasjrel:
signed_arg = -arg if _is_backward_jump(deop) else arg
argval = offset + 2 + signed_arg*2
caches = _get_cache_size(_all_opname[deop])
argval += 2 * caches
if deop == ENTER_EXECUTOR:
argval += 2
return argval
return None

def get_label_for_offset(self, offset):
return self.labels_map.get(offset, None)

Expand Down Expand Up @@ -536,17 +550,11 @@ def get_argval_argrepr(self, op, arg, offset):
argrepr = f"{argrepr} + NULL|self"
else:
argval, argrepr = _get_name_info(arg, get_name)
elif deop in hasjabs:
argval = arg*2
argrepr = f"to L{self.labels_map[argval]}"
elif deop in hasjrel:
signed_arg = -arg if _is_backward_jump(deop) else arg
argval = offset + 2 + signed_arg*2
caches = _get_cache_size(_all_opname[deop])
argval += 2 * caches
if deop == ENTER_EXECUTOR:
argval += 2
argrepr = f"to L{self.labels_map[argval]}"
elif deop in hasjump or deop in hasexc:
argval = self.offset_from_jump_arg(op, arg, offset)
lbl = self.get_label_for_offset(argval)
assert lbl is not None
argrepr = f"to L{lbl}"
elif deop in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
arg1 = arg >> 4
arg2 = arg & 15
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,23 @@ def f(opcode, oparg, offset, *init_args):
self.assertEqual(f(opcode.opmap["BINARY_OP"], 3, *args), (3, '<<'))
self.assertEqual(f(opcode.opmap["CALL_INTRINSIC_1"], 2, *args), (2, 'INTRINSIC_IMPORT_STAR'))

def test_custom_arg_resolver(self):
class MyArgResolver(dis.ArgResolver):
def offset_from_jump_arg(self, op, arg, offset):
return arg + 1

def get_label_for_offset(self, offset):
return 2 * offset

def f(opcode, oparg, offset, *init_args):
arg_resolver = MyArgResolver(*init_args)
return arg_resolver.get_argval_argrepr(opcode, oparg, offset)

offset = 42
self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 1, offset), (2, 'to L4'))
self.assertEqual(f(opcode.opmap["SETUP_FINALLY"], 2, offset), (3, 'to L6'))


def get_instructions(self, code):
return dis._get_instructions_bytes(code)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Refactor :class:`dis.ArgResolver` to make it possible to subclass and change
the way jump args are interpreted.

0 comments on commit 7bff89d

Please sign in to comment.