(root)/
Python-3.12.0/
Include/
internal/
pycore_opcode_utils.h
       1  #ifndef Py_INTERNAL_OPCODE_UTILS_H
       2  #define Py_INTERNAL_OPCODE_UTILS_H
       3  #ifdef __cplusplus
       4  extern "C" {
       5  #endif
       6  
       7  #ifndef Py_BUILD_CORE
       8  #  error "this header requires Py_BUILD_CORE define"
       9  #endif
      10  
      11  #include "pycore_opcode.h"        // _PyOpcode_Jump
      12  
      13  
      14  #define MAX_REAL_OPCODE 254
      15  
      16  #define IS_WITHIN_OPCODE_RANGE(opcode) \
      17          (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
      18           IS_PSEUDO_OPCODE(opcode))
      19  
      20  #define IS_JUMP_OPCODE(opcode) \
      21           is_bit_set_in_table(_PyOpcode_Jump, opcode)
      22  
      23  #define IS_BLOCK_PUSH_OPCODE(opcode) \
      24          ((opcode) == SETUP_FINALLY || \
      25           (opcode) == SETUP_WITH || \
      26           (opcode) == SETUP_CLEANUP)
      27  
      28  #define HAS_TARGET(opcode) \
      29          (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode))
      30  
      31  /* opcodes that must be last in the basicblock */
      32  #define IS_TERMINATOR_OPCODE(opcode) \
      33          (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
      34  
      35  /* opcodes which are not emitted in codegen stage, only by the assembler */
      36  #define IS_ASSEMBLER_OPCODE(opcode) \
      37          ((opcode) == JUMP_FORWARD || \
      38           (opcode) == JUMP_BACKWARD || \
      39           (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
      40  
      41  #define IS_BACKWARDS_JUMP_OPCODE(opcode) \
      42          ((opcode) == JUMP_BACKWARD || \
      43           (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
      44  
      45  #define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \
      46          ((opcode) == JUMP || \
      47           (opcode) == JUMP_NO_INTERRUPT || \
      48           (opcode) == JUMP_FORWARD || \
      49           (opcode) == JUMP_BACKWARD || \
      50           (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
      51  
      52  #define IS_SCOPE_EXIT_OPCODE(opcode) \
      53          ((opcode) == RETURN_VALUE || \
      54           (opcode) == RETURN_CONST || \
      55           (opcode) == RAISE_VARARGS || \
      56           (opcode) == RERAISE)
      57  
      58  #define IS_SUPERINSTRUCTION_OPCODE(opcode) \
      59          ((opcode) == LOAD_FAST__LOAD_FAST || \
      60           (opcode) == LOAD_FAST__LOAD_CONST || \
      61           (opcode) == LOAD_CONST__LOAD_FAST || \
      62           (opcode) == STORE_FAST__LOAD_FAST || \
      63           (opcode) == STORE_FAST__STORE_FAST)
      64  
      65  
      66  #define LOG_BITS_PER_INT 5
      67  #define MASK_LOW_LOG_BITS 31
      68  
      69  static inline int
      70  is_bit_set_in_table(const uint32_t *table, int bitindex) {
      71      /* Is the relevant bit set in the relevant word? */
      72      /* 512 bits fit into 9 32-bits words.
      73       * Word is indexed by (bitindex>>ln(size of int in bits)).
      74       * Bit within word is the low bits of bitindex.
      75       */
      76      if (bitindex >= 0 && bitindex < 512) {
      77          uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
      78          return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
      79      }
      80      else {
      81          return 0;
      82      }
      83  }
      84  
      85  #undef LOG_BITS_PER_INT
      86  #undef MASK_LOW_LOG_BITS
      87  
      88  
      89  #ifdef __cplusplus
      90  }
      91  #endif
      92  #endif /* !Py_INTERNAL_OPCODE_UTILS_H */