opcode.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. """
  2. opcode module - potentially shared between dis and other modules which
  3. operate on bytecodes (e.g. peephole optimizers).
  4. """
  5. __all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
  6. "haslocal", "hascompare", "hasfree", "opname", "opmap",
  7. "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"]
  8. # It's a chicken-and-egg I'm afraid:
  9. # We're imported before _opcode's made.
  10. # With exception unheeded
  11. # (stack_effect is not needed)
  12. # Both our chickens and eggs are allayed.
  13. # --Larry Hastings, 2013/11/23
  14. try:
  15. from _opcode import stack_effect
  16. __all__.append('stack_effect')
  17. except ImportError:
  18. pass
  19. cmp_op = ('<', '<=', '==', '!=', '>', '>=')
  20. hasconst = []
  21. hasname = []
  22. hasjrel = []
  23. hasjabs = []
  24. haslocal = []
  25. hascompare = []
  26. hasfree = []
  27. hasnargs = [] # unused
  28. opmap = {}
  29. opname = ['<%r>' % (op,) for op in range(256)]
  30. def def_op(name, op):
  31. opname[op] = name
  32. opmap[name] = op
  33. def name_op(name, op):
  34. def_op(name, op)
  35. hasname.append(op)
  36. def jrel_op(name, op):
  37. def_op(name, op)
  38. hasjrel.append(op)
  39. def jabs_op(name, op):
  40. def_op(name, op)
  41. hasjabs.append(op)
  42. # Instruction opcodes for compiled code
  43. # Blank lines correspond to available opcodes
  44. def_op('CACHE', 0)
  45. def_op('POP_TOP', 1)
  46. def_op('PUSH_NULL', 2)
  47. def_op('NOP', 9)
  48. def_op('UNARY_POSITIVE', 10)
  49. def_op('UNARY_NEGATIVE', 11)
  50. def_op('UNARY_NOT', 12)
  51. def_op('UNARY_INVERT', 15)
  52. def_op('BINARY_SUBSCR', 25)
  53. def_op('GET_LEN', 30)
  54. def_op('MATCH_MAPPING', 31)
  55. def_op('MATCH_SEQUENCE', 32)
  56. def_op('MATCH_KEYS', 33)
  57. def_op('PUSH_EXC_INFO', 35)
  58. def_op('CHECK_EXC_MATCH', 36)
  59. def_op('CHECK_EG_MATCH', 37)
  60. def_op('WITH_EXCEPT_START', 49)
  61. def_op('GET_AITER', 50)
  62. def_op('GET_ANEXT', 51)
  63. def_op('BEFORE_ASYNC_WITH', 52)
  64. def_op('BEFORE_WITH', 53)
  65. def_op('END_ASYNC_FOR', 54)
  66. def_op('STORE_SUBSCR', 60)
  67. def_op('DELETE_SUBSCR', 61)
  68. def_op('GET_ITER', 68)
  69. def_op('GET_YIELD_FROM_ITER', 69)
  70. def_op('PRINT_EXPR', 70)
  71. def_op('LOAD_BUILD_CLASS', 71)
  72. def_op('LOAD_ASSERTION_ERROR', 74)
  73. def_op('RETURN_GENERATOR', 75)
  74. def_op('LIST_TO_TUPLE', 82)
  75. def_op('RETURN_VALUE', 83)
  76. def_op('IMPORT_STAR', 84)
  77. def_op('SETUP_ANNOTATIONS', 85)
  78. def_op('YIELD_VALUE', 86)
  79. def_op('ASYNC_GEN_WRAP', 87)
  80. def_op('PREP_RERAISE_STAR', 88)
  81. def_op('POP_EXCEPT', 89)
  82. HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
  83. name_op('STORE_NAME', 90) # Index in name list
  84. name_op('DELETE_NAME', 91) # ""
  85. def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
  86. jrel_op('FOR_ITER', 93)
  87. def_op('UNPACK_EX', 94)
  88. name_op('STORE_ATTR', 95) # Index in name list
  89. name_op('DELETE_ATTR', 96) # ""
  90. name_op('STORE_GLOBAL', 97) # ""
  91. name_op('DELETE_GLOBAL', 98) # ""
  92. def_op('SWAP', 99)
  93. def_op('LOAD_CONST', 100) # Index in const list
  94. hasconst.append(100)
  95. name_op('LOAD_NAME', 101) # Index in name list
  96. def_op('BUILD_TUPLE', 102) # Number of tuple items
  97. def_op('BUILD_LIST', 103) # Number of list items
  98. def_op('BUILD_SET', 104) # Number of set items
  99. def_op('BUILD_MAP', 105) # Number of dict entries
  100. name_op('LOAD_ATTR', 106) # Index in name list
  101. def_op('COMPARE_OP', 107) # Comparison operator
  102. hascompare.append(107)
  103. name_op('IMPORT_NAME', 108) # Index in name list
  104. name_op('IMPORT_FROM', 109) # Index in name list
  105. jrel_op('JUMP_FORWARD', 110) # Number of words to skip
  106. jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
  107. jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
  108. jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114)
  109. jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115)
  110. name_op('LOAD_GLOBAL', 116) # Index in name list
  111. def_op('IS_OP', 117)
  112. def_op('CONTAINS_OP', 118)
  113. def_op('RERAISE', 119)
  114. def_op('COPY', 120)
  115. def_op('BINARY_OP', 122)
  116. jrel_op('SEND', 123) # Number of bytes to skip
  117. def_op('LOAD_FAST', 124) # Local variable number
  118. haslocal.append(124)
  119. def_op('STORE_FAST', 125) # Local variable number
  120. haslocal.append(125)
  121. def_op('DELETE_FAST', 126) # Local variable number
  122. haslocal.append(126)
  123. jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128)
  124. jrel_op('POP_JUMP_FORWARD_IF_NONE', 129)
  125. def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
  126. def_op('GET_AWAITABLE', 131)
  127. def_op('MAKE_FUNCTION', 132) # Flags
  128. def_op('BUILD_SLICE', 133) # Number of items
  129. jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards)
  130. def_op('MAKE_CELL', 135)
  131. hasfree.append(135)
  132. def_op('LOAD_CLOSURE', 136)
  133. hasfree.append(136)
  134. def_op('LOAD_DEREF', 137)
  135. hasfree.append(137)
  136. def_op('STORE_DEREF', 138)
  137. hasfree.append(138)
  138. def_op('DELETE_DEREF', 139)
  139. hasfree.append(139)
  140. jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards)
  141. def_op('CALL_FUNCTION_EX', 142) # Flags
  142. def_op('EXTENDED_ARG', 144)
  143. EXTENDED_ARG = 144
  144. def_op('LIST_APPEND', 145)
  145. def_op('SET_ADD', 146)
  146. def_op('MAP_ADD', 147)
  147. def_op('LOAD_CLASSDEREF', 148)
  148. hasfree.append(148)
  149. def_op('COPY_FREE_VARS', 149)
  150. def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py
  151. def_op('MATCH_CLASS', 152)
  152. def_op('FORMAT_VALUE', 155)
  153. def_op('BUILD_CONST_KEY_MAP', 156)
  154. def_op('BUILD_STRING', 157)
  155. name_op('LOAD_METHOD', 160)
  156. def_op('LIST_EXTEND', 162)
  157. def_op('SET_UPDATE', 163)
  158. def_op('DICT_MERGE', 164)
  159. def_op('DICT_UPDATE', 165)
  160. def_op('PRECALL', 166)
  161. def_op('CALL', 171)
  162. def_op('KW_NAMES', 172)
  163. hasconst.append(172)
  164. jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173)
  165. jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174)
  166. jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175)
  167. jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176)
  168. del def_op, name_op, jrel_op, jabs_op
  169. _nb_ops = [
  170. ("NB_ADD", "+"),
  171. ("NB_AND", "&"),
  172. ("NB_FLOOR_DIVIDE", "//"),
  173. ("NB_LSHIFT", "<<"),
  174. ("NB_MATRIX_MULTIPLY", "@"),
  175. ("NB_MULTIPLY", "*"),
  176. ("NB_REMAINDER", "%"),
  177. ("NB_OR", "|"),
  178. ("NB_POWER", "**"),
  179. ("NB_RSHIFT", ">>"),
  180. ("NB_SUBTRACT", "-"),
  181. ("NB_TRUE_DIVIDE", "/"),
  182. ("NB_XOR", "^"),
  183. ("NB_INPLACE_ADD", "+="),
  184. ("NB_INPLACE_AND", "&="),
  185. ("NB_INPLACE_FLOOR_DIVIDE", "//="),
  186. ("NB_INPLACE_LSHIFT", "<<="),
  187. ("NB_INPLACE_MATRIX_MULTIPLY", "@="),
  188. ("NB_INPLACE_MULTIPLY", "*="),
  189. ("NB_INPLACE_REMAINDER", "%="),
  190. ("NB_INPLACE_OR", "|="),
  191. ("NB_INPLACE_POWER", "**="),
  192. ("NB_INPLACE_RSHIFT", ">>="),
  193. ("NB_INPLACE_SUBTRACT", "-="),
  194. ("NB_INPLACE_TRUE_DIVIDE", "/="),
  195. ("NB_INPLACE_XOR", "^="),
  196. ]
  197. _specializations = {
  198. "BINARY_OP": [
  199. "BINARY_OP_ADAPTIVE",
  200. "BINARY_OP_ADD_FLOAT",
  201. "BINARY_OP_ADD_INT",
  202. "BINARY_OP_ADD_UNICODE",
  203. "BINARY_OP_INPLACE_ADD_UNICODE",
  204. "BINARY_OP_MULTIPLY_FLOAT",
  205. "BINARY_OP_MULTIPLY_INT",
  206. "BINARY_OP_SUBTRACT_FLOAT",
  207. "BINARY_OP_SUBTRACT_INT",
  208. ],
  209. "BINARY_SUBSCR": [
  210. "BINARY_SUBSCR_ADAPTIVE",
  211. "BINARY_SUBSCR_DICT",
  212. "BINARY_SUBSCR_GETITEM",
  213. "BINARY_SUBSCR_LIST_INT",
  214. "BINARY_SUBSCR_TUPLE_INT",
  215. ],
  216. "CALL": [
  217. "CALL_ADAPTIVE",
  218. "CALL_PY_EXACT_ARGS",
  219. "CALL_PY_WITH_DEFAULTS",
  220. ],
  221. "COMPARE_OP": [
  222. "COMPARE_OP_ADAPTIVE",
  223. "COMPARE_OP_FLOAT_JUMP",
  224. "COMPARE_OP_INT_JUMP",
  225. "COMPARE_OP_STR_JUMP",
  226. ],
  227. "EXTENDED_ARG": [
  228. "EXTENDED_ARG_QUICK",
  229. ],
  230. "JUMP_BACKWARD": [
  231. "JUMP_BACKWARD_QUICK",
  232. ],
  233. "LOAD_ATTR": [
  234. "LOAD_ATTR_ADAPTIVE",
  235. "LOAD_ATTR_INSTANCE_VALUE",
  236. "LOAD_ATTR_MODULE",
  237. "LOAD_ATTR_SLOT",
  238. "LOAD_ATTR_WITH_HINT",
  239. ],
  240. "LOAD_CONST": [
  241. "LOAD_CONST__LOAD_FAST",
  242. ],
  243. "LOAD_FAST": [
  244. "LOAD_FAST__LOAD_CONST",
  245. "LOAD_FAST__LOAD_FAST",
  246. ],
  247. "LOAD_GLOBAL": [
  248. "LOAD_GLOBAL_ADAPTIVE",
  249. "LOAD_GLOBAL_BUILTIN",
  250. "LOAD_GLOBAL_MODULE",
  251. ],
  252. "LOAD_METHOD": [
  253. "LOAD_METHOD_ADAPTIVE",
  254. "LOAD_METHOD_CLASS",
  255. "LOAD_METHOD_MODULE",
  256. "LOAD_METHOD_NO_DICT",
  257. "LOAD_METHOD_WITH_DICT",
  258. "LOAD_METHOD_WITH_VALUES",
  259. ],
  260. "PRECALL": [
  261. "PRECALL_ADAPTIVE",
  262. "PRECALL_BOUND_METHOD",
  263. "PRECALL_BUILTIN_CLASS",
  264. "PRECALL_BUILTIN_FAST_WITH_KEYWORDS",
  265. "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
  266. "PRECALL_NO_KW_BUILTIN_FAST",
  267. "PRECALL_NO_KW_BUILTIN_O",
  268. "PRECALL_NO_KW_ISINSTANCE",
  269. "PRECALL_NO_KW_LEN",
  270. "PRECALL_NO_KW_LIST_APPEND",
  271. "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST",
  272. "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
  273. "PRECALL_NO_KW_METHOD_DESCRIPTOR_O",
  274. "PRECALL_NO_KW_STR_1",
  275. "PRECALL_NO_KW_TUPLE_1",
  276. "PRECALL_NO_KW_TYPE_1",
  277. "PRECALL_PYFUNC",
  278. ],
  279. "RESUME": [
  280. "RESUME_QUICK",
  281. ],
  282. "STORE_ATTR": [
  283. "STORE_ATTR_ADAPTIVE",
  284. "STORE_ATTR_INSTANCE_VALUE",
  285. "STORE_ATTR_SLOT",
  286. "STORE_ATTR_WITH_HINT",
  287. ],
  288. "STORE_FAST": [
  289. "STORE_FAST__LOAD_FAST",
  290. "STORE_FAST__STORE_FAST",
  291. ],
  292. "STORE_SUBSCR": [
  293. "STORE_SUBSCR_ADAPTIVE",
  294. "STORE_SUBSCR_DICT",
  295. "STORE_SUBSCR_LIST_INT",
  296. ],
  297. "UNPACK_SEQUENCE": [
  298. "UNPACK_SEQUENCE_ADAPTIVE",
  299. "UNPACK_SEQUENCE_LIST",
  300. "UNPACK_SEQUENCE_TUPLE",
  301. "UNPACK_SEQUENCE_TWO_TUPLE",
  302. ],
  303. }
  304. _specialized_instructions = [
  305. opcode for family in _specializations.values() for opcode in family
  306. ]
  307. _specialization_stats = [
  308. "success",
  309. "failure",
  310. "hit",
  311. "deferred",
  312. "miss",
  313. "deopt",
  314. ]
  315. _cache_format = {
  316. "LOAD_GLOBAL": {
  317. "counter": 1,
  318. "index": 1,
  319. "module_keys_version": 2,
  320. "builtin_keys_version": 1,
  321. },
  322. "BINARY_OP": {
  323. "counter": 1,
  324. },
  325. "UNPACK_SEQUENCE": {
  326. "counter": 1,
  327. },
  328. "COMPARE_OP": {
  329. "counter": 1,
  330. "mask": 1,
  331. },
  332. "BINARY_SUBSCR": {
  333. "counter": 1,
  334. "type_version": 2,
  335. "func_version": 1,
  336. },
  337. "LOAD_ATTR": {
  338. "counter": 1,
  339. "version": 2,
  340. "index": 1,
  341. },
  342. "STORE_ATTR": {
  343. "counter": 1,
  344. "version": 2,
  345. "index": 1,
  346. },
  347. "LOAD_METHOD": {
  348. "counter": 1,
  349. "type_version": 2,
  350. "dict_offset": 1,
  351. "keys_version": 2,
  352. "descr": 4,
  353. },
  354. "CALL": {
  355. "counter": 1,
  356. "func_version": 2,
  357. "min_args": 1,
  358. },
  359. "PRECALL": {
  360. "counter": 1,
  361. },
  362. "STORE_SUBSCR": {
  363. "counter": 1,
  364. },
  365. }
  366. _inline_cache_entries = [
  367. sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256)
  368. ]