MCPcopy
hub / github.com/rocky/python-uncompyle6 / detect_control_flow

Method detect_control_flow

uncompyle6/scanners/scanner3.py:981–1490  ·  view source on GitHub ↗

Detect type of block structures and their boundaries to fix optimized jumps in python2.3+

(self, offset, targets, inst_index)

Source from the content-addressed store, hash-verified

979 slist += [codelen] * (codelen - len(slist))
980
981 def detect_control_flow(self, offset, targets, inst_index):
982 """
983 Detect type of block structures and their boundaries to fix optimized jumps
984 in python2.3+
985 """
986
987 code = self.code
988 inst = self.insts[inst_index]
989 op = inst.opcode
990
991 # Detect parent structure
992 parent = self.structs[0]
993 start = parent["start"]
994 end = parent["end"]
995
996 # Pick inner-most parent for our offset
997 for struct in self.structs:
998 current_start = struct["start"]
999 current_end = struct["end"]
1000 if (current_start <= offset < current_end) and (
1001 current_start >= start and current_end <= end
1002 ):
1003 start = current_start
1004 end = current_end
1005 parent = struct
1006
1007 if self.version < (3, 8) and op == self.opc.SETUP_LOOP:
1008 # We categorize loop types: 'for', 'while', 'while 1' with
1009 # possibly suffixes '-loop' and '-else'
1010 # Try to find the jump_back instruction of the loop.
1011 # It could be a return instruction.
1012
1013 start += inst.inst_size
1014 target = self.get_target(offset)
1015 end = self.restrict_to_parent(target, parent)
1016 self.setup_loops[target] = offset
1017
1018 if target != end:
1019 self.fixed_jumps[offset] = end
1020
1021 (line_no, next_line_byte) = self.lines[offset]
1022 jump_back = self.last_instr(
1023 start, end, self.opc.JUMP_ABSOLUTE, next_line_byte, False
1024 )
1025
1026 if jump_back:
1027 jump_forward_offset = xdis.next_offset(
1028 code[jump_back], self.opc, jump_back
1029 )
1030 else:
1031 jump_forward_offset = None
1032
1033 return_val_offset1 = self.prev[self.prev[end]]
1034
1035 if (
1036 jump_back
1037 and jump_back != self.prev_op[end]
1038 and self.is_jump_forward(jump_forward_offset)

Callers 1

find_jump_targetsMethod · 0.95

Calls 13

rem_orMethod · 0.95
is_jump_backMethod · 0.95
get_targetMethod · 0.80
restrict_to_parentMethod · 0.80
last_instrMethod · 0.80
next_offsetMethod · 0.80
is_jump_forwardMethod · 0.80
get_instMethod · 0.80
addMethod · 0.80
remove_mid_line_ifsMethod · 0.80
inst_matchesMethod · 0.80
appendMethod · 0.45

Tested by

no test coverage detected