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