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

Method detect_control_flow

uncompyle6/scanners/scanner2.py:640–1278  ·  view source on GitHub ↗

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

(self, offset, op, extended_arg)

Source from the content-addressed store, hash-verified

638 count_SETUP_ += 1
639
640 def detect_control_flow(self, offset, op, extended_arg):
641 """
642 Detect type of block structures and their boundaries to fix optimized jumps
643 in python2.3+
644 """
645
646 code = self.code
647
648 # Detect parent structure
649 parent = self.structs[0]
650 start = parent["start"]
651 end = parent["end"]
652 next_line_byte = end
653
654 # Pick inner-most parent for our offset
655 for struct in self.structs:
656 current_start = struct["start"]
657 current_end = struct["end"]
658 if (current_start <= offset < current_end) and (
659 current_start >= start and current_end <= end
660 ):
661 start = current_start
662 end = current_end
663 parent = struct
664
665 if op == self.opc.SETUP_LOOP:
666 # We categorize loop types: 'for', 'while', 'while 1' with
667 # possibly suffixes '-loop' and '-else'
668 # Try to find the jump_back instruction of the loop.
669 # It could be a return instruction.
670
671 inst = self.insts[self.offset2inst_index[offset]]
672 start += instruction_size(op, self.opc)
673 setup_target = inst.argval
674 loop_end_offset = self.restrict_to_parent(setup_target, parent)
675 self.setup_loop_targets[offset] = setup_target
676 self.setup_loops[setup_target] = offset
677
678 if setup_target != loop_end_offset:
679 self.fixed_jumps[offset] = loop_end_offset
680
681 if self.lines:
682 (line_no, next_line_byte) = self.lines[offset]
683
684 # jump_back_offset is the instruction after the SETUP_LOOP
685 # where we iterate back to.
686 jump_back_offset = self.last_instr(
687 start, loop_end_offset, self.opc.JUMP_ABSOLUTE, next_line_byte, False
688 )
689
690 if jump_back_offset:
691 # Account for the fact that < 2.7 has an explicit
692 # POP_TOP instruction in the equivalate POP_JUMP_IF
693 # construct
694 if self.version < (2, 7):
695 jump_forward_offset = jump_back_offset + 4
696 return_val_offset1 = self.prev[
697 self.prev[self.prev[loop_end_offset]]

Callers 1

find_jump_targetsMethod · 0.95

Calls 12

next_except_jumpMethod · 0.95
rem_orMethod · 0.95
restrict_to_parentMethod · 0.80
last_instrMethod · 0.80
get_targetMethod · 0.80
addMethod · 0.80
remove_mid_line_ifsMethod · 0.80
all_instrMethod · 0.80
op_nameMethod · 0.80
opname_for_offsetMethod · 0.80
appendMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected