summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-11-07 10:48:27 (GMT)
committerGitHub <noreply@github.com>2024-11-07 10:48:27 (GMT)
commit85036c8d612007356d2118eb25b460505078b023 (patch)
tree78dfc47664d812b777308256384a08b8b83cbed9
parentc9cda1608edf7664c10f4f467e24591062c2fe62 (diff)
downloadcpython-85036c8d612007356d2118eb25b460505078b023.zip
cpython-85036c8d612007356d2118eb25b460505078b023.tar.gz
cpython-85036c8d612007356d2118eb25b460505078b023.tar.bz2
GH-126222: Fix `_PyUop_num_popped` (GH-126507)
-rw-r--r--Include/internal/pycore_uop_metadata.h112
-rw-r--r--Lib/test/test_capi/test_opt.py8
-rw-r--r--Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst3
-rw-r--r--Tools/cases_generator/uop_metadata_generator.py2
4 files changed, 69 insertions, 56 deletions
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index ade2972..98a41d1 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -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:
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index c352325..7b3d9e4 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -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
index 0000000..ebf6673
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst
@@ -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.
diff --git a/Tools/cases_generator/uop_metadata_generator.py b/Tools/cases_generator/uop_metadata_generator.py
index 7b3325a..6eb0228 100644
--- a/Tools/cases_generator/uop_metadata_generator.py
+++ b/Tools/cases_generator/uop_metadata_generator.py
@@ -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")