https://github.com/python/cpython/commit/726a17e26541579b762ab2c9ee3ff201de777c35
commit: 726a17e26541579b762ab2c9ee3ff201de777c35
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-05-03T13:26:05+03:00
summary:
gh-149243: Check for recursion limits in `CALL_ALLOC_AND_ENTER_INIT` (#149310)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst
M Include/internal/pycore_opcode_metadata.h
M Modules/_testinternalcapi/test_cases.c.h
M Python/bytecodes.c
M Python/generated_cases.c.h
diff --git a/Include/internal/pycore_opcode_metadata.h
b/Include/internal/pycore_opcode_metadata.h
index 4f8b48db23d1ef..0d7e367a5618b2 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1386,7 +1386,7 @@ _PyOpcode_macro_expansion[256] = {
[BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, OPARG_SIMPLE, 0
} } },
[BUILD_TEMPLATE] = { .nuops = 1, .uops = { { _BUILD_TEMPLATE,
OPARG_SIMPLE, 0 } } },
[BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, OPARG_SIMPLE, 0 }
} },
- [CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 6, .uops = { { _RECORD_CALLABLE,
OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_OBJECT, 2, 1
}, { _ALLOCATE_OBJECT, OPARG_SIMPLE, 3 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3
}, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
+ [CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 7, .uops = { { _RECORD_CALLABLE,
OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_OBJECT, 2, 1
}, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _ALLOCATE_OBJECT,
OPARG_SIMPLE, 3 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME,
OPARG_SIMPLE, 3 } } },
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 11, .uops = { {
_RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, {
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, {
_INIT_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, {
_CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3
}, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING,
OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, {
_SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME,
OPARG_SIMPLE, 3 } } },
[CALL_BOUND_METHOD_GENERAL] = { .nuops = 8, .uops = { {
_RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, {
_CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, OPARG_SIMPLE, 3 }, {
_CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL,
OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, {
_PUSH_FRAME, OPARG_SIMPLE, 3 } } },
[CALL_BUILTIN_CLASS] = { .nuops = 6, .uops = { { _RECORD_CALLABLE,
OPARG_SIMPLE, 0 }, { _GUARD_CALLABLE_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, {
_CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _POP_TOP_OPARG, OPARG_SIMPLE, 3 }, {
_POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst
new file mode 100644
index 00000000000000..5c1956fe398364
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst
@@ -0,0 +1 @@
+Check for recursion limits in ``CALL_ALLOC_AND_ENTER_INIT`` opcode.
diff --git a/Modules/_testinternalcapi/test_cases.c.h
b/Modules/_testinternalcapi/test_cases.c.h
index 8897854078bd45..bd69211fd22206 100644
--- a/Modules/_testinternalcapi/test_cases.c.h
+++ b/Modules/_testinternalcapi/test_cases.c.h
@@ -1925,6 +1925,14 @@
JUMP_TO_PREDICTED(CALL);
}
}
+ // _CHECK_RECURSION_REMAINING
+ {
+ if (tstate->py_recursion_remaining <= 1) {
+ UPDATE_MISS_STATS(CALL);
+ assert(_PyOpcode_Deopt[opcode] == (CALL));
+ JUMP_TO_PREDICTED(CALL);
+ }
+ }
// _ALLOCATE_OBJECT
{
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 4239ba58bc390b..963391e7598fb6 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -4737,6 +4737,7 @@ dummy_func(
unused/1 +
_CHECK_PEP_523 +
_CHECK_OBJECT +
+ _CHECK_RECURSION_REMAINING +
_ALLOCATE_OBJECT +
_CREATE_INIT_FRAME +
_PUSH_FRAME;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index dccee0e4a3b110..105375e41e360b 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -1925,6 +1925,14 @@
JUMP_TO_PREDICTED(CALL);
}
}
+ // _CHECK_RECURSION_REMAINING
+ {
+ if (tstate->py_recursion_remaining <= 1) {
+ UPDATE_MISS_STATS(CALL);
+ assert(_PyOpcode_Deopt[opcode] == (CALL));
+ JUMP_TO_PREDICTED(CALL);
+ }
+ }
// _ALLOCATE_OBJECT
{
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]