Detect all offsets in a byte code which are jump targets where we might insert a COME_FROM instruction. Return the list of offsets. Return the list of offsets. An instruction can be jumped to in from multiple instructions.
(self, debug)
| 813 | return new_tokens, customize |
| 814 | |
| 815 | def find_jump_targets(self, debug): |
| 816 | """ |
| 817 | Detect all offsets in a byte code which are jump targets |
| 818 | where we might insert a COME_FROM instruction. |
| 819 | |
| 820 | Return the list of offsets. |
| 821 | |
| 822 | Return the list of offsets. An instruction can be jumped |
| 823 | to in from multiple instructions. |
| 824 | """ |
| 825 | code = self.code |
| 826 | n = len(code) |
| 827 | self.structs = [{"type": "root", "start": 0, "end": n - 1}] |
| 828 | |
| 829 | # All loop entry points |
| 830 | self.loops = [] |
| 831 | |
| 832 | # Map fixed jumps to their real destination |
| 833 | self.fixed_jumps = {} |
| 834 | self.except_targets = {} |
| 835 | self.ignore_if = set() |
| 836 | self.build_statement_indices() |
| 837 | self.else_start = {} |
| 838 | |
| 839 | # Containers filled by detect_control_flow() |
| 840 | self.not_continue = set() |
| 841 | self.return_end_ifs = set() |
| 842 | self.setup_loop_targets = {} # target given setup_loop offset |
| 843 | self.setup_loops = {} # setup_loop offset given target |
| 844 | |
| 845 | targets = {} |
| 846 | for i, inst in enumerate(self.insts): |
| 847 | offset = inst.offset |
| 848 | op = inst.opcode |
| 849 | |
| 850 | # Determine structures and fix jumps in Python versions |
| 851 | # since 2.3 |
| 852 | self.detect_control_flow(offset, targets, i) |
| 853 | |
| 854 | if inst.has_arg: |
| 855 | label = self.fixed_jumps.get(offset) |
| 856 | oparg = inst.arg |
| 857 | if ( |
| 858 | self.version >= (3, 6) |
| 859 | and self.code[offset] == self.opc.EXTENDED_ARG |
| 860 | ): |
| 861 | j = xdis.next_offset(op, self.opc, offset) |
| 862 | next_offset = xdis.next_offset(op, self.opc, j) |
| 863 | else: |
| 864 | next_offset = xdis.next_offset(op, self.opc, offset) |
| 865 | |
| 866 | if label is None: |
| 867 | if op in self.opc.hasjrel and op != self.opc.FOR_ITER: |
| 868 | label = next_offset + oparg |
| 869 | elif op in self.opc.hasjabs: |
| 870 | if op in self.jump_if_pop: |
| 871 | if oparg > offset: |
| 872 | label = oparg |