diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a24589fd0a5af3..e1592563a176a4 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1752,6 +1752,25 @@ iterations of the loop. .. versionadded:: 3.13 +.. opcode:: MATCH_CLASS_ISINSTANCE + + Read match subject ``Stack[-2]`` and the type object ``Stack[-1]`` from stack. + Pop ``Stack[-1]`` and push ``True`` or ``False`` for the result of :func:`isinstance`. + + .. versionadded:: 3.15 + + +.. opcode:: MATCH_CLASS_GET_OPT_ATTR (namei) + + Replaces ``STACK[-1]`` with ``getattr(STACK[-1], co_names[namei])`` and get + optional attribute from match subject ``STACK[-2]``. + + Pop ``Stack[-1]``. If attribute is found, push it and ``True`` onto the stack. + Otherwise push ``None`` and ``False``. + + .. versionadded:: 3.15 + + .. opcode:: MATCH_CLASS (count) ``STACK[-1]`` is a tuple of keyword attribute names, ``STACK[-2]`` is the class diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 2fb46a6df50bb3..7fd39e478b7436 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -287,6 +287,7 @@ Known values: Python 3.15a1 3654 (Fix missing exception handlers in logical expression) Python 3.15a1 3655 (Fix miscompilation of some module-level annotations) Python 3.15a1 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter) + Python 3.15a3 3657 (Add MATCH_CLASS_ISINSTANCE & MATCH_CLASS_GET_OPT_ATTR) Python 3.16 will start with 3700 @@ -300,7 +301,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3656 +#define PYC_MAGIC_NUMBER 3657 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes (little-endian) and then appending b'\r\n'. */ #define PYC_MAGIC_NUMBER_TOKEN \ diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 92423fe51408fc..a2c14d58090dad 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -380,6 +380,10 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 3 + (oparg - 1); case MATCH_CLASS: return 3; + case MATCH_CLASS_GET_OPT_ATTR: + return 1; + case MATCH_CLASS_ISINSTANCE: + return 2; case MATCH_KEYS: return 2; case MATCH_MAPPING: @@ -865,6 +869,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1 + (oparg - 1); case MATCH_CLASS: return 1; + case MATCH_CLASS_GET_OPT_ATTR: + return 3; + case MATCH_CLASS_ISINSTANCE: + return 2; case MATCH_KEYS: return 3; case MATCH_MAPPING: @@ -1244,6 +1252,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [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 }, [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MATCH_CLASS_GET_OPT_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MATCH_CLASS_ISINSTANCE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MATCH_KEYS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 }, [MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 }, @@ -1459,6 +1469,8 @@ _PyOpcode_macro_expansion[256] = { [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, OPARG_SIMPLE, 0 } } }, [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, OPARG_SIMPLE, 0 } } }, [MATCH_CLASS] = { .nuops = 1, .uops = { { _MATCH_CLASS, OPARG_SIMPLE, 0 } } }, + [MATCH_CLASS_GET_OPT_ATTR] = { .nuops = 1, .uops = { { _MATCH_CLASS_GET_OPT_ATTR, OPARG_SIMPLE, 0 } } }, + [MATCH_CLASS_ISINSTANCE] = { .nuops = 1, .uops = { { _MATCH_CLASS_ISINSTANCE, OPARG_SIMPLE, 0 } } }, [MATCH_KEYS] = { .nuops = 1, .uops = { { _MATCH_KEYS, OPARG_SIMPLE, 0 } } }, [MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, OPARG_SIMPLE, 0 } } }, [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, OPARG_SIMPLE, 0 } } }, @@ -1691,6 +1703,8 @@ const char *_PyOpcode_OpName[267] = { [MAKE_FUNCTION] = "MAKE_FUNCTION", [MAP_ADD] = "MAP_ADD", [MATCH_CLASS] = "MATCH_CLASS", + [MATCH_CLASS_GET_OPT_ATTR] = "MATCH_CLASS_GET_OPT_ATTR", + [MATCH_CLASS_ISINSTANCE] = "MATCH_CLASS_ISINSTANCE", [MATCH_KEYS] = "MATCH_KEYS", [MATCH_MAPPING] = "MATCH_MAPPING", [MATCH_SEQUENCE] = "MATCH_SEQUENCE", @@ -1787,8 +1801,6 @@ const uint8_t _PyOpcode_Caches[256] = { extern const uint8_t _PyOpcode_Deopt[256]; #ifdef NEED_OPCODE_METADATA const uint8_t _PyOpcode_Deopt[256] = { - [121] = 121, - [122] = 122, [123] = 123, [124] = 124, [125] = 125, @@ -1983,6 +1995,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [MAKE_FUNCTION] = MAKE_FUNCTION, [MAP_ADD] = MAP_ADD, [MATCH_CLASS] = MATCH_CLASS, + [MATCH_CLASS_GET_OPT_ATTR] = MATCH_CLASS_GET_OPT_ATTR, + [MATCH_CLASS_ISINSTANCE] = MATCH_CLASS_ISINSTANCE, [MATCH_KEYS] = MATCH_KEYS, [MATCH_MAPPING] = MATCH_MAPPING, [MATCH_SEQUENCE] = MATCH_SEQUENCE, @@ -2048,8 +2062,6 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_METADATA #define EXTRA_CASES \ - case 121: \ - case 122: \ case 123: \ case 124: \ case 125: \ diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index a11959fb4057df..8d642182817674 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -267,6 +267,8 @@ extern "C" { #define _MAKE_WARM 492 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS +#define _MATCH_CLASS_GET_OPT_ATTR MATCH_CLASS_GET_OPT_ATTR +#define _MATCH_CLASS_ISINSTANCE MATCH_CLASS_ISINSTANCE #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE @@ -929,180 +931,182 @@ extern "C" { #define _MAKE_WARM_r33 1122 #define _MAP_ADD_r20 1123 #define _MATCH_CLASS_r31 1124 -#define _MATCH_KEYS_r23 1125 -#define _MATCH_MAPPING_r02 1126 -#define _MATCH_MAPPING_r12 1127 -#define _MATCH_MAPPING_r23 1128 -#define _MATCH_SEQUENCE_r02 1129 -#define _MATCH_SEQUENCE_r12 1130 -#define _MATCH_SEQUENCE_r23 1131 -#define _MAYBE_EXPAND_METHOD_r00 1132 -#define _MAYBE_EXPAND_METHOD_KW_r11 1133 -#define _MONITOR_CALL_r00 1134 -#define _MONITOR_CALL_KW_r11 1135 -#define _MONITOR_JUMP_BACKWARD_r00 1136 -#define _MONITOR_JUMP_BACKWARD_r11 1137 -#define _MONITOR_JUMP_BACKWARD_r22 1138 -#define _MONITOR_JUMP_BACKWARD_r33 1139 -#define _MONITOR_RESUME_r00 1140 -#define _NOP_r00 1141 -#define _NOP_r11 1142 -#define _NOP_r22 1143 -#define _NOP_r33 1144 -#define _POP_CALL_r20 1145 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1146 -#define _POP_CALL_ONE_r30 1147 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1148 -#define _POP_CALL_TWO_r30 1149 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1150 -#define _POP_EXCEPT_r10 1151 -#define _POP_ITER_r20 1152 -#define _POP_JUMP_IF_FALSE_r00 1153 -#define _POP_JUMP_IF_FALSE_r10 1154 -#define _POP_JUMP_IF_FALSE_r21 1155 -#define _POP_JUMP_IF_FALSE_r32 1156 -#define _POP_JUMP_IF_TRUE_r00 1157 -#define _POP_JUMP_IF_TRUE_r10 1158 -#define _POP_JUMP_IF_TRUE_r21 1159 -#define _POP_JUMP_IF_TRUE_r32 1160 -#define _POP_TOP_r10 1161 -#define _POP_TOP_FLOAT_r00 1162 -#define _POP_TOP_FLOAT_r10 1163 -#define _POP_TOP_FLOAT_r21 1164 -#define _POP_TOP_FLOAT_r32 1165 -#define _POP_TOP_INT_r00 1166 -#define _POP_TOP_INT_r10 1167 -#define _POP_TOP_INT_r21 1168 -#define _POP_TOP_INT_r32 1169 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1170 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1171 -#define _POP_TOP_NOP_r00 1172 -#define _POP_TOP_NOP_r10 1173 -#define _POP_TOP_NOP_r21 1174 -#define _POP_TOP_NOP_r32 1175 -#define _POP_TOP_UNICODE_r00 1176 -#define _POP_TOP_UNICODE_r10 1177 -#define _POP_TOP_UNICODE_r21 1178 -#define _POP_TOP_UNICODE_r32 1179 -#define _POP_TWO_r20 1180 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1181 -#define _PUSH_EXC_INFO_r02 1182 -#define _PUSH_EXC_INFO_r12 1183 -#define _PUSH_EXC_INFO_r23 1184 -#define _PUSH_FRAME_r10 1185 -#define _PUSH_NULL_r01 1186 -#define _PUSH_NULL_r12 1187 -#define _PUSH_NULL_r23 1188 -#define _PUSH_NULL_CONDITIONAL_r00 1189 -#define _PY_FRAME_GENERAL_r01 1190 -#define _PY_FRAME_KW_r11 1191 -#define _QUICKEN_RESUME_r00 1192 -#define _QUICKEN_RESUME_r11 1193 -#define _QUICKEN_RESUME_r22 1194 -#define _QUICKEN_RESUME_r33 1195 -#define _REPLACE_WITH_TRUE_r11 1196 -#define _RESUME_CHECK_r00 1197 -#define _RESUME_CHECK_r11 1198 -#define _RESUME_CHECK_r22 1199 -#define _RESUME_CHECK_r33 1200 -#define _RETURN_GENERATOR_r01 1201 -#define _RETURN_VALUE_r11 1202 -#define _SAVE_RETURN_OFFSET_r00 1203 -#define _SAVE_RETURN_OFFSET_r11 1204 -#define _SAVE_RETURN_OFFSET_r22 1205 -#define _SAVE_RETURN_OFFSET_r33 1206 -#define _SEND_r22 1207 -#define _SEND_GEN_FRAME_r22 1208 -#define _SETUP_ANNOTATIONS_r00 1209 -#define _SET_ADD_r10 1210 -#define _SET_FUNCTION_ATTRIBUTE_r01 1211 -#define _SET_FUNCTION_ATTRIBUTE_r11 1212 -#define _SET_FUNCTION_ATTRIBUTE_r21 1213 -#define _SET_FUNCTION_ATTRIBUTE_r32 1214 -#define _SET_IP_r00 1215 -#define _SET_IP_r11 1216 -#define _SET_IP_r22 1217 -#define _SET_IP_r33 1218 -#define _SET_UPDATE_r10 1219 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1220 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1221 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1222 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1223 -#define _SPILL_OR_RELOAD_r01 1224 -#define _SPILL_OR_RELOAD_r02 1225 -#define _SPILL_OR_RELOAD_r03 1226 -#define _SPILL_OR_RELOAD_r10 1227 -#define _SPILL_OR_RELOAD_r12 1228 -#define _SPILL_OR_RELOAD_r13 1229 -#define _SPILL_OR_RELOAD_r20 1230 -#define _SPILL_OR_RELOAD_r21 1231 -#define _SPILL_OR_RELOAD_r23 1232 -#define _SPILL_OR_RELOAD_r30 1233 -#define _SPILL_OR_RELOAD_r31 1234 -#define _SPILL_OR_RELOAD_r32 1235 -#define _START_EXECUTOR_r00 1236 -#define _STORE_ATTR_r20 1237 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1238 -#define _STORE_ATTR_SLOT_r21 1239 -#define _STORE_ATTR_WITH_HINT_r21 1240 -#define _STORE_DEREF_r10 1241 -#define _STORE_FAST_r10 1242 -#define _STORE_FAST_0_r10 1243 -#define _STORE_FAST_1_r10 1244 -#define _STORE_FAST_2_r10 1245 -#define _STORE_FAST_3_r10 1246 -#define _STORE_FAST_4_r10 1247 -#define _STORE_FAST_5_r10 1248 -#define _STORE_FAST_6_r10 1249 -#define _STORE_FAST_7_r10 1250 -#define _STORE_FAST_LOAD_FAST_r11 1251 -#define _STORE_FAST_STORE_FAST_r20 1252 -#define _STORE_GLOBAL_r10 1253 -#define _STORE_NAME_r10 1254 -#define _STORE_SLICE_r30 1255 -#define _STORE_SUBSCR_r30 1256 -#define _STORE_SUBSCR_DICT_r31 1257 -#define _STORE_SUBSCR_LIST_INT_r32 1258 -#define _SWAP_r11 1259 -#define _SWAP_2_r02 1260 -#define _SWAP_2_r12 1261 -#define _SWAP_2_r22 1262 -#define _SWAP_2_r33 1263 -#define _SWAP_3_r03 1264 -#define _SWAP_3_r13 1265 -#define _SWAP_3_r23 1266 -#define _SWAP_3_r33 1267 -#define _TIER2_RESUME_CHECK_r00 1268 -#define _TIER2_RESUME_CHECK_r11 1269 -#define _TIER2_RESUME_CHECK_r22 1270 -#define _TIER2_RESUME_CHECK_r33 1271 -#define _TO_BOOL_r11 1272 -#define _TO_BOOL_BOOL_r01 1273 -#define _TO_BOOL_BOOL_r11 1274 -#define _TO_BOOL_BOOL_r22 1275 -#define _TO_BOOL_BOOL_r33 1276 -#define _TO_BOOL_INT_r11 1277 -#define _TO_BOOL_LIST_r11 1278 -#define _TO_BOOL_NONE_r01 1279 -#define _TO_BOOL_NONE_r11 1280 -#define _TO_BOOL_NONE_r22 1281 -#define _TO_BOOL_NONE_r33 1282 -#define _TO_BOOL_STR_r11 1283 -#define _TRACE_RECORD_r00 1284 -#define _UNARY_INVERT_r11 1285 -#define _UNARY_NEGATIVE_r11 1286 -#define _UNARY_NOT_r01 1287 -#define _UNARY_NOT_r11 1288 -#define _UNARY_NOT_r22 1289 -#define _UNARY_NOT_r33 1290 -#define _UNPACK_EX_r10 1291 -#define _UNPACK_SEQUENCE_r10 1292 -#define _UNPACK_SEQUENCE_LIST_r10 1293 -#define _UNPACK_SEQUENCE_TUPLE_r10 1294 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1295 -#define _WITH_EXCEPT_START_r33 1296 -#define _YIELD_VALUE_r11 1297 -#define MAX_UOP_REGS_ID 1297 +#define _MATCH_CLASS_GET_OPT_ATTR_r13 1125 +#define _MATCH_CLASS_ISINSTANCE_r22 1126 +#define _MATCH_KEYS_r23 1127 +#define _MATCH_MAPPING_r02 1128 +#define _MATCH_MAPPING_r12 1129 +#define _MATCH_MAPPING_r23 1130 +#define _MATCH_SEQUENCE_r02 1131 +#define _MATCH_SEQUENCE_r12 1132 +#define _MATCH_SEQUENCE_r23 1133 +#define _MAYBE_EXPAND_METHOD_r00 1134 +#define _MAYBE_EXPAND_METHOD_KW_r11 1135 +#define _MONITOR_CALL_r00 1136 +#define _MONITOR_CALL_KW_r11 1137 +#define _MONITOR_JUMP_BACKWARD_r00 1138 +#define _MONITOR_JUMP_BACKWARD_r11 1139 +#define _MONITOR_JUMP_BACKWARD_r22 1140 +#define _MONITOR_JUMP_BACKWARD_r33 1141 +#define _MONITOR_RESUME_r00 1142 +#define _NOP_r00 1143 +#define _NOP_r11 1144 +#define _NOP_r22 1145 +#define _NOP_r33 1146 +#define _POP_CALL_r20 1147 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1148 +#define _POP_CALL_ONE_r30 1149 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1150 +#define _POP_CALL_TWO_r30 1151 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1152 +#define _POP_EXCEPT_r10 1153 +#define _POP_ITER_r20 1154 +#define _POP_JUMP_IF_FALSE_r00 1155 +#define _POP_JUMP_IF_FALSE_r10 1156 +#define _POP_JUMP_IF_FALSE_r21 1157 +#define _POP_JUMP_IF_FALSE_r32 1158 +#define _POP_JUMP_IF_TRUE_r00 1159 +#define _POP_JUMP_IF_TRUE_r10 1160 +#define _POP_JUMP_IF_TRUE_r21 1161 +#define _POP_JUMP_IF_TRUE_r32 1162 +#define _POP_TOP_r10 1163 +#define _POP_TOP_FLOAT_r00 1164 +#define _POP_TOP_FLOAT_r10 1165 +#define _POP_TOP_FLOAT_r21 1166 +#define _POP_TOP_FLOAT_r32 1167 +#define _POP_TOP_INT_r00 1168 +#define _POP_TOP_INT_r10 1169 +#define _POP_TOP_INT_r21 1170 +#define _POP_TOP_INT_r32 1171 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1172 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1173 +#define _POP_TOP_NOP_r00 1174 +#define _POP_TOP_NOP_r10 1175 +#define _POP_TOP_NOP_r21 1176 +#define _POP_TOP_NOP_r32 1177 +#define _POP_TOP_UNICODE_r00 1178 +#define _POP_TOP_UNICODE_r10 1179 +#define _POP_TOP_UNICODE_r21 1180 +#define _POP_TOP_UNICODE_r32 1181 +#define _POP_TWO_r20 1182 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1183 +#define _PUSH_EXC_INFO_r02 1184 +#define _PUSH_EXC_INFO_r12 1185 +#define _PUSH_EXC_INFO_r23 1186 +#define _PUSH_FRAME_r10 1187 +#define _PUSH_NULL_r01 1188 +#define _PUSH_NULL_r12 1189 +#define _PUSH_NULL_r23 1190 +#define _PUSH_NULL_CONDITIONAL_r00 1191 +#define _PY_FRAME_GENERAL_r01 1192 +#define _PY_FRAME_KW_r11 1193 +#define _QUICKEN_RESUME_r00 1194 +#define _QUICKEN_RESUME_r11 1195 +#define _QUICKEN_RESUME_r22 1196 +#define _QUICKEN_RESUME_r33 1197 +#define _REPLACE_WITH_TRUE_r11 1198 +#define _RESUME_CHECK_r00 1199 +#define _RESUME_CHECK_r11 1200 +#define _RESUME_CHECK_r22 1201 +#define _RESUME_CHECK_r33 1202 +#define _RETURN_GENERATOR_r01 1203 +#define _RETURN_VALUE_r11 1204 +#define _SAVE_RETURN_OFFSET_r00 1205 +#define _SAVE_RETURN_OFFSET_r11 1206 +#define _SAVE_RETURN_OFFSET_r22 1207 +#define _SAVE_RETURN_OFFSET_r33 1208 +#define _SEND_r22 1209 +#define _SEND_GEN_FRAME_r22 1210 +#define _SETUP_ANNOTATIONS_r00 1211 +#define _SET_ADD_r10 1212 +#define _SET_FUNCTION_ATTRIBUTE_r01 1213 +#define _SET_FUNCTION_ATTRIBUTE_r11 1214 +#define _SET_FUNCTION_ATTRIBUTE_r21 1215 +#define _SET_FUNCTION_ATTRIBUTE_r32 1216 +#define _SET_IP_r00 1217 +#define _SET_IP_r11 1218 +#define _SET_IP_r22 1219 +#define _SET_IP_r33 1220 +#define _SET_UPDATE_r10 1221 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1222 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1223 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1224 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1225 +#define _SPILL_OR_RELOAD_r01 1226 +#define _SPILL_OR_RELOAD_r02 1227 +#define _SPILL_OR_RELOAD_r03 1228 +#define _SPILL_OR_RELOAD_r10 1229 +#define _SPILL_OR_RELOAD_r12 1230 +#define _SPILL_OR_RELOAD_r13 1231 +#define _SPILL_OR_RELOAD_r20 1232 +#define _SPILL_OR_RELOAD_r21 1233 +#define _SPILL_OR_RELOAD_r23 1234 +#define _SPILL_OR_RELOAD_r30 1235 +#define _SPILL_OR_RELOAD_r31 1236 +#define _SPILL_OR_RELOAD_r32 1237 +#define _START_EXECUTOR_r00 1238 +#define _STORE_ATTR_r20 1239 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1240 +#define _STORE_ATTR_SLOT_r21 1241 +#define _STORE_ATTR_WITH_HINT_r21 1242 +#define _STORE_DEREF_r10 1243 +#define _STORE_FAST_r10 1244 +#define _STORE_FAST_0_r10 1245 +#define _STORE_FAST_1_r10 1246 +#define _STORE_FAST_2_r10 1247 +#define _STORE_FAST_3_r10 1248 +#define _STORE_FAST_4_r10 1249 +#define _STORE_FAST_5_r10 1250 +#define _STORE_FAST_6_r10 1251 +#define _STORE_FAST_7_r10 1252 +#define _STORE_FAST_LOAD_FAST_r11 1253 +#define _STORE_FAST_STORE_FAST_r20 1254 +#define _STORE_GLOBAL_r10 1255 +#define _STORE_NAME_r10 1256 +#define _STORE_SLICE_r30 1257 +#define _STORE_SUBSCR_r30 1258 +#define _STORE_SUBSCR_DICT_r31 1259 +#define _STORE_SUBSCR_LIST_INT_r32 1260 +#define _SWAP_r11 1261 +#define _SWAP_2_r02 1262 +#define _SWAP_2_r12 1263 +#define _SWAP_2_r22 1264 +#define _SWAP_2_r33 1265 +#define _SWAP_3_r03 1266 +#define _SWAP_3_r13 1267 +#define _SWAP_3_r23 1268 +#define _SWAP_3_r33 1269 +#define _TIER2_RESUME_CHECK_r00 1270 +#define _TIER2_RESUME_CHECK_r11 1271 +#define _TIER2_RESUME_CHECK_r22 1272 +#define _TIER2_RESUME_CHECK_r33 1273 +#define _TO_BOOL_r11 1274 +#define _TO_BOOL_BOOL_r01 1275 +#define _TO_BOOL_BOOL_r11 1276 +#define _TO_BOOL_BOOL_r22 1277 +#define _TO_BOOL_BOOL_r33 1278 +#define _TO_BOOL_INT_r11 1279 +#define _TO_BOOL_LIST_r11 1280 +#define _TO_BOOL_NONE_r01 1281 +#define _TO_BOOL_NONE_r11 1282 +#define _TO_BOOL_NONE_r22 1283 +#define _TO_BOOL_NONE_r33 1284 +#define _TO_BOOL_STR_r11 1285 +#define _TRACE_RECORD_r00 1286 +#define _UNARY_INVERT_r11 1287 +#define _UNARY_NEGATIVE_r11 1288 +#define _UNARY_NOT_r01 1289 +#define _UNARY_NOT_r11 1290 +#define _UNARY_NOT_r22 1291 +#define _UNARY_NOT_r33 1292 +#define _UNPACK_EX_r10 1293 +#define _UNPACK_SEQUENCE_r10 1294 +#define _UNPACK_SEQUENCE_LIST_r10 1295 +#define _UNPACK_SEQUENCE_TUPLE_r10 1296 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1297 +#define _WITH_EXCEPT_START_r33 1298 +#define _YIELD_VALUE_r11 1299 +#define MAX_UOP_REGS_ID 1299 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index ec374dd5818432..56c241dec78dd8 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -215,6 +215,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_IMPORT_FROM] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_IS_NONE] = HAS_ESCAPES_FLAG, [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_MATCH_CLASS_ISINSTANCE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_MATCH_CLASS_GET_OPT_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MATCH_MAPPING] = 0, [_MATCH_SEQUENCE] = 0, @@ -1986,6 +1988,24 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, }, }, + [_MATCH_CLASS_ISINSTANCE] = { + .best = { 2, 2, 2, 2 }, + .entries = { + { -1, -1, -1 }, + { -1, -1, -1 }, + { 2, 2, _MATCH_CLASS_ISINSTANCE_r22 }, + { -1, -1, -1 }, + }, + }, + [_MATCH_CLASS_GET_OPT_ATTR] = { + .best = { 1, 1, 1, 1 }, + .entries = { + { -1, -1, -1 }, + { 3, 1, _MATCH_CLASS_GET_OPT_ATTR_r13 }, + { -1, -1, -1 }, + { -1, -1, -1 }, + }, + }, [_MATCH_CLASS] = { .best = { 3, 3, 3, 3 }, .entries = { @@ -3578,6 +3598,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_IMPORT_FROM_r12] = _IMPORT_FROM, [_IS_NONE_r11] = _IS_NONE, [_GET_LEN_r12] = _GET_LEN, + [_MATCH_CLASS_ISINSTANCE_r22] = _MATCH_CLASS_ISINSTANCE, + [_MATCH_CLASS_GET_OPT_ATTR_r13] = _MATCH_CLASS_GET_OPT_ATTR, [_MATCH_CLASS_r31] = _MATCH_CLASS, [_MATCH_MAPPING_r02] = _MATCH_MAPPING, [_MATCH_MAPPING_r12] = _MATCH_MAPPING, @@ -4665,6 +4687,10 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_MAP_ADD_r20] = "_MAP_ADD_r20", [_MATCH_CLASS] = "_MATCH_CLASS", [_MATCH_CLASS_r31] = "_MATCH_CLASS_r31", + [_MATCH_CLASS_GET_OPT_ATTR] = "_MATCH_CLASS_GET_OPT_ATTR", + [_MATCH_CLASS_GET_OPT_ATTR_r13] = "_MATCH_CLASS_GET_OPT_ATTR_r13", + [_MATCH_CLASS_ISINSTANCE] = "_MATCH_CLASS_ISINSTANCE", + [_MATCH_CLASS_ISINSTANCE_r22] = "_MATCH_CLASS_ISINSTANCE_r22", [_MATCH_KEYS] = "_MATCH_KEYS", [_MATCH_KEYS_r23] = "_MATCH_KEYS_r23", [_MATCH_MAPPING] = "_MATCH_MAPPING", @@ -5262,6 +5288,10 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _GET_LEN: return 0; + case _MATCH_CLASS_ISINSTANCE: + return 1; + case _MATCH_CLASS_GET_OPT_ATTR: + return 0; case _MATCH_CLASS: return 3; case _MATCH_MAPPING: diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 0d066c169019a7..db143723aa7de5 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -34,103 +34,105 @@ extern "C" { #define LOAD_BUILD_CLASS 21 #define LOAD_LOCALS 22 #define MAKE_FUNCTION 23 -#define MATCH_KEYS 24 -#define MATCH_MAPPING 25 -#define MATCH_SEQUENCE 26 -#define NOP 27 -#define NOT_TAKEN 28 -#define POP_EXCEPT 29 -#define POP_ITER 30 -#define POP_TOP 31 -#define PUSH_EXC_INFO 32 -#define PUSH_NULL 33 -#define RETURN_GENERATOR 34 -#define RETURN_VALUE 35 -#define SETUP_ANNOTATIONS 36 -#define STORE_SLICE 37 -#define STORE_SUBSCR 38 -#define TO_BOOL 39 -#define UNARY_INVERT 40 -#define UNARY_NEGATIVE 41 -#define UNARY_NOT 42 -#define WITH_EXCEPT_START 43 -#define BINARY_OP 44 -#define BUILD_INTERPOLATION 45 -#define BUILD_LIST 46 -#define BUILD_MAP 47 -#define BUILD_SET 48 -#define BUILD_SLICE 49 -#define BUILD_STRING 50 -#define BUILD_TUPLE 51 -#define CALL 52 -#define CALL_INTRINSIC_1 53 -#define CALL_INTRINSIC_2 54 -#define CALL_KW 55 -#define COMPARE_OP 56 -#define CONTAINS_OP 57 -#define CONVERT_VALUE 58 -#define COPY 59 -#define COPY_FREE_VARS 60 -#define DELETE_ATTR 61 -#define DELETE_DEREF 62 -#define DELETE_FAST 63 -#define DELETE_GLOBAL 64 -#define DELETE_NAME 65 -#define DICT_MERGE 66 -#define DICT_UPDATE 67 -#define END_ASYNC_FOR 68 -#define EXTENDED_ARG 69 -#define FOR_ITER 70 -#define GET_AWAITABLE 71 -#define IMPORT_FROM 72 -#define IMPORT_NAME 73 -#define IS_OP 74 -#define JUMP_BACKWARD 75 -#define JUMP_BACKWARD_NO_INTERRUPT 76 -#define JUMP_FORWARD 77 -#define LIST_APPEND 78 -#define LIST_EXTEND 79 -#define LOAD_ATTR 80 -#define LOAD_COMMON_CONSTANT 81 -#define LOAD_CONST 82 -#define LOAD_DEREF 83 -#define LOAD_FAST 84 -#define LOAD_FAST_AND_CLEAR 85 -#define LOAD_FAST_BORROW 86 -#define LOAD_FAST_BORROW_LOAD_FAST_BORROW 87 -#define LOAD_FAST_CHECK 88 -#define LOAD_FAST_LOAD_FAST 89 -#define LOAD_FROM_DICT_OR_DEREF 90 -#define LOAD_FROM_DICT_OR_GLOBALS 91 -#define LOAD_GLOBAL 92 -#define LOAD_NAME 93 -#define LOAD_SMALL_INT 94 -#define LOAD_SPECIAL 95 -#define LOAD_SUPER_ATTR 96 -#define MAKE_CELL 97 -#define MAP_ADD 98 -#define MATCH_CLASS 99 -#define POP_JUMP_IF_FALSE 100 -#define POP_JUMP_IF_NONE 101 -#define POP_JUMP_IF_NOT_NONE 102 -#define POP_JUMP_IF_TRUE 103 -#define RAISE_VARARGS 104 -#define RERAISE 105 -#define SEND 106 -#define SET_ADD 107 -#define SET_FUNCTION_ATTRIBUTE 108 -#define SET_UPDATE 109 -#define STORE_ATTR 110 -#define STORE_DEREF 111 -#define STORE_FAST 112 -#define STORE_FAST_LOAD_FAST 113 -#define STORE_FAST_STORE_FAST 114 -#define STORE_GLOBAL 115 -#define STORE_NAME 116 -#define SWAP 117 -#define UNPACK_EX 118 -#define UNPACK_SEQUENCE 119 -#define YIELD_VALUE 120 +#define MATCH_CLASS_ISINSTANCE 24 +#define MATCH_KEYS 25 +#define MATCH_MAPPING 26 +#define MATCH_SEQUENCE 27 +#define NOP 28 +#define NOT_TAKEN 29 +#define POP_EXCEPT 30 +#define POP_ITER 31 +#define POP_TOP 32 +#define PUSH_EXC_INFO 33 +#define PUSH_NULL 34 +#define RETURN_GENERATOR 35 +#define RETURN_VALUE 36 +#define SETUP_ANNOTATIONS 37 +#define STORE_SLICE 38 +#define STORE_SUBSCR 39 +#define TO_BOOL 40 +#define UNARY_INVERT 41 +#define UNARY_NEGATIVE 42 +#define UNARY_NOT 43 +#define WITH_EXCEPT_START 44 +#define BINARY_OP 45 +#define BUILD_INTERPOLATION 46 +#define BUILD_LIST 47 +#define BUILD_MAP 48 +#define BUILD_SET 49 +#define BUILD_SLICE 50 +#define BUILD_STRING 51 +#define BUILD_TUPLE 52 +#define CALL 53 +#define CALL_INTRINSIC_1 54 +#define CALL_INTRINSIC_2 55 +#define CALL_KW 56 +#define COMPARE_OP 57 +#define CONTAINS_OP 58 +#define CONVERT_VALUE 59 +#define COPY 60 +#define COPY_FREE_VARS 61 +#define DELETE_ATTR 62 +#define DELETE_DEREF 63 +#define DELETE_FAST 64 +#define DELETE_GLOBAL 65 +#define DELETE_NAME 66 +#define DICT_MERGE 67 +#define DICT_UPDATE 68 +#define END_ASYNC_FOR 69 +#define EXTENDED_ARG 70 +#define FOR_ITER 71 +#define GET_AWAITABLE 72 +#define IMPORT_FROM 73 +#define IMPORT_NAME 74 +#define IS_OP 75 +#define JUMP_BACKWARD 76 +#define JUMP_BACKWARD_NO_INTERRUPT 77 +#define JUMP_FORWARD 78 +#define LIST_APPEND 79 +#define LIST_EXTEND 80 +#define LOAD_ATTR 81 +#define LOAD_COMMON_CONSTANT 82 +#define LOAD_CONST 83 +#define LOAD_DEREF 84 +#define LOAD_FAST 85 +#define LOAD_FAST_AND_CLEAR 86 +#define LOAD_FAST_BORROW 87 +#define LOAD_FAST_BORROW_LOAD_FAST_BORROW 88 +#define LOAD_FAST_CHECK 89 +#define LOAD_FAST_LOAD_FAST 90 +#define LOAD_FROM_DICT_OR_DEREF 91 +#define LOAD_FROM_DICT_OR_GLOBALS 92 +#define LOAD_GLOBAL 93 +#define LOAD_NAME 94 +#define LOAD_SMALL_INT 95 +#define LOAD_SPECIAL 96 +#define LOAD_SUPER_ATTR 97 +#define MAKE_CELL 98 +#define MAP_ADD 99 +#define MATCH_CLASS 100 +#define MATCH_CLASS_GET_OPT_ATTR 101 +#define POP_JUMP_IF_FALSE 102 +#define POP_JUMP_IF_NONE 103 +#define POP_JUMP_IF_NOT_NONE 104 +#define POP_JUMP_IF_TRUE 105 +#define RAISE_VARARGS 106 +#define RERAISE 107 +#define SEND 108 +#define SET_ADD 109 +#define SET_FUNCTION_ATTRIBUTE 110 +#define SET_UPDATE 111 +#define STORE_ATTR 112 +#define STORE_DEREF 113 +#define STORE_FAST 114 +#define STORE_FAST_LOAD_FAST 115 +#define STORE_FAST_STORE_FAST 116 +#define STORE_GLOBAL 117 +#define STORE_NAME 118 +#define SWAP 119 +#define UNPACK_EX 120 +#define UNPACK_SEQUENCE 121 +#define YIELD_VALUE 122 #define RESUME 128 #define BINARY_OP_ADD_FLOAT 129 #define BINARY_OP_ADD_INT 130 @@ -248,7 +250,7 @@ extern "C" { #define SETUP_WITH 265 #define STORE_FAST_MAYBE_NULL 266 -#define HAVE_ARGUMENT 43 +#define HAVE_ARGUMENT 44 #define MIN_SPECIALIZED_OPCODE 129 #define MIN_INSTRUMENTED_OPCODE 233 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index e681cb17e43e04..0dbd4ed478f5c3 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -232,103 +232,105 @@ 'LOAD_BUILD_CLASS': 21, 'LOAD_LOCALS': 22, 'MAKE_FUNCTION': 23, - 'MATCH_KEYS': 24, - 'MATCH_MAPPING': 25, - 'MATCH_SEQUENCE': 26, - 'NOP': 27, - 'NOT_TAKEN': 28, - 'POP_EXCEPT': 29, - 'POP_ITER': 30, - 'POP_TOP': 31, - 'PUSH_EXC_INFO': 32, - 'PUSH_NULL': 33, - 'RETURN_GENERATOR': 34, - 'RETURN_VALUE': 35, - 'SETUP_ANNOTATIONS': 36, - 'STORE_SLICE': 37, - 'STORE_SUBSCR': 38, - 'TO_BOOL': 39, - 'UNARY_INVERT': 40, - 'UNARY_NEGATIVE': 41, - 'UNARY_NOT': 42, - 'WITH_EXCEPT_START': 43, - 'BINARY_OP': 44, - 'BUILD_INTERPOLATION': 45, - 'BUILD_LIST': 46, - 'BUILD_MAP': 47, - 'BUILD_SET': 48, - 'BUILD_SLICE': 49, - 'BUILD_STRING': 50, - 'BUILD_TUPLE': 51, - 'CALL': 52, - 'CALL_INTRINSIC_1': 53, - 'CALL_INTRINSIC_2': 54, - 'CALL_KW': 55, - 'COMPARE_OP': 56, - 'CONTAINS_OP': 57, - 'CONVERT_VALUE': 58, - 'COPY': 59, - 'COPY_FREE_VARS': 60, - 'DELETE_ATTR': 61, - 'DELETE_DEREF': 62, - 'DELETE_FAST': 63, - 'DELETE_GLOBAL': 64, - 'DELETE_NAME': 65, - 'DICT_MERGE': 66, - 'DICT_UPDATE': 67, - 'END_ASYNC_FOR': 68, - 'EXTENDED_ARG': 69, - 'FOR_ITER': 70, - 'GET_AWAITABLE': 71, - 'IMPORT_FROM': 72, - 'IMPORT_NAME': 73, - 'IS_OP': 74, - 'JUMP_BACKWARD': 75, - 'JUMP_BACKWARD_NO_INTERRUPT': 76, - 'JUMP_FORWARD': 77, - 'LIST_APPEND': 78, - 'LIST_EXTEND': 79, - 'LOAD_ATTR': 80, - 'LOAD_COMMON_CONSTANT': 81, - 'LOAD_CONST': 82, - 'LOAD_DEREF': 83, - 'LOAD_FAST': 84, - 'LOAD_FAST_AND_CLEAR': 85, - 'LOAD_FAST_BORROW': 86, - 'LOAD_FAST_BORROW_LOAD_FAST_BORROW': 87, - 'LOAD_FAST_CHECK': 88, - 'LOAD_FAST_LOAD_FAST': 89, - 'LOAD_FROM_DICT_OR_DEREF': 90, - 'LOAD_FROM_DICT_OR_GLOBALS': 91, - 'LOAD_GLOBAL': 92, - 'LOAD_NAME': 93, - 'LOAD_SMALL_INT': 94, - 'LOAD_SPECIAL': 95, - 'LOAD_SUPER_ATTR': 96, - 'MAKE_CELL': 97, - 'MAP_ADD': 98, - 'MATCH_CLASS': 99, - 'POP_JUMP_IF_FALSE': 100, - 'POP_JUMP_IF_NONE': 101, - 'POP_JUMP_IF_NOT_NONE': 102, - 'POP_JUMP_IF_TRUE': 103, - 'RAISE_VARARGS': 104, - 'RERAISE': 105, - 'SEND': 106, - 'SET_ADD': 107, - 'SET_FUNCTION_ATTRIBUTE': 108, - 'SET_UPDATE': 109, - 'STORE_ATTR': 110, - 'STORE_DEREF': 111, - 'STORE_FAST': 112, - 'STORE_FAST_LOAD_FAST': 113, - 'STORE_FAST_STORE_FAST': 114, - 'STORE_GLOBAL': 115, - 'STORE_NAME': 116, - 'SWAP': 117, - 'UNPACK_EX': 118, - 'UNPACK_SEQUENCE': 119, - 'YIELD_VALUE': 120, + 'MATCH_CLASS_ISINSTANCE': 24, + 'MATCH_KEYS': 25, + 'MATCH_MAPPING': 26, + 'MATCH_SEQUENCE': 27, + 'NOP': 28, + 'NOT_TAKEN': 29, + 'POP_EXCEPT': 30, + 'POP_ITER': 31, + 'POP_TOP': 32, + 'PUSH_EXC_INFO': 33, + 'PUSH_NULL': 34, + 'RETURN_GENERATOR': 35, + 'RETURN_VALUE': 36, + 'SETUP_ANNOTATIONS': 37, + 'STORE_SLICE': 38, + 'STORE_SUBSCR': 39, + 'TO_BOOL': 40, + 'UNARY_INVERT': 41, + 'UNARY_NEGATIVE': 42, + 'UNARY_NOT': 43, + 'WITH_EXCEPT_START': 44, + 'BINARY_OP': 45, + 'BUILD_INTERPOLATION': 46, + 'BUILD_LIST': 47, + 'BUILD_MAP': 48, + 'BUILD_SET': 49, + 'BUILD_SLICE': 50, + 'BUILD_STRING': 51, + 'BUILD_TUPLE': 52, + 'CALL': 53, + 'CALL_INTRINSIC_1': 54, + 'CALL_INTRINSIC_2': 55, + 'CALL_KW': 56, + 'COMPARE_OP': 57, + 'CONTAINS_OP': 58, + 'CONVERT_VALUE': 59, + 'COPY': 60, + 'COPY_FREE_VARS': 61, + 'DELETE_ATTR': 62, + 'DELETE_DEREF': 63, + 'DELETE_FAST': 64, + 'DELETE_GLOBAL': 65, + 'DELETE_NAME': 66, + 'DICT_MERGE': 67, + 'DICT_UPDATE': 68, + 'END_ASYNC_FOR': 69, + 'EXTENDED_ARG': 70, + 'FOR_ITER': 71, + 'GET_AWAITABLE': 72, + 'IMPORT_FROM': 73, + 'IMPORT_NAME': 74, + 'IS_OP': 75, + 'JUMP_BACKWARD': 76, + 'JUMP_BACKWARD_NO_INTERRUPT': 77, + 'JUMP_FORWARD': 78, + 'LIST_APPEND': 79, + 'LIST_EXTEND': 80, + 'LOAD_ATTR': 81, + 'LOAD_COMMON_CONSTANT': 82, + 'LOAD_CONST': 83, + 'LOAD_DEREF': 84, + 'LOAD_FAST': 85, + 'LOAD_FAST_AND_CLEAR': 86, + 'LOAD_FAST_BORROW': 87, + 'LOAD_FAST_BORROW_LOAD_FAST_BORROW': 88, + 'LOAD_FAST_CHECK': 89, + 'LOAD_FAST_LOAD_FAST': 90, + 'LOAD_FROM_DICT_OR_DEREF': 91, + 'LOAD_FROM_DICT_OR_GLOBALS': 92, + 'LOAD_GLOBAL': 93, + 'LOAD_NAME': 94, + 'LOAD_SMALL_INT': 95, + 'LOAD_SPECIAL': 96, + 'LOAD_SUPER_ATTR': 97, + 'MAKE_CELL': 98, + 'MAP_ADD': 99, + 'MATCH_CLASS': 100, + 'MATCH_CLASS_GET_OPT_ATTR': 101, + 'POP_JUMP_IF_FALSE': 102, + 'POP_JUMP_IF_NONE': 103, + 'POP_JUMP_IF_NOT_NONE': 104, + 'POP_JUMP_IF_TRUE': 105, + 'RAISE_VARARGS': 106, + 'RERAISE': 107, + 'SEND': 108, + 'SET_ADD': 109, + 'SET_FUNCTION_ATTRIBUTE': 110, + 'SET_UPDATE': 111, + 'STORE_ATTR': 112, + 'STORE_DEREF': 113, + 'STORE_FAST': 114, + 'STORE_FAST_LOAD_FAST': 115, + 'STORE_FAST_STORE_FAST': 116, + 'STORE_GLOBAL': 117, + 'STORE_NAME': 118, + 'SWAP': 119, + 'UNPACK_EX': 120, + 'UNPACK_SEQUENCE': 121, + 'YIELD_VALUE': 122, 'INSTRUMENTED_END_FOR': 233, 'INSTRUMENTED_POP_ITER': 234, 'INSTRUMENTED_END_SEND': 235, @@ -362,5 +364,5 @@ 'STORE_FAST_MAYBE_NULL': 266, } -HAVE_ARGUMENT = 43 +HAVE_ARGUMENT = 44 MIN_INSTRUMENTED_OPCODE = 233 diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 3e7477487200d0..8a8329f29be0eb 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1011,7 +1011,8 @@ def test_widths(self): long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT', 'LOAD_FAST_BORROW_LOAD_FAST_BORROW', 'INSTRUMENTED_CALL_FUNCTION_EX', - 'ANNOTATIONS_PLACEHOLDER']) + 'ANNOTATIONS_PLACEHOLDER', + 'MATCH_CLASS_ISINSTANCE']) for op, opname in enumerate(dis.opname): if opname in long_opcodes or opname.startswith("INSTRUMENTED"): continue diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 1caf6de4a14e39..f98bfc4797f734 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -781,6 +781,14 @@ def test_static_swaps_match_mapping(self): self.assertNotInBytecode(code, "SWAP") def test_static_swaps_match_class(self): + swaps = { + "C(a=a, b=_, c=_)", + "C(a=a, b=_, c=c)", + "C(a=a, b=b, c=_)", + "C(a=a, b=b, c=c)", + "C(a=_, b=b, c=_)", + "C(a=_, b=b, c=c)", + } forms = [ "C({}, {}, {})", "C({}, {}, c={})", @@ -792,7 +800,12 @@ def test_static_swaps_match_class(self): pattern = form.format(a, b, c) with self.subTest(pattern): code = compile_pattern_with_fast_locals(pattern) - self.assertNotInBytecode(code, "SWAP") + if pattern in swaps: + # Swaps are expected here. Class patterns without + # positional sub-patterns are evaluated depth first. + self.assertInBytecode(code, "SWAP") + else: + self.assertNotInBytecode(code, "SWAP") def test_static_swaps_match_sequence(self): swaps = {"*_, b, c", "a, *_, c", "a, b, *_"} diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-22-12-38.gh-issue-138912.PijFSS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-22-12-38.gh-issue-138912.PijFSS.rst new file mode 100644 index 00000000000000..0fbc17a6e4b59f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-22-12-38.gh-issue-138912.PijFSS.rst @@ -0,0 +1,3 @@ +Add :opcode:`MATCH_CLASS_ISINSTANCE` and :opcode:`MATCH_CLASS_GET_OPT_ATTR` +to improve the performance of :keyword:`match` class patterns without any +positional sub-patterns by ~60%. Patch by Marc Mueller. diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index dbeedb7ffe0ce6..2f09817778cfb3 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,19 +1,19 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, - 0,0,0,0,0,243,184,0,0,0,128,0,94,0,82,1, - 73,0,116,0,94,0,82,1,73,1,116,1,93,2,33,0, - 82,2,52,1,0,0,0,0,0,0,31,0,93,2,33,0, - 82,3,93,0,80,6,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,52,2,0,0,0,0,0,0, - 31,0,93,1,80,8,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,33,0,52,0,0,0,0,0, - 0,0,82,4,44,26,0,0,0,0,0,0,0,0,0,0, - 116,5,82,7,16,0,70,24,0,0,116,6,93,2,33,0, - 82,5,93,6,12,0,82,6,93,5,93,6,44,26,0,0, - 0,0,0,0,0,0,0,0,12,0,50,4,52,1,0,0, - 0,0,0,0,31,0,75,26,0,0,9,0,30,0,82,1, - 35,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 0,0,0,0,0,243,184,0,0,0,128,0,95,0,83,1, + 74,0,118,0,95,0,83,1,74,1,118,1,94,2,34,0, + 83,2,53,1,0,0,0,0,0,0,32,0,94,2,34,0, + 83,3,94,0,81,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,53,2,0,0,0,0,0,0, + 32,0,94,1,81,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,34,0,53,0,0,0,0,0, + 0,0,83,4,45,26,0,0,0,0,0,0,0,0,0,0, + 118,5,83,7,16,0,71,24,0,0,118,6,94,2,34,0, + 83,5,94,6,12,0,83,6,94,5,94,6,45,26,0,0, + 0,0,0,0,0,0,0,0,12,0,51,4,53,1,0,0, + 0,0,0,0,32,0,76,26,0,0,9,0,31,0,83,1, + 36,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, 122,7,99,111,110,102,105,103,32,122,2,58,32,41,5,218, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index f7eb006e686800..fe37dd0e7f6818 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3068,6 +3068,39 @@ dummy_func( len = PyStackRef_FromPyObjectSteal(len_o); } + inst(MATCH_CLASS_ISINSTANCE, (subject, type -- subject, res)) { + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *type_o = PyStackRef_AsPyObjectBorrow(type); + if (!PyType_Check(type_o)) { + const char *e = "called match pattern must be a class"; + _PyErr_Format(tstate, PyExc_TypeError, e); + PyStackRef_CLOSE(type); + ERROR_IF(true); + } + int retval = PyObject_IsInstance(subject_o, type_o); + PyStackRef_CLOSE(type); + ERROR_IF(retval < 0); + assert(!_PyErr_Occurred(tstate)); + res = retval ? PyStackRef_True : PyStackRef_False; + } + + inst(MATCH_CLASS_GET_OPT_ATTR, (subject -- subject, attr, res)) { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + assert(PyUnicode_CheckExact(name)); + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *attr_o; + (void)PyObject_GetOptionalAttr(subject_o, name, &attr_o); + if (attr_o) { + assert(!_PyErr_Occurred(tstate)); // Success! + attr = PyStackRef_FromPyObjectSteal(attr_o); + res = PyStackRef_True; + } else { + ERROR_IF(_PyErr_Occurred(tstate)); // Error! + attr = PyStackRef_FromPyObjectSteal(Py_None); // No attribute found! + res = PyStackRef_False; + } + } + inst(MATCH_CLASS, (subject, type, names -- attrs)) { // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. diff --git a/Python/ceval.c b/Python/ceval.c index ec21d6bc2b852c..9cf7911a479457 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -865,6 +865,7 @@ PyObject* _PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs) { + assert(nargs > 0); if (!PyType_Check(type)) { const char *e = "called match pattern must be a class"; _PyErr_Format(tstate, PyExc_TypeError, e); diff --git a/Python/codegen.c b/Python/codegen.c index c4109fcaa48dbe..e9472f216c50a5 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -5887,6 +5887,64 @@ validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* pa return SUCCESS; } +static int +codegen_addop_name_match_class_attr(compiler *c, location loc, int opcode, + PyObject *name) +{ + // No name mangling for match attributes + Py_ssize_t arg = _PyCompile_DictAddObj(METADATA(c)->u_names, name); + if (arg < 0) { + return ERROR; + } + ADDOP_I(c, loc, opcode, arg); + return SUCCESS; +} + +static int +codegen_pattern_class_fast(compiler *c, pattern_ty p, pattern_context *pc) +{ + NEW_JUMP_TARGET_LABEL(c, end); + assert(p->kind == MatchClass_kind); + assert(!asdl_seq_LEN(p->v.MatchClass.patterns)); + asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs; + asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns; + Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs); + VISIT(c, expr, p->v.MatchClass.cls); + ADDOP(c, LOC(p), MATCH_CLASS_ISINSTANCE); + // TOS is now subject: + pc->on_top++; + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + if (!nattrs) { + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + } + + Py_ssize_t i; + identifier name; + pattern_ty pattern; + for (i = 0; i < nattrs; i++) { + name = asdl_seq_GET(kwd_attrs, i); + RETURN_IF_ERROR(codegen_addop_name_match_class_attr(c, LOC(p), + MATCH_CLASS_GET_OPT_ATTR, name)); + // TOS is now attribute: + pc->on_top++; + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + pc->on_top--; + + pattern = asdl_seq_GET(kwd_patterns, i); + if (WILDCARD_CHECK(pattern)) { + ADDOP(c, LOC(p), POP_TOP); + continue; + } + RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc)); + } + + USE_LABEL(c, end); + pc->on_top--; + // Success! POP subject: + ADDOP(c, LOC(p), POP_TOP); + return SUCCESS; +} + static int codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc) { @@ -5910,6 +5968,10 @@ codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc) if (nattrs) { RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); } + if (!nargs) { + // Fast path if there are no positional sub-patterns + return codegen_pattern_class_fast(c, p, pc); + } VISIT(c, expr, p->v.MatchClass.cls); PyObject *attr_names = PyTuple_New(nattrs); if (attr_names == NULL) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index b3eff63b30ab55..fb52cc0868e034 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -9621,6 +9621,104 @@ break; } + case _MATCH_CLASS_ISINSTANCE_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef type; + _PyStackRef subject; + _PyStackRef res; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + type = _stack_item_1; + subject = _stack_item_0; + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *type_o = PyStackRef_AsPyObjectBorrow(type); + if (!PyType_Check(type_o)) { + const char *e = "called match pattern must be a class"; + stack_pointer[0] = subject; + stack_pointer[1] = type; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyErr_Format(tstate, PyExc_TypeError, e); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(type); + stack_pointer = _PyFrame_GetStackPointer(frame); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); + } + stack_pointer[0] = subject; + stack_pointer[1] = type; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + int retval = PyObject_IsInstance(subject_o, type_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(type); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (retval < 0) { + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); + } + assert(!_PyErr_Occurred(tstate)); + res = retval ? PyStackRef_True : PyStackRef_False; + _tos_cache1 = res; + _tos_cache0 = subject; + _tos_cache2 = PyStackRef_ZERO_BITS; + SET_CURRENT_CACHED_VALUES(2); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _MATCH_CLASS_GET_OPT_ATTR_r13: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef subject; + _PyStackRef attr; + _PyStackRef res; + _PyStackRef _stack_item_0 = _tos_cache0; + oparg = CURRENT_OPARG(); + subject = _stack_item_0; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + assert(PyUnicode_CheckExact(name)); + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *attr_o; + stack_pointer[0] = subject; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)PyObject_GetOptionalAttr(subject_o, name, &attr_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (attr_o) { + assert(!_PyErr_Occurred(tstate)); + attr = PyStackRef_FromPyObjectSteal(attr_o); + res = PyStackRef_True; + } else { + if (_PyErr_Occurred(tstate)) { + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); + } + attr = PyStackRef_FromPyObjectSteal(Py_None); + res = PyStackRef_False; + } + _tos_cache2 = res; + _tos_cache1 = attr; + _tos_cache0 = subject; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _MATCH_CLASS_r31: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index eaaa5f3bb96abc..17eebb78bdbdab 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -9679,6 +9679,89 @@ DISPATCH(); } + TARGET(MATCH_CLASS_GET_OPT_ATTR) { + #if _Py_TAIL_CALL_INTERP + int opcode = MATCH_CLASS_GET_OPT_ATTR; + (void)(opcode); + #endif + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_CLASS_GET_OPT_ATTR); + _PyStackRef subject; + _PyStackRef attr; + _PyStackRef res; + subject = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + assert(PyUnicode_CheckExact(name)); + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *attr_o; + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)PyObject_GetOptionalAttr(subject_o, name, &attr_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (attr_o) { + assert(!_PyErr_Occurred(tstate)); + attr = PyStackRef_FromPyObjectSteal(attr_o); + res = PyStackRef_True; + } else { + if (_PyErr_Occurred(tstate)) { + JUMP_TO_LABEL(error); + } + attr = PyStackRef_FromPyObjectSteal(Py_None); + res = PyStackRef_False; + } + stack_pointer[0] = attr; + stack_pointer[1] = res; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + DISPATCH(); + } + + TARGET(MATCH_CLASS_ISINSTANCE) { + #if _Py_TAIL_CALL_INTERP + int opcode = MATCH_CLASS_ISINSTANCE; + (void)(opcode); + #endif + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_CLASS_ISINSTANCE); + _PyStackRef subject; + _PyStackRef type; + _PyStackRef res; + type = stack_pointer[-1]; + subject = stack_pointer[-2]; + PyObject *subject_o = PyStackRef_AsPyObjectBorrow(subject); + PyObject *type_o = PyStackRef_AsPyObjectBorrow(type); + if (!PyType_Check(type_o)) { + const char *e = "called match pattern must be a class"; + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyErr_Format(tstate, PyExc_TypeError, e); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(type); + stack_pointer = _PyFrame_GetStackPointer(frame); + JUMP_TO_LABEL(error); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + int retval = PyObject_IsInstance(subject_o, type_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(type); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (retval < 0) { + JUMP_TO_LABEL(error); + } + assert(!_PyErr_Occurred(tstate)); + res = retval ? PyStackRef_True : PyStackRef_False; + stack_pointer[0] = res; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + DISPATCH(); + } + TARGET(MATCH_KEYS) { #if _Py_TAIL_CALL_INTERP int opcode = MATCH_KEYS; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index b2fa7d01e8f6c2..725d5e56fc535c 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -24,6 +24,7 @@ static void *opcode_targets_table[256] = { &&TARGET_LOAD_BUILD_CLASS, &&TARGET_LOAD_LOCALS, &&TARGET_MAKE_FUNCTION, + &&TARGET_MATCH_CLASS_ISINSTANCE, &&TARGET_MATCH_KEYS, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, @@ -100,6 +101,7 @@ static void *opcode_targets_table[256] = { &&TARGET_MAKE_CELL, &&TARGET_MAP_ADD, &&TARGET_MATCH_CLASS, + &&TARGET_MATCH_CLASS_GET_OPT_ATTR, &&TARGET_POP_JUMP_IF_FALSE, &&TARGET_POP_JUMP_IF_NONE, &&TARGET_POP_JUMP_IF_NOT_NONE, @@ -126,8 +128,6 @@ static void *opcode_targets_table[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_RESUME, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, @@ -380,8 +380,8 @@ static void *opcode_tracing_targets_table[256] = { &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_TRACE_RECORD, + &&TARGET_TRACE_RECORD, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -696,6 +696,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAKE_CELL(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAKE_FUNCTION(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAP_ADD(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_CLASS(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_CLASS_GET_OPT_ATTR(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_CLASS_ISINSTANCE(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_KEYS(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_MAPPING(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_SEQUENCE(TAIL_CALL_PARAMS); @@ -934,6 +936,8 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [MAKE_FUNCTION] = _TAIL_CALL_MAKE_FUNCTION, [MAP_ADD] = _TAIL_CALL_MAP_ADD, [MATCH_CLASS] = _TAIL_CALL_MATCH_CLASS, + [MATCH_CLASS_GET_OPT_ATTR] = _TAIL_CALL_MATCH_CLASS_GET_OPT_ATTR, + [MATCH_CLASS_ISINSTANCE] = _TAIL_CALL_MATCH_CLASS_ISINSTANCE, [MATCH_KEYS] = _TAIL_CALL_MATCH_KEYS, [MATCH_MAPPING] = _TAIL_CALL_MATCH_MAPPING, [MATCH_SEQUENCE] = _TAIL_CALL_MATCH_SEQUENCE, @@ -994,8 +998,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE, [WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START, [YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE, - [121] = _TAIL_CALL_UNKNOWN_OPCODE, - [122] = _TAIL_CALL_UNKNOWN_OPCODE, [123] = _TAIL_CALL_UNKNOWN_OPCODE, [124] = _TAIL_CALL_UNKNOWN_OPCODE, [125] = _TAIL_CALL_UNKNOWN_OPCODE, @@ -1192,6 +1194,8 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [MAKE_FUNCTION] = _TAIL_CALL_TRACE_RECORD, [MAP_ADD] = _TAIL_CALL_TRACE_RECORD, [MATCH_CLASS] = _TAIL_CALL_TRACE_RECORD, + [MATCH_CLASS_GET_OPT_ATTR] = _TAIL_CALL_TRACE_RECORD, + [MATCH_CLASS_ISINSTANCE] = _TAIL_CALL_TRACE_RECORD, [MATCH_KEYS] = _TAIL_CALL_TRACE_RECORD, [MATCH_MAPPING] = _TAIL_CALL_TRACE_RECORD, [MATCH_SEQUENCE] = _TAIL_CALL_TRACE_RECORD, @@ -1252,8 +1256,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_TRACE_RECORD, [WITH_EXCEPT_START] = _TAIL_CALL_TRACE_RECORD, [YIELD_VALUE] = _TAIL_CALL_TRACE_RECORD, - [121] = _TAIL_CALL_UNKNOWN_OPCODE, - [122] = _TAIL_CALL_UNKNOWN_OPCODE, [123] = _TAIL_CALL_UNKNOWN_OPCODE, [124] = _TAIL_CALL_UNKNOWN_OPCODE, [125] = _TAIL_CALL_UNKNOWN_OPCODE, diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 85d3d041215103..aa2365df4a4473 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2120,6 +2120,26 @@ break; } + case _MATCH_CLASS_ISINSTANCE: { + JitOptRef res; + res = sym_new_not_null(ctx); + stack_pointer[-1] = res; + break; + } + + case _MATCH_CLASS_GET_OPT_ATTR: { + JitOptRef attr; + JitOptRef res; + attr = sym_new_not_null(ctx); + res = sym_new_not_null(ctx); + CHECK_STACK_BOUNDS(2); + stack_pointer[0] = attr; + stack_pointer[1] = res; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + break; + } + case _MATCH_CLASS: { JitOptRef attrs; attrs = sym_new_not_null(ctx);