def _update_label_offsets(code_obj, breakpoint_offset, breakpoint_code_list):
"""
Update labels for the relative and absolute jump targets
:param code_obj: code to modify
:param breakpoint_offset: offset for the inserted code
:param breakpoint_code_list: size of the inserted code
:return: bytes sequence with modified labels; list of tuples (resulting offset, list of code instructions) with
information about all inserted pieces of code
"""
inserted_code = list()
# the list with all inserted pieces of code
inserted_code.append((breakpoint_offset, breakpoint_code_list))
code_list = list(code_obj)
j = 0
while j < len(inserted_code):
current_offset, current_code_list = inserted_code[j]
offsets_for_modification = []
for offset, op, arg in _unpack_opargs(code_list, inserted_code, j):
if arg is not None:
if op in dis.hasjrel:
# has relative jump target
label = offset + 2 + arg
if offset < current_offset < label:
# change labels for relative jump targets if code was inserted inside
offsets_for_modification.append(offset)
elif op in dis.hasjabs:
# change label for absolute jump if code was inserted before it
if current_offset < arg:
offsets_for_modification.append(offset)
for i in range(0, len(code_list), 2):
op = code_list[i]
if i in offsets_for_modification and op >= dis.HAVE_ARGUMENT:
new_arg = code_list[i + 1] + len(current_code_list)
if new_arg <= MAX_BYTE:
code_list[i + 1] = new_arg
else:
# handle bytes overflow
if i - 2 > 0 and code_list[i - 2] == EXTENDED_ARG and code_list[i - 1] < MAX_BYTE:
# if new argument > 255 and EXTENDED_ARG already exists we need to increase it's argument
code_list[i - 1] += 1
else:
# if there isn't EXTENDED_ARG operator yet we have to insert the new operator
extended_arg_code = [EXTENDED_ARG, new_arg >> 8]
inserted_code.append((i, extended_arg_code))
code_list[i + 1] = new_arg & MAX_BYTE
code_list = code_list[:current_offset] + current_code_list + code_list[current_offset:]
for k in range(len(inserted_code)):
offset, inserted_code_list = inserted_code[k]
if current_offset < offset:
inserted_code[k] = (offset + len(current_code_list), inserted_code_list)
j += 1
return bytes(code_list), inserted_code
评论列表
文章目录