@@ -1074,135 +1074,49 @@ basicblock_next_instr(basicblock *b)
10741074static int
10751075stack_effect (int opcode , int oparg , int jump )
10761076{
1077- switch (opcode ) {
1078- case NOP :
1079- case EXTENDED_ARG :
1080- case RESUME :
1081- case CACHE :
1082- return 0 ;
1083-
1084- /* Stack manipulation */
1085- case POP_TOP :
1086- return -1 ;
1087- case SWAP :
1088- return 0 ;
1089- case END_FOR :
1090- return -2 ;
1091-
1092- /* Unary operators */
1093- case UNARY_NEGATIVE :
1094- case UNARY_NOT :
1095- case UNARY_INVERT :
1096- return 0 ;
1097-
1098- case SET_ADD :
1099- case LIST_APPEND :
1100- return -1 ;
1101- case MAP_ADD :
1102- return -2 ;
1103-
1104- case BINARY_SUBSCR :
1105- return -1 ;
1106- case BINARY_SLICE :
1107- return -2 ;
1108- case STORE_SUBSCR :
1109- return -3 ;
1110- case STORE_SLICE :
1111- return -4 ;
1112- case DELETE_SUBSCR :
1113- return -2 ;
1114-
1115- case GET_ITER :
1116- return 0 ;
1117-
1118- case LOAD_BUILD_CLASS :
1119- return 1 ;
1077+ if (0 <= opcode && opcode <= MAX_REAL_OPCODE ) {
1078+ if (_PyOpcode_Deopt [opcode ] != opcode ) {
1079+ // Specialized instructions are not supported.
1080+ return PY_INVALID_STACK_EFFECT ;
1081+ }
1082+ int popped , pushed ;
1083+ if (jump > 0 ) {
1084+ popped = _PyOpcode_num_popped (opcode , oparg , true);
1085+ pushed = _PyOpcode_num_pushed (opcode , oparg , true);
1086+ }
1087+ else {
1088+ popped = _PyOpcode_num_popped (opcode , oparg , false);
1089+ pushed = _PyOpcode_num_pushed (opcode , oparg , false);
1090+ }
1091+ if (popped < 0 || pushed < 0 ) {
1092+ return PY_INVALID_STACK_EFFECT ;
1093+ }
1094+ if (jump >= 0 ) {
1095+ return pushed - popped ;
1096+ }
1097+ if (jump < 0 ) {
1098+ // Compute max(pushed - popped, alt_pushed - alt_popped)
1099+ int alt_popped = _PyOpcode_num_popped (opcode , oparg , true);
1100+ int alt_pushed = _PyOpcode_num_pushed (opcode , oparg , true);
1101+ if (alt_popped < 0 || alt_pushed < 0 ) {
1102+ return PY_INVALID_STACK_EFFECT ;
1103+ }
1104+ int diff = pushed - popped ;
1105+ int alt_diff = alt_pushed - alt_popped ;
1106+ if (alt_diff > diff ) {
1107+ return alt_diff ;
1108+ }
1109+ return diff ;
1110+ }
1111+ }
11201112
1121- case RETURN_VALUE :
1122- return -1 ;
1123- case RETURN_CONST :
1124- return 0 ;
1125- case SETUP_ANNOTATIONS :
1126- return 0 ;
1127- case YIELD_VALUE :
1128- return 0 ;
1113+ // Pseudo ops
1114+ switch (opcode ) {
11291115 case POP_BLOCK :
1130- return 0 ;
1131- case POP_EXCEPT :
1132- return -1 ;
1133-
1134- case STORE_NAME :
1135- return -1 ;
1136- case DELETE_NAME :
1137- return 0 ;
1138- case UNPACK_SEQUENCE :
1139- return oparg - 1 ;
1140- case UNPACK_EX :
1141- return (oparg & 0xFF ) + (oparg >>8 );
1142- case FOR_ITER :
1143- return 1 ;
1144- case SEND :
1145- return jump > 0 ? -1 : 0 ;
1146- case STORE_ATTR :
1147- return -2 ;
1148- case DELETE_ATTR :
1149- return -1 ;
1150- case STORE_GLOBAL :
1151- return -1 ;
1152- case DELETE_GLOBAL :
1153- return 0 ;
1154- case LOAD_CONST :
1155- return 1 ;
1156- case LOAD_NAME :
1157- return 1 ;
1158- case BUILD_TUPLE :
1159- case BUILD_LIST :
1160- case BUILD_SET :
1161- case BUILD_STRING :
1162- return 1 - oparg ;
1163- case BUILD_MAP :
1164- return 1 - 2 * oparg ;
1165- case BUILD_CONST_KEY_MAP :
1166- return - oparg ;
1167- case LOAD_ATTR :
1168- return (oparg & 1 );
1169- case COMPARE_OP :
1170- case IS_OP :
1171- case CONTAINS_OP :
1172- return -1 ;
1173- case CHECK_EXC_MATCH :
1174- return 0 ;
1175- case CHECK_EG_MATCH :
1176- return 0 ;
1177- case IMPORT_NAME :
1178- return -1 ;
1179- case IMPORT_FROM :
1180- return 1 ;
1181-
1182- /* Jumps */
1183- case JUMP_FORWARD :
1184- case JUMP_BACKWARD :
11851116 case JUMP :
1186- case JUMP_BACKWARD_NO_INTERRUPT :
11871117 case JUMP_NO_INTERRUPT :
11881118 return 0 ;
11891119
1190- case JUMP_IF_TRUE_OR_POP :
1191- case JUMP_IF_FALSE_OR_POP :
1192- return jump ? 0 : -1 ;
1193-
1194- case POP_JUMP_IF_NONE :
1195- case POP_JUMP_IF_NOT_NONE :
1196- case POP_JUMP_IF_FALSE :
1197- case POP_JUMP_IF_TRUE :
1198- return -1 ;
1199-
1200- case COMPARE_AND_BRANCH :
1201- return -2 ;
1202-
1203- case LOAD_GLOBAL :
1204- return (oparg & 1 ) + 1 ;
1205-
12061120 /* Exception handling pseudo-instructions */
12071121 case SETUP_FINALLY :
12081122 /* 0 in the normal flow.
@@ -1218,109 +1132,13 @@ stack_effect(int opcode, int oparg, int jump)
12181132 * of __(a)enter__ and push 2 values before jumping to the handler
12191133 * if an exception be raised. */
12201134 return jump ? 1 : 0 ;
1221- case PREP_RERAISE_STAR :
1222- return -1 ;
1223- case RERAISE :
1224- return -1 ;
1225- case PUSH_EXC_INFO :
1226- return 1 ;
1227-
1228- case WITH_EXCEPT_START :
1229- return 1 ;
1230-
1231- case LOAD_FAST :
1232- case LOAD_FAST_CHECK :
1233- return 1 ;
1234- case STORE_FAST :
1235- return -1 ;
1236- case DELETE_FAST :
1237- return 0 ;
1238-
1239- case RETURN_GENERATOR :
1240- return 0 ;
12411135
1242- case RAISE_VARARGS :
1243- return - oparg ;
1244-
1245- /* Functions and calls */
1246- case KW_NAMES :
1247- return 0 ;
1248- case CALL :
1249- return -1 - oparg ;
1250- case CALL_INTRINSIC_1 :
1251- return 0 ;
1252- case CALL_FUNCTION_EX :
1253- return -2 - ((oparg & 0x01 ) != 0 );
1254- case MAKE_FUNCTION :
1255- return 0 - ((oparg & 0x01 ) != 0 ) - ((oparg & 0x02 ) != 0 ) -
1256- ((oparg & 0x04 ) != 0 ) - ((oparg & 0x08 ) != 0 );
1257- case BUILD_SLICE :
1258- if (oparg == 3 )
1259- return -2 ;
1260- else
1261- return -1 ;
1262-
1263- /* Closures */
1264- case MAKE_CELL :
1265- case COPY_FREE_VARS :
1266- return 0 ;
1267- case LOAD_CLOSURE :
1268- return 1 ;
1269- case LOAD_DEREF :
1270- case LOAD_CLASSDEREF :
1271- return 1 ;
1272- case STORE_DEREF :
1273- return -1 ;
1274- case DELETE_DEREF :
1275- return 0 ;
1276-
1277- /* Iterators and generators */
1278- case GET_AWAITABLE :
1279- return 0 ;
1280-
1281- case BEFORE_ASYNC_WITH :
1282- case BEFORE_WITH :
1283- return 1 ;
1284- case GET_AITER :
1285- return 0 ;
1286- case GET_ANEXT :
1287- return 1 ;
1288- case GET_YIELD_FROM_ITER :
1289- return 0 ;
1290- case END_ASYNC_FOR :
1291- return -2 ;
1292- case CLEANUP_THROW :
1293- return -2 ;
1294- case FORMAT_VALUE :
1295- /* If there's a fmt_spec on the stack, we go from 2->1,
1296- else 1->1. */
1297- return (oparg & FVS_MASK ) == FVS_HAVE_SPEC ? -1 : 0 ;
12981136 case LOAD_METHOD :
12991137 return 1 ;
1300- case LOAD_ASSERTION_ERROR :
1301- return 1 ;
1302- case LIST_EXTEND :
1303- case SET_UPDATE :
1304- case DICT_MERGE :
1305- case DICT_UPDATE :
1306- return -1 ;
1307- case MATCH_CLASS :
1308- return -2 ;
1309- case GET_LEN :
1310- case MATCH_MAPPING :
1311- case MATCH_SEQUENCE :
1312- case MATCH_KEYS :
1313- return 1 ;
1314- case COPY :
1315- case PUSH_NULL :
1316- return 1 ;
1317- case BINARY_OP :
1318- return -1 ;
1319- case INTERPRETER_EXIT :
1320- return -1 ;
13211138 default :
13221139 return PY_INVALID_STACK_EFFECT ;
13231140 }
1141+
13241142 return PY_INVALID_STACK_EFFECT ; /* not reachable */
13251143}
13261144
0 commit comments