]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-126222: Fix `_PyUop_num_popped` (GH-126507)
authorMark Shannon <mark@hotpy.org>
Thu, 7 Nov 2024 10:48:27 +0000 (10:48 +0000)
committerGitHub <noreply@github.com>
Thu, 7 Nov 2024 10:48:27 +0000 (10:48 +0000)
Include/internal/pycore_uop_metadata.h
Lib/test/test_capi/test_opt.py
Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst [new file with mode: 0644]
Tools/cases_generator/uop_metadata_generator.py

index ade297201f0ac299e8eaa246798fb4ef2b127db3..98a41d1f23f569b142990bb116286570b4a5495b 100644 (file)
@@ -658,7 +658,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _TO_BOOL:
             return 1;
         case _TO_BOOL_BOOL:
-            return 1;
+            return 0;
         case _TO_BOOL_INT:
             return 1;
         case _TO_BOOL_LIST:
@@ -672,11 +672,11 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _UNARY_INVERT:
             return 1;
         case _GUARD_BOTH_INT:
-            return 2;
+            return 0;
         case _GUARD_NOS_INT:
-            return 2;
+            return 0;
         case _GUARD_TOS_INT:
-            return 1;
+            return 0;
         case _BINARY_OP_MULTIPLY_INT:
             return 2;
         case _BINARY_OP_ADD_INT:
@@ -684,11 +684,11 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _BINARY_OP_SUBTRACT_INT:
             return 2;
         case _GUARD_BOTH_FLOAT:
-            return 2;
+            return 0;
         case _GUARD_NOS_FLOAT:
-            return 2;
+            return 0;
         case _GUARD_TOS_FLOAT:
-            return 1;
+            return 0;
         case _BINARY_OP_MULTIPLY_FLOAT:
             return 2;
         case _BINARY_OP_ADD_FLOAT:
@@ -696,7 +696,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _BINARY_OP_SUBTRACT_FLOAT:
             return 2;
         case _GUARD_BOTH_UNICODE:
-            return 2;
+            return 0;
         case _BINARY_OP_ADD_UNICODE:
             return 2;
         case _BINARY_OP_INPLACE_ADD_UNICODE:
@@ -716,13 +716,13 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _BINARY_SUBSCR_DICT:
             return 2;
         case _BINARY_SUBSCR_CHECK_FUNC:
-            return 2;
+            return 0;
         case _BINARY_SUBSCR_INIT_CALL:
             return 2;
         case _LIST_APPEND:
-            return 2 + (oparg-1);
+            return 1;
         case _SET_ADD:
-            return 2 + (oparg-1);
+            return 1;
         case _STORE_SUBSCR:
             return 3;
         case _STORE_SUBSCR_LIST_INT:
@@ -740,11 +740,11 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _GET_AITER:
             return 1;
         case _GET_ANEXT:
-            return 1;
+            return 0;
         case _GET_AWAITABLE:
             return 1;
         case _SEND_GEN_FRAME:
-            return 2;
+            return 1;
         case _YIELD_VALUE:
             return 1;
         case _POP_EXCEPT:
@@ -812,9 +812,9 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _BUILD_LIST:
             return oparg;
         case _LIST_EXTEND:
-            return 2 + (oparg-1);
+            return 1;
         case _SET_UPDATE:
-            return 2 + (oparg-1);
+            return 1;
         case _BUILD_SET:
             return oparg;
         case _BUILD_MAP:
@@ -822,11 +822,11 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _SETUP_ANNOTATIONS:
             return 0;
         case _DICT_UPDATE:
-            return 2 + (oparg - 1);
+            return 1;
         case _DICT_MERGE:
-            return 5 + (oparg - 1);
+            return 1;
         case _MAP_ADD:
-            return 3 + (oparg - 1);
+            return 2;
         case _LOAD_SUPER_ATTR_ATTR:
             return 3;
         case _LOAD_SUPER_ATTR_METHOD:
@@ -834,9 +834,9 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _LOAD_ATTR:
             return 1;
         case _GUARD_TYPE_VERSION:
-            return 1;
+            return 0;
         case _CHECK_MANAGED_OBJECT_HAS_VALUES:
-            return 1;
+            return 0;
         case _LOAD_ATTR_INSTANCE_VALUE_0:
             return 1;
         case _LOAD_ATTR_INSTANCE_VALUE_1:
@@ -844,11 +844,11 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _LOAD_ATTR_INSTANCE_VALUE:
             return 1;
         case _CHECK_ATTR_MODULE:
-            return 1;
+            return 0;
         case _LOAD_ATTR_MODULE:
             return 1;
         case _CHECK_ATTR_WITH_HINT:
-            return 1;
+            return 0;
         case _LOAD_ATTR_WITH_HINT:
             return 1;
         case _LOAD_ATTR_SLOT_0:
@@ -858,7 +858,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _LOAD_ATTR_SLOT:
             return 1;
         case _CHECK_ATTR_CLASS:
-            return 1;
+            return 0;
         case _LOAD_ATTR_CLASS_0:
             return 1;
         case _LOAD_ATTR_CLASS_1:
@@ -868,7 +868,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _LOAD_ATTR_PROPERTY_FRAME:
             return 1;
         case _GUARD_DORV_NO_DICT:
-            return 1;
+            return 0;
         case _STORE_ATTR_INSTANCE_VALUE:
             return 2;
         case _STORE_ATTR_WITH_HINT:
@@ -894,59 +894,59 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _CHECK_EG_MATCH:
             return 2;
         case _CHECK_EXC_MATCH:
-            return 2;
+            return 1;
         case _IMPORT_NAME:
             return 2;
         case _IMPORT_FROM:
