summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_opcode_metadata.h1166
-rw-r--r--Include/internal/pycore_uop_ids.h193
-rw-r--r--Include/internal/pycore_uop_metadata.h403
-rw-r--r--Include/opcode_ids.h2
-rw-r--r--Lib/_opcode_metadata.py18
-rw-r--r--Lib/test/test_capi/test_opt.py5
-rw-r--r--Makefile.pre.in25
-rw-r--r--Python/assemble.c10
-rw-r--r--Python/bytecodes.c72
-rw-r--r--Python/ceval.c1
-rw-r--r--Python/compile.c37
-rw-r--r--Python/flowgraph.c4
-rw-r--r--Python/generated_cases.c.h19
-rw-r--r--Python/optimizer.c32
-rw-r--r--Python/specialize.c1
-rw-r--r--Tools/cases_generator/analyzer.py162
-rw-r--r--Tools/cases_generator/cwriter.py35
-rw-r--r--Tools/cases_generator/generate_cases.py1
-rw-r--r--Tools/cases_generator/generators_common.py45
-rw-r--r--Tools/cases_generator/opcode_id_generator.py112
-rw-r--r--Tools/cases_generator/opcode_metadata_generator.py386
-rw-r--r--Tools/cases_generator/py_metadata_generator.py97
-rw-r--r--Tools/cases_generator/stack.py40
-rw-r--r--Tools/cases_generator/tier1_generator.py1
-rw-r--r--Tools/cases_generator/tier2_generator.py11
-rw-r--r--Tools/cases_generator/uop_id_generator.py60
-rw-r--r--Tools/cases_generator/uop_metadata_generator.py73
27 files changed, 1740 insertions, 1271 deletions
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 36b6cd5..a9e0cd1 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1,13 +1,20 @@
-// This file is generated by Tools/cases_generator/generate_cases.py
+// This file is generated by Tools/cases_generator/opcode_metadata_generator.py
// from:
// Python/bytecodes.c
// Do not edit!
+#ifndef Py_CORE_OPCODE_METADATA_H
+#define Py_CORE_OPCODE_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
#include <stdbool.h> // bool
+#include "opcode_ids.h"
#define IS_PSEUDO_INSTR(OP) ( \
@@ -26,10 +33,9 @@
0)
#include "pycore_uop_ids.h"
-
-extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
+extern int _PyOpcode_num_popped(int opcode, int oparg);
#ifdef NEED_OPCODE_METADATA
-int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
+int _PyOpcode_num_popped(int opcode, int oparg) {
switch(opcode) {
case BEFORE_ASYNC_WITH:
return 1;
@@ -68,7 +74,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case BINARY_SUBSCR_TUPLE_INT:
return 2;
case BUILD_CONST_KEY_MAP:
- return oparg + 1;
+ return 1 + oparg;
case BUILD_LIST:
return oparg;
case BUILD_MAP:
@@ -76,7 +82,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case BUILD_SET:
return oparg;
case BUILD_SLICE:
- return ((oparg == 3) ? 1 : 0) + 2;
+ return 2 + (((oparg == 3) ? 1 : 0));
case BUILD_STRING:
return oparg;
case BUILD_TUPLE:
@@ -84,51 +90,51 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case CACHE:
return 0;
case CALL:
- return oparg + 2;
+ return 2 + oparg;
case CALL_ALLOC_AND_ENTER_INIT:
- return oparg + 2;
+ return 2 + oparg;
case CALL_BOUND_METHOD_EXACT_ARGS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_BUILTIN_CLASS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_BUILTIN_FAST:
- return oparg + 2;
+ return 2 + oparg;
case CALL_BUILTIN_FAST_WITH_KEYWORDS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_BUILTIN_O:
- return oparg + 2;
+ return 2 + oparg;
case CALL_FUNCTION_EX:
- return ((oparg & 1) ? 1 : 0) + 3;
+ return 3 + ((oparg & 1));
case CALL_INTRINSIC_1:
return 1;
case CALL_INTRINSIC_2:
return 2;
case CALL_ISINSTANCE:
- return oparg + 2;
+ return 2 + oparg;
case CALL_KW:
- return oparg + 3;
+ return 3 + oparg;
case CALL_LEN:
- return oparg + 2;
+ return 2 + oparg;
case CALL_LIST_APPEND:
- return oparg + 2;
+ return 2 + oparg;
case CALL_METHOD_DESCRIPTOR_FAST:
- return oparg + 2;
+ return 2 + oparg;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_METHOD_DESCRIPTOR_NOARGS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_METHOD_DESCRIPTOR_O:
- return oparg + 2;
+ return 2 + oparg;
case CALL_PY_EXACT_ARGS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_PY_WITH_DEFAULTS:
- return oparg + 2;
+ return 2 + oparg;
case CALL_STR_1:
- return oparg + 2;
+ return 2 + oparg;
case CALL_TUPLE_1:
- return oparg + 2;
+ return 2 + oparg;
case CALL_TYPE_1:
- return oparg + 2;
+ return 2 + oparg;
case CHECK_EG_MATCH:
return 2;
case CHECK_EXC_MATCH:
@@ -148,7 +154,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case CONVERT_VALUE:
return 1;
case COPY:
- return (oparg-1) + 1;
+ return 1 + (oparg-1);
case COPY_FREE_VARS:
return 0;
case DELETE_ATTR:
@@ -164,9 +170,9 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case DELETE_SUBSCR:
return 2;
case DICT_MERGE:
- return (oparg - 1) + 5;
+ return 5 + (oparg - 1);
case DICT_UPDATE:
- return (oparg - 1) + 2;
+ return 2 + (oparg - 1);
case END_ASYNC_FOR:
return 2;
case END_FOR:
@@ -249,20 +255,16 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case IS_OP:
return 2;
- case JUMP:
- return 0;
case JUMP_BACKWARD:
return 0;
case JUMP_BACKWARD_NO_INTERRUPT:
return 0;
case JUMP_FORWARD:
return 0;
- case JUMP_NO_INTERRUPT:
- return 0;
case LIST_APPEND:
- return (oparg-1) + 2;
+ return 2 + (oparg-1);
case LIST_EXTEND:
- return (oparg-1) + 2;
+ return 2 + (oparg-1);
case LOAD_ASSERTION_ERROR:
return 0;
case LOAD_ATTR:
@@ -293,8 +295,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case LOAD_BUILD_CLASS:
return 0;
- case LOAD_CLOSURE:
- return 0;
case LOAD_CONST:
return 0;
case LOAD_DEREF:
@@ -319,8 +319,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 0;
case LOAD_LOCALS:
return 0;
- case LOAD_METHOD:
- return 1;
case LOAD_NAME:
return 0;
case LOAD_SUPER_ATTR:
@@ -329,18 +327,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 3;
case LOAD_SUPER_ATTR_METHOD:
return 3;
- case LOAD_SUPER_METHOD:
- return 3;
- case LOAD_ZERO_SUPER_ATTR:
- return 3;
- case LOAD_ZERO_SUPER_METHOD:
- return 3;
case MAKE_CELL:
return 0;
case MAKE_FUNCTION:
return 1;
case MAP_ADD:
- return (oparg - 1) + 3;
+ return 3 + (oparg - 1);
case MATCH_CLASS:
return 3;
case MATCH_KEYS:
@@ -351,8 +343,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case NOP:
return 0;
- case POP_BLOCK:
- return 0;
case POP_EXCEPT:
return 1;
case POP_JUMP_IF_FALSE:
@@ -372,7 +362,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case RAISE_VARARGS:
return oparg;
case RERAISE:
- return oparg + 1;
+ return 1 + oparg;
case RESERVED:
return 0;
case RESUME:
@@ -391,18 +381,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 2;
case SETUP_ANNOTATIONS:
return 0;
- case SETUP_CLEANUP:
- return 0;
- case SETUP_FINALLY:
- return 0;
- case SETUP_WITH:
- return 0;
case SET_ADD:
- return (oparg-1) + 2;
+ return 2 + (oparg-1);
case SET_FUNCTION_ATTRIBUTE:
return 2;
case SET_UPDATE:
- return (oparg-1) + 2;
+ return 2 + (oparg-1);
case STORE_ATTR:
return 2;
case STORE_ATTR_INSTANCE_VALUE:
@@ -417,8 +401,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case STORE_FAST_LOAD_FAST:
return 1;
- case STORE_FAST_MAYBE_NULL:
- return 1;
case STORE_FAST_STORE_FAST:
return 2;
case STORE_GLOBAL:
@@ -434,7 +416,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case STORE_SUBSCR_LIST_INT:
return 3;
case SWAP:
- return (oparg-2) + 2;
+ return 2 + (oparg-2);
case TO_BOOL:
return 1;
case TO_BOOL_ALWAYS_TRUE:
@@ -469,207 +451,16 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 4;
case YIELD_VALUE:
return 1;
- case _BINARY_OP:
- return 2;
- case _BINARY_OP_ADD_FLOAT:
- return 2;
- case _BINARY_OP_ADD_INT:
- return 2;
- case _BINARY_OP_ADD_UNICODE:
- return 2;
- case _BINARY_OP_INPLACE_ADD_UNICODE:
- return 2;
- case _BINARY_OP_MULTIPLY_FLOAT:
- return 2;
- case _BINARY_OP_MULTIPLY_INT:
- return 2;
- case _BINARY_OP_SUBTRACT_FLOAT:
- return 2;
- case _BINARY_OP_SUBTRACT_INT:
- return 2;
- case _BINARY_SUBSCR:
- return 2;
- case _CALL:
- return oparg + 2;
- case _CHECK_ATTR_CLASS:
- return 1;
- case _CHECK_ATTR_METHOD_LAZY_DICT:
- return 1;
- case _CHECK_ATTR_MODULE:
- return 1;
- case _CHECK_ATTR_WITH_HINT:
- return 1;
- case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
- return oparg + 2;
- case _CHECK_FUNCTION_EXACT_ARGS:
- return oparg + 2;
- case _CHECK_MANAGED_OBJECT_HAS_VALUES:
- return 1;
- case _CHECK_PEP_523:
- return 0;
- case _CHECK_STACK_SPACE:
- return oparg + 2;
- case _CHECK_VALIDITY:
- return 0;
- case _COMPARE_OP:
- return 2;
- case _EXIT_TRACE:
- return 0;
- case _FOR_ITER:
- return 1;
- case _FOR_ITER_TIER_TWO:
- return 1;
- case _GUARD_BOTH_FLOAT:
- return 2;
- case _GUARD_BOTH_INT:
- return 2;
- case _GUARD_BOTH_UNICODE:
- return 2;
- case _GUARD_BUILTINS_VERSION:
- return 0;
- case _GUARD_DORV_VALUES:
- return 1;
- case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
- return 1;
- case _GUARD_GLOBALS_VERSION:
- return 0;
- case _GUARD_IS_FALSE_POP:
- return 1;
- case _GUARD_IS_NONE_POP:
- return 1;
- case _GUARD_IS_NOT_NONE_POP:
- return 1;
- case _GUARD_IS_TRUE_POP:
- return 1;
- case _GUARD_KEYS_VERSION:
- return 1;
- case _GUARD_NOT_EXHAUSTED_LIST:
- return 1;
- case _GUARD_NOT_EXHAUSTED_RANGE:
- return 1;
- case _GUARD_NOT_EXHAUSTED_TUPLE:
- return 1;
- case _GUARD_TYPE_VERSION:
- return 1;
- case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
- return oparg + 2;
- case _INIT_CALL_PY_EXACT_ARGS:
- return oparg + 2;
- case _INSERT:
- return oparg + 1;
- case _IS_NONE:
- return 1;
- case _ITER_CHECK_LIST:
- return 1;
- case _ITER_CHECK_RANGE:
- return 1;
- case _ITER_CHECK_TUPLE:
- return 1;
- case _ITER_JUMP_LIST:
- return 1;
- case _ITER_JUMP_RANGE:
- return 1;
- case _ITER_JUMP_TUPLE:
- return 1;
- case _ITER_NEXT_LIST:
- return 1;
- case _ITER_NEXT_RANGE:
- return 1;
- case _ITER_NEXT_TUPLE:
- return 1;
- case _JUMP_TO_TOP:
- return 0;
- case _LOAD_ATTR:
- return 1;
- case _LOAD_ATTR_CLASS:
- return 1;
- case _LOAD_ATTR_INSTANCE_VALUE:
- return 1;
- case _LOAD_ATTR_METHOD_LAZY_DICT:
- return 1;
- case _LOAD_ATTR_METHOD_NO_DICT:
- return 1;
- case _LOAD_ATTR_METHOD_WITH_VALUES:
- return 1;
- case _LOAD_ATTR_MODULE:
- return 1;
- case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
- return 1;
- case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
- return 1;
- case _LOAD_ATTR_SLOT:
- return 1;
- case _LOAD_ATTR_WITH_HINT:
- return 1;
- case _LOAD_GLOBAL:
- return 0;
- case _LOAD_GLOBAL_BUILTINS:
- return 0;
- case _LOAD_GLOBAL_MODULE:
- return 0;
- case _LOAD_SUPER_ATTR:
- return 3;
- case _POP_FRAME:
- return 1;
- case _POP_JUMP_IF_FALSE:
- return 1;
- case _POP_JUMP_IF_TRUE:
- return 1;
- case _PUSH_FRAME:
- return 1;
- case _SAVE_RETURN_OFFSET:
- return 0;
- case _SEND:
- return 2;
- case _SET_IP:
- return 0;
- case _SPECIALIZE_BINARY_OP:
- return 2;
- case _SPECIALIZE_BINARY_SUBSCR:
- return 2;
- case _SPECIALIZE_CALL:
- return oparg + 2;
- case _SPECIALIZE_COMPARE_OP:
- return 2;
- case _SPECIALIZE_FOR_ITER:
- return 1;
- case _SPECIALIZE_LOAD_ATTR:
- return 1;
- case _SPECIALIZE_LOAD_GLOBAL:
- return 0;
- case _SPECIALIZE_LOAD_SUPER_ATTR:
- return 3;
- case _SPECIALIZE_SEND:
- return 2;
- case _SPECIALIZE_STORE_ATTR:
- return 1;
- case _SPECIALIZE_STORE_SUBSCR:
- return 2;
- case _SPECIALIZE_TO_BOOL:
- return 1;
- case _SPECIALIZE_UNPACK_SEQUENCE:
- return 1;
- case _STORE_ATTR:
- return 2;
- case _STORE_ATTR_INSTANCE_VALUE:
- return 2;
- case _STORE_ATTR_SLOT:
- return 2;
- case _STORE_SUBSCR:
- return 3;
- case _TO_BOOL:
- return 1;
- case _UNPACK_SEQUENCE:
- return 1;
default:
return -1;
}
}
-#endif // NEED_OPCODE_METADATA
-extern int _PyOpcode_num_pushed(int opcode, int oparg, bool jump);
+#endif
+
+extern int _PyOpcode_num_pushed(int opcode, int oparg);
#ifdef NEED_OPCODE_METADATA
-int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
+int _PyOpcode_num_pushed(int opcode, int oparg) {
switch(opcode) {
case BEFORE_ASYNC_WITH:
return 2;
@@ -728,7 +519,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case CALL_ALLOC_AND_ENTER_INIT:
return 1;
case CALL_BOUND_METHOD_EXACT_ARGS:
- return 0;
+ return (((0) ? 1 : 0));
case CALL_BUILTIN_CLASS:
return 1;
case CALL_BUILTIN_FAST:
@@ -760,7 +551,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case CALL_METHOD_DESCRIPTOR_O:
return 1;
case CALL_PY_EXACT_ARGS:
- return 0;
+ return (((0) ? 1 : 0));
case CALL_PY_WITH_DEFAULTS:
return 1;
case CALL_STR_1:
@@ -788,7 +579,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case CONVERT_VALUE:
return 1;
case COPY:
- return (oparg-1) + 2;
+ return 2 + (oparg-1);
case COPY_FREE_VARS:
return 0;
case DELETE_ATTR:
@@ -804,9 +595,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case DELETE_SUBSCR:
return 0;
case DICT_MERGE:
- return (oparg - 1) + 4;
+ return 4 + (oparg - 1);
case DICT_UPDATE:
- return (oparg - 1) + 1;
+ return 1 + (oparg - 1);
case END_ASYNC_FOR:
return 0;
case END_FOR:
@@ -868,7 +659,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case INSTRUMENTED_JUMP_FORWARD:
return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR:
- return ((oparg & 1) ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case INSTRUMENTED_POP_JUMP_IF_FALSE:
return 0;
case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -889,52 +680,46 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 0;
case IS_OP:
return 1;
- case JUMP:
- return 0;
case JUMP_BACKWARD:
return 0;
case JUMP_BACKWARD_NO_INTERRUPT:
return 0;
case JUMP_FORWARD:
return 0;
- case JUMP_NO_INTERRUPT:
- return 0;
case LIST_APPEND:
- return (oparg-1) + 1;
+ return 1 + (oparg-1);
case LIST_EXTEND:
- return (oparg-1) + 1;
+ return 1 + (oparg-1);
case LOAD_ASSERTION_ERROR:
return 1;
case LOAD_ATTR:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_ATTR_CLASS:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
- return 1;
+ return 1 + (((0) ? 1 : 0));
case LOAD_ATTR_INSTANCE_VALUE:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_ATTR_METHOD_LAZY_DICT:
- return 2;
+ return 1 + (((1) ? 1 : 0));
case LOAD_ATTR_METHOD_NO_DICT:
- return 2;
+ return 1 + (((1) ? 1 : 0));
case LOAD_ATTR_METHOD_WITH_VALUES:
- return 2;
+ return 1 + (((1) ? 1 : 0));
case LOAD_ATTR_MODULE:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
- return 1;
+ return 1 + (((0) ? 1 : 0));
case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
- return 1;
+ return 1 + (((0) ? 1 : 0));
case LOAD_ATTR_PROPERTY:
- return 1;
+ return 1 + (((0) ? 1 : 0));
case LOAD_ATTR_SLOT:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_ATTR_WITH_HINT:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_BUILD_CLASS:
return 1;
- case LOAD_CLOSURE:
- return 1;
case LOAD_CONST:
return 1;
case LOAD_DEREF:
@@ -952,35 +737,27 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case LOAD_FROM_DICT_OR_GLOBALS:
return 1;
case LOAD_GLOBAL:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_GLOBAL_BUILTIN:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_GLOBAL_MODULE:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_LOCALS:
return 1;
- case LOAD_METHOD:
- return (oparg & 1 ? 1 : 0) + 1;
case LOAD_NAME:
return 1;
case LOAD_SUPER_ATTR:
- return (oparg & 1 ? 1 : 0) + 1;
+ return 1 + ((oparg & 1));
case LOAD_SUPER_ATTR_ATTR:
- return 1;
+ return 1 + (((0) ? 1 : 0));
case LOAD_SUPER_ATTR_METHOD:
return 2;
- case LOAD_SUPER_METHOD:
- return (oparg & 1 ? 1 : 0) + 1;
- case LOAD_ZERO_SUPER_ATTR:
- return (oparg & 1 ? 1 : 0) + 1;
- case LOAD_ZERO_SUPER_METHOD:
- return (oparg & 1 ? 1 : 0) + 1;
case MAKE_CELL:
return 0;
case MAKE_FUNCTION:
return 1;
case MAP_ADD:
- return (oparg - 1) + 1;
+ return 1 + (oparg - 1);
case MATCH_CLASS:
return 1;
case MATCH_KEYS:
@@ -991,8 +768,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 2;
case NOP:
return 0;
- case POP_BLOCK:
- return 0;
case POP_EXCEPT:
return 0;
case POP_JUMP_IF_FALSE:
@@ -1031,18 +806,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 2;
case SETUP_ANNOTATIONS:
return 0;
- case SETUP_CLEANUP:
- return 0;
- case SETUP_FINALLY:
- return 0;
- case SETUP_WITH:
- return 0;
case SET_ADD:
- return (oparg-1) + 1;
+ return 1 + (oparg-1);
case SET_FUNCTION_ATTRIBUTE:
return 1;
case SET_UPDATE:
- return (oparg-1) + 1;
+ return 1 + (oparg-1);
case STORE_ATTR:
return 0;
case STORE_ATTR_INSTANCE_VALUE:
@@ -1057,8 +826,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 0;
case STORE_FAST_LOAD_FAST:
return 1;
- case STORE_FAST_MAYBE_NULL:
- return 0;
case STORE_FAST_STORE_FAST:
return 0;
case STORE_GLOBAL:
@@ -1074,7 +841,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case STORE_SUBSCR_LIST_INT:
return 0;
case SWAP:
- return (oparg-2) + 2;
+ return 2 + (oparg-2);
case TO_BOOL:
return 1;
case TO_BOOL_ALWAYS_TRUE:
@@ -1096,7 +863,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case UNARY_NOT:
return 1;
case UNPACK_EX:
- return (oparg & 0xFF) + (oparg >> 8) + 1;
+ return 1 + (oparg >> 8) + (oparg & 0xFF);
case UNPACK_SEQUENCE:
return oparg;
case UNPACK_SEQUENCE_LIST:
@@ -1109,221 +876,27 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 5;
case YIELD_VALUE:
return 1;
- case _BINARY_OP:
- return 1;
- case _BINARY_OP_ADD_FLOAT:
- return 1;
- case _BINARY_OP_ADD_INT:
- return 1;
- case _BINARY_OP_ADD_UNICODE:
- return 1;
- case _BINARY_OP_INPLACE_ADD_UNICODE:
- return 0;
- case _BINARY_OP_MULTIPLY_FLOAT:
- return 1;
- case _BINARY_OP_MULTIPLY_INT:
- return 1;
- case _BINARY_OP_SUBTRACT_FLOAT:
- return 1;
- case _BINARY_OP_SUBTRACT_INT:
- return 1;
- case _BINARY_SUBSCR:
- return 1;
- case _CALL:
- return 1;
- case _CHECK_ATTR_CLASS:
- return 1;
- case _CHECK_ATTR_METHOD_LAZY_DICT:
- return 1;
- case _CHECK_ATTR_MODULE:
- return 1;
- case _CHECK_ATTR_WITH_HINT:
- return 1;
- case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
- return oparg + 2;
- case _CHECK_FUNCTION_EXACT_ARGS:
- return oparg + 2;
- case _CHECK_MANAGED_OBJECT_HAS_VALUES:
- return 1;
- case _CHECK_PEP_523:
- return 0;
- case _CHECK_STACK_SPACE:
- return oparg + 2;
- case _CHECK_VALIDITY:
- return 0;
- case _COMPARE_OP:
- return 1;
- case _EXIT_TRACE:
- return 0;
- case _FOR_ITER:
- return 2;
- case _FOR_ITER_TIER_TWO:
- return 2;
- case _GUARD_BOTH_FLOAT:
- return 2;
- case _GUARD_BOTH_INT:
- return 2;
- case _GUARD_BOTH_UNICODE:
- return 2;
- case _GUARD_BUILTINS_VERSION:
- return 0;
- case _GUARD_DORV_VALUES:
- return 1;
- case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
- return 1;
- case _GUARD_GLOBALS_VERSION:
- return 0;
- case _GUARD_IS_FALSE_POP:
- return 0;
- case _GUARD_IS_NONE_POP:
- return 0;
- case _GUARD_IS_NOT_NONE_POP:
- return 0;
- case _GUARD_IS_TRUE_POP:
- return 0;
- case _GUARD_KEYS_VERSION:
- return 1;
- case _GUARD_NOT_EXHAUSTED_LIST:
- return 1;
- case _GUARD_NOT_EXHAUSTED_RANGE:
- return 1;
- case _GUARD_NOT_EXHAUSTED_TUPLE:
- return 1;
- case _GUARD_TYPE_VERSION:
- return 1;
- case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
- return oparg + 2;
- case _INIT_CALL_PY_EXACT_ARGS:
- return 1;
- case _INSERT:
- return oparg + 1;
- case _IS_NONE:
- return 1;
- case _ITER_CHECK_LIST:
- return 1;
- case _ITER_CHECK_RANGE:
- return 1;
- case _ITER_CHECK_TUPLE:
- return 1;
- case _ITER_JUMP_LIST:
- return 1;
- case _ITER_JUMP_RANGE:
- return 1;
- case _ITER_JUMP_TUPLE:
- return 1;
- case _ITER_NEXT_LIST:
- return 2;
- case _ITER_NEXT_RANGE:
- return 2;
- case _ITER_NEXT_TUPLE:
- return 2;
- case _JUMP_TO_TOP:
- return 0;
- case _LOAD_ATTR:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_ATTR_CLASS:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_ATTR_INSTANCE_VALUE:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_ATTR_METHOD_LAZY_DICT:
- return 2;
- case _LOAD_ATTR_METHOD_NO_DICT:
- return 2;
- case _LOAD_ATTR_METHOD_WITH_VALUES:
- return 2;
- case _LOAD_ATTR_MODULE:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
- return 1;
- case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
- return 1;
- case _LOAD_ATTR_SLOT:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_ATTR_WITH_HINT:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_GLOBAL:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_GLOBAL_BUILTINS:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_GLOBAL_MODULE:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _LOAD_SUPER_ATTR:
- return ((oparg & 1) ? 1 : 0) + 1;
- case _POP_FRAME:
- return 0;
- case _POP_JUMP_IF_FALSE:
- return 0;
- case _POP_JUMP_IF_TRUE:
- return 0;
- case _PUSH_FRAME:
- return 0;
- case _SAVE_RETURN_OFFSET:
- return 0;
- case _SEND:
- return 2;
- case _SET_IP:
- return 0;
- case _SPECIALIZE_BINARY_OP:
- return 2;
- case _SPECIALIZE_BINARY_SUBSCR:
- return 2;
- case _SPECIALIZE_CALL:
- return oparg + 2;
- case _SPECIALIZE_COMPARE_OP:
- return 2;
- case _SPECIALIZE_FOR_ITER:
- return 1;
- case _SPECIALIZE_LOAD_ATTR:
- return 1;
- case _SPECIALIZE_LOAD_GLOBAL:
- return 0;
- case _SPECIALIZE_LOAD_SUPER_ATTR:
- return 3;
- case _SPECIALIZE_SEND:
- return 2;
- case _SPECIALIZE_STORE_ATTR:
- return 1;
- case _SPECIALIZE_STORE_SUBSCR:
- return 2;
- case _SPECIALIZE_TO_BOOL:
- return 1;
- case _SPECIALIZE_UNPACK_SEQUENCE:
- return 1;
- case _STORE_ATTR:
- return 0;
- case _STORE_ATTR_INSTANCE_VALUE:
- return 0;
- case _STORE_ATTR_SLOT:
- return 0;
- case _STORE_SUBSCR:
- return 0;
- case _TO_BOOL:
- return 1;
- case _UNPACK_SEQUENCE:
- return oparg;
default:
return -1;
}
}
-#endif // NEED_OPCODE_METADATA
+
+#endif
enum InstructionFormat {
- INSTR_FMT_IB,
- INSTR_FMT_IBC,
- INSTR_FMT_IBC0,
- INSTR_FMT_IBC00,
- INSTR_FMT_IBC000,
- INSTR_FMT_IBC0000000,
- INSTR_FMT_IBC00000000,
- INSTR_FMT_IX,
- INSTR_FMT_IXC,
- INSTR_FMT_IXC0,
- INSTR_FMT_IXC00,
- INSTR_FMT_IXC000,
+ INSTR_FMT_IB = 1,
+ INSTR_FMT_IBC = 2,
+ INSTR_FMT_IBC00 = 3,
+ INSTR_FMT_IBC000 = 4,
+ INSTR_FMT_IBC00000000 = 5,
+ INSTR_FMT_IX = 6,
+ INSTR_FMT_IXC = 7,
+ INSTR_FMT_IXC00 = 8,
+ INSTR_FMT_IXC000 = 9,
};
#define IS_VALID_OPCODE(OP) \
- (((OP) >= 0) && ((OP) < OPCODE_METADATA_SIZE) && \
+ (((OP) >= 0) && ((OP) < 268) && \
(_PyOpcode_opcode_metadata[(OP)].valid_entry))
#define HAS_ARG_FLAG (1)
@@ -1347,17 +920,6 @@ enum InstructionFormat {
#define OPCODE_HAS_ERROR(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_FLAG))
#define OPCODE_HAS_ESCAPES(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ESCAPES_FLAG))
-struct opcode_metadata {
- bool valid_entry;
- enum InstructionFormat instr_format;
- int flags;
-};
-
-struct opcode_macro_expansion {
- int nuops;
- struct { int16_t uop; int8_t size; int8_t offset; } uops[12];
-};
-
#define OPARG_FULL 0
#define OPARG_CACHE_1 1
#define OPARG_CACHE_2 2
@@ -1365,18 +927,17 @@ struct opcode_macro_expansion {
#define OPARG_TOP 5
#define OPARG_BOTTOM 6
#define OPARG_SAVE_RETURN_OFFSET 7
+#define OPARG_REPLACED 9
-#define OPCODE_METADATA_FLAGS(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG))
-#define SAME_OPCODE_METADATA(OP1, OP2) \
- (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2))
-
-#define OPCODE_METADATA_SIZE 512
-#define OPCODE_UOP_NAME_SIZE 512
-#define OPCODE_MACRO_EXPANSION_SIZE 256
+struct opcode_metadata {
+ uint8_t valid_entry;
+ int8_t instr_format;
+ int16_t flags;
+};
-extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE];
+extern const struct opcode_metadata _PyOpcode_opcode_metadata[268];
#ifdef NEED_OPCODE_METADATA
-const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
+const struct opcode_metadata _PyOpcode_opcode_metadata[268] = {
[BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1486,11 +1047,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[INTERPRETER_EXIT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 },
@@ -1508,7 +1067,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_CLOSURE] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
[LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
@@ -1521,14 +1079,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_ZERO_SUPER_ATTR] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_ZERO_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1537,7 +1091,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 },
[MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 },
[NOP] = { true, INSTR_FMT_IX, 0 },
- [POP_BLOCK] = { true, 0, 0 },
[POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
@@ -1557,9 +1110,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
[SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [SETUP_CLEANUP] = { true, 0, HAS_ARG_FLAG },
- [SETUP_FINALLY] = { true, 0, HAS_ARG_FLAG },
- [SETUP_WITH] = { true, 0, HAS_ARG_FLAG },
[SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
[SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1570,7 +1120,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
[STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
- [STORE_FAST_MAYBE_NULL] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1596,110 +1145,33 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_BINARY_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
- [_BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 },
- [_BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
- [_BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 },
- [_BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
- [_BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, 0 },
- [_BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
- [_BINARY_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_CALL] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
- [_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_CHECK_ATTR_MODULE] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
- [_CHECK_ATTR_WITH_HINT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
- [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_CHECK_FUNCTION_EXACT_ARGS] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_CHECK_MANAGED_OBJECT_HAS_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_CHECK_PEP_523] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_CHECK_STACK_SPACE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_CHECK_VALIDITY] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_COMPARE_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_EXIT_TRACE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_FOR_ITER_TIER_TWO] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_GUARD_BOTH_FLOAT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_BOTH_INT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_BOTH_UNICODE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_BUILTINS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
- [_GUARD_DORV_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_GLOBALS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
- [_GUARD_IS_FALSE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_IS_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_IS_NOT_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_IS_TRUE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
- [_GUARD_NOT_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_NOT_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_NOT_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_GUARD_TYPE_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
- [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_INSERT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [_IS_NONE] = { true, INSTR_FMT_IX, 0 },
- [_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_ITER_CHECK_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_ITER_CHECK_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
- [_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [_ITER_JUMP_RANGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [_ITER_JUMP_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [_ITER_NEXT_LIST] = { true, INSTR_FMT_IX, 0 },
- [_ITER_NEXT_RANGE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_ITER_NEXT_TUPLE] = { true, INSTR_FMT_IX, 0 },
- [_JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG },
- [_LOAD_ATTR] = { true, INSTR_FMT_IBC0000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
- [_LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
- [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
- [_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_GLOBAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_LOAD_GLOBAL_BUILTINS] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_POP_FRAME] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
- [_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [_PUSH_FRAME] = { true, INSTR_FMT_IX, 0 },
- [_SAVE_RETURN_OFFSET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [_SEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_SPECIALIZE_CALL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_LOAD_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_LOAD_GLOBAL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_SEND] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_SPECIALIZE_STORE_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
- [_SPECIALIZE_STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_SPECIALIZE_TO_BOOL] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_SPECIALIZE_UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
- [_STORE_ATTR] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
- [_STORE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_TO_BOOL] = { true, INSTR_FMT_IXC0, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [_UNPACK_SEQUENCE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [LOAD_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ZERO_SUPER_ATTR] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ZERO_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [POP_BLOCK] = { true, -1, 0 },
+ [SETUP_CLEANUP] = { true, -1, HAS_ARG_FLAG },
+ [SETUP_FINALLY] = { true, -1, HAS_ARG_FLAG },
+ [SETUP_WITH] = { true, -1, HAS_ARG_FLAG },
+ [STORE_FAST_MAYBE_NULL] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
};
-#endif // NEED_OPCODE_METADATA
+#endif
+
+#define MAX_UOP_PER_EXPANSION 8
+struct opcode_macro_expansion {
+ int nuops;
+ struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
+};
+extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];
-extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE];
#ifdef NEED_OPCODE_METADATA
-const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] = {
- [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { BEFORE_ASYNC_WITH, 0, 0 } } },
- [BEFORE_WITH] = { .nuops = 1, .uops = { { BEFORE_WITH, 0, 0 } } },
+const struct opcode_macro_expansion
+_PyOpcode_macro_expansion[256] = {
+ [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { _BEFORE_ASYNC_WITH, 0, 0 } } },
+ [BEFORE_WITH] = { .nuops = 1, .uops = { { _BEFORE_WITH, 0, 0 } } },
[BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, 0, 0 } } },
[BINARY_OP_ADD_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_ADD_FLOAT, 0, 0 } } },
[BINARY_OP_ADD_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_ADD_INT, 0, 0 } } },
@@ -1708,73 +1180,73 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
[BINARY_OP_MULTIPLY_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_MULTIPLY_INT, 0, 0 } } },
[BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, 0, 0 } } },
[BINARY_OP_SUBTRACT_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_SUBTRACT_INT, 0, 0 } } },
- [BINARY_SLICE] = { .nuops = 1, .uops = { { BINARY_SLICE, 0, 0 } } },
+ [BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, 0, 0 } } },
[BINARY_SUBSCR] = { .nuops = 1, .uops = { { _BINARY_SUBSCR, 0, 0 } } },
- [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_DICT, 0, 0 } } },
- [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_LIST_INT, 0, 0 } } },
- [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_STR_INT, 0, 0 } } },
- [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
- [BUILD_CONST_KEY_MAP] = { .nuops = 1, .uops = { { BUILD_CONST_KEY_MAP, 0, 0 } } },
- [BUILD_LIST] = { .nuops = 1, .uops = { { BUILD_LIST, 0, 0 } } },
- [BUILD_MAP] = { .nuops = 1, .uops = { { BUILD_MAP, 0, 0 } } },
- [BUILD_SET] = { .nuops = 1, .uops = { { BUILD_SET, 0, 0 } } },
- [BUILD_SLICE] = { .nuops = 1, .uops = { { BUILD_SLICE, 0, 0 } } },
- [BUILD_STRING] = { .nuops = 1, .uops = { { BUILD_STRING, 0, 0 } } },
- [BUILD_TUPLE] = { .nuops = 1, .uops = { { BUILD_TUPLE, 0, 0 } } },
+ [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_DICT, 0, 0 } } },
+ [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_LIST_INT, 0, 0 } } },
+ [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_STR_INT, 0, 0 } } },
+ [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
+ [BUILD_CONST_KEY_MAP] = { .nuops = 1, .uops = { { _BUILD_CONST_KEY_MAP, 0, 0 } } },
+ [BUILD_LIST] = { .nuops = 1, .uops = { { _BUILD_LIST, 0, 0 } } },
+ [BUILD_MAP] = { .nuops = 1, .uops = { { _BUILD_MAP, 0, 0 } } },
+ [BUILD_SET] = { .nuops = 1, .uops = { { _BUILD_SET, 0, 0 } } },
+ [BUILD_SLICE] = { .nuops = 1, .uops = { { _BUILD_SLICE, 0, 0 } } },
+ [BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
+ [BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 0, 0 } } },
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
- [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { CALL_BUILTIN_CLASS, 0, 0 } } },
- [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST, 0, 0 } } },
- [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
- [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_BUILTIN_O, 0, 0 } } },
- [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { CALL_INTRINSIC_1, 0, 0 } } },
- [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { CALL_INTRINSIC_2, 0, 0 } } },
- [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_ISINSTANCE, 0, 0 } } },
- [CALL_LEN] = { .nuops = 1, .uops = { { CALL_LEN, 0, 0 } } },
- [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
- [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } },
- [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
- [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_O, 0, 0 } } },
+ [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { _CALL_BUILTIN_CLASS, 0, 0 } } },
+ [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { _CALL_BUILTIN_FAST, 0, 0 } } },
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
+ [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { _CALL_BUILTIN_O, 0, 0 } } },
+ [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, 0, 0 } } },
+ [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, 0, 0 } } },
+ [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { _CALL_ISINSTANCE, 0, 0 } } },
+ [CALL_LEN] = { .nuops = 1, .uops = { { _CALL_LEN, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_O, 0, 0 } } },
[CALL_PY_EXACT_ARGS] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
- [CALL_STR_1] = { .nuops = 1, .uops = { { CALL_STR_1, 0, 0 } } },
- [CALL_TUPLE_1] = { .nuops = 1, .uops = { { CALL_TUPLE_1, 0, 0 } } },
- [CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } },
- [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { CHECK_EG_MATCH, 0, 0 } } },
- [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { CHECK_EXC_MATCH, 0, 0 } } },
+ [CALL_STR_1] = { .nuops = 1, .uops = { { _CALL_STR_1, 0, 0 } } },
+ [CALL_TUPLE_1] = { .nuops = 1, .uops = { { _CALL_TUPLE_1, 0, 0 } } },
+ [CALL_TYPE_1] = { .nuops = 1, .uops = { { _CALL_TYPE_1, 0, 0 } } },
+ [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, 0, 0 } } },
+ [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, 0, 0 } } },
[COMPARE_OP] = { .nuops = 1, .uops = { { _COMPARE_OP, 0, 0 } } },
- [COMPARE_OP_FLOAT] = { .nuops = 1, .uops = { { COMPARE_OP_FLOAT, 0, 0 } } },
- [COMPARE_OP_INT] = { .nuops = 1, .uops = { { COMPARE_OP_INT, 0, 0 } } },
- [COMPARE_OP_STR] = { .nuops = 1, .uops = { { COMPARE_OP_STR, 0, 0 } } },
- [CONTAINS_OP] = { .nuops = 1, .uops = { { CONTAINS_OP, 0, 0 } } },
- [CONVERT_VALUE] = { .nuops = 1, .uops = { { CONVERT_VALUE, 0, 0 } } },
- [COPY] = { .nuops = 1, .uops = { { COPY, 0, 0 } } },
- [COPY_FREE_VARS] = { .nuops = 1, .uops = { { COPY_FREE_VARS, 0, 0 } } },
- [DELETE_ATTR] = { .nuops = 1, .uops = { { DELETE_ATTR, 0, 0 } } },
- [DELETE_DEREF] = { .nuops = 1, .uops = { { DELETE_DEREF, 0, 0 } } },
- [DELETE_FAST] = { .nuops = 1, .uops = { { DELETE_FAST, 0, 0 } } },
- [DELETE_GLOBAL] = { .nuops = 1, .uops = { { DELETE_GLOBAL, 0, 0 } } },
- [DELETE_NAME] = { .nuops = 1, .uops = { { DELETE_NAME, 0, 0 } } },
- [DELETE_SUBSCR] = { .nuops = 1, .uops = { { DELETE_SUBSCR, 0, 0 } } },
- [DICT_MERGE] = { .nuops = 1, .uops = { { DICT_MERGE, 0, 0 } } },
- [DICT_UPDATE] = { .nuops = 1, .uops = { { DICT_UPDATE, 0, 0 } } },
- [END_FOR] = { .nuops = 2, .uops = { { POP_TOP, 0, 0 }, { POP_TOP, 0, 0 } } },
- [END_SEND] = { .nuops = 1, .uops = { { END_SEND, 0, 0 } } },
- [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { EXIT_INIT_CHECK, 0, 0 } } },
- [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { FORMAT_SIMPLE, 0, 0 } } },
- [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { FORMAT_WITH_SPEC, 0, 0 } } },
- [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 0, 0 } } },
- [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 0, 0 }, { _ITER_NEXT_LIST, 0, 0 } } },
- [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 0, 0 }, { _ITER_NEXT_RANGE, 0, 0 } } },
- [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 0, 0 }, { _ITER_NEXT_TUPLE, 0, 0 } } },
- [GET_AITER] = { .nuops = 1, .uops = { { GET_AITER, 0, 0 } } },
- [GET_ANEXT] = { .nuops = 1, .uops = { { GET_ANEXT, 0, 0 } } },
- [GET_AWAITABLE] = { .nuops = 1, .uops = { { GET_AWAITABLE, 0, 0 } } },
- [GET_ITER] = { .nuops = 1, .uops = { { GET_ITER, 0, 0 } } },
- [GET_LEN] = { .nuops = 1, .uops = { { GET_LEN, 0, 0 } } },
- [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } },
- [IS_OP] = { .nuops = 1, .uops = { { IS_OP, 0, 0 } } },
- [LIST_APPEND] = { .nuops = 1, .uops = { { LIST_APPEND, 0, 0 } } },
- [LIST_EXTEND] = { .nuops = 1, .uops = { { LIST_EXTEND, 0, 0 } } },
- [LOAD_ASSERTION_ERROR] = { .nuops = 1, .uops = { { LOAD_ASSERTION_ERROR, 0, 0 } } },
+ [COMPARE_OP_FLOAT] = { .nuops = 1, .uops = { { _COMPARE_OP_FLOAT, 0, 0 } } },
+ [COMPARE_OP_INT] = { .nuops = 1, .uops = { { _COMPARE_OP_INT, 0, 0 } } },
+ [COMPARE_OP_STR] = { .nuops = 1, .uops = { { _COMPARE_OP_STR, 0, 0 } } },
+ [CONTAINS_OP] = { .nuops = 1, .uops = { { _CONTAINS_OP, 0, 0 } } },
+ [CONVERT_VALUE] = { .nuops = 1, .uops = { { _CONVERT_VALUE, 0, 0 } } },
+ [COPY] = { .nuops = 1, .uops = { { _COPY, 0, 0 } } },
+ [COPY_FREE_VARS] = { .nuops = 1, .uops = { { _COPY_FREE_VARS, 0, 0 } } },
+ [DELETE_ATTR] = { .nuops = 1, .uops = { { _DELETE_ATTR, 0, 0 } } },
+ [DELETE_DEREF] = { .nuops = 1, .uops = { { _DELETE_DEREF, 0, 0 } } },
+ [DELETE_FAST] = { .nuops = 1, .uops = { { _DELETE_FAST, 0, 0 } } },
+ [DELETE_GLOBAL] = { .nuops = 1, .uops = { { _DELETE_GLOBAL, 0, 0 } } },
+ [DELETE_NAME] = { .nuops = 1, .uops = { { _DELETE_NAME, 0, 0 } } },
+ [DELETE_SUBSCR] = { .nuops = 1, .uops = { { _DELETE_SUBSCR, 0, 0 } } },
+ [DICT_MERGE] = { .nuops = 1, .uops = { { _DICT_MERGE, 0, 0 } } },
+ [DICT_UPDATE] = { .nuops = 1, .uops = { { _DICT_UPDATE, 0, 0 } } },
+ [END_FOR] = { .nuops = 2, .uops = { { _POP_TOP, 0, 0 }, { _POP_TOP, 0, 0 } } },
+ [END_SEND] = { .nuops = 1, .uops = { { _END_SEND, 0, 0 } } },
+ [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { _EXIT_INIT_CHECK, 0, 0 } } },
+ [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, 0, 0 } } },
+ [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, 0, 0 } } },
+ [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 9, 0 } } },
+ [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 9, 1 }, { _ITER_NEXT_LIST, 0, 0 } } },
+ [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 9, 1 }, { _ITER_NEXT_RANGE, 0, 0 } } },
+ [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 9, 1 }, { _ITER_NEXT_TUPLE, 0, 0 } } },
+ [GET_AITER] = { .nuops = 1, .uops = { { _GET_AITER, 0, 0 } } },
+ [GET_ANEXT] = { .nuops = 1, .uops = { { _GET_ANEXT, 0, 0 } } },
+ [GET_AWAITABLE] = { .nuops = 1, .uops = { { _GET_AWAITABLE, 0, 0 } } },
+ [GET_ITER] = { .nuops = 1, .uops = { { _GET_ITER, 0, 0 } } },
+ [GET_LEN] = { .nuops = 1, .uops = { { _GET_LEN, 0, 0 } } },
+ [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { _GET_YIELD_FROM_ITER, 0, 0 } } },
+ [IS_OP] = { .nuops = 1, .uops = { { _IS_OP, 0, 0 } } },
+ [LIST_APPEND] = { .nuops = 1, .uops = { { _LIST_APPEND, 0, 0 } } },
+ [LIST_EXTEND] = { .nuops = 1, .uops = { { _LIST_EXTEND, 0, 0 } } },
+ [LOAD_ASSERTION_ERROR] = { .nuops = 1, .uops = { { _LOAD_ASSERTION_ERROR, 0, 0 } } },
[LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, 0, 0 } } },
[LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } },
@@ -1786,183 +1258,81 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
[LOAD_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 } } },
[LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_WITH_HINT, 0, 0 }, { _LOAD_ATTR_WITH_HINT, 1, 3 } } },
- [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { LOAD_BUILD_CLASS, 0, 0 } } },
- [LOAD_CONST] = { .nuops = 1, .uops = { { LOAD_CONST, 0, 0 } } },
- [LOAD_DEREF] = { .nuops = 1, .uops = { { LOAD_DEREF, 0, 0 } } },
- [LOAD_FAST] = { .nuops = 1, .uops = { { LOAD_FAST, 0, 0 } } },
- [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { LOAD_FAST_AND_CLEAR, 0, 0 } } },
- [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { LOAD_FAST_CHECK, 0, 0 } } },
- [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { LOAD_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
- [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
- [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } },
+ [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, 0, 0 } } },
+ [LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, 0, 0 } } },
+ [LOAD_DEREF] = { .nuops = 1, .uops = { { _LOAD_DEREF, 0, 0 } } },
+ [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } },
+ [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } },
+ [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { _LOAD_FAST_CHECK, 0, 0 } } },
+ [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _LOAD_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+ [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
+ [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } },
[LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } },
[LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } },
[LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } },
- [LOAD_LOCALS] = { .nuops = 1, .uops = { { LOAD_LOCALS, 0, 0 } } },
- [LOAD_NAME] = { .nuops = 1, .uops = { { LOAD_NAME, 0, 0 } } },
- [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
- [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
- [MAKE_CELL] = { .nuops = 1, .uops = { { MAKE_CELL, 0, 0 } } },
- [MAKE_FUNCTION] = { .nuops = 1, .uops = { { MAKE_FUNCTION, 0, 0 } } },
- [MAP_ADD] = { .nuops = 1, .uops = { { MAP_ADD, 0, 0 } } },
- [MATCH_CLASS] = { .nuops = 1, .uops = { { MATCH_CLASS, 0, 0 } } },
- [MATCH_KEYS] = { .nuops = 1, .uops = { { MATCH_KEYS, 0, 0 } } },
- [MATCH_MAPPING] = { .nuops = 1, .uops = { { MATCH_MAPPING, 0, 0 } } },
- [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { MATCH_SEQUENCE, 0, 0 } } },
- [NOP] = { .nuops = 1, .uops = { { NOP, 0, 0 } } },
- [POP_EXCEPT] = { .nuops = 1, .uops = { { POP_EXCEPT, 0, 0 } } },
- [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 0, 0 } } },
- [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 0, 0 } } },
- [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 0, 0 } } },
- [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 0, 0 } } },
- [POP_TOP] = { .nuops = 1, .uops = { { POP_TOP, 0, 0 } } },
- [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } },
- [PUSH_NULL] = { .nuops = 1, .uops = { { PUSH_NULL, 0, 0 } } },
- [RESUME_CHECK] = { .nuops = 1, .uops = { { RESUME_CHECK, 0, 0 } } },
- [RETURN_CONST] = { .nuops = 2, .uops = { { LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
+ [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } },
+ [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } },
+ [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
+ [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
+ [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } },
+ [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } },
+ [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } },
+ [MATCH_CLASS] = { .nuops = 1, .uops = { { _MATCH_CLASS, 0, 0 } } },
+ [MATCH_KEYS] = { .nuops = 1, .uops = { { _MATCH_KEYS, 0, 0 } } },
+ [MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, 0, 0 } } },
+ [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, 0, 0 } } },
+ [NOP] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
+ [POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, 0, 0 } } },
+ [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 9, 1 } } },
+ [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 9, 1 } } },
+ [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 9, 1 } } },
+ [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 9, 1 } } },
+ [POP_TOP] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
+ [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, 0, 0 } } },
+ [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } },
+ [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } },
+ [RETURN_CONST] = { .nuops = 2, .uops = { { _LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
[RETURN_VALUE] = { .nuops = 1, .uops = { { _POP_FRAME, 0, 0 } } },
- [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { SETUP_ANNOTATIONS, 0, 0 } } },
- [SET_ADD] = { .nuops = 1, .uops = { { SET_ADD, 0, 0 } } },
- [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
- [SET_UPDATE] = { .nuops = 1, .uops = { { SET_UPDATE, 0, 0 } } },
+ [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } },
+ [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } },
+ [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
+ [SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, 0, 0 } } },
[STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, 0, 0 } } },
[STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } },
[STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } },
- [STORE_DEREF] = { .nuops = 1, .uops = { { STORE_DEREF, 0, 0 } } },
- [STORE_FAST] = { .nuops = 1, .uops = { { STORE_FAST, 0, 0 } } },
- [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
- [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { STORE_FAST, 6, 0 } } },
- [STORE_GLOBAL] = { .nuops = 1, .uops = { { STORE_GLOBAL, 0, 0 } } },
- [STORE_NAME] = { .nuops = 1, .uops = { { STORE_NAME, 0, 0 } } },
- [STORE_SLICE] = { .nuops = 1, .uops = { { STORE_SLICE, 0, 0 } } },
+ [STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, 0, 0 } } },
+ [STORE_FAST] = { .nuops = 1, .uops = { { _STORE_FAST, 0, 0 } } },
+ [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+ [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _STORE_FAST, 6, 0 } } },
+ [STORE_GLOBAL] = { .nuops = 1, .uops = { { _STORE_GLOBAL, 0, 0 } } },
+ [STORE_NAME] = { .nuops = 1, .uops = { { _STORE_NAME, 0, 0 } } },
+ [STORE_SLICE] = { .nuops = 1, .uops = { { _STORE_SLICE, 0, 0 } } },
[STORE_SUBSCR] = { .nuops = 1, .uops = { { _STORE_SUBSCR, 0, 0 } } },
- [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { STORE_SUBSCR_DICT, 0, 0 } } },
- [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { STORE_SUBSCR_LIST_INT, 0, 0 } } },
- [SWAP] = { .nuops = 1, .uops = { { SWAP, 0, 0 } } },
+ [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_DICT, 0, 0 } } },
+ [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_LIST_INT, 0, 0 } } },
+ [SWAP] = { .nuops = 1, .uops = { { _SWAP, 0, 0 } } },
[TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, 0, 0 } } },
- [TO_BOOL_ALWAYS_TRUE] = { .nuops = 1, .uops = { { TO_BOOL_ALWAYS_TRUE, 2, 1 } } },
- [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { TO_BOOL_BOOL, 0, 0 } } },
- [TO_BOOL_INT] = { .nuops = 1, .uops = { { TO_BOOL_INT, 0, 0 } } },
- [TO_BOOL_LIST] = { .nuops = 1, .uops = { { TO_BOOL_LIST, 0, 0 } } },
- [TO_BOOL_NONE] = { .nuops = 1, .uops = { { TO_BOOL_NONE, 0, 0 } } },
- [TO_BOOL_STR] = { .nuops = 1, .uops = { { TO_BOOL_STR, 0, 0 } } },
- [UNARY_INVERT] = { .nuops = 1, .uops = { { UNARY_INVERT, 0, 0 } } },
- [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { UNARY_NEGATIVE, 0, 0 } } },
- [UNARY_NOT] = { .nuops = 1, .uops = { { UNARY_NOT, 0, 0 } } },
- [UNPACK_EX] = { .nuops = 1, .uops = { { UNPACK_EX, 0, 0 } } },
+ [TO_BOOL_ALWAYS_TRUE] = { .nuops = 1, .uops = { { _TO_BOOL_ALWAYS_TRUE, 2, 1 } } },
+ [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL_BOOL, 0, 0 } } },
+ [TO_BOOL_INT] = { .nuops = 1, .uops = { { _TO_BOOL_INT, 0, 0 } } },
+ [TO_BOOL_LIST] = { .nuops = 1, .uops = { { _TO_BOOL_LIST, 0, 0 } } },
+ [TO_BOOL_NONE] = { .nuops = 1, .uops = { { _TO_BOOL_NONE, 0, 0 } } },
+ [TO_BOOL_STR] = { .nuops = 1, .uops = { { _TO_BOOL_STR, 0, 0 } } },
+ [UNARY_INVERT] = { .nuops = 1, .uops = { { _UNARY_INVERT, 0, 0 } } },
+ [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, 0, 0 } } },
+ [UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, 0, 0 } } },
+ [UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, 0, 0 } } },
[UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, 0, 0 } } },
- [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_LIST, 0, 0 } } },
- [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TUPLE, 0, 0 } } },
- [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } },
- [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } },
+ [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_LIST, 0, 0 } } },
+ [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TUPLE, 0, 0 } } },
+ [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } },
+ [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, 0, 0 } } },
};
#endif // NEED_OPCODE_METADATA
-extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE];
+extern const char *_PyOpcode_OpName[268];
#ifdef NEED_OPCODE_METADATA
-const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = {
- [_EXIT_TRACE] = "_EXIT_TRACE",
- [_SET_IP] = "_SET_IP",
- [_BINARY_OP] = "_BINARY_OP",
- [_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
- [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
- [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
- [_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE",
- [_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
- [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
- [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
- [_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
- [_BINARY_SUBSCR] = "_BINARY_SUBSCR",
- [_CALL] = "_CALL",
- [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
- [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
- [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
- [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
- [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
- [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
- [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
- [_CHECK_PEP_523] = "_CHECK_PEP_523",
- [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
- [_CHECK_VALIDITY] = "_CHECK_VALIDITY",
- [_COMPARE_OP] = "_COMPARE_OP",
- [_FOR_ITER] = "_FOR_ITER",
- [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
- [_GUARD_BOTH_FLOAT] = "_GUARD_BOTH_FLOAT",
- [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT",
- [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
- [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION",
- [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES",
- [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
- [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
- [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP",
- [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP",
- [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP",
- [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP",
- [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
- [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
- [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_EXHAUSTED_RANGE",
- [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_EXHAUSTED_TUPLE",
- [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
- [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
- [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS",
- [_INSERT] = "_INSERT",
- [_IS_NONE] = "_IS_NONE",
- [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
- [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE",
- [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE",
- [_ITER_JUMP_LIST] = "_ITER_JUMP_LIST",
- [_ITER_JUMP_RANGE] = "_ITER_JUMP_RANGE",
- [_ITER_JUMP_TUPLE] = "_ITER_JUMP_TUPLE",
- [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST",
- [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE",
- [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE",
- [_JUMP_TO_TOP] = "_JUMP_TO_TOP",
- [_LOAD_ATTR] = "_LOAD_ATTR",
- [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
- [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
- [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
- [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
- [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
- [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
- [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
- [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
- [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
- [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
- [_LOAD_GLOBAL] = "_LOAD_GLOBAL",
- [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS",
- [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
- [_LOAD_SUPER_ATTR] = "_LOAD_SUPER_ATTR",
- [_POP_FRAME] = "_POP_FRAME",
- [_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE",
- [_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE",
- [_PUSH_FRAME] = "_PUSH_FRAME",
- [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
- [_SEND] = "_SEND",
- [_SPECIALIZE_BINARY_OP] = "_SPECIALIZE_BINARY_OP",
- [_SPECIALIZE_BINARY_SUBSCR] = "_SPECIALIZE_BINARY_SUBSCR",
- [_SPECIALIZE_CALL] = "_SPECIALIZE_CALL",
- [_SPECIALIZE_COMPARE_OP] = "_SPECIALIZE_COMPARE_OP",
- [_SPECIALIZE_FOR_ITER] = "_SPECIALIZE_FOR_ITER",
- [_SPECIALIZE_LOAD_ATTR] = "_SPECIALIZE_LOAD_ATTR",
- [_SPECIALIZE_LOAD_GLOBAL] = "_SPECIALIZE_LOAD_GLOBAL",
- [_SPECIALIZE_LOAD_SUPER_ATTR] = "_SPECIALIZE_LOAD_SUPER_ATTR",
- [_SPECIALIZE_SEND] = "_SPECIALIZE_SEND",
- [_SPECIALIZE_STORE_ATTR] = "_SPECIALIZE_STORE_ATTR",
- [_SPECIALIZE_STORE_SUBSCR] = "_SPECIALIZE_STORE_SUBSCR",
- [_SPECIALIZE_TO_BOOL] = "_SPECIALIZE_TO_BOOL",
- [_SPECIALIZE_UNPACK_SEQUENCE] = "_SPECIALIZE_UNPACK_SEQUENCE",
- [_STORE_ATTR] = "_STORE_ATTR",
- [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
- [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
- [_STORE_SUBSCR] = "_STORE_SUBSCR",
- [_TO_BOOL] = "_TO_BOOL",
- [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
-};
-#endif // NEED_OPCODE_METADATA
-
-extern const char *const _PyOpcode_OpName[268];
-#ifdef NEED_OPCODE_METADATA
-const char *const _PyOpcode_OpName[268] = {
+const char *_PyOpcode_OpName[268] = {
[BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH",
[BEFORE_WITH] = "BEFORE_WITH",
[BINARY_OP] = "BINARY_OP",
@@ -2184,13 +1554,13 @@ const char *const _PyOpcode_OpName[268] = {
[WITH_EXCEPT_START] = "WITH_EXCEPT_START",
[YIELD_VALUE] = "YIELD_VALUE",
};
-#endif // NEED_OPCODE_METADATA
+#endif
extern const uint8_t _PyOpcode_Caches[256];
#ifdef NEED_OPCODE_METADATA
const uint8_t _PyOpcode_Caches[256] = {
+ [JUMP_BACKWARD] = 1,
[TO_BOOL] = 3,
- [BINARY_OP_INPLACE_ADD_UNICODE] = 1,
[BINARY_SUBSCR] = 1,
[STORE_SUBSCR] = 1,
[SEND] = 1,
@@ -2200,7 +1570,6 @@ const uint8_t _PyOpcode_Caches[256] = {
[LOAD_SUPER_ATTR] = 1,
[LOAD_ATTR] = 9,
[COMPARE_OP] = 1,
- [JUMP_BACKWARD] = 1,
[POP_JUMP_IF_TRUE] = 1,
[POP_JUMP_IF_FALSE] = 1,
[POP_JUMP_IF_NONE] = 1,
@@ -2209,7 +1578,7 @@ const uint8_t _PyOpcode_Caches[256] = {
[CALL] = 3,
[BINARY_OP] = 1,
};
-#endif // NEED_OPCODE_METADATA
+#endif
extern const uint8_t _PyOpcode_Deopt[256];
#ifdef NEED_OPCODE_METADATA
@@ -2423,6 +1792,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[WITH_EXCEPT_START] = WITH_EXCEPT_START,
[YIELD_VALUE] = YIELD_VALUE,
};
+
#endif // NEED_OPCODE_METADATA
#define EXTRA_CASES \
@@ -2475,4 +1845,40 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 235: \
case 255: \
;
+struct pseudo_targets {
+ uint8_t targets[3];
+};
+extern const struct pseudo_targets _PyOpcode_PseudoTargets[12];
+#ifdef NEED_OPCODE_METADATA
+const struct pseudo_targets _PyOpcode_PseudoTargets[12] = {
+ [LOAD_CLOSURE-256] = { { LOAD_FAST, 0, 0 } },
+ [STORE_FAST_MAYBE_NULL-256] = { { STORE_FAST, 0, 0 } },
+ [LOAD_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_ZERO_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_ZERO_SUPER_ATTR-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_METHOD-256] = { { LOAD_ATTR, 0, 0 } },
+ [JUMP-256] = { { JUMP_FORWARD, JUMP_BACKWARD, 0 } },
+ [JUMP_NO_INTERRUPT-256] = { { JUMP_FORWARD, JUMP_BACKWARD_NO_INTERRUPT, 0 } },
+ [SETUP_FINALLY-256] = { { NOP, 0, 0 } },
+ [SETUP_CLEANUP-256] = { { NOP, 0, 0 } },
+ [SETUP_WITH-256] = { { NOP, 0, 0 } },
+ [POP_BLOCK-256] = { { NOP, 0, 0 } },
+};
+#endif // NEED_OPCODE_METADATA
+static inline bool
+is_pseudo_target(int pseudo, int target) {
+ if (pseudo < 256 || pseudo >= 268) {
+ return false;
+ }
+ for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) {
+ if (_PyOpcode_PseudoTargets[pseudo-256].targets[i] == target) return true;
+ }
+ return false;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_OPCODE_METADATA_H */
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index c96ea51..4a9a00b 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -2,6 +2,7 @@
// from:
// Python/bytecodes.c
// Do not edit!
+
#ifndef Py_CORE_UOP_IDS_H
#define Py_CORE_UOP_IDS_H
#ifdef __cplusplus
@@ -11,7 +12,6 @@ extern "C" {
#define _EXIT_TRACE 300
#define _SET_IP 301
#define _NOP NOP
-#define _RESUME RESUME
#define _RESUME_CHECK RESUME_CHECK
#define _INSTRUMENTED_RESUME INSTRUMENTED_RESUME
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
@@ -24,13 +24,10 @@ extern "C" {
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _POP_TOP POP_TOP
#define _PUSH_NULL PUSH_NULL
-#define _INSTRUMENTED_END_FOR INSTRUMENTED_END_FOR
#define _END_SEND END_SEND
-#define _INSTRUMENTED_END_SEND INSTRUMENTED_END_SEND
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
-#define _SPECIALIZE_TO_BOOL 302
-#define _TO_BOOL 303
+#define _TO_BOOL 302
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST
@@ -38,19 +35,17 @@ extern "C" {
#define _TO_BOOL_STR TO_BOOL_STR
#define _TO_BOOL_ALWAYS_TRUE TO_BOOL_ALWAYS_TRUE
#define _UNARY_INVERT UNARY_INVERT
-#define _GUARD_BOTH_INT 304
-#define _BINARY_OP_MULTIPLY_INT 305
-#define _BINARY_OP_ADD_INT 306
-#define _BINARY_OP_SUBTRACT_INT 307
-#define _GUARD_BOTH_FLOAT 308
-#define _BINARY_OP_MULTIPLY_FLOAT 309
-#define _BINARY_OP_ADD_FLOAT 310
-#define _BINARY_OP_SUBTRACT_FLOAT 311
-#define _GUARD_BOTH_UNICODE 312
-#define _BINARY_OP_ADD_UNICODE 313
-#define _BINARY_OP_INPLACE_ADD_UNICODE 314
-#define _SPECIALIZE_BINARY_SUBSCR 315
-#define _BINARY_SUBSCR 316
+#define _GUARD_BOTH_INT 303
+#define _BINARY_OP_MULTIPLY_INT 304
+#define _BINARY_OP_ADD_INT 305
+#define _BINARY_OP_SUBTRACT_INT 306
+#define _GUARD_BOTH_FLOAT 307
+#define _BINARY_OP_MULTIPLY_FLOAT 308
+#define _BINARY_OP_ADD_FLOAT 309
+#define _BINARY_OP_SUBTRACT_FLOAT 310
+#define _GUARD_BOTH_UNICODE 311
+#define _BINARY_OP_ADD_UNICODE 312
+#define _BINARY_SUBSCR 313
#define _BINARY_SLICE BINARY_SLICE
#define _STORE_SLICE STORE_SLICE
#define _BINARY_SUBSCR_LIST_INT BINARY_SUBSCR_LIST_INT
@@ -60,54 +55,43 @@ extern "C" {
#define _BINARY_SUBSCR_GETITEM BINARY_SUBSCR_GETITEM
#define _LIST_APPEND LIST_APPEND
#define _SET_ADD SET_ADD
-#define _SPECIALIZE_STORE_SUBSCR 317
-#define _STORE_SUBSCR 318
+#define _STORE_SUBSCR 314
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _DELETE_SUBSCR DELETE_SUBSCR
#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
-#define _RAISE_VARARGS RAISE_VARARGS
-#define _INTERPRETER_EXIT INTERPRETER_EXIT
-#define _POP_FRAME 319
+#define _POP_FRAME 315
#define _INSTRUMENTED_RETURN_VALUE INSTRUMENTED_RETURN_VALUE
#define _INSTRUMENTED_RETURN_CONST INSTRUMENTED_RETURN_CONST
#define _GET_AITER GET_AITER
#define _GET_ANEXT GET_ANEXT
#define _GET_AWAITABLE GET_AWAITABLE
-#define _SPECIALIZE_SEND 320
-#define _SEND 321
+#define _SEND 316
#define _SEND_GEN SEND_GEN
#define _INSTRUMENTED_YIELD_VALUE INSTRUMENTED_YIELD_VALUE
-#define _YIELD_VALUE YIELD_VALUE
#define _POP_EXCEPT POP_EXCEPT
-#define _RERAISE RERAISE
-#define _END_ASYNC_FOR END_ASYNC_FOR
-#define _CLEANUP_THROW CLEANUP_THROW
#define _LOAD_ASSERTION_ERROR LOAD_ASSERTION_ERROR
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
#define _STORE_NAME STORE_NAME
#define _DELETE_NAME DELETE_NAME
-#define _SPECIALIZE_UNPACK_SEQUENCE 322
-#define _UNPACK_SEQUENCE 323
+#define _UNPACK_SEQUENCE 317
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_EX UNPACK_EX
-#define _SPECIALIZE_STORE_ATTR 324
-#define _STORE_ATTR 325
+#define _STORE_ATTR 318
#define _DELETE_ATTR DELETE_ATTR
#define _STORE_GLOBAL STORE_GLOBAL
#define _DELETE_GLOBAL DELETE_GLOBAL
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
#define _LOAD_NAME LOAD_NAME
-#define _SPECIALIZE_LOAD_GLOBAL 326
-#define _LOAD_GLOBAL 327
-#define _GUARD_GLOBALS_VERSION 328
-#define _GUARD_BUILTINS_VERSION 329
-#define _LOAD_GLOBAL_MODULE 330
-#define _LOAD_GLOBAL_BUILTINS 331
+#define _LOAD_GLOBAL 319
+#define _GUARD_GLOBALS_VERSION 320
+#define _GUARD_BUILTINS_VERSION 321
+#define _LOAD_GLOBAL_MODULE 322
+#define _LOAD_GLOBAL_BUILTINS 323
#define _DELETE_FAST DELETE_FAST
#define _MAKE_CELL MAKE_CELL
#define _DELETE_DEREF DELETE_DEREF
@@ -128,30 +112,26 @@ extern "C" {
#define _DICT_MERGE DICT_MERGE
#define _MAP_ADD MAP_ADD
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
-#define _SPECIALIZE_LOAD_SUPER_ATTR 332
-#define _LOAD_SUPER_ATTR 333
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _SPECIALIZE_LOAD_ATTR 334
-#define _LOAD_ATTR 335
-#define _GUARD_TYPE_VERSION 336
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES 337
-#define _LOAD_ATTR_INSTANCE_VALUE 338
-#define _CHECK_ATTR_MODULE 339
-#define _LOAD_ATTR_MODULE 340
-#define _CHECK_ATTR_WITH_HINT 341
-#define _LOAD_ATTR_WITH_HINT 342
-#define _LOAD_ATTR_SLOT 343
-#define _CHECK_ATTR_CLASS 344
-#define _LOAD_ATTR_CLASS 345
+#define _LOAD_ATTR 324
+#define _GUARD_TYPE_VERSION 325
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES 326
+#define _LOAD_ATTR_INSTANCE_VALUE 327
+#define _CHECK_ATTR_MODULE 328
+#define _LOAD_ATTR_MODULE 329
+#define _CHECK_ATTR_WITH_HINT 330
+#define _LOAD_ATTR_WITH_HINT 331
+#define _LOAD_ATTR_SLOT 332
+#define _CHECK_ATTR_CLASS 333
+#define _LOAD_ATTR_CLASS 334
#define _LOAD_ATTR_PROPERTY LOAD_ATTR_PROPERTY
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _GUARD_DORV_VALUES 346
-#define _STORE_ATTR_INSTANCE_VALUE 347
+#define _GUARD_DORV_VALUES 335
+#define _STORE_ATTR_INSTANCE_VALUE 336
#define _STORE_ATTR_WITH_HINT STORE_ATTR_WITH_HINT
-#define _STORE_ATTR_SLOT 348
-#define _SPECIALIZE_COMPARE_OP 349
-#define _COMPARE_OP 350
+#define _STORE_ATTR_SLOT 337
+#define _COMPARE_OP 338
#define _COMPARE_OP_FLOAT COMPARE_OP_FLOAT
#define _COMPARE_OP_INT COMPARE_OP_INT
#define _COMPARE_OP_STR COMPARE_OP_STR
@@ -159,15 +139,10 @@ extern "C" {
#define _CONTAINS_OP CONTAINS_OP
#define _CHECK_EG_MATCH CHECK_EG_MATCH
#define _CHECK_EXC_MATCH CHECK_EXC_MATCH
-#define _IMPORT_NAME IMPORT_NAME
-#define _IMPORT_FROM IMPORT_FROM
-#define _JUMP_FORWARD JUMP_FORWARD
#define _JUMP_BACKWARD JUMP_BACKWARD
-#define _ENTER_EXECUTOR ENTER_EXECUTOR
-#define _POP_JUMP_IF_FALSE 351
-#define _POP_JUMP_IF_TRUE 352
-#define _IS_NONE 353
-#define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT
+#define _POP_JUMP_IF_FALSE 339
+#define _POP_JUMP_IF_TRUE 340
+#define _IS_NONE 341
#define _GET_LEN GET_LEN
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_MAPPING MATCH_MAPPING
@@ -175,45 +150,43 @@ extern "C" {
#define _MATCH_KEYS MATCH_KEYS
#define _GET_ITER GET_ITER
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _SPECIALIZE_FOR_ITER 354
-#define _FOR_ITER 355
-#define _FOR_ITER_TIER_TWO 356
+#define _FOR_ITER 342
+#define _FOR_ITER_TIER_TWO 343
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
-#define _ITER_CHECK_LIST 357
-#define _ITER_JUMP_LIST 358
-#define _GUARD_NOT_EXHAUSTED_LIST 359
-#define _ITER_NEXT_LIST 360
-#define _ITER_CHECK_TUPLE 361
-#define _ITER_JUMP_TUPLE 362
-#define _GUARD_NOT_EXHAUSTED_TUPLE 363
-#define _ITER_NEXT_TUPLE 364
-#define _ITER_CHECK_RANGE 365
-#define _ITER_JUMP_RANGE 366
-#define _GUARD_NOT_EXHAUSTED_RANGE 367
-#define _ITER_NEXT_RANGE 368
+#define _ITER_CHECK_LIST 344
+#define _ITER_JUMP_LIST 345
+#define _GUARD_NOT_EXHAUSTED_LIST 346
+#define _ITER_NEXT_LIST 347
+#define _ITER_CHECK_TUPLE 348
+#define _ITER_JUMP_TUPLE 349
+#define _GUARD_NOT_EXHAUSTED_TUPLE 350
+#define _ITER_NEXT_TUPLE 351
+#define _ITER_CHECK_RANGE 352
+#define _ITER_JUMP_RANGE 353
+#define _GUARD_NOT_EXHAUSTED_RANGE 354
+#define _ITER_NEXT_RANGE 355
#define _FOR_ITER_GEN FOR_ITER_GEN
#define _BEFORE_ASYNC_WITH BEFORE_ASYNC_WITH
#define _BEFORE_WITH BEFORE_WITH
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 369
-#define _GUARD_KEYS_VERSION 370
-#define _LOAD_ATTR_METHOD_WITH_VALUES 371
-#define _LOAD_ATTR_METHOD_NO_DICT 372
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 373
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 374
-#define _CHECK_ATTR_METHOD_LAZY_DICT 375
-#define _LOAD_ATTR_METHOD_LAZY_DICT 376
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 356
+#define _GUARD_KEYS_VERSION 357
+#define _LOAD_ATTR_METHOD_WITH_VALUES 358
+#define _LOAD_ATTR_METHOD_NO_DICT 359
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 360
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 361
+#define _CHECK_ATTR_METHOD_LAZY_DICT 362
+#define _LOAD_ATTR_METHOD_LAZY_DICT 363
#define _INSTRUMENTED_CALL INSTRUMENTED_CALL
-#define _SPECIALIZE_CALL 377
-#define _CALL 378
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 379
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 380
-#define _CHECK_PEP_523 381
-#define _CHECK_FUNCTION_EXACT_ARGS 382
-#define _CHECK_STACK_SPACE 383
-#define _INIT_CALL_PY_EXACT_ARGS 384
-#define _PUSH_FRAME 385
+#define _CALL 364
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 365
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 366
+#define _CHECK_PEP_523 367
+#define _CHECK_FUNCTION_EXACT_ARGS 368
+#define _CHECK_STACK_SPACE 369
+#define _INIT_CALL_PY_EXACT_ARGS 370
+#define _PUSH_FRAME 371
#define _CALL_PY_WITH_DEFAULTS CALL_PY_WITH_DEFAULTS
#define _CALL_TYPE_1 CALL_TYPE_1
#define _CALL_STR_1 CALL_STR_1
@@ -226,7 +199,6 @@ extern "C" {
#define _CALL_BUILTIN_FAST_WITH_KEYWORDS CALL_BUILTIN_FAST_WITH_KEYWORDS
#define _CALL_LEN CALL_LEN
#define _CALL_ISINSTANCE CALL_ISINSTANCE
-#define _CALL_LIST_APPEND CALL_LIST_APPEND
#define _CALL_METHOD_DESCRIPTOR_O CALL_METHOD_DESCRIPTOR_O
#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
#define _CALL_METHOD_DESCRIPTOR_NOARGS CALL_METHOD_DESCRIPTOR_NOARGS
@@ -237,14 +209,12 @@ extern "C" {
#define _CALL_FUNCTION_EX CALL_FUNCTION_EX
#define _MAKE_FUNCTION MAKE_FUNCTION
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
-#define _RETURN_GENERATOR RETURN_GENERATOR
#define _BUILD_SLICE BUILD_SLICE
#define _CONVERT_VALUE CONVERT_VALUE
#define _FORMAT_SIMPLE FORMAT_SIMPLE
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
#define _COPY COPY
-#define _SPECIALIZE_BINARY_OP 386
-#define _BINARY_OP 387
+#define _BINARY_OP 372
#define _SWAP SWAP
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -253,16 +223,17 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
-#define _GUARD_IS_TRUE_POP 388
-#define _GUARD_IS_FALSE_POP 389
-#define _GUARD_IS_NONE_POP 390
-#define _GUARD_IS_NOT_NONE_POP 391
-#define _JUMP_TO_TOP 392
-#define _SAVE_RETURN_OFFSET 393
-#define _INSERT 394
-#define _CHECK_VALIDITY 395
+#define _GUARD_IS_TRUE_POP 373
+#define _GUARD_IS_FALSE_POP 374
+#define _GUARD_IS_NONE_POP 375
+#define _GUARD_IS_NOT_NONE_POP 376
+#define _JUMP_TO_TOP 377
+#define _SAVE_RETURN_OFFSET 378
+#define _INSERT 379
+#define _CHECK_VALIDITY 380
+#define MAX_UOP_ID 380
#ifdef __cplusplus
}
#endif
-#endif /* !Py_OPCODE_IDS_H */
+#endif /* !Py_CORE_UOP_IDS_H */
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
new file mode 100644
index 0000000..300bd3b
--- /dev/null
+++ b/Include/internal/pycore_uop_metadata.h
@@ -0,0 +1,403 @@
+// This file is generated by Tools/cases_generator/uop_metadata_generator.py
+// from:
+// Python/bytecodes.c
+// Do not edit!
+
+#ifndef Py_CORE_UOP_METADATA_H
+#define Py_CORE_UOP_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "pycore_uop_ids.h"
+extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];
+extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];
+
+#ifdef NEED_OPCODE_METADATA
+const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
+ [_NOP] = 0,
+ [_RESUME_CHECK] = HAS_DEOPT_FLAG,
+ [_LOAD_FAST_CHECK] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG,
+ [_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG,
+ [_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_STORE_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_STORE_FAST_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_POP_TOP] = 0,
+ [_PUSH_NULL] = 0,
+ [_END_SEND] = 0,
+ [_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_UNARY_NOT] = 0,
+ [_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_TO_BOOL_BOOL] = HAS_DEOPT_FLAG,
+ [_TO_BOOL_INT] = HAS_DEOPT_FLAG,
+ [_TO_BOOL_LIST] = HAS_DEOPT_FLAG,
+ [_TO_BOOL_NONE] = HAS_DEOPT_FLAG,
+ [_TO_BOOL_STR] = HAS_DEOPT_FLAG,
+ [_TO_BOOL_ALWAYS_TRUE] = HAS_DEOPT_FLAG,
+ [_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_BOTH_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_OP_MULTIPLY_INT] = HAS_ERROR_FLAG,
+ [_BINARY_OP_ADD_INT] = HAS_ERROR_FLAG,
+ [_BINARY_OP_SUBTRACT_INT] = HAS_ERROR_FLAG,
+ [_GUARD_BOTH_FLOAT] = HAS_DEOPT_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT] = 0,
+ [_BINARY_OP_ADD_FLOAT] = 0,
+ [_BINARY_OP_SUBTRACT_FLOAT] = 0,
+ [_GUARD_BOTH_UNICODE] = HAS_DEOPT_FLAG,
+ [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_STR_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_TUPLE_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LIST_APPEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_SET_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_POP_FRAME] = HAS_ESCAPES_FLAG,
+ [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_POP_EXCEPT] = HAS_ESCAPES_FLAG,
+ [_LOAD_ASSERTION_ERROR] = 0,
+ [_LOAD_BUILD_CLASS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_LOCALS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_FROM_DICT_OR_GLOBALS] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
+ [_GUARD_BUILTINS_VERSION] = HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG,
+ [_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_FROM_DICT_OR_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG,
+ [_COPY_FREE_VARS] = HAS_ARG_FLAG,
+ [_BUILD_STRING] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_TUPLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_LIST] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LIST_EXTEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SET_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SETUP_ANNOTATIONS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_CONST_KEY_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DICT_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_TYPE_VERSION] = HAS_DEOPT_FLAG,
+ [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_ATTR_MODULE] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_ATTR_WITH_HINT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_ATTR_CLASS] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_CLASS] = HAS_ARG_FLAG,
+ [_GUARD_DORV_VALUES] = HAS_DEOPT_FLAG,
+ [_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG,
+ [_STORE_ATTR_SLOT] = HAS_ESCAPES_FLAG,
+ [_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_COMPARE_OP_FLOAT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_COMPARE_OP_INT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_COMPARE_OP_STR] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_IS_OP] = HAS_ARG_FLAG,
+ [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_EXC_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_IS_NONE] = 0,
+ [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MATCH_MAPPING] = 0,
+ [_MATCH_SEQUENCE] = 0,
+ [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_YIELD_FROM_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_FOR_ITER_TIER_TWO] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_ITER_CHECK_LIST] = HAS_DEOPT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_LIST] = HAS_DEOPT_FLAG,
+ [_ITER_NEXT_LIST] = 0,
+ [_ITER_CHECK_TUPLE] = HAS_DEOPT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_TUPLE] = HAS_DEOPT_FLAG,
+ [_ITER_NEXT_TUPLE] = 0,
+ [_ITER_CHECK_RANGE] = HAS_DEOPT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_RANGE] = HAS_DEOPT_FLAG,
+ [_ITER_NEXT_RANGE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BEFORE_ASYNC_WITH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BEFORE_WITH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_WITH_EXCEPT_START] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_PUSH_EXC_INFO] = 0,
+ [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
+ [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG,
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG,
+ [_CHECK_PEP_523] = HAS_DEOPT_FLAG,
+ [_CHECK_FUNCTION_EXACT_ARGS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_STACK_SPACE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_PUSH_FRAME] = 0,
+ [_CALL_TYPE_1] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CALL_STR_1] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG,
+ [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_LEN] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_ISINSTANCE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_NOARGS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_FAST] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_SLICE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CONVERT_VALUE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_FORMAT_SIMPLE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_FORMAT_WITH_SPEC] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_COPY] = HAS_ARG_FLAG,
+ [_BINARY_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_SWAP] = HAS_ARG_FLAG,
+ [_GUARD_IS_TRUE_POP] = HAS_DEOPT_FLAG,
+ [_GUARD_IS_FALSE_POP] = HAS_DEOPT_FLAG,
+ [_GUARD_IS_NONE_POP] = HAS_DEOPT_FLAG,
+ [_GUARD_IS_NOT_NONE_POP] = HAS_DEOPT_FLAG,
+ [_JUMP_TO_TOP] = HAS_EVAL_BREAK_FLAG,
+ [_SET_IP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
+ [_EXIT_TRACE] = HAS_DEOPT_FLAG,
+ [_INSERT] = HAS_ARG_FLAG,
+ [_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
+};
+
+const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
+ [_BEFORE_ASYNC_WITH] = "_BEFORE_ASYNC_WITH",
+ [_BEFORE_WITH] = "_BEFORE_WITH",
+ [_BINARY_OP] = "_BINARY_OP",
+ [_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
+ [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
+ [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
+ [_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
+ [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
+ [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
+ [_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
+ [_BINARY_SLICE] = "_BINARY_SLICE",
+ [_BINARY_SUBSCR] = "_BINARY_SUBSCR",
+ [_BINARY_SUBSCR_DICT] = "_BINARY_SUBSCR_DICT",
+ [_BINARY_SUBSCR_LIST_INT] = "_BINARY_SUBSCR_LIST_INT",
+ [_BINARY_SUBSCR_STR_INT] = "_BINARY_SUBSCR_STR_INT",
+ [_BINARY_SUBSCR_TUPLE_INT] = "_BINARY_SUBSCR_TUPLE_INT",
+ [_BUILD_CONST_KEY_MAP] = "_BUILD_CONST_KEY_MAP",
+ [_BUILD_LIST] = "_BUILD_LIST",
+ [_BUILD_MAP] = "_BUILD_MAP",
+ [_BUILD_SET] = "_BUILD_SET",
+ [_BUILD_SLICE] = "_BUILD_SLICE",
+ [_BUILD_STRING] = "_BUILD_STRING",
+ [_BUILD_TUPLE] = "_BUILD_TUPLE",
+ [_CALL_BUILTIN_CLASS] = "_CALL_BUILTIN_CLASS",
+ [_CALL_BUILTIN_FAST] = "_CALL_BUILTIN_FAST",
+ [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = "_CALL_BUILTIN_FAST_WITH_KEYWORDS",
+ [_CALL_BUILTIN_O] = "_CALL_BUILTIN_O",
+ [_CALL_INTRINSIC_1] = "_CALL_INTRINSIC_1",
+ [_CALL_INTRINSIC_2] = "_CALL_INTRINSIC_2",
+ [_CALL_ISINSTANCE] = "_CALL_ISINSTANCE",
+ [_CALL_LEN] = "_CALL_LEN",
+ [_CALL_METHOD_DESCRIPTOR_FAST] = "_CALL_METHOD_DESCRIPTOR_FAST",
+ [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
+ [_CALL_METHOD_DESCRIPTOR_NOARGS] = "_CALL_METHOD_DESCRIPTOR_NOARGS",
+ [_CALL_METHOD_DESCRIPTOR_O] = "_CALL_METHOD_DESCRIPTOR_O",
+ [_CALL_STR_1] = "_CALL_STR_1",
+ [_CALL_TUPLE_1] = "_CALL_TUPLE_1",
+ [_CALL_TYPE_1] = "_CALL_TYPE_1",
+ [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
+ [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
+ [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
+ [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
+ [_CHECK_EG_MATCH] = "_CHECK_EG_MATCH",
+ [_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH",
+ [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
+ [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
+ [_CHECK_PEP_523] = "_CHECK_PEP_523",
+ [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
+ [_CHECK_VALIDITY] = "_CHECK_VALIDITY",
+ [_COMPARE_OP] = "_COMPARE_OP",
+ [_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
+ [_COMPARE_OP_INT] = "_COMPARE_OP_INT",
+ [_COMPARE_OP_STR] = "_COMPARE_OP_STR",
+ [_CONTAINS_OP] = "_CONTAINS_OP",
+ [_CONVERT_VALUE] = "_CONVERT_VALUE",
+ [_COPY] = "_COPY",
+ [_COPY_FREE_VARS] = "_COPY_FREE_VARS",
+ [_DELETE_ATTR] = "_DELETE_ATTR",
+ [_DELETE_DEREF] = "_DELETE_DEREF",
+ [_DELETE_FAST] = "_DELETE_FAST",
+ [_DELETE_GLOBAL] = "_DELETE_GLOBAL",
+ [_DELETE_NAME] = "_DELETE_NAME",
+ [_DELETE_SUBSCR] = "_DELETE_SUBSCR",
+ [_DICT_MERGE] = "_DICT_MERGE",
+ [_DICT_UPDATE] = "_DICT_UPDATE",
+ [_END_SEND] = "_END_SEND",
+ [_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
+ [_EXIT_TRACE] = "_EXIT_TRACE",
+ [_FORMAT_SIMPLE] = "_FORMAT_SIMPLE",
+ [_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC",
+ [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
+ [_GET_AITER] = "_GET_AITER",
+ [_GET_ANEXT] = "_GET_ANEXT",
+ [_GET_AWAITABLE] = "_GET_AWAITABLE",
+ [_GET_ITER] = "_GET_ITER",
+ [_GET_LEN] = "_GET_LEN",
+ [_GET_YIELD_FROM_ITER] = "_GET_YIELD_FROM_ITER",
+ [_GUARD_BOTH_FLOAT] = "_GUARD_BOTH_FLOAT",
+ [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT",
+ [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
+ [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION",
+ [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES",
+ [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
+ [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
+ [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP",
+ [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP",
+ [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP",
+ [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP",
+ [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
+ [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
+ [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_EXHAUSTED_RANGE",
+ [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_EXHAUSTED_TUPLE",
+ [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
+ [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
+ [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS",
+ [_INSERT] = "_INSERT",
+ [_IS_NONE] = "_IS_NONE",
+ [_IS_OP] = "_IS_OP",
+ [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
+ [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE",
+ [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE",
+ [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST",
+ [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE",
+ [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE",
+ [_JUMP_TO_TOP] = "_JUMP_TO_TOP",
+ [_LIST_APPEND] = "_LIST_APPEND",
+ [_LIST_EXTEND] = "_LIST_EXTEND",
+ [_LOAD_ASSERTION_ERROR] = "_LOAD_ASSERTION_ERROR",
+ [_LOAD_ATTR] = "_LOAD_ATTR",
+ [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
+ [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
+ [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
+ [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
+ [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
+ [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
+ [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
+ [_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
+ [_LOAD_CONST] = "_LOAD_CONST",
+ [_LOAD_DEREF] = "_LOAD_DEREF",
+ [_LOAD_FAST] = "_LOAD_FAST",
+ [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR",
+ [_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK",
+ [_LOAD_FAST_LOAD_FAST] = "_LOAD_FAST_LOAD_FAST",
+ [_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF",
+ [_LOAD_FROM_DICT_OR_GLOBALS] = "_LOAD_FROM_DICT_OR_GLOBALS",
+ [_LOAD_GLOBAL] = "_LOAD_GLOBAL",
+ [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS",
+ [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
+ [_LOAD_LOCALS] = "_LOAD_LOCALS",
+ [_LOAD_NAME] = "_LOAD_NAME",
+ [_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR",
+ [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD",
+ [_MAKE_CELL] = "_MAKE_CELL",
+ [_MAKE_FUNCTION] = "_MAKE_FUNCTION",
+ [_MAP_ADD] = "_MAP_ADD",
+ [_MATCH_CLASS] = "_MATCH_CLASS",
+ [_MATCH_KEYS] = "_MATCH_KEYS",
+ [_MATCH_MAPPING] = "_MATCH_MAPPING",
+ [_MATCH_SEQUENCE] = "_MATCH_SEQUENCE",
+ [_NOP] = "_NOP",
+ [_POP_EXCEPT] = "_POP_EXCEPT",
+ [_POP_FRAME] = "_POP_FRAME",
+ [_POP_TOP] = "_POP_TOP",
+ [_PUSH_EXC_INFO] = "_PUSH_EXC_INFO",
+ [_PUSH_FRAME] = "_PUSH_FRAME",
+ [_PUSH_NULL] = "_PUSH_NULL",
+ [_RESUME_CHECK] = "_RESUME_CHECK",
+ [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
+ [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS",
+ [_SET_ADD] = "_SET_ADD",
+ [_SET_FUNCTION_ATTRIBUTE] = "_SET_FUNCTION_ATTRIBUTE",
+ [_SET_IP] = "_SET_IP",
+ [_SET_UPDATE] = "_SET_UPDATE",
+ [_STORE_ATTR] = "_STORE_ATTR",
+ [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
+ [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
+ [_STORE_DEREF] = "_STORE_DEREF",
+ [_STORE_FAST] = "_STORE_FAST",
+ [_STORE_FAST_LOAD_FAST] = "_STORE_FAST_LOAD_FAST",
+ [_STORE_FAST_STORE_FAST] = "_STORE_FAST_STORE_FAST",
+ [_STORE_GLOBAL] = "_STORE_GLOBAL",
+ [_STORE_NAME] = "_STORE_NAME",
+ [_STORE_SLICE] = "_STORE_SLICE",
+ [_STORE_SUBSCR] = "_STORE_SUBSCR",
+ [_STORE_SUBSCR_DICT] = "_STORE_SUBSCR_DICT",
+ [_STORE_SUBSCR_LIST_INT] = "_STORE_SUBSCR_LIST_INT",
+ [_SWAP] = "_SWAP",
+ [_TO_BOOL] = "_TO_BOOL",
+ [_TO_BOOL_ALWAYS_TRUE] = "_TO_BOOL_ALWAYS_TRUE",
+ [_TO_BOOL_BOOL] = "_TO_BOOL_BOOL",
+ [_TO_BOOL_INT] = "_TO_BOOL_INT",
+ [_TO_BOOL_LIST] = "_TO_BOOL_LIST",
+ [_TO_BOOL_NONE] = "_TO_BOOL_NONE",
+ [_TO_BOOL_STR] = "_TO_BOOL_STR",
+ [_UNARY_INVERT] = "_UNARY_INVERT",
+ [_UNARY_NEGATIVE] = "_UNARY_NEGATIVE",
+ [_UNARY_NOT] = "_UNARY_NOT",
+ [_UNPACK_EX] = "_UNPACK_EX",
+ [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
+ [_UNPACK_SEQUENCE_LIST] = "_UNPACK_SEQUENCE_LIST",
+ [_UNPACK_SEQUENCE_TUPLE] = "_UNPACK_SEQUENCE_TUPLE",
+ [_UNPACK_SEQUENCE_TWO_TUPLE] = "_UNPACK_SEQUENCE_TWO_TUPLE",
+ [_WITH_EXCEPT_START] = "_WITH_EXCEPT_START",
+};
+#endif // NEED_OPCODE_METADATA
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_UOP_METADATA_H */
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index e2e27ca..fe96934 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -231,7 +231,7 @@ extern "C" {
#define SETUP_WITH 266
#define STORE_FAST_MAYBE_NULL 267
-#define HAVE_ARGUMENT 45
+#define HAVE_ARGUMENT 44
#define MIN_INSTRUMENTED_OPCODE 236
#ifdef __cplusplus
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index 5dd06ae..fdb099b 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -1,8 +1,7 @@
-# This file is generated by Tools/cases_generator/generate_cases.py
+# This file is generated by Tools/cases_generator/py_metadata_generator.py
# from:
# Python/bytecodes.c
# Do not edit!
-
_specializations = {
"RESUME": [
"RESUME_CHECK",
@@ -23,6 +22,7 @@ _specializations = {
"BINARY_OP_ADD_FLOAT",
"BINARY_OP_SUBTRACT_FLOAT",
"BINARY_OP_ADD_UNICODE",
+ "BINARY_OP_INPLACE_ADD_UNICODE",
],
"BINARY_SUBSCR": [
"BINARY_SUBSCR_DICT",
@@ -103,14 +103,11 @@ _specializations = {
],
}
-# An irregular case:
-_specializations["BINARY_OP"].append("BINARY_OP_INPLACE_ADD_UNICODE")
-
_specialized_opmap = {
- 'BINARY_OP_INPLACE_ADD_UNICODE': 3,
'BINARY_OP_ADD_FLOAT': 150,
'BINARY_OP_ADD_INT': 151,
'BINARY_OP_ADD_UNICODE': 152,
+ 'BINARY_OP_INPLACE_ADD_UNICODE': 3,
'BINARY_OP_MULTIPLY_FLOAT': 153,
'BINARY_OP_MULTIPLY_INT': 154,
'BINARY_OP_SUBTRACT_FLOAT': 155,
@@ -181,6 +178,9 @@ _specialized_opmap = {
opmap = {
'CACHE': 0,
+ 'RESERVED': 17,
+ 'RESUME': 149,
+ 'INSTRUMENTED_LINE': 254,
'BEFORE_ASYNC_WITH': 1,
'BEFORE_WITH': 2,
'BINARY_SLICE': 4,
@@ -196,7 +196,6 @@ opmap = {
'FORMAT_SIMPLE': 14,
'FORMAT_WITH_SPEC': 15,
'GET_AITER': 16,
- 'RESERVED': 17,
'GET_ANEXT': 18,
'GET_ITER': 19,
'GET_LEN': 20,
@@ -298,7 +297,6 @@ opmap = {
'UNPACK_EX': 116,
'UNPACK_SEQUENCE': 117,
'YIELD_VALUE': 118,
- 'RESUME': 149,
'INSTRUMENTED_RESUME': 236,
'INSTRUMENTED_END_FOR': 237,
'INSTRUMENTED_END_SEND': 238,
@@ -317,7 +315,6 @@ opmap = {
'INSTRUMENTED_POP_JUMP_IF_FALSE': 251,
'INSTRUMENTED_POP_JUMP_IF_NONE': 252,
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 253,
- 'INSTRUMENTED_LINE': 254,
'JUMP': 256,
'JUMP_NO_INTERRUPT': 257,
'LOAD_CLOSURE': 258,
@@ -331,5 +328,6 @@ opmap = {
'SETUP_WITH': 266,
'STORE_FAST_MAYBE_NULL': 267,
}
+
+HAVE_ARGUMENT = 44
MIN_INSTRUMENTED_OPCODE = 236
-HAVE_ARGUMENT = 45
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 9f47311..5c8c059 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -176,6 +176,7 @@ class TestExecutorInvalidation(unittest.TestCase):
with temporary_optimizer(opt):
f()
exe = get_first_executor(f)
+ self.assertIsNotNone(exe)
self.assertTrue(exe.is_valid())
_testinternalcapi.invalidate_executors(f.__code__)
self.assertFalse(exe.is_valid())
@@ -196,7 +197,7 @@ class TestUops(unittest.TestCase):
self.assertIsNotNone(ex)
uops = {opname for opname, _, _ in ex}
self.assertIn("_SET_IP", uops)
- self.assertIn("LOAD_FAST", uops)
+ self.assertIn("_LOAD_FAST", uops)
def test_extended_arg(self):
"Check EXTENDED_ARG handling in superblock creation"
@@ -243,7 +244,7 @@ class TestUops(unittest.TestCase):
ex = get_first_executor(many_vars)
self.assertIsNotNone(ex)
- self.assertIn(("LOAD_FAST", 259, 0), list(ex))
+ self.assertIn(("_LOAD_FAST", 259, 0), list(ex))
def test_unspecialized_unpack(self):
# An example of an unspecialized opcode
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 195fc0d..92827ec 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1588,23 +1588,28 @@ regen-cases:
$(srcdir)/Tools/cases_generator/generate_cases.py \
$(CASESFLAG) \
-t $(srcdir)/Python/opcode_targets.h.new \
- -m $(srcdir)/Include/internal/pycore_opcode_metadata.h.new \
- -p $(srcdir)/Lib/_opcode_metadata.py.new \
-a $(srcdir)/Python/abstract_interp_cases.c.h.new \
$(srcdir)/Python/bytecodes.c
- $(PYTHON_FOR_REGEN) \
- $(srcdir)/Tools/cases_generator/opcode_id_generator.py -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c
- $(PYTHON_FOR_REGEN) \
- $(srcdir)/Tools/cases_generator/uop_id_generator.py -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c
- $(PYTHON_FOR_REGEN) \
- $(srcdir)/Tools/cases_generator/tier1_generator.py -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
- $(PYTHON_FOR_REGEN) \
- $(srcdir)/Tools/cases_generator/tier2_generator.py -o $(srcdir)/Python/executor_cases.c.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_id_generator.py \
+ -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_id_generator.py \
+ -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/py_metadata_generator.py \
+ -o $(srcdir)/Lib/_opcode_metadata.py.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_generator.py \
+ -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier2_generator.py \
+ -o $(srcdir)/Python/executor_cases.c.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_metadata_generator.py \
+ -o $(srcdir)/Include/internal/pycore_opcode_metadata.h.new $(srcdir)/Python/bytecodes.c
+ $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_metadata_generator.py -o \
+ $(srcdir)/Include/internal/pycore_uop_metadata.h.new $(srcdir)/Python/bytecodes.c
$(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new
$(UPDATE_FILE) $(srcdir)/Include/opcode_ids.h $(srcdir)/Include/opcode_ids.h.new
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_ids.h $(srcdir)/Include/internal/pycore_uop_ids.h.new
$(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode_metadata.h $(srcdir)/Include/internal/pycore_opcode_metadata.h.new
+ $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_metadata.h $(srcdir)/Include/internal/pycore_uop_metadata.h.new
$(UPDATE_FILE) $(srcdir)/Python/executor_cases.c.h $(srcdir)/Python/executor_cases.c.h.new
$(UPDATE_FILE) $(srcdir)/Python/abstract_interp_cases.c.h $(srcdir)/Python/abstract_interp_cases.c.h.new
$(UPDATE_FILE) $(srcdir)/Lib/_opcode_metadata.py $(srcdir)/Lib/_opcode_metadata.py.new
diff --git a/Python/assemble.c b/Python/assemble.c
index b6fb432..569454e 100644
--- a/Python/assemble.c
+++ b/Python/assemble.c
@@ -4,7 +4,7 @@
#include "pycore_code.h" // write_location_entry_start()
#include "pycore_compile.h"
#include "pycore_opcode_utils.h" // IS_BACKWARDS_JUMP_OPCODE
-#include "pycore_opcode_metadata.h" // IS_PSEUDO_INSTR, _PyOpcode_Caches
+#include "pycore_opcode_metadata.h" // is_pseudo_target, _PyOpcode_Caches
#define DEFAULT_CODE_SIZE 128
@@ -710,13 +710,13 @@ resolve_unconditional_jumps(instr_sequence *instrs)
bool is_forward = (instr->i_oparg > i);
switch(instr->i_opcode) {
case JUMP:
- assert(SAME_OPCODE_METADATA(JUMP, JUMP_FORWARD));
- assert(SAME_OPCODE_METADATA(JUMP, JUMP_BACKWARD));
+ assert(is_pseudo_target(JUMP, JUMP_FORWARD));
+ assert(is_pseudo_target(JUMP, JUMP_BACKWARD));
instr->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
break;
case JUMP_NO_INTERRUPT:
- assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_FORWARD));
- assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
+ assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_FORWARD));
+ assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
instr->i_opcode = is_forward ?
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
break;
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 19e2268..82d7a71 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -330,14 +330,14 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_TO_BOOL, (unused/2, value -- res)) {
+ op(_TO_BOOL, (value -- res)) {
int err = PyObject_IsTrue(value);
DECREF_INPUTS();
ERROR_IF(err < 0, error);
res = err ? Py_True : Py_False;
}
- macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + _TO_BOOL;
+ macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + unused/2 + _TO_BOOL;
inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
DEOPT_IF(!PyBool_Check(value));
@@ -416,7 +416,7 @@ dummy_func(
DEOPT_IF(!PyLong_CheckExact(right));
}
- op(_BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -424,7 +424,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
- op(_BINARY_OP_ADD_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -432,7 +432,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
- op(_BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -441,18 +441,18 @@ dummy_func(
}
macro(BINARY_OP_MULTIPLY_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_MULTIPLY_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_MULTIPLY_INT;
macro(BINARY_OP_ADD_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_ADD_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_ADD_INT;
macro(BINARY_OP_SUBTRACT_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_SUBTRACT_INT;
op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) {
DEOPT_IF(!PyFloat_CheckExact(left));
DEOPT_IF(!PyFloat_CheckExact(right));
}
- op(_BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval *
@@ -460,7 +460,7 @@ dummy_func(
DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
}
- op(_BINARY_OP_ADD_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval +
@@ -468,7 +468,7 @@ dummy_func(
DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
}
- op(_BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval -
@@ -477,18 +477,18 @@ dummy_func(
}
macro(BINARY_OP_MULTIPLY_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_MULTIPLY_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_MULTIPLY_FLOAT;
macro(BINARY_OP_ADD_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_ADD_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_ADD_FLOAT;
macro(BINARY_OP_SUBTRACT_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_SUBTRACT_FLOAT;
op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) {
DEOPT_IF(!PyUnicode_CheckExact(left));
DEOPT_IF(!PyUnicode_CheckExact(right));
}
- op(_BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = PyUnicode_Concat(left, right);
_Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
@@ -497,7 +497,7 @@ dummy_func(
}
macro(BINARY_OP_ADD_UNICODE) =
- _GUARD_BOTH_UNICODE + _BINARY_OP_ADD_UNICODE;
+ _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_ADD_UNICODE;
// This is a subtle one. It's a super-instruction for
// BINARY_OP_ADD_UNICODE followed by STORE_FAST
@@ -505,7 +505,7 @@ dummy_func(
// So the inputs are the same as for all BINARY_OP
// specializations, but there is no output.
// At the end we just skip over the STORE_FAST.
- op(_BINARY_OP_INPLACE_ADD_UNICODE, (unused/1, left, right --)) {
+ op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
TIER_ONE_ONLY
assert(next_instr->op.code == STORE_FAST);
PyObject **target_local = &GETLOCAL(next_instr->op.arg);
@@ -533,7 +533,7 @@ dummy_func(
}
macro(BINARY_OP_INPLACE_ADD_UNICODE) =
- _GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE;
+ _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_INPLACE_ADD_UNICODE;
family(BINARY_SUBSCR, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
BINARY_SUBSCR_DICT,
@@ -1295,14 +1295,14 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_STORE_ATTR, (unused/3, v, owner --)) {
+ op(_STORE_ATTR, (v, owner --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, v);
DECREF_INPUTS();
ERROR_IF(err, error);
}
- macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + _STORE_ATTR;
+ macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + unused/3 + _STORE_ATTR;
inst(DELETE_ATTR, (owner --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1414,7 +1414,7 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_LOAD_GLOBAL, (unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) {
+ op(_LOAD_GLOBAL, ( -- res, null if (oparg & 1))) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (PyDict_CheckExact(GLOBALS())
&& PyDict_CheckExact(BUILTINS()))
@@ -1451,7 +1451,12 @@ dummy_func(
null = NULL;
}
- macro(LOAD_GLOBAL) = _SPECIALIZE_LOAD_GLOBAL + _LOAD_GLOBAL;
+ macro(LOAD_GLOBAL) =
+ _SPECIALIZE_LOAD_GLOBAL +
+ counter/1 +
+ globals_version/1 +
+ builtins_version/1 +
+ _LOAD_GLOBAL;
op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
PyDictObject *dict = (PyDictObject *)GLOBALS();
@@ -1853,7 +1858,7 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_LOAD_ATTR, (unused/8, owner -- attr, self_or_null if (oparg & 1))) {
+ op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (oparg & 1) {
/* Designed to work in tandem with CALL, pushes two values. */
@@ -1886,7 +1891,10 @@ dummy_func(
}
}
- macro(LOAD_ATTR) = _SPECIALIZE_LOAD_ATTR + _LOAD_ATTR;
+ macro(LOAD_ATTR) =
+ _SPECIALIZE_LOAD_ATTR +
+ unused/8 +
+ _LOAD_ATTR;
pseudo(LOAD_METHOD) = {
LOAD_ATTR,
@@ -2369,7 +2377,7 @@ dummy_func(
stack_pointer = _PyFrame_GetStackPointer(frame);
}
- replaced op(_POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
+ replaced op(_POP_JUMP_IF_FALSE, (cond -- )) {
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
#if ENABLE_SPECIALIZATION
@@ -2378,7 +2386,7 @@ dummy_func(
JUMPBY(oparg * flag);
}
- replaced op(_POP_JUMP_IF_TRUE, (unused/1, cond -- )) {
+ replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
#if ENABLE_SPECIALIZATION
@@ -2397,13 +2405,13 @@ dummy_func(
}
}
- macro(POP_JUMP_IF_TRUE) = _POP_JUMP_IF_TRUE;
+ macro(POP_JUMP_IF_TRUE) = unused/1 + _POP_JUMP_IF_TRUE;
- macro(POP_JUMP_IF_FALSE) = _POP_JUMP_IF_FALSE;
+ macro(POP_JUMP_IF_FALSE) = unused/1 + _POP_JUMP_IF_FALSE;
- macro(POP_JUMP_IF_NONE) = _IS_NONE + _POP_JUMP_IF_TRUE;
+ macro(POP_JUMP_IF_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_TRUE;
- macro(POP_JUMP_IF_NOT_NONE) = _IS_NONE + _POP_JUMP_IF_FALSE;
+ macro(POP_JUMP_IF_NOT_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_FALSE;
inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
TIER_ONE_ONLY
@@ -3010,7 +3018,7 @@ dummy_func(
}
// When calling Python, inline the call using DISPATCH_INLINED().
- op(_CALL, (unused/2, callable, self_or_null, args[oparg] -- res)) {
+ op(_CALL, (callable, self_or_null, args[oparg] -- res)) {
// oparg counts all of the args, but *not* self:
int total_args = oparg;
if (self_or_null != NULL) {
@@ -3079,7 +3087,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
- macro(CALL) = _SPECIALIZE_CALL + _CALL;
+ macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL;
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
DEOPT_IF(null != NULL);
diff --git a/Python/ceval.c b/Python/ceval.c
index 27304d3..1fea974 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -24,6 +24,7 @@
#include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_typeobject.h" // _PySuper_Lookup()
+#include "pycore_uop_ids.h" // Uops
#include "pycore_uops.h" // _PyUOpExecutorObject
#include "pycore_pyerrors.h"
diff --git a/Python/compile.c b/Python/compile.c
index 8b9e2f0..65ac05a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -796,35 +796,12 @@ stack_effect(int opcode, int oparg, int jump)
// Specialized instructions are not supported.
return PY_INVALID_STACK_EFFECT;
}
- int popped, pushed;
- if (jump > 0) {
- popped = _PyOpcode_num_popped(opcode, oparg, true);
- pushed = _PyOpcode_num_pushed(opcode, oparg, true);
- }
- else {
- popped = _PyOpcode_num_popped(opcode, oparg, false);
- pushed = _PyOpcode_num_pushed(opcode, oparg, false);
- }
+ int popped = _PyOpcode_num_popped(opcode, oparg);
+ int pushed = _PyOpcode_num_pushed(opcode, oparg);
if (popped < 0 || pushed < 0) {
return PY_INVALID_STACK_EFFECT;
}
- if (jump >= 0) {
- return pushed - popped;
- }
- if (jump < 0) {
- // Compute max(pushed - popped, alt_pushed - alt_popped)
- int alt_popped = _PyOpcode_num_popped(opcode, oparg, true);
- int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true);
- if (alt_popped < 0 || alt_pushed < 0) {
- return PY_INVALID_STACK_EFFECT;
- }
- int diff = pushed - popped;
- int alt_diff = alt_pushed - alt_popped;
- if (alt_diff > diff) {
- return alt_diff;
- }
- return diff;
- }
+ return pushed - popped;
}
// Pseudo ops
@@ -1125,7 +1102,7 @@ compiler_addop_name(struct compiler_unit *u, location loc,
arg <<= 1;
}
if (opcode == LOAD_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_METHOD, LOAD_ATTR));
+ assert(is_pseudo_target(LOAD_METHOD, LOAD_ATTR));
opcode = LOAD_ATTR;
arg <<= 1;
arg |= 1;
@@ -1135,18 +1112,18 @@ compiler_addop_name(struct compiler_unit *u, location loc,
arg |= 2;
}
if (opcode == LOAD_SUPER_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
arg |= 3;
}
if (opcode == LOAD_ZERO_SUPER_ATTR) {
- assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
}
if (opcode == LOAD_ZERO_SUPER_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
arg |= 1;
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index d2e3a7a..e6c824a 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -2258,11 +2258,11 @@ convert_pseudo_ops(basicblock *entryblock)
INSTR_SET_OP0(instr, NOP);
}
else if (instr->i_opcode == LOAD_CLOSURE) {
- assert(SAME_OPCODE_METADATA(LOAD_CLOSURE, LOAD_FAST));
+ assert(is_pseudo_target(LOAD_CLOSURE, LOAD_FAST));
instr->i_opcode = LOAD_FAST;
}
else if (instr->i_opcode == STORE_FAST_MAYBE_NULL) {
- assert(SAME_OPCODE_METADATA(STORE_FAST_MAYBE_NULL, STORE_FAST));
+ assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST));
instr->i_opcode = STORE_FAST;
}
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index a274427..e935f33 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -153,6 +153,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -181,6 +182,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_INT
{
STAT_INC(BINARY_OP, hit);
@@ -209,6 +211,7 @@
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_UNICODE
{
STAT_INC(BINARY_OP, hit);
@@ -236,6 +239,7 @@
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_INPLACE_ADD_UNICODE
{
TIER_ONE_ONLY
@@ -282,6 +286,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_MULTIPLY_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -310,6 +315,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_MULTIPLY_INT
{
STAT_INC(BINARY_OP, hit);
@@ -338,6 +344,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_SUBTRACT_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -366,6 +373,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_SUBTRACT_INT
{
STAT_INC(BINARY_OP, hit);
@@ -763,6 +771,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 2 cache entries */
// _CALL
{
// oparg counts all of the args, but *not* self:
@@ -3400,6 +3409,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 8 cache entries */
// _LOAD_ATTR
{
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
@@ -4096,6 +4106,9 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 1 cache entry */
+ /* Skip 1 cache entry */
+ /* Skip 1 cache entry */
// _LOAD_GLOBAL
{
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
@@ -4564,6 +4577,7 @@
next_instr += 2;
INSTRUCTION_STATS(POP_JUMP_IF_FALSE);
PyObject *cond;
+ /* Skip 1 cache entry */
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
@@ -4582,6 +4596,7 @@
PyObject *value;
PyObject *b;
PyObject *cond;
+ /* Skip 1 cache entry */
// _IS_NONE
value = stack_pointer[-1];
{
@@ -4614,6 +4629,7 @@
PyObject *value;
PyObject *b;
PyObject *cond;
+ /* Skip 1 cache entry */
// _IS_NONE
value = stack_pointer[-1];
{
@@ -4644,6 +4660,7 @@
next_instr += 2;
INSTRUCTION_STATS(POP_JUMP_IF_TRUE);
PyObject *cond;
+ /* Skip 1 cache entry */
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
@@ -5117,6 +5134,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 3 cache entries */
// _STORE_ATTR
v = stack_pointer[-2];
{
@@ -5509,6 +5527,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 2 cache entries */
// _TO_BOOL
{
int err = PyObject_IsTrue(value);
diff --git a/Python/optimizer.c b/Python/optimizer.c
index d44e733..0ff1619 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -6,14 +6,20 @@
#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_uop_ids.h"
#include "pycore_uops.h"
#include "cpython/optimizer.h"
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
+#define NEED_OPCODE_METADATA
+#include "pycore_uop_metadata.h" // Uop tables
+#undef NEED_OPCODE_METADATA
+
#define MAX_EXECUTORS_SIZE 256
+
static bool
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
{
@@ -327,9 +333,6 @@ uop_dealloc(_PyUOpExecutorObject *self) {
const char *
_PyUOpName(int index)
{
- if (index <= MAX_REAL_OPCODE) {
- return _PyOpcode_OpName[index];
- }
return _PyOpcode_uop_name[index];
}
@@ -388,7 +391,7 @@ PyTypeObject _PyUOpExecutor_Type = {
/* TO DO -- Generate these tables */
static const uint16_t
-_PyUOp_Replacements[OPCODE_METADATA_SIZE] = {
+_PyUOp_Replacements[MAX_UOP_ID + 1] = {
[_ITER_JUMP_RANGE] = _GUARD_NOT_EXHAUSTED_RANGE,
[_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST,
[_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE,
@@ -629,14 +632,6 @@ top: // Jump here after _PUSH_FRAME or likely branches
oparg += extras;
}
}
- if (_PyUOp_Replacements[uop]) {
- uop = _PyUOp_Replacements[uop];
- if (uop == _FOR_ITER_TIER_TWO) {
- target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
- assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
- _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
- }
- }
break;
case OPARG_CACHE_1:
operand = read_u16(&instr[offset].cache);
@@ -657,7 +652,15 @@ top: // Jump here after _PUSH_FRAME or likely branches
oparg = offset;
assert(uop == _SAVE_RETURN_OFFSET);
break;
-
+ case OPARG_REPLACED:
+ uop = _PyUOp_Replacements[uop];
+ assert(uop != 0);
+ if (uop == _FOR_ITER_TIER_TWO) {
+ target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
+ assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
+ _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
+ }
+ break;
default:
fprintf(stderr,
"opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n",
@@ -799,7 +802,8 @@ compute_used(_PyUOpInstruction *buffer, uint32_t *used)
}
/* All other micro-ops fall through, so i+1 is reachable */
SET_BIT(used, i+1);
- if (OPCODE_HAS_JUMP(opcode)) {
+ assert(opcode <= MAX_UOP_ID);
+ if (_PyUop_Flags[opcode] & HAS_JUMP_FLAG) {
/* Mark target as reachable */
SET_BIT(used, buffer[i].oparg);
}
diff --git a/Python/specialize.c b/Python/specialize.c
index 7c2a4a4..369b962 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -10,6 +10,7 @@
#include "pycore_moduleobject.h"
#include "pycore_object.h"
#include "pycore_opcode_metadata.h" // _PyOpcode_Caches
+#include "pycore_uop_metadata.h" // _PyOpcode_uop_name
#include "pycore_opcode_utils.h" // RESUME_AT_FUNC_START
#include "pycore_pylifecycle.h" // _PyOS_URandomNonblock()
#include "pycore_runtime.h" // _Py_ID()
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index e077eb0..d7aca50 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -11,11 +11,16 @@ class Properties:
deopts: bool
oparg: bool
jumps: bool
+ eval_breaker: bool
ends_with_eval_breaker: bool
needs_this: bool
always_exits: bool
stores_sp: bool
tier_one_only: bool
+ uses_co_consts: bool
+ uses_co_names: bool
+ uses_locals: bool
+ has_free: bool
def dump(self, indent: str) -> None:
print(indent, end="")
@@ -30,11 +35,16 @@ class Properties:
deopts=any(p.deopts for p in properties),
oparg=any(p.oparg for p in properties),
jumps=any(p.jumps for p in properties),
+ eval_breaker=any(p.eval_breaker for p in properties),
ends_with_eval_breaker=any(p.ends_with_eval_breaker for p in properties),
needs_this=any(p.needs_this for p in properties),
always_exits=any(p.always_exits for p in properties),
stores_sp=any(p.stores_sp for p in properties),
tier_one_only=any(p.tier_one_only for p in properties),
+ uses_co_consts=any(p.uses_co_consts for p in properties),
+ uses_co_names=any(p.uses_co_names for p in properties),
+ uses_locals=any(p.uses_locals for p in properties),
+ has_free=any(p.has_free for p in properties),
)
@@ -44,11 +54,16 @@ SKIP_PROPERTIES = Properties(
deopts=False,
oparg=False,
jumps=False,
+ eval_breaker=False,
ends_with_eval_breaker=False,
needs_this=False,
always_exits=False,
stores_sp=False,
tier_one_only=False,
+ uses_co_consts=False,
+ uses_co_names=False,
+ uses_locals=False,
+ has_free=False,
)
@@ -142,6 +157,12 @@ class Uop:
return False
return True
+ def is_super(self) -> bool:
+ for tkn in self.body:
+ if tkn.kind == "IDENTIFIER" and tkn.text == "oparg1":
+ return True
+ return False
+
Part = Uop | Skip
@@ -153,6 +174,7 @@ class Instruction:
_properties: Properties | None
is_target: bool = False
family: Optional["Family"] = None
+ opcode: int = -1
@property
def properties(self) -> Properties:
@@ -171,16 +193,30 @@ class Instruction:
def size(self) -> int:
return 1 + sum(part.size for part in self.parts)
+ def is_super(self) -> bool:
+ if len(self.parts) != 1:
+ return False
+ uop = self.parts[0]
+ if isinstance(uop, Uop):
+ return uop.is_super()
+ else:
+ return False
+
@dataclass
class PseudoInstruction:
name: str
targets: list[Instruction]
flags: list[str]
+ opcode: int = -1
def dump(self, indent: str) -> None:
print(indent, self.name, "->", " or ".join([t.name for t in self.targets]))
+ @property
+ def properties(self) -> Properties:
+ return Properties.from_list([i.properties for i in self.targets])
+
@dataclass
class Family:
@@ -198,12 +234,15 @@ class Analysis:
uops: dict[str, Uop]
families: dict[str, Family]
pseudos: dict[str, PseudoInstruction]
+ opmap: dict[str, int]
+ have_arg: int
+ min_instrumented: int
def analysis_error(message: str, tkn: lexer.Token) -> SyntaxError:
# To do -- support file and line output
# Construct a SyntaxError instance from message and token
- return lexer.make_syntax_error(message, "", tkn.line, tkn.column, "")
+ return lexer.make_syntax_error(message, tkn.filename, tkn.line, tkn.column, "")
def override_error(
@@ -238,6 +277,11 @@ def analyze_caches(inputs: list[parser.InputEffect]) -> list[CacheEntry]:
caches: list[parser.CacheEffect] = [
i for i in inputs if isinstance(i, parser.CacheEffect)
]
+ for cache in caches:
+ if cache.name == "unused":
+ raise analysis_error(
+ "Unused cache entry in op. Move to enclosing macro.", cache.tokens[0]
+ )
return [CacheEntry(i.name, int(i.size)) for i in caches]
@@ -300,17 +344,28 @@ def always_exits(op: parser.InstDef) -> bool:
def compute_properties(op: parser.InstDef) -> Properties:
+ has_free = (
+ variable_used(op, "PyCell_New")
+ or variable_used(op, "PyCell_GET")
+ or variable_used(op, "PyCell_SET")
+ )
return Properties(
escapes=makes_escaping_api_call(op),
infallible=is_infallible(op),
deopts=variable_used(op, "DEOPT_IF"),
oparg=variable_used(op, "oparg"),
jumps=variable_used(op, "JUMPBY"),
+ eval_breaker=variable_used(op, "CHECK_EVAL_BREAKER"),
ends_with_eval_breaker=eval_breaker_at_end(op),
needs_this=variable_used(op, "this_instr"),
always_exits=always_exits(op),
stores_sp=variable_used(op, "STORE_SP"),
tier_one_only=variable_used(op, "TIER_ONE_ONLY"),
+ uses_co_consts=variable_used(op, "FRAME_CO_CONSTS"),
+ uses_co_names=variable_used(op, "FRAME_CO_NAMES"),
+ uses_locals=(variable_used(op, "GETLOCAL") or variable_used(op, "SETLOCAL"))
+ and not has_free,
+ has_free=has_free,
)
@@ -417,6 +472,95 @@ def add_pseudo(
)
+def assign_opcodes(
+ instructions: dict[str, Instruction],
+ families: dict[str, Family],
+ pseudos: dict[str, PseudoInstruction],
+) -> tuple[dict[str, int], int, int]:
+ """Assigns opcodes, then returns the opmap,
+ have_arg and min_instrumented values"""
+ instmap: dict[str, int] = {}
+
+ # 0 is reserved for cache entries. This helps debugging.
+ instmap["CACHE"] = 0
+
+ # 17 is reserved as it is the initial value for the specializing counter.
+ # This helps catch cases where we attempt to execute a cache.
+ instmap["RESERVED"] = 17
+
+ # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py
+ instmap["RESUME"] = 149
+
+ # This is an historical oddity.
+ instmap["BINARY_OP_INPLACE_ADD_UNICODE"] = 3
+
+ instmap["INSTRUMENTED_LINE"] = 254
+
+ instrumented = [name for name in instructions if name.startswith("INSTRUMENTED")]
+
+ # Special case: this instruction is implemented in ceval.c
+ # rather than bytecodes.c, so we need to add it explicitly
+ # here (at least until we add something to bytecodes.c to
+ # declare external instructions).
+ instrumented.append("INSTRUMENTED_LINE")
+
+ specialized: set[str] = set()
+ no_arg: list[str] = []
+ has_arg: list[str] = []
+
+ for family in families.values():
+ specialized.update(inst.name for inst in family.members)
+
+ for inst in instructions.values():
+ name = inst.name
+ if name in specialized:
+ continue
+ if name in instrumented:
+ continue
+ if inst.properties.oparg:
+ has_arg.append(name)
+ else:
+ no_arg.append(name)
+
+ # Specialized ops appear in their own section
+ # Instrumented opcodes are at the end of the valid range
+ min_internal = 150
+ min_instrumented = 254 - (len(instrumented) - 1)
+ assert min_internal + len(specialized) < min_instrumented
+
+ next_opcode = 1
+
+ def add_instruction(name: str) -> None:
+ nonlocal next_opcode
+ if name in instmap:
+ return # Pre-defined name
+ while next_opcode in instmap.values():
+ next_opcode += 1
+ instmap[name] = next_opcode
+ next_opcode += 1
+
+ for name in sorted(no_arg):
+ add_instruction(name)
+ for name in sorted(has_arg):
+ add_instruction(name)
+ # For compatibility
+ next_opcode = min_internal
+ for name in sorted(specialized):
+ add_instruction(name)
+ next_opcode = min_instrumented
+ for name in instrumented:
+ add_instruction(name)
+
+ for name in instructions:
+ instructions[name].opcode = instmap[name]
+
+ for op, name in enumerate(sorted(pseudos), 256):
+ instmap[name] = op
+ pseudos[name].opcode = op
+
+ return instmap, len(no_arg), min_instrumented
+
+
def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
instructions: dict[str, Instruction] = {}
uops: dict[str, Uop] = {}
@@ -460,10 +604,20 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
continue
if target.text in instructions:
instructions[target.text].is_target = True
- # Hack
+ # Special case BINARY_OP_INPLACE_ADD_UNICODE
+ # BINARY_OP_INPLACE_ADD_UNICODE is not a normal family member,
+ # as it is the wrong size, but we need it to maintain an
+ # historical optimization.
if "BINARY_OP_INPLACE_ADD_UNICODE" in instructions:
- instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"]
- return Analysis(instructions, uops, families, pseudos)
+ inst = instructions["BINARY_OP_INPLACE_ADD_UNICODE"]
+ inst.family = families["BINARY_OP"]
+ families["BINARY_OP"].members.append(inst)
+ opmap, first_arg, min_instrumented = assign_opcodes(
+ instructions, families, pseudos
+ )
+ return Analysis(
+ instructions, uops, families, pseudos, opmap, first_arg, min_instrumented
+ )
def analyze_files(filenames: list[str]) -> Analysis:
diff --git a/Tools/cases_generator/cwriter.py b/Tools/cases_generator/cwriter.py
index 67b1c9a..069f017 100644
--- a/Tools/cases_generator/cwriter.py
+++ b/Tools/cases_generator/cwriter.py
@@ -1,5 +1,6 @@
+import contextlib
from lexer import Token
-from typing import TextIO
+from typing import TextIO, Iterator
class CWriter:
@@ -44,9 +45,12 @@ class CWriter:
def maybe_indent(self, txt: str) -> None:
parens = txt.count("(") - txt.count(")")
- if parens > 0 and self.last_token:
- offset = self.last_token.end_column - 1
- if offset <= self.indents[-1] or offset > 40:
+ if parens > 0:
+ if self.last_token:
+ offset = self.last_token.end_column - 1
+ if offset <= self.indents[-1] or offset > 40:
+ offset = self.indents[-1] + 4
+ else:
offset = self.indents[-1] + 4
self.indents.append(offset)
if is_label(txt):
@@ -54,6 +58,7 @@ class CWriter:
else:
braces = txt.count("{") - txt.count("}")
if braces > 0:
+ assert braces == 1
if 'extern "C"' in txt:
self.indents.append(self.indents[-1])
else:
@@ -114,6 +119,28 @@ class CWriter:
self.newline = True
self.last_token = None
+ @contextlib.contextmanager
+ def header_guard(self, name: str) -> Iterator[None]:
+ self.out.write(
+ f"""
+#ifndef {name}
+#define {name}
+#ifdef __cplusplus
+extern "C" {{
+#endif
+
+"""
+ )
+ yield
+ self.out.write(
+ f"""
+#ifdef __cplusplus
+}}
+#endif
+#endif /* !{name} */
+"""
+ )
+
def is_label(txt: str) -> bool:
return not txt.startswith("//") and txt.endswith(":")
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 50bc14a..bb027f3 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -840,7 +840,6 @@ def main() -> None:
a.assign_opcode_ids()
a.write_opcode_targets(args.opcode_targets_h)
- a.write_metadata(args.metadata, args.pymetadata)
a.write_abstract_interpreter_instructions(
args.abstract_interpreter_cases, args.emit_line_directives
)
diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py
index 1b565bf..5a42a05 100644
--- a/Tools/cases_generator/generators_common.py
+++ b/Tools/cases_generator/generators_common.py
@@ -2,14 +2,11 @@ from pathlib import Path
from typing import TextIO
from analyzer import (
- Analysis,
Instruction,
Uop,
- Part,
analyze_files,
+ Properties,
Skip,
- StackItem,
- analysis_error,
)
from cwriter import CWriter
from typing import Callable, Mapping, TextIO, Iterator
@@ -25,14 +22,16 @@ def root_relative_path(filename: str) -> str:
try:
return Path(filename).absolute().relative_to(ROOT).as_posix()
except ValueError:
+ # Not relative to root, just return original path.
return filename
-def write_header(generator: str, sources: list[str], outfile: TextIO) -> None:
+
+def write_header(generator: str, sources: list[str], outfile: TextIO, comment: str = "//") -> None:
outfile.write(
- f"""// This file is generated by {root_relative_path(generator)}
-// from:
-// {", ".join(root_relative_path(src) for src in sources)}
-// Do not edit!
+ f"""{comment} This file is generated by {root_relative_path(generator)}
+{comment} from:
+{comment} {", ".join(root_relative_path(src) for src in sources)}
+{comment} Do not edit!
"""
)
@@ -186,3 +185,31 @@ def emit_tokens(
replacement_functions[tkn.text](out, tkn, tkn_iter, uop, stack, inst)
else:
out.emit(tkn)
+
+
+def cflags(p: Properties) -> str:
+ flags: list[str] = []
+ if p.oparg:
+ flags.append("HAS_ARG_FLAG")
+ if p.uses_co_consts:
+ flags.append("HAS_CONST_FLAG")
+ if p.uses_co_names:
+ flags.append("HAS_NAME_FLAG")
+ if p.jumps:
+ flags.append("HAS_JUMP_FLAG")
+ if p.has_free:
+ flags.append("HAS_FREE_FLAG")
+ if p.uses_locals:
+ flags.append("HAS_LOCAL_FLAG")
+ if p.eval_breaker:
+ flags.append("HAS_EVAL_BREAK_FLAG")
+ if p.deopts:
+ flags.append("HAS_DEOPT_FLAG")
+ if not p.infallible:
+ flags.append("HAS_ERROR_FLAG")
+ if p.escapes:
+ flags.append("HAS_ESCAPES_FLAG")
+ if flags:
+ return " | ".join(flags)
+ else:
+ return "0"
diff --git a/Tools/cases_generator/opcode_id_generator.py b/Tools/cases_generator/opcode_id_generator.py
index ddbb409..dbea3d0 100644
--- a/Tools/cases_generator/opcode_id_generator.py
+++ b/Tools/cases_generator/opcode_id_generator.py
@@ -24,111 +24,23 @@ from typing import TextIO
DEFAULT_OUTPUT = ROOT / "Include/opcode_ids.h"
-def generate_opcode_header(filenames: list[str], analysis: Analysis, outfile: TextIO) -> None:
+def generate_opcode_header(
+ filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
write_header(__file__, filenames, outfile)
out = CWriter(outfile, 0, False)
- out.emit("\n")
- instmap: dict[str, int] = {}
+ with out.header_guard("Py_OPCODE_IDS_H"):
+ out.emit("/* Instruction opcodes for compiled code */\n")
- # 0 is reserved for cache entries. This helps debugging.
- instmap["CACHE"] = 0
+ def write_define(name: str, op: int) -> None:
+ out.emit(f"#define {name:<38} {op:>3}\n")
- # 17 is reserved as it is the initial value for the specializing counter.
- # This helps catch cases where we attempt to execute a cache.
- instmap["RESERVED"] = 17
+ for op, name in sorted([(op, name) for (name, op) in analysis.opmap.items()]):
+ write_define(name, op)
- # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py
- instmap["RESUME"] = 149
- instmap["INSTRUMENTED_LINE"] = 254
-
- instrumented = [
- name for name in analysis.instructions if name.startswith("INSTRUMENTED")
- ]
-
- # Special case: this instruction is implemented in ceval.c
- # rather than bytecodes.c, so we need to add it explicitly
- # here (at least until we add something to bytecodes.c to
- # declare external instructions).
- instrumented.append("INSTRUMENTED_LINE")
-
- specialized: set[str] = set()
- no_arg: list[str] = []
- has_arg: list[str] = []
-
- for family in analysis.families.values():
- specialized.update(inst.name for inst in family.members)
-
- for inst in analysis.instructions.values():
- name = inst.name
- if name in specialized:
- continue
- if name in instrumented:
- continue
- if inst.properties.oparg:
- has_arg.append(name)
- else:
- no_arg.append(name)
-
- # Specialized ops appear in their own section
- # Instrumented opcodes are at the end of the valid range
- min_internal = 150
- min_instrumented = 254 - (len(instrumented) - 1)
- assert min_internal + len(specialized) < min_instrumented
-
- next_opcode = 1
-
- def add_instruction(name: str) -> None:
- nonlocal next_opcode
- if name in instmap:
- return # Pre-defined name
- while next_opcode in instmap.values():
- next_opcode += 1
- instmap[name] = next_opcode
- next_opcode += 1
-
- for name in sorted(no_arg):
- add_instruction(name)
- for name in sorted(has_arg):
- add_instruction(name)
- # For compatibility
- next_opcode = min_internal
- for name in sorted(specialized):
- add_instruction(name)
- next_opcode = min_instrumented
- for name in instrumented:
- add_instruction(name)
-
- for op, name in enumerate(sorted(analysis.pseudos), 256):
- instmap[name] = op
-
- assert 255 not in instmap.values()
-
- out.emit(
- """#ifndef Py_OPCODE_IDS_H
-#define Py_OPCODE_IDS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Instruction opcodes for compiled code */
-"""
- )
-
- def write_define(name: str, op: int) -> None:
- out.emit(f"#define {name:<38} {op:>3}\n")
-
- for op, name in sorted([(op, name) for (name, op) in instmap.items()]):
- write_define(name, op)
-
- out.emit("\n")
- write_define("HAVE_ARGUMENT", len(no_arg))
- write_define("MIN_INSTRUMENTED_OPCODE", min_instrumented)
-
- out.emit("\n")
- out.emit("#ifdef __cplusplus\n")
- out.emit("}\n")
- out.emit("#endif\n")
- out.emit("#endif /* !Py_OPCODE_IDS_H */\n")
+ out.emit("\n")
+ write_define("HAVE_ARGUMENT", analysis.have_arg)
+ write_define("MIN_INSTRUMENTED_OPCODE", analysis.min_instrumented)
arg_parser = argparse.ArgumentParser(
diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py
new file mode 100644
index 0000000..427bb54
--- /dev/null
+++ b/Tools/cases_generator/opcode_metadata_generator.py
@@ -0,0 +1,386 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+import os.path
+import sys
+
+from analyzer import (
+ Analysis,
+ Instruction,
+ analyze_files,
+ Skip,
+ Uop,
+)
+from generators_common import (
+ DEFAULT_INPUT,
+ ROOT,
+ write_header,
+ cflags,
+ StackOffset,
+)
+from cwriter import CWriter
+from typing import TextIO
+from stack import get_stack_effect
+
+# Constants used instead of size for macro expansions.
+# Note: 1, 2, 4 must match actual cache entry sizes.
+OPARG_KINDS = {
+ "OPARG_FULL": 0,
+ "OPARG_CACHE_1": 1,
+ "OPARG_CACHE_2": 2,
+ "OPARG_CACHE_4": 4,
+ "OPARG_TOP": 5,
+ "OPARG_BOTTOM": 6,
+ "OPARG_SAVE_RETURN_OFFSET": 7,
+ # Skip 8 as the other powers of 2 are sizes
+ "OPARG_REPLACED": 9,
+}
+
+FLAGS = [
+ "ARG",
+ "CONST",
+ "NAME",
+ "JUMP",
+ "FREE",
+ "LOCAL",
+ "EVAL_BREAK",
+ "DEOPT",
+ "ERROR",
+ "ESCAPES",
+]
+
+
+def generate_flag_macros(out: CWriter) -> None:
+ for i, flag in enumerate(FLAGS):
+ out.emit(f"#define HAS_{flag}_FLAG ({1<<i})\n")
+ for i, flag in enumerate(FLAGS):
+ out.emit(
+ f"#define OPCODE_HAS_{flag}(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_{flag}_FLAG))\n"
+ )
+ out.emit("\n")
+
+
+def generate_oparg_macros(out: CWriter) -> None:
+ for name, value in OPARG_KINDS.items():
+ out.emit(f"#define {name} {value}\n")
+ out.emit("\n")
+
+
+def emit_stack_effect_function(
+ out: CWriter, direction: str, data: list[tuple[str, str]]
+) -> None:
+ out.emit(f"extern int _PyOpcode_num_{direction}(int opcode, int oparg);\n")
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit(f"int _PyOpcode_num_{direction}(int opcode, int oparg) {{\n")
+ out.emit("switch(opcode) {\n")
+ for name, effect in data:
+ out.emit(f"case {name}:\n")
+ out.emit(f" return {effect};\n")
+ out.emit("default:\n")
+ out.emit(" return -1;\n")
+ out.emit("}\n")
+ out.emit("}\n\n")
+ out.emit("#endif\n\n")
+
+
+def generate_stack_effect_functions(analysis: Analysis, out: CWriter) -> None:
+ popped_data: list[tuple[str, str]] = []
+ pushed_data: list[tuple[str, str]] = []
+ for inst in analysis.instructions.values():
+ stack = get_stack_effect(inst)
+ popped = (-stack.base_offset).to_c()
+ pushed = (stack.top_offset - stack.base_offset).to_c()
+ popped_data.append((inst.name, popped))
+ pushed_data.append((inst.name, pushed))
+ emit_stack_effect_function(out, "popped", sorted(popped_data))
+ emit_stack_effect_function(out, "pushed", sorted(pushed_data))
+
+
+def generate_is_pseudo(analysis: Analysis, out: CWriter) -> None:
+ """Write the IS_PSEUDO_INSTR macro"""
+ out.emit("\n\n#define IS_PSEUDO_INSTR(OP) ( \\\n")
+ for op in analysis.pseudos:
+ out.emit(f"((OP) == {op}) || \\\n")
+ out.emit("0")
+ out.emit(")\n\n")
+
+
+def get_format(inst: Instruction) -> str:
+ if inst.properties.oparg:
+ format = "INSTR_FMT_IB"
+ else:
+ format = "INSTR_FMT_IX"
+ if inst.size > 1:
+ format += "C"
+ format += "0" * (inst.size - 2)
+ return format
+
+
+def generate_instruction_formats(analysis: Analysis, out: CWriter) -> None:
+ # Compute the set of all instruction formats.
+ formats: set[str] = set()
+ for inst in analysis.instructions.values():
+ formats.add(get_format(inst))
+ # Generate an enum for it
+ out.emit("enum InstructionFormat {\n")
+ next_id = 1
+ for format in sorted(formats):
+ out.emit(f"{format} = {next_id},\n")
+ next_id += 1
+ out.emit("};\n\n")
+
+
+def generate_deopt_table(analysis: Analysis, out: CWriter) -> None:
+ out.emit("extern const uint8_t _PyOpcode_Deopt[256];\n")
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit("const uint8_t _PyOpcode_Deopt[256] = {\n")
+ deopts: list[tuple[str, str]] = []
+ for inst in analysis.instructions.values():
+ deopt = inst.name
+ if inst.family is not None:
+ deopt = inst.family.name
+ deopts.append((inst.name, deopt))
+ deopts.append(("INSTRUMENTED_LINE", "INSTRUMENTED_LINE"))
+ for name, deopt in sorted(deopts):
+ out.emit(f"[{name}] = {deopt},\n")
+ out.emit("};\n\n")
+ out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def generate_cache_table(analysis: Analysis, out: CWriter) -> None:
+ out.emit("extern const uint8_t _PyOpcode_Caches[256];\n")
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit("const uint8_t _PyOpcode_Caches[256] = {\n")
+ for inst in analysis.instructions.values():
+ if inst.family and inst.family.name != inst.name:
+ continue
+ if inst.name.startswith("INSTRUMENTED"):
+ continue
+ if inst.size > 1:
+ out.emit(f"[{inst.name}] = {inst.size-1},\n")
+ out.emit("};\n")
+ out.emit("#endif\n\n")
+
+
+def generate_name_table(analysis: Analysis, out: CWriter) -> None:
+ table_size = 256 + len(analysis.pseudos)
+ out.emit(f"extern const char *_PyOpcode_OpName[{table_size}];\n")
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit(f"const char *_PyOpcode_OpName[{table_size}] = {{\n")
+ names = list(analysis.instructions) + list(analysis.pseudos)
+ names.append("INSTRUMENTED_LINE")
+ for name in sorted(names):
+ out.emit(f'[{name}] = "{name}",\n')
+ out.emit("};\n")
+ out.emit("#endif\n\n")
+
+
+def generate_metadata_table(analysis: Analysis, out: CWriter) -> None:
+ table_size = 256 + len(analysis.pseudos)
+ out.emit("struct opcode_metadata {\n")
+ out.emit("uint8_t valid_entry;\n")
+ out.emit("int8_t instr_format;\n")
+ out.emit("int16_t flags;\n")
+ out.emit("};\n\n")
+ out.emit(
+ f"extern const struct opcode_metadata _PyOpcode_opcode_metadata[{table_size}];\n"
+ )
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit(
+ f"const struct opcode_metadata _PyOpcode_opcode_metadata[{table_size}] = {{\n"
+ )
+ for inst in sorted(analysis.instructions.values(), key=lambda t: t.name):
+ out.emit(
+ f"[{inst.name}] = {{ true, {get_format(inst)}, {cflags(inst.properties)} }},\n"
+ )
+ for pseudo in sorted(analysis.pseudos.values(), key=lambda t: t.name):
+ flags = cflags(pseudo.properties)
+ for flag in pseudo.flags:
+ if flags == "0":
+ flags = f"{flag}_FLAG"
+ else:
+ flags += f" | {flag}_FLAG"
+ out.emit(f"[{pseudo.name}] = {{ true, -1, {flags} }},\n")
+ out.emit("};\n")
+ out.emit("#endif\n\n")
+
+
+def generate_expansion_table(analysis: Analysis, out: CWriter) -> None:
+ expansions_table: dict[str, list[tuple[str, int, int]]] = {}
+ for inst in sorted(analysis.instructions.values(), key=lambda t: t.name):
+ offset: int = 0 # Cache effect offset
+ expansions: list[tuple[str, int, int]] = [] # [(name, size, offset), ...]
+ if inst.is_super():
+ pieces = inst.name.split("_")
+ assert len(pieces) == 4, f"{inst.name} doesn't look like a super-instr"
+ name1 = "_".join(pieces[:2])
+ name2 = "_".join(pieces[2:])
+ assert name1 in analysis.instructions, f"{name1} doesn't match any instr"
+ assert name2 in analysis.instructions, f"{name2} doesn't match any instr"
+ instr1 = analysis.instructions[name1]
+ instr2 = analysis.instructions[name2]
+ assert (
+ len(instr1.parts) == 1
+ ), f"{name1} is not a good superinstruction part"
+ assert (
+ len(instr2.parts) == 1
+ ), f"{name2} is not a good superinstruction part"
+ expansions.append((instr1.parts[0].name, OPARG_KINDS["OPARG_TOP"], 0))
+ expansions.append((instr2.parts[0].name, OPARG_KINDS["OPARG_BOTTOM"], 0))
+ elif not is_viable_expansion(inst):
+ continue
+ else:
+ for part in inst.parts:
+ size = part.size
+ if part.name == "_SAVE_RETURN_OFFSET":
+ size = OPARG_KINDS["OPARG_SAVE_RETURN_OFFSET"]
+ if isinstance(part, Uop):
+ # Skip specializations
+ if "specializing" in part.annotations:
+ continue
+ if "replaced" in part.annotations:
+ size = OPARG_KINDS["OPARG_REPLACED"]
+ expansions.append((part.name, size, offset if size else 0))
+ offset += part.size
+ expansions_table[inst.name] = expansions
+ max_uops = max(len(ex) for ex in expansions_table.values())
+ out.emit(f"#define MAX_UOP_PER_EXPANSION {max_uops}\n")
+ out.emit("struct opcode_macro_expansion {\n")
+ out.emit("int nuops;\n")
+ out.emit(
+ "struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];\n"
+ )
+ out.emit("};\n")
+ out.emit(
+ "extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];\n\n"
+ )
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit("const struct opcode_macro_expansion\n")
+ out.emit("_PyOpcode_macro_expansion[256] = {\n")
+ for inst_name, expansions in expansions_table.items():
+ uops = [
+ f"{{ {name}, {size}, {offset} }}" for (name, size, offset) in expansions
+ ]
+ out.emit(
+ f'[{inst_name}] = {{ .nuops = {len(expansions)}, .uops = {{ {", ".join(uops)} }} }},\n'
+ )
+ out.emit("};\n")
+ out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def is_viable_expansion(inst: Instruction) -> bool:
+ "An instruction can be expanded if all its parts are viable for tier 2"
+ for part in inst.parts:
+ if isinstance(part, Uop):
+ # Skip specializing and replaced uops
+ if "specializing" in part.annotations:
+ continue
+ if "replaced" in part.annotations:
+ continue
+ if part.properties.tier_one_only or not part.is_viable():
+ return False
+ return True
+
+
+def generate_extra_cases(analysis: Analysis, out: CWriter) -> None:
+ out.emit("#define EXTRA_CASES \\\n")
+ valid_opcodes = set(analysis.opmap.values())
+ for op in range(256):
+ if op not in valid_opcodes:
+ out.emit(f" case {op}: \\\n")
+ out.emit(" ;\n")
+
+
+def generate_pseudo_targets(analysis: Analysis, out: CWriter) -> None:
+ table_size = len(analysis.pseudos)
+ max_targets = max(len(pseudo.targets) for pseudo in analysis.pseudos.values())
+ out.emit("struct pseudo_targets {\n")
+ out.emit(f"uint8_t targets[{max_targets + 1}];\n")
+ out.emit("};\n")
+ out.emit(
+ f"extern const struct pseudo_targets _PyOpcode_PseudoTargets[{table_size}];\n"
+ )
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit(
+ f"const struct pseudo_targets _PyOpcode_PseudoTargets[{table_size}] = {{\n"
+ )
+ for pseudo in analysis.pseudos.values():
+ targets = ["0"] * (max_targets + 1)
+ for i, target in enumerate(pseudo.targets):
+ targets[i] = target.name
+ out.emit(f"[{pseudo.name}-256] = {{ {{ {', '.join(targets)} }} }},\n")
+ out.emit("};\n\n")
+ out.emit("#endif // NEED_OPCODE_METADATA\n")
+ out.emit("static inline bool\n")
+ out.emit("is_pseudo_target(int pseudo, int target) {\n")
+ out.emit(f"if (pseudo < 256 || pseudo >= {256+table_size}) {{\n")
+ out.emit(f"return false;\n")
+ out.emit("}\n")
+ out.emit(
+ f"for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) {{\n"
+ )
+ out.emit(
+ f"if (_PyOpcode_PseudoTargets[pseudo-256].targets[i] == target) return true;\n"
+ )
+ out.emit("}\n")
+ out.emit(f"return false;\n")
+ out.emit("}\n\n")
+
+
+def generate_opcode_metadata(
+ filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+ write_header(__file__, filenames, outfile)
+ out = CWriter(outfile, 0, False)
+ with out.header_guard("Py_CORE_OPCODE_METADATA_H"):
+ out.emit("#ifndef Py_BUILD_CORE\n")
+ out.emit('# error "this header requires Py_BUILD_CORE define"\n')
+ out.emit("#endif\n\n")
+ out.emit("#include <stdbool.h> // bool\n")
+ out.emit('#include "opcode_ids.h"\n')
+ generate_is_pseudo(analysis, out)
+ out.emit('#include "pycore_uop_ids.h"\n')
+ generate_stack_effect_functions(analysis, out)
+ generate_instruction_formats(analysis, out)
+ table_size = 256 + len(analysis.pseudos)
+ out.emit("#define IS_VALID_OPCODE(OP) \\\n")
+ out.emit(f" (((OP) >= 0) && ((OP) < {table_size}) && \\\n")
+ out.emit(" (_PyOpcode_opcode_metadata[(OP)].valid_entry))\n\n")
+ generate_flag_macros(out)
+ generate_oparg_macros(out)
+ generate_metadata_table(analysis, out)
+ generate_expansion_table(analysis, out)
+ generate_name_table(analysis, out)
+ generate_cache_table(analysis, out)
+ generate_deopt_table(analysis, out)
+ generate_extra_cases(analysis, out)
+ generate_pseudo_targets(analysis, out)
+
+
+arg_parser = argparse.ArgumentParser(
+ description="Generate the header file with opcode metadata.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+
+DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_metadata.h"
+
+
+arg_parser.add_argument(
+ "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+ "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+ args = arg_parser.parse_args()
+ if len(args.input) == 0:
+ args.input.append(DEFAULT_INPUT)
+ data = analyze_files(args.input)
+ with open(args.output, "w") as outfile:
+ generate_opcode_metadata(args.input, data, outfile)
diff --git a/Tools/cases_generator/py_metadata_generator.py b/Tools/cases_generator/py_metadata_generator.py
new file mode 100644
index 0000000..43811fd
--- /dev/null
+++ b/Tools/cases_generator/py_metadata_generator.py
@@ -0,0 +1,97 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+
+from analyzer import (
+ Analysis,
+ analyze_files,
+)
+from generators_common import (
+ DEFAULT_INPUT,
+ ROOT,
+ root_relative_path,
+ write_header,
+)
+from cwriter import CWriter
+from typing import TextIO
+
+
+
+DEFAULT_OUTPUT = ROOT / "Lib/_opcode_metadata.py"
+
+
+def get_specialized(analysis: Analysis) -> set[str]:
+ specialized: set[str] = set()
+ for family in analysis.families.values():
+ for member in family.members:
+ specialized.add(member.name)
+ return specialized
+
+
+def generate_specializations(analysis: Analysis, out: CWriter) -> None:
+ out.emit("_specializations = {\n")
+ for family in analysis.families.values():
+ out.emit(f'"{family.name}": [\n')
+ for member in family.members:
+ out.emit(f' "{member.name}",\n')
+ out.emit("],\n")
+ out.emit("}\n\n")
+
+
+def generate_specialized_opmap(analysis: Analysis, out: CWriter) -> None:
+ out.emit("_specialized_opmap = {\n")
+ names = []
+ for family in analysis.families.values():
+ for member in family.members:
+ if member.name == family.name:
+ continue
+ names.append(member.name)
+ for name in sorted(names):
+ out.emit(f"'{name}': {analysis.opmap[name]},\n")
+ out.emit("}\n\n")
+
+
+def generate_opmap(analysis: Analysis, out: CWriter) -> None:
+ specialized = get_specialized(analysis)
+ out.emit("opmap = {\n")
+ for inst, op in analysis.opmap.items():
+ if inst not in specialized:
+ out.emit(f"'{inst}': {analysis.opmap[inst]},\n")
+ out.emit("}\n\n")
+
+
+def generate_py_metadata(
+ filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+ write_header(__file__, filenames, outfile, "#")
+ out = CWriter(outfile, 0, False)
+ generate_specializations(analysis, out)
+ generate_specialized_opmap(analysis, out)
+ generate_opmap(analysis, out)
+ out.emit(f"HAVE_ARGUMENT = {analysis.have_arg}\n")
+ out.emit(f"MIN_INSTRUMENTED_OPCODE = {analysis.min_instrumented}\n")
+
+
+arg_parser = argparse.ArgumentParser(
+ description="Generate the Python file with opcode metadata.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+arg_parser.add_argument(
+ "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+ "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+ args = arg_parser.parse_args()
+ if len(args.input) == 0:
+ args.input.append(DEFAULT_INPUT)
+ data = analyze_files(args.input)
+ with open(args.output, "w") as outfile:
+ generate_py_metadata(args.input, data, outfile)
diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py
index 0b31ce4..94fb82d 100644
--- a/Tools/cases_generator/stack.py
+++ b/Tools/cases_generator/stack.py
@@ -1,5 +1,5 @@
import sys
-from analyzer import StackItem
+from analyzer import StackItem, Instruction, Uop
from dataclasses import dataclass
from formatting import maybe_parenthesize
from cwriter import CWriter
@@ -15,13 +15,16 @@ def var_size(var: StackItem) -> str:
else:
return var.size
-
+@dataclass
class StackOffset:
"The stack offset of the virtual base of the stack from the physical stack pointer"
- def __init__(self) -> None:
- self.popped: list[str] = []
- self.pushed: list[str] = []
+ popped: list[str]
+ pushed: list[str]
+
+ @staticmethod
+ def empty() -> "StackOffset":
+ return StackOffset([], [])
def pop(self, item: StackItem) -> None:
self.popped.append(var_size(item))
@@ -29,6 +32,15 @@ class StackOffset:
def push(self, item: StackItem) -> None:
self.pushed.append(var_size(item))
+ def __sub__(self, other: "StackOffset") -> "StackOffset":
+ return StackOffset(
+ self.popped + other.pushed,
+ self.pushed + other.popped
+ )
+
+ def __neg__(self) -> "StackOffset":
+ return StackOffset(self.pushed, self.popped)
+
def simplify(self) -> None:
"Remove matching values from both the popped and pushed list"
if not self.popped or not self.pushed:
@@ -88,9 +100,9 @@ class SizeMismatch(Exception):
class Stack:
def __init__(self) -> None:
- self.top_offset = StackOffset()
- self.base_offset = StackOffset()
- self.peek_offset = StackOffset()
+ self.top_offset = StackOffset.empty()
+ self.base_offset = StackOffset.empty()
+ self.peek_offset = StackOffset.empty()
self.variables: list[StackItem] = []
self.defined: set[str] = set()
@@ -166,3 +178,15 @@ class Stack:
def as_comment(self) -> str:
return f"/* Variables: {[v.name for v in self.variables]}. Base offset: {self.base_offset.to_c()}. Top offset: {self.top_offset.to_c()} */"
+
+
+def get_stack_effect(inst: Instruction) -> Stack:
+ stack = Stack()
+ for uop in inst.parts:
+ if not isinstance(uop, Uop):
+ continue
+ for var in reversed(uop.stack.inputs):
+ stack.pop(var)
+ for i, var in enumerate(uop.stack.outputs):
+ stack.push(var)
+ return stack
diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py
index 49cede9..aba36ec 100644
--- a/Tools/cases_generator/tier1_generator.py
+++ b/Tools/cases_generator/tier1_generator.py
@@ -190,6 +190,7 @@ def generate_tier1_from_files(
with open(outfilename, "w") as outfile:
generate_tier1(filenames, data, outfile, lines)
+
if __name__ == "__main__":
args = arg_parser.parse_args()
if len(args.input) == 0:
diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py
index a22fb6d..7897b89 100644
--- a/Tools/cases_generator/tier2_generator.py
+++ b/Tools/cases_generator/tier2_generator.py
@@ -103,13 +103,6 @@ TIER2_REPLACEMENT_FUNCTIONS["ERROR_IF"] = tier2_replace_error
TIER2_REPLACEMENT_FUNCTIONS["DEOPT_IF"] = tier2_replace_deopt
-def is_super(uop: Uop) -> bool:
- for tkn in uop.body:
- if tkn.kind == "IDENTIFIER" and tkn.text == "oparg1":
- return True
- return False
-
-
def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
try:
out.start_line()
@@ -123,7 +116,7 @@ def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
for cache in uop.caches:
if cache.name != "unused":
if cache.size == 4:
- type = cast ="PyObject *"
+ type = cast = "PyObject *"
else:
type = f"uint{cache.size*16}_t "
cast = f"uint{cache.size*16}_t"
@@ -156,7 +149,7 @@ def generate_tier2(
for name, uop in analysis.uops.items():
if uop.properties.tier_one_only:
continue
- if is_super(uop):
+ if uop.is_super():
continue
if not uop.is_viable():
out.emit(f"/* {uop.name} is not a viable micro-op for tier 2 */\n\n")
diff --git a/Tools/cases_generator/uop_id_generator.py b/Tools/cases_generator/uop_id_generator.py
index 277da25..633249f 100644
--- a/Tools/cases_generator/uop_id_generator.py
+++ b/Tools/cases_generator/uop_id_generator.py
@@ -24,50 +24,32 @@ from typing import TextIO
DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_ids.h"
-OMIT = {"_CACHE", "_RESERVED", "_EXTENDED_ARG"}
-
-
def generate_uop_ids(
filenames: list[str], analysis: Analysis, outfile: TextIO, distinct_namespace: bool
) -> None:
write_header(__file__, filenames, outfile)
out = CWriter(outfile, 0, False)
- out.emit(
- """#ifndef Py_CORE_UOP_IDS_H
-#define Py_CORE_UOP_IDS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-"""
- )
-
- next_id = 1 if distinct_namespace else 300
- # These two are first by convention
- out.emit(f"#define _EXIT_TRACE {next_id}\n")
- next_id += 1
- out.emit(f"#define _SET_IP {next_id}\n")
- next_id += 1
- PRE_DEFINED = {"_EXIT_TRACE", "_SET_IP"}
-
- for uop in analysis.uops.values():
- if uop.name in PRE_DEFINED:
- continue
- # TODO: We should omit all tier-1 only uops, but
- # generate_cases.py still generates code for those.
- if uop.name in OMIT:
- continue
- if uop.implicitly_created and not distinct_namespace:
- out.emit(f"#define {uop.name} {uop.name[1:]}\n")
- else:
- out.emit(f"#define {uop.name} {next_id}\n")
- next_id += 1
-
- out.emit("\n")
- out.emit("#ifdef __cplusplus\n")
- out.emit("}\n")
- out.emit("#endif\n")
- out.emit("#endif /* !Py_OPCODE_IDS_H */\n")
+ with out.header_guard("Py_CORE_UOP_IDS_H"):
+ next_id = 1 if distinct_namespace else 300
+ # These two are first by convention
+ out.emit(f"#define _EXIT_TRACE {next_id}\n")
+ next_id += 1
+ out.emit(f"#define _SET_IP {next_id}\n")
+ next_id += 1
+ PRE_DEFINED = {"_EXIT_TRACE", "_SET_IP"}
+
+ for uop in analysis.uops.values():
+ if uop.name in PRE_DEFINED:
+ continue
+ if uop.properties.tier_one_only:
+ continue
+ if uop.implicitly_created and not distinct_namespace:
+ out.emit(f"#define {uop.name} {uop.name[1:]}\n")
+ else:
+ out.emit(f"#define {uop.name} {next_id}\n")
+ next_id += 1
+
+ out.emit(f"#define MAX_UOP_ID {next_id-1}\n")
arg_parser = argparse.ArgumentParser(
diff --git a/Tools/cases_generator/uop_metadata_generator.py b/Tools/cases_generator/uop_metadata_generator.py
new file mode 100644
index 0000000..d4f3a09
--- /dev/null
+++ b/Tools/cases_generator/uop_metadata_generator.py
@@ -0,0 +1,73 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+
+from analyzer import (
+ Analysis,
+ analyze_files,
+)
+from generators_common import (
+ DEFAULT_INPUT,
+ ROOT,
+ write_header,
+ cflags,
+)
+from cwriter import CWriter
+from typing import TextIO
+
+
+DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_metadata.h"
+
+
+def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
+ out.emit("extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];\n")
+ out.emit("extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];\n\n")
+ out.emit("#ifdef NEED_OPCODE_METADATA\n")
+ out.emit("const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {\n")
+ for uop in analysis.uops.values():
+ if uop.is_viable() and not uop.properties.tier_one_only:
+ out.emit(f"[{uop.name}] = {cflags(uop.properties)},\n")
+
+ out.emit("};\n\n")
+ out.emit("const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {\n")
+ for uop in sorted(analysis.uops.values(), key=lambda t: t.name):
+ if uop.is_viable() and not uop.properties.tier_one_only:
+ out.emit(f'[{uop.name}] = "{uop.name}",\n')
+ out.emit("};\n")
+ out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def generate_uop_metadata(
+ filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+ write_header(__file__, filenames, outfile)
+ out = CWriter(outfile, 0, False)
+ with out.header_guard("Py_CORE_UOP_METADATA_H"):
+ out.emit("#include <stdint.h>\n")
+ out.emit('#include "pycore_uop_ids.h"\n')
+ generate_names_and_flags(analysis, out)
+
+
+arg_parser = argparse.ArgumentParser(
+ description="Generate the header file with uop metadata.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+arg_parser.add_argument(
+ "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+ "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+ args = arg_parser.parse_args()
+ if len(args.input) == 0:
+ args.input.append(DEFAULT_INPUT)
+ data = analyze_files(args.input)
+ with open(args.output, "w") as outfile:
+ generate_uop_metadata(args.input, data, outfile)