(root)/
Python-3.12.0/
Lib/
opcode.py
       1  
       2  """
       3  opcode module - potentially shared between dis and other modules which
       4  operate on bytecodes (e.g. peephole optimizers).
       5  """
       6  
       7  __all__ = ["cmp_op", "hasarg", "hasconst", "hasname", "hasjrel", "hasjabs",
       8             "haslocal", "hascompare", "hasfree", "hasexc", "opname", "opmap",
       9             "HAVE_ARGUMENT", "EXTENDED_ARG"]
      10  
      11  # It's a chicken-and-egg I'm afraid:
      12  # We're imported before _opcode's made.
      13  # With exception unheeded
      14  # (stack_effect is not needed)
      15  # Both our chickens and eggs are allayed.
      16  #     --Larry Hastings, 2013/11/23
      17  
      18  try:
      19      from _opcode import stack_effect
      20      __all__.append('stack_effect')
      21  except ImportError:
      22      pass
      23  
      24  cmp_op = ('<', '<=', '==', '!=', '>', '>=')
      25  
      26  hasarg = []
      27  hasconst = []
      28  hasname = []
      29  hasjrel = []
      30  hasjabs = []
      31  haslocal = []
      32  hascompare = []
      33  hasfree = []
      34  hasexc = []
      35  
      36  
      37  ENABLE_SPECIALIZATION = True
      38  
      39  def is_pseudo(op):
      40      return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
      41  
      42  oplists = [hasarg, hasconst, hasname, hasjrel, hasjabs,
      43             haslocal, hascompare, hasfree, hasexc]
      44  
      45  opmap = {}
      46  
      47  ## pseudo opcodes (used in the compiler) mapped to the values
      48  ## they can become in the actual code.
      49  _pseudo_ops = {}
      50  
      51  def def_op(name, op):
      52      opmap[name] = op
      53  
      54  def name_op(name, op):
      55      def_op(name, op)
      56      hasname.append(op)
      57  
      58  def jrel_op(name, op):
      59      def_op(name, op)
      60      hasjrel.append(op)
      61  
      62  def jabs_op(name, op):
      63      def_op(name, op)
      64      hasjabs.append(op)
      65  
      66  def pseudo_op(name, op, real_ops):
      67      def_op(name, op)
      68      _pseudo_ops[name] = real_ops
      69      # add the pseudo opcode to the lists its targets are in
      70      for oplist in oplists:
      71          res = [opmap[rop] in oplist for rop in real_ops]
      72          if any(res):
      73              assert all(res)
      74              oplist.append(op)
      75  
      76  
      77  # Instruction opcodes for compiled code
      78  # Blank lines correspond to available opcodes
      79  
      80  def_op('CACHE', 0)
      81  def_op('POP_TOP', 1)
      82  def_op('PUSH_NULL', 2)
      83  def_op('INTERPRETER_EXIT', 3)
      84  
      85  def_op('END_FOR', 4)
      86  def_op('END_SEND', 5)
      87  
      88  def_op('NOP', 9)
      89  
      90  def_op('UNARY_NEGATIVE', 11)
      91  def_op('UNARY_NOT', 12)
      92  
      93  def_op('UNARY_INVERT', 15)
      94  
      95  # We reserve 17 as it is the initial value for the specializing counter
      96  # This helps us catch cases where we attempt to execute a cache.
      97  def_op('RESERVED', 17)
      98  
      99  def_op('BINARY_SUBSCR', 25)
     100  def_op('BINARY_SLICE', 26)
     101  def_op('STORE_SLICE', 27)
     102  
     103  def_op('GET_LEN', 30)
     104  def_op('MATCH_MAPPING', 31)
     105  def_op('MATCH_SEQUENCE', 32)
     106  def_op('MATCH_KEYS', 33)
     107  
     108  def_op('PUSH_EXC_INFO', 35)
     109  def_op('CHECK_EXC_MATCH', 36)
     110  def_op('CHECK_EG_MATCH', 37)
     111  
     112  def_op('WITH_EXCEPT_START', 49)
     113  def_op('GET_AITER', 50)
     114  def_op('GET_ANEXT', 51)
     115  def_op('BEFORE_ASYNC_WITH', 52)
     116  def_op('BEFORE_WITH', 53)
     117  def_op('END_ASYNC_FOR', 54)
     118  def_op('CLEANUP_THROW', 55)
     119  
     120  def_op('STORE_SUBSCR', 60)
     121  def_op('DELETE_SUBSCR', 61)
     122  
     123  def_op('GET_ITER', 68)
     124  def_op('GET_YIELD_FROM_ITER', 69)
     125  
     126  def_op('LOAD_BUILD_CLASS', 71)
     127  
     128  def_op('LOAD_ASSERTION_ERROR', 74)
     129  def_op('RETURN_GENERATOR', 75)
     130  
     131  def_op('RETURN_VALUE', 83)
     132  
     133  def_op('SETUP_ANNOTATIONS', 85)
     134  def_op('LOAD_LOCALS', 87)
     135  
     136  def_op('POP_EXCEPT', 89)
     137  
     138  HAVE_ARGUMENT = 90             # real opcodes from here have an argument:
     139  
     140  name_op('STORE_NAME', 90)       # Index in name list
     141  name_op('DELETE_NAME', 91)      # ""
     142  def_op('UNPACK_SEQUENCE', 92)   # Number of tuple items
     143  jrel_op('FOR_ITER', 93)
     144  def_op('UNPACK_EX', 94)
     145  name_op('STORE_ATTR', 95)       # Index in name list
     146  name_op('DELETE_ATTR', 96)      # ""
     147  name_op('STORE_GLOBAL', 97)     # ""
     148  name_op('DELETE_GLOBAL', 98)    # ""
     149  def_op('SWAP', 99)
     150  def_op('LOAD_CONST', 100)       # Index in const list
     151  hasconst.append(100)
     152  name_op('LOAD_NAME', 101)       # Index in name list
     153  def_op('BUILD_TUPLE', 102)      # Number of tuple items
     154  def_op('BUILD_LIST', 103)       # Number of list items
     155  def_op('BUILD_SET', 104)        # Number of set items
     156  def_op('BUILD_MAP', 105)        # Number of dict entries
     157  name_op('LOAD_ATTR', 106)       # Index in name list
     158  def_op('COMPARE_OP', 107)       # Comparison operator
     159  hascompare.append(107)
     160  name_op('IMPORT_NAME', 108)     # Index in name list
     161  name_op('IMPORT_FROM', 109)     # Index in name list
     162  jrel_op('JUMP_FORWARD', 110)    # Number of words to skip
     163  jrel_op('POP_JUMP_IF_FALSE', 114)
     164  jrel_op('POP_JUMP_IF_TRUE', 115)
     165  name_op('LOAD_GLOBAL', 116)     # Index in name list
     166  def_op('IS_OP', 117)
     167  def_op('CONTAINS_OP', 118)
     168  def_op('RERAISE', 119)
     169  def_op('COPY', 120)
     170  def_op('RETURN_CONST', 121)
     171  hasconst.append(121)
     172  def_op('BINARY_OP', 122)
     173  jrel_op('SEND', 123)            # Number of words to skip
     174  def_op('LOAD_FAST', 124)        # Local variable number, no null check
     175  haslocal.append(124)
     176  def_op('STORE_FAST', 125)       # Local variable number
     177  haslocal.append(125)
     178  def_op('DELETE_FAST', 126)      # Local variable number
     179  haslocal.append(126)
     180  def_op('LOAD_FAST_CHECK', 127)  # Local variable number
     181  haslocal.append(127)
     182  jrel_op('POP_JUMP_IF_NOT_NONE', 128)
     183  jrel_op('POP_JUMP_IF_NONE', 129)
     184  def_op('RAISE_VARARGS', 130)    # Number of raise arguments (1, 2, or 3)
     185  def_op('GET_AWAITABLE', 131)
     186  def_op('MAKE_FUNCTION', 132)    # Flags
     187  def_op('BUILD_SLICE', 133)      # Number of items
     188  jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards)
     189  def_op('MAKE_CELL', 135)
     190  hasfree.append(135)
     191  def_op('LOAD_CLOSURE', 136)
     192  hasfree.append(136)
     193  def_op('LOAD_DEREF', 137)
     194  hasfree.append(137)
     195  def_op('STORE_DEREF', 138)
     196  hasfree.append(138)
     197  def_op('DELETE_DEREF', 139)
     198  hasfree.append(139)
     199  jrel_op('JUMP_BACKWARD', 140)    # Number of words to skip (backwards)
     200  name_op('LOAD_SUPER_ATTR', 141)
     201  def_op('CALL_FUNCTION_EX', 142)  # Flags
     202  def_op('LOAD_FAST_AND_CLEAR', 143)  # Local variable number
     203  haslocal.append(143)
     204  
     205  def_op('EXTENDED_ARG', 144)
     206  EXTENDED_ARG = 144
     207  def_op('LIST_APPEND', 145)
     208  def_op('SET_ADD', 146)
     209  def_op('MAP_ADD', 147)
     210  hasfree.append(148)
     211  def_op('COPY_FREE_VARS', 149)
     212  def_op('YIELD_VALUE', 150)
     213  def_op('RESUME', 151)   # This must be kept in sync with deepfreeze.py
     214  def_op('MATCH_CLASS', 152)
     215  
     216  def_op('FORMAT_VALUE', 155)
     217  def_op('BUILD_CONST_KEY_MAP', 156)
     218  def_op('BUILD_STRING', 157)
     219  
     220  def_op('LIST_EXTEND', 162)
     221  def_op('SET_UPDATE', 163)
     222  def_op('DICT_MERGE', 164)
     223  def_op('DICT_UPDATE', 165)
     224  
     225  def_op('CALL', 171)
     226  def_op('KW_NAMES', 172)
     227  hasconst.append(172)
     228  def_op('CALL_INTRINSIC_1', 173)
     229  def_op('CALL_INTRINSIC_2', 174)
     230  
     231  name_op('LOAD_FROM_DICT_OR_GLOBALS', 175)
     232  def_op('LOAD_FROM_DICT_OR_DEREF', 176)
     233  hasfree.append(176)
     234  
     235  # Instrumented instructions
     236  MIN_INSTRUMENTED_OPCODE = 237
     237  
     238  def_op('INSTRUMENTED_LOAD_SUPER_ATTR', 237)
     239  def_op('INSTRUMENTED_POP_JUMP_IF_NONE', 238)
     240  def_op('INSTRUMENTED_POP_JUMP_IF_NOT_NONE', 239)
     241  def_op('INSTRUMENTED_RESUME', 240)
     242  def_op('INSTRUMENTED_CALL', 241)
     243  def_op('INSTRUMENTED_RETURN_VALUE', 242)
     244  def_op('INSTRUMENTED_YIELD_VALUE', 243)
     245  def_op('INSTRUMENTED_CALL_FUNCTION_EX', 244)
     246  def_op('INSTRUMENTED_JUMP_FORWARD', 245)
     247  def_op('INSTRUMENTED_JUMP_BACKWARD', 246)
     248  def_op('INSTRUMENTED_RETURN_CONST', 247)
     249  def_op('INSTRUMENTED_FOR_ITER', 248)
     250  def_op('INSTRUMENTED_POP_JUMP_IF_FALSE', 249)
     251  def_op('INSTRUMENTED_POP_JUMP_IF_TRUE', 250)
     252  def_op('INSTRUMENTED_END_FOR', 251)
     253  def_op('INSTRUMENTED_END_SEND', 252)
     254  def_op('INSTRUMENTED_INSTRUCTION', 253)
     255  def_op('INSTRUMENTED_LINE', 254)
     256  # 255 is reserved
     257  
     258  hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
     259  
     260  MIN_PSEUDO_OPCODE = 256
     261  
     262  pseudo_op('SETUP_FINALLY', 256, ['NOP'])
     263  hasexc.append(256)
     264  pseudo_op('SETUP_CLEANUP', 257, ['NOP'])
     265  hasexc.append(257)
     266  pseudo_op('SETUP_WITH', 258, ['NOP'])
     267  hasexc.append(258)
     268  pseudo_op('POP_BLOCK', 259, ['NOP'])
     269  
     270  pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
     271  pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
     272  
     273  pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR'])
     274  pseudo_op('LOAD_SUPER_METHOD', 263, ['LOAD_SUPER_ATTR'])
     275  pseudo_op('LOAD_ZERO_SUPER_METHOD', 264, ['LOAD_SUPER_ATTR'])
     276  pseudo_op('LOAD_ZERO_SUPER_ATTR', 265, ['LOAD_SUPER_ATTR'])
     277  
     278  pseudo_op('STORE_FAST_MAYBE_NULL', 266, ['STORE_FAST'])
     279  
     280  MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
     281  
     282  del def_op, name_op, jrel_op, jabs_op, pseudo_op
     283  
     284  opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)]
     285  for op, i in opmap.items():
     286      opname[i] = op
     287  
     288  
     289  _nb_ops = [
     290      ("NB_ADD", "+"),
     291      ("NB_AND", "&"),
     292      ("NB_FLOOR_DIVIDE", "//"),
     293      ("NB_LSHIFT", "<<"),
     294      ("NB_MATRIX_MULTIPLY", "@"),
     295      ("NB_MULTIPLY", "*"),
     296      ("NB_REMAINDER", "%"),
     297      ("NB_OR", "|"),
     298      ("NB_POWER", "**"),
     299      ("NB_RSHIFT", ">>"),
     300      ("NB_SUBTRACT", "-"),
     301      ("NB_TRUE_DIVIDE", "/"),
     302      ("NB_XOR", "^"),
     303      ("NB_INPLACE_ADD", "+="),
     304      ("NB_INPLACE_AND", "&="),
     305      ("NB_INPLACE_FLOOR_DIVIDE", "//="),
     306      ("NB_INPLACE_LSHIFT", "<<="),
     307      ("NB_INPLACE_MATRIX_MULTIPLY", "@="),
     308      ("NB_INPLACE_MULTIPLY", "*="),
     309      ("NB_INPLACE_REMAINDER", "%="),
     310      ("NB_INPLACE_OR", "|="),
     311      ("NB_INPLACE_POWER", "**="),
     312      ("NB_INPLACE_RSHIFT", ">>="),
     313      ("NB_INPLACE_SUBTRACT", "-="),
     314      ("NB_INPLACE_TRUE_DIVIDE", "/="),
     315      ("NB_INPLACE_XOR", "^="),
     316  ]
     317  
     318  _intrinsic_1_descs = [
     319      "INTRINSIC_1_INVALID",
     320      "INTRINSIC_PRINT",
     321      "INTRINSIC_IMPORT_STAR",
     322      "INTRINSIC_STOPITERATION_ERROR",
     323      "INTRINSIC_ASYNC_GEN_WRAP",
     324      "INTRINSIC_UNARY_POSITIVE",
     325      "INTRINSIC_LIST_TO_TUPLE",
     326      "INTRINSIC_TYPEVAR",
     327      "INTRINSIC_PARAMSPEC",
     328      "INTRINSIC_TYPEVARTUPLE",
     329      "INTRINSIC_SUBSCRIPT_GENERIC",
     330      "INTRINSIC_TYPEALIAS",
     331  ]
     332  
     333  _intrinsic_2_descs = [
     334      "INTRINSIC_2_INVALID",
     335      "INTRINSIC_PREP_RERAISE_STAR",
     336      "INTRINSIC_TYPEVAR_WITH_BOUND",
     337      "INTRINSIC_TYPEVAR_WITH_CONSTRAINTS",
     338      "INTRINSIC_SET_FUNCTION_TYPE_PARAMS",
     339  ]
     340  
     341  _specializations = {
     342      "BINARY_OP": [
     343          "BINARY_OP_ADD_FLOAT",
     344          "BINARY_OP_ADD_INT",
     345          "BINARY_OP_ADD_UNICODE",
     346          "BINARY_OP_INPLACE_ADD_UNICODE",
     347          "BINARY_OP_MULTIPLY_FLOAT",
     348          "BINARY_OP_MULTIPLY_INT",
     349          "BINARY_OP_SUBTRACT_FLOAT",
     350          "BINARY_OP_SUBTRACT_INT",
     351      ],
     352      "BINARY_SUBSCR": [
     353          "BINARY_SUBSCR_DICT",
     354          "BINARY_SUBSCR_GETITEM",
     355          "BINARY_SUBSCR_LIST_INT",
     356          "BINARY_SUBSCR_TUPLE_INT",
     357      ],
     358      "CALL": [
     359          "CALL_PY_EXACT_ARGS",
     360          "CALL_PY_WITH_DEFAULTS",
     361          "CALL_BOUND_METHOD_EXACT_ARGS",
     362          "CALL_BUILTIN_CLASS",
     363          "CALL_BUILTIN_FAST_WITH_KEYWORDS",
     364          "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
     365          "CALL_NO_KW_BUILTIN_FAST",
     366          "CALL_NO_KW_BUILTIN_O",
     367          "CALL_NO_KW_ISINSTANCE",
     368          "CALL_NO_KW_LEN",
     369          "CALL_NO_KW_LIST_APPEND",
     370          "CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
     371          "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
     372          "CALL_NO_KW_METHOD_DESCRIPTOR_O",
     373          "CALL_NO_KW_STR_1",
     374          "CALL_NO_KW_TUPLE_1",
     375          "CALL_NO_KW_TYPE_1",
     376      ],
     377      "COMPARE_OP": [
     378          "COMPARE_OP_FLOAT",
     379          "COMPARE_OP_INT",
     380          "COMPARE_OP_STR",
     381      ],
     382      "FOR_ITER": [
     383          "FOR_ITER_LIST",
     384          "FOR_ITER_TUPLE",
     385          "FOR_ITER_RANGE",
     386          "FOR_ITER_GEN",
     387      ],
     388      "LOAD_SUPER_ATTR": [
     389          "LOAD_SUPER_ATTR_ATTR",
     390          "LOAD_SUPER_ATTR_METHOD",
     391      ],
     392      "LOAD_ATTR": [
     393          # These potentially push [NULL, bound method] onto the stack.
     394          "LOAD_ATTR_CLASS",
     395          "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
     396          "LOAD_ATTR_INSTANCE_VALUE",
     397          "LOAD_ATTR_MODULE",
     398          "LOAD_ATTR_PROPERTY",
     399          "LOAD_ATTR_SLOT",
     400          "LOAD_ATTR_WITH_HINT",
     401          # These will always push [unbound method, self] onto the stack.
     402          "LOAD_ATTR_METHOD_LAZY_DICT",
     403          "LOAD_ATTR_METHOD_NO_DICT",
     404          "LOAD_ATTR_METHOD_WITH_VALUES",
     405      ],
     406      "LOAD_CONST": [
     407          "LOAD_CONST__LOAD_FAST",
     408      ],
     409      "LOAD_FAST": [
     410          "LOAD_FAST__LOAD_CONST",
     411          "LOAD_FAST__LOAD_FAST",
     412      ],
     413      "LOAD_GLOBAL": [
     414          "LOAD_GLOBAL_BUILTIN",
     415          "LOAD_GLOBAL_MODULE",
     416      ],
     417      "STORE_ATTR": [
     418          "STORE_ATTR_INSTANCE_VALUE",
     419          "STORE_ATTR_SLOT",
     420          "STORE_ATTR_WITH_HINT",
     421      ],
     422      "STORE_FAST": [
     423          "STORE_FAST__LOAD_FAST",
     424          "STORE_FAST__STORE_FAST",
     425      ],
     426      "STORE_SUBSCR": [
     427          "STORE_SUBSCR_DICT",
     428          "STORE_SUBSCR_LIST_INT",
     429      ],
     430      "UNPACK_SEQUENCE": [
     431          "UNPACK_SEQUENCE_LIST",
     432          "UNPACK_SEQUENCE_TUPLE",
     433          "UNPACK_SEQUENCE_TWO_TUPLE",
     434      ],
     435      "SEND": [
     436          "SEND_GEN",
     437      ],
     438  }
     439  _specialized_instructions = [
     440      opcode for family in _specializations.values() for opcode in family
     441  ]
     442  
     443  _cache_format = {
     444      "LOAD_GLOBAL": {
     445          "counter": 1,
     446          "index": 1,
     447          "module_keys_version": 1,
     448          "builtin_keys_version": 1,
     449      },
     450      "BINARY_OP": {
     451          "counter": 1,
     452      },
     453      "UNPACK_SEQUENCE": {
     454          "counter": 1,
     455      },
     456      "COMPARE_OP": {
     457          "counter": 1,
     458      },
     459      "BINARY_SUBSCR": {
     460          "counter": 1,
     461      },
     462      "FOR_ITER": {
     463          "counter": 1,
     464      },
     465      "LOAD_SUPER_ATTR": {
     466          "counter": 1,
     467      },
     468      "LOAD_ATTR": {
     469          "counter": 1,
     470          "version": 2,
     471          "keys_version": 2,
     472          "descr": 4,
     473      },
     474      "STORE_ATTR": {
     475          "counter": 1,
     476          "version": 2,
     477          "index": 1,
     478      },
     479      "CALL": {
     480          "counter": 1,
     481          "func_version": 2,
     482      },
     483      "STORE_SUBSCR": {
     484          "counter": 1,
     485      },
     486      "SEND": {
     487          "counter": 1,
     488      },
     489  }
     490  
     491  _inline_cache_entries = [
     492      sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256)
     493  ]