-            return 1;
+            return 0;
         case _IS_NONE:
             return 1;
         case _GET_LEN:
-            return 1;
+            return 0;
         case _MATCH_CLASS:
             return 3;
         case _MATCH_MAPPING:
-            return 1;
+            return 0;
         case _MATCH_SEQUENCE:
-            return 1;
+            return 0;
         case _MATCH_KEYS:
-            return 2;
+            return 0;
         case _GET_ITER:
             return 1;
         case _GET_YIELD_FROM_ITER:
             return 1;
         case _FOR_ITER_TIER_TWO:
-            return 1;
+            return 0;
         case _ITER_CHECK_LIST:
-            return 1;
+            return 0;
         case _GUARD_NOT_EXHAUSTED_LIST:
-            return 1;
+            return 0;
         case _ITER_NEXT_LIST:
-            return 1;
+            return 0;
         case _ITER_CHECK_TUPLE:
-            return 1;
+            return 0;
         case _GUARD_NOT_EXHAUSTED_TUPLE:
-            return 1;
+            return 0;
         case _ITER_NEXT_TUPLE:
-            return 1;
+            return 0;
         case _ITER_CHECK_RANGE:
-            return 1;
+            return 0;
         case _GUARD_NOT_EXHAUSTED_RANGE:
-            return 1;
+            return 0;
         case _ITER_NEXT_RANGE:
-            return 1;
+            return 0;
         case _FOR_ITER_GEN_FRAME:
-            return 1;
+            return 0;
         case _LOAD_SPECIAL:
             return 1;
         case _WITH_EXCEPT_START:
-            return 5;
+            return 0;
         case _PUSH_EXC_INFO:
             return 1;
         case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
-            return 1;
+            return 0;
         case _GUARD_KEYS_VERSION:
-            return 1;
+            return 0;
         case _LOAD_ATTR_METHOD_WITH_VALUES:
             return 1;
         case _LOAD_ATTR_METHOD_NO_DICT:
@@ -956,7 +956,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
             return 1;
         case _CHECK_ATTR_METHOD_LAZY_DICT:
-            return 1;
+            return 0;
         case _LOAD_ATTR_METHOD_LAZY_DICT:
             return 1;
         case _MAYBE_EXPAND_METHOD:
@@ -964,25 +964,25 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _PY_FRAME_GENERAL:
             return 2 + oparg;
         case _CHECK_FUNCTION_VERSION:
-            return 2 + oparg;
+            return 0;
         case _CHECK_METHOD_VERSION:
-            return 2 + oparg;
+            return 0;
         case _EXPAND_METHOD:
             return 2 + oparg;
         case _CHECK_IS_NOT_PY_CALLABLE:
-            return 2 + oparg;
+            return 0;
         case _CALL_NON_PY_GENERAL:
             return 2 + oparg;
         case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
-            return 2 + oparg;
+            return 0;
         case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
             return 2 + oparg;
         case _CHECK_PEP_523:
             return 0;
         case _CHECK_FUNCTION_EXACT_ARGS:
-            return 2 + oparg;
+            return 0;
         case _CHECK_STACK_SPACE:
-            return 2 + oparg;
+            return 0;
         case _INIT_CALL_PY_EXACT_ARGS_0:
             return 2 + oparg;
         case _INIT_CALL_PY_EXACT_ARGS_1:
@@ -1036,17 +1036,17 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _PY_FRAME_KW:
             return 3 + oparg;
         case _CHECK_FUNCTION_VERSION_KW:
-            return 3 + oparg;
+            return 0;
         case _CHECK_METHOD_VERSION_KW:
-            return 3 + oparg;
+            return 0;
         case _EXPAND_METHOD_KW:
             return 3 + oparg;
         case _CHECK_IS_NOT_PY_CALLABLE_KW:
-            return 3 + oparg;
+            return 0;
         case _CALL_KW_NON_PY:
             return 3 + oparg;
         case _MAKE_CALLARGS_A_TUPLE:
-            return 3 + (oparg & 1);
+            return 1 + (oparg & 1);
         case _MAKE_FUNCTION:
             return 1;
         case _SET_FUNCTION_ATTRIBUTE:
@@ -1062,7 +1062,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _FORMAT_WITH_SPEC:
             return 2;
         case _COPY:
-            return 1 + (oparg-1);
+            return 0;
         case _BINARY_OP:
             return 2;
         case _SWAP:
index c352325ff3d08af1353bdab38531e8405bfa2a5c..7b3d9e4fd1126fc3a9d02dc008f7da23fb862f78 100644 (file)
@@ -1486,6 +1486,14 @@ class TestUopsOptimization(unittest.TestCase):
 
         fn(A())
 
+    def test_jit_error_pops(self):
+        """
+        Tests that the correct number of pops are inserted into the
+        exit stub
+        """
+        items = 17 * [None] + [[]]
+        with self.assertRaises(TypeError):
+            {item for item in items}
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst
new file mode 100644 (file)
index 0000000..ebf6673
--- /dev/null
@@ -0,0 +1,3 @@
+Do not include count of "peek" items in ``_PyUop_num_popped``. This ensures
+that the correct number of items are popped from the stack when a micro-op
+exits with an error.
index 7b3325ada4a49fed6a8bd00825dc0e3086b19127..6eb022899d6cae73d545cde78ec157bf814c6d90 100644 (file)
@@ -51,6 +51,8 @@ def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
         if uop.is_viable() and uop.properties.tier != 1:
             stack = Stack()
             for var in reversed(uop.stack.inputs):
+                if var.peek:
+                    break
                 stack.pop(var)
             popped = (-stack.base_offset).to_c()
             out.emit(f"case {uop.name}:\n")