Skip to content

Commit 888fe67

Browse files
itamarometa-codesync[bot]
authored andcommitted
Sync pre-release CPython main branch from GitHub (2026-05-06)
Summary: Imported python/cpython `3.15.0a8+` from upstream rev [`7cea70e`](https://www.github.com/python/cpython/commit/7cea70e14dac091cbd7e0601b96a59458f8c9bee) (committed 2026-05-06 16:07:43+00:00). # Commit Info Base: (`3.15.0a8+`) - [`5dd2161`](https://www.github.com/python/cpython/commit/5dd21617164cf69e848a70e3d7e32faf0bc3f279) (commit date: 2026-05-05 03:30:03+00:00) Imported: (`3.15.0a8+`) - [`7cea70e`](https://www.github.com/python/cpython/commit/7cea70e14dac091cbd7e0601b96a59458f8c9bee) (commit date: 2026-05-06 16:07:43+00:00) # Noteworthy file changes - C files (9 added, 1 removed): ``` + Include/internal/pycore_jit_publish.h + Include/internal/pycore_slots.h + Include/internal/pycore_slots_generated.h + Include/slots.h + Include/slots_generated.h + Modules/_testlimitedcapi/slots.c + Python/jit_publish.c + Python/slots.c + Python/slots_generated.c - Include/typeslots.h ``` - Stdlib files (1 added) - Test files (2 added) - Low-signal files (18 added) (NEWS.d, docs, .github) - Other files (2 added, 2 removed) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GJw6XylIQbliXBcHAHGAA4Hid68gbr0LAAAz Reviewed By: fried Differential Revision: D104075893 fbshipit-source-id: 025b3adb8cef7d0268de744ef41d819835501cce
1 parent 6eb8b17 commit 888fe67

3 files changed

Lines changed: 160 additions & 60 deletions

File tree

cinderx/Interpreter/3.15/Includes/Python/ceval_macros.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,3 +640,6 @@ gen_try_set_executing(PyGenObject *gen)
640640
(PyLongObject *)PyStackRef_AsPyObjectBorrow(left), \
641641
(PyLongObject *)PyStackRef_AsPyObjectBorrow(right)); \
642642
}
643+
644+
#define CALL_TP_ITERITEM_NO_ESCAPE(ITER, INDEX) \
645+
Py_TYPE(ITER)->_tp_iteritem((ITER), (INDEX))

cinderx/Interpreter/3.15/Includes/generated_cases.c.h

Lines changed: 147 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3783,8 +3783,7 @@
37833783
// _GUARD_NOS_NOT_NULL
37843784
{
37853785
nos = stack_pointer[-2];
3786-
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
3787-
if (o == NULL) {
3786+
if (PyStackRef_IsNull(nos)) {
37883787
UPDATE_MISS_STATS(CALL);
37893788
assert(_PyOpcode_Deopt[opcode] == (CALL));
37903789
JUMP_TO_PREDICTED(CALL);
@@ -5785,9 +5784,7 @@
57855784
int err = PyDict_Update(dict_o, update_o);
57865785
stack_pointer = _PyFrame_GetStackPointer(frame);
57875786
if (err < 0) {
5788-
_PyFrame_SetStackPointer(frame, stack_pointer);
57895787
int matches = _PyErr_ExceptionMatches(tstate, PyExc_AttributeError);
5790-
stack_pointer = _PyFrame_GetStackPointer(frame);
57915788
if (matches) {
57925789
_PyFrame_SetStackPointer(frame, stack_pointer);
57935790
PyObject *exc = _PyErr_GetRaisedException(tstate);
@@ -7868,23 +7865,22 @@
78687865
next_instr += 2;
78697866
INSTRUCTION_STATS(FOR_ITER_VIRTUAL);
78707867
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
7871-
_PyStackRef iter;
78727868
_PyStackRef null_or_index;
7869+
_PyStackRef iter;
78737870
_PyStackRef next;
78747871
/* Skip 1 cache entry */
7875-
// _GUARD_NOS_ITER_VIRTUAL
7872+
// _GUARD_TOS_NOT_NULL
78767873
{
7877-
iter = stack_pointer[-2];
7878-
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
7879-
if (Py_TYPE(iter_o)->_tp_iteritem == NULL) {
7874+
null_or_index = stack_pointer[-1];
7875+
if (PyStackRef_IsNull(null_or_index)) {
78807876
UPDATE_MISS_STATS(FOR_ITER);
78817877
assert(_PyOpcode_Deopt[opcode] == (FOR_ITER));
78827878
JUMP_TO_PREDICTED(FOR_ITER);
78837879
}
78847880
}
78857881
// _FOR_ITER_VIRTUAL
78867882
{
7887-
null_or_index = stack_pointer[-1];
7883+
iter = stack_pointer[-2];
78887884
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
78897885
Py_ssize_t index = PyStackRef_UntagInt(null_or_index);
78907886
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -9704,9 +9700,7 @@
97049700
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
97059701
stack_pointer = _PyFrame_GetStackPointer(frame);
97069702
if (none_val == NULL) {
9707-
_PyFrame_SetStackPointer(frame, stack_pointer);
97089703
int matches = _PyErr_ExceptionMatches(tstate, PyExc_TypeError);
9709-
stack_pointer = _PyFrame_GetStackPointer(frame);
97109704
if (matches &&
97119705
(Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable)))
97129706
{
@@ -12589,7 +12583,6 @@
1258912583
v = stack_pointer[-1];
1259012584
null_or_index = stack_pointer[-2];
1259112585
PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
12592-
PyObject *retval_o;
1259312586
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
1259412587
if (!IS_PEP523_HOOKED(tstate) &&
1259512588
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) &&
@@ -12608,7 +12601,7 @@
1260812601
gen_frame->previous = frame;
1260912602
DISPATCH_INLINED(gen_frame);
1261012603
}
12611-
if (!PyStackRef_IsNull(null_or_index)) {
12604+
if (!PyStackRef_IsNull(null_or_index) && PyStackRef_IsNone(v)) {
1261212605
_PyFrame_SetStackPointer(frame, stack_pointer);
1261312606
_PyStackRef item = _PyForIter_VirtualIteratorNext(tstate, frame, receiver, &null_or_index);
1261412607
stack_pointer = _PyFrame_GetStackPointer(frame);
@@ -12623,51 +12616,89 @@
1262312616
retval = item;
1262412617
}
1262512618
else {
12626-
if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
12627-
_PyFrame_SetStackPointer(frame, stack_pointer);
12628-
retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
12629-
stack_pointer = _PyFrame_GetStackPointer(frame);
12630-
}
12631-
else {
12632-
_PyFrame_SetStackPointer(frame, stack_pointer);
12633-
retval_o = PyObject_CallMethodOneArg(receiver_o,
12634-
&_Py_ID(send),
12635-
PyStackRef_AsPyObjectBorrow(v));
12636-
stack_pointer = _PyFrame_GetStackPointer(frame);
12619+
PyObject *v_o = PyStackRef_AsPyObjectBorrow(v);
12620+
_PyFrame_SetStackPointer(frame, stack_pointer);
12621+
PySendResultPair res = _PyIter_Send(receiver_o, v_o);
12622+
stack_pointer = _PyFrame_GetStackPointer(frame);
12623+
if (res.kind == PYGEN_ERROR) {
12624+
JUMP_TO_LABEL(error);
1263712625
}
12638-
if (retval_o == NULL) {
12639-
_PyFrame_SetStackPointer(frame, stack_pointer);
12640-
int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
12641-
stack_pointer = _PyFrame_GetStackPointer(frame);
12642-
if (matches) {
12643-
_PyFrame_SetStackPointer(frame, stack_pointer);
12644-
_PyEval_MonitorRaise(tstate, frame, this_instr);
12645-
stack_pointer = _PyFrame_GetStackPointer(frame);
12646-
}
12647-
_PyFrame_SetStackPointer(frame, stack_pointer);
12648-
int err = _PyGen_FetchStopIterationValue(&retval_o);
12649-
stack_pointer = _PyFrame_GetStackPointer(frame);
12650-
if (err == 0) {
12651-
assert(retval_o != NULL);
12652-
JUMPBY(oparg);
12653-
}
12654-
else {
12655-
stack_pointer += -1;
12656-
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
12657-
_PyFrame_SetStackPointer(frame, stack_pointer);
12658-
PyStackRef_CLOSE(v);
12659-
stack_pointer = _PyFrame_GetStackPointer(frame);
12660-
JUMP_TO_LABEL(error);
12661-
}
12626+
stack_pointer += -1;
12627+
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
12628+
_PyFrame_SetStackPointer(frame, stack_pointer);
12629+
PyStackRef_CLOSE(v);
12630+
stack_pointer = _PyFrame_GetStackPointer(frame);
12631+
retval = PyStackRef_FromPyObjectSteal(res.object);
12632+
if (res.kind == PYGEN_RETURN) {
12633+
JUMPBY(oparg);
1266212634
}
12663-
retval = PyStackRef_FromPyObjectSteal(retval_o);
12635+
stack_pointer += 1;
12636+
}
12637+
}
12638+
stack_pointer[-2] = null_or_index;
12639+
stack_pointer[-1] = retval;
12640+
DISPATCH();
12641+
}
12642+
12643+
TARGET(SEND_ASYNC_GEN) {
12644+
#if _Py_TAIL_CALL_INTERP
12645+
int opcode = SEND_ASYNC_GEN;
12646+
(void)(opcode);
12647+
#endif
12648+
_Py_CODEUNIT* const this_instr = next_instr;
12649+
(void)this_instr;
12650+
frame->instr_ptr = next_instr;
12651+
next_instr += 2;
12652+
INSTRUCTION_STATS(SEND_ASYNC_GEN);
12653+
static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size");
12654+
_PyStackRef iter;
12655+
_PyStackRef null_in;
12656+
_PyStackRef v;
12657+
_PyStackRef asend;
12658+
_PyStackRef null_out;
12659+
_PyStackRef retval;
12660+
/* Skip 1 cache entry */
12661+
// _GUARD_3OS_ASYNC_GEN_ASEND
12662+
{
12663+
iter = stack_pointer[-3];
12664+
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
12665+
if (!PyAsyncGenASend_CheckExact(iter_o)) {
12666+
UPDATE_MISS_STATS(SEND);
12667+
assert(_PyOpcode_Deopt[opcode] == (SEND));
12668+
JUMP_TO_PREDICTED(SEND);
1266412669
}
12665-
stack_pointer[-2] = null_or_index;
12666-
stack_pointer[-1] = retval;
12670+
}
12671+
// _SEND_ASYNC_GEN
12672+
{
12673+
v = stack_pointer[-1];
12674+
null_in = stack_pointer[-2];
12675+
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
12676+
assert(PyAsyncGenASend_CheckExact(iter_o));
12677+
PyObject *val = PyStackRef_AsPyObjectBorrow(v);
12678+
PyObject *retval_o;
12679+
_PyFrame_SetStackPointer(frame, stack_pointer);
12680+
PySendResult what = _PyAsyncGenASend_Send(iter_o, val, &retval_o);
12681+
stack_pointer = _PyFrame_GetStackPointer(frame);
12682+
if (what == PYGEN_ERROR) {
12683+
JUMP_TO_LABEL(error);
12684+
}
12685+
stack_pointer += -1;
12686+
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
1266712687
_PyFrame_SetStackPointer(frame, stack_pointer);
1266812688
PyStackRef_CLOSE(v);
1266912689
stack_pointer = _PyFrame_GetStackPointer(frame);
12690+
asend = iter;
12691+
null_out = null_in;
12692+
retval = PyStackRef_FromPyObjectSteal(retval_o);
12693+
if (what == PYGEN_RETURN) {
12694+
JUMPBY(oparg);
12695+
}
1267012696
}
12697+
stack_pointer[-2] = asend;
12698+
stack_pointer[-1] = null_out;
12699+
stack_pointer[0] = retval;
12700+
stack_pointer += 1;
12701+
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
1267112702
DISPATCH();
1267212703
}
1267312704

@@ -12740,6 +12771,70 @@
1274012771
DISPATCH();
1274112772
}
1274212773

12774+
TARGET(SEND_VIRTUAL) {
12775+
#if _Py_TAIL_CALL_INTERP
12776+
int opcode = SEND_VIRTUAL;
12777+
(void)(opcode);
12778+
#endif
12779+
_Py_CODEUNIT* const this_instr = next_instr;
12780+
(void)this_instr;
12781+
frame->instr_ptr = next_instr;
12782+
next_instr += 2;
12783+
INSTRUCTION_STATS(SEND_VIRTUAL);
12784+
static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size");
12785+
_PyStackRef val;
12786+
_PyStackRef nos;
12787+
_PyStackRef iter;
12788+
_PyStackRef null_or_index;
12789+
_PyStackRef none;
12790+
_PyStackRef next;
12791+
/* Skip 1 cache entry */
12792+
// _GUARD_TOS_IS_NONE
12793+
{
12794+
val = stack_pointer[-1];
12795+
if (!PyStackRef_IsNone(val)) {
12796+
UPDATE_MISS_STATS(SEND);
12797+
assert(_PyOpcode_Deopt[opcode] == (SEND));
12798+
JUMP_TO_PREDICTED(SEND);
12799+
}
12800+
}
12801+
// _GUARD_NOS_NOT_NULL
12802+
{
12803+
nos = stack_pointer[-2];
12804+
if (PyStackRef_IsNull(nos)) {
12805+
UPDATE_MISS_STATS(SEND);
12806+
assert(_PyOpcode_Deopt[opcode] == (SEND));
12807+
JUMP_TO_PREDICTED(SEND);
12808+
}
12809+
}
12810+
// _SEND_VIRTUAL
12811+
{
12812+
none = val;
12813+
null_or_index = nos;
12814+
iter = stack_pointer[-3];
12815+
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
12816+
Py_ssize_t index = PyStackRef_UntagInt(null_or_index);
12817+
_PyFrame_SetStackPointer(frame, stack_pointer);
12818+
_PyObjectIndexPair next_index = Py_TYPE(iter_o)->_tp_iteritem(iter_o, index);
12819+
stack_pointer = _PyFrame_GetStackPointer(frame);
12820+
PyObject *next_o = next_index.object;
12821+
index = next_index.index;
12822+
if (next_o == NULL) {
12823+
if (index < 0) {
12824+
JUMP_TO_LABEL(error);
12825+
}
12826+
next = none;
12827+
JUMPBY(oparg);
12828+
DISPATCH();
12829+
}
12830+
next = PyStackRef_FromPyObjectSteal(next_o);
12831+
null_or_index = PyStackRef_TagInt(index);
12832+
}
12833+
stack_pointer[-2] = null_or_index;
12834+
stack_pointer[-1] = next;
12835+
DISPATCH();
12836+
}
12837+
1274312838
TARGET(SETUP_ANNOTATIONS) {
1274412839
#if _Py_TAIL_CALL_INTERP
1274512840
int opcode = SETUP_ANNOTATIONS;

cinderx/Interpreter/3.15/cinderx_opcode_targets.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ static void *opcode_targets_table[256] = {
202202
&&TARGET_LOAD_SUPER_ATTR_METHOD,
203203
&&TARGET_RESUME_CHECK,
204204
&&TARGET_RESUME_CHECK_JIT,
205+
&&TARGET_SEND_ASYNC_GEN,
205206
&&TARGET_SEND_GEN,
207+
&&TARGET_SEND_VIRTUAL,
206208
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
207209
&&TARGET_STORE_ATTR_SLOT,
208210
&&TARGET_STORE_ATTR_WITH_HINT,
@@ -231,8 +233,6 @@ static void *opcode_targets_table[256] = {
231233
&&_unknown_opcode,
232234
&&_unknown_opcode,
233235
&&_unknown_opcode,
234-
&&_unknown_opcode,
235-
&&_unknown_opcode,
236236
&&TARGET_INSTRUMENTED_END_FOR,
237237
&&TARGET_INSTRUMENTED_POP_ITER,
238238
&&TARGET_INSTRUMENTED_END_SEND,
@@ -476,8 +476,8 @@ static void *opcode_tracing_targets_table[256] = {
476476
&&TARGET_TRACE_RECORD,
477477
&&TARGET_TRACE_RECORD,
478478
&&TARGET_TRACE_RECORD,
479-
&&_unknown_opcode,
480-
&&_unknown_opcode,
479+
&&TARGET_TRACE_RECORD,
480+
&&TARGET_TRACE_RECORD,
481481
&&_unknown_opcode,
482482
&&_unknown_opcode,
483483
&&_unknown_opcode,
@@ -726,7 +726,9 @@ static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK_JIT(TAIL_CALL_PARAM
726726
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_GENERATOR(TAIL_CALL_PARAMS);
727727
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_VALUE(TAIL_CALL_PARAMS);
728728
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND(TAIL_CALL_PARAMS);
729+
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND_ASYNC_GEN(TAIL_CALL_PARAMS);
729730
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND_GEN(TAIL_CALL_PARAMS);
731+
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND_VIRTUAL(TAIL_CALL_PARAMS);
730732
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SETUP_ANNOTATIONS(TAIL_CALL_PARAMS);
731733
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SET_ADD(TAIL_CALL_PARAMS);
732734
static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SET_FUNCTION_ATTRIBUTE(TAIL_CALL_PARAMS);
@@ -971,7 +973,9 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
971973
[RETURN_GENERATOR] = _TAIL_CALL_RETURN_GENERATOR,
972974
[RETURN_VALUE] = _TAIL_CALL_RETURN_VALUE,
973975
[SEND] = _TAIL_CALL_SEND,
976+
[SEND_ASYNC_GEN] = _TAIL_CALL_SEND_ASYNC_GEN,
974977
[SEND_GEN] = _TAIL_CALL_SEND_GEN,
978+
[SEND_VIRTUAL] = _TAIL_CALL_SEND_VIRTUAL,
975979
[SETUP_ANNOTATIONS] = _TAIL_CALL_SETUP_ANNOTATIONS,
976980
[SET_ADD] = _TAIL_CALL_SET_ADD,
977981
[SET_FUNCTION_ATTRIBUTE] = _TAIL_CALL_SET_FUNCTION_ATTRIBUTE,
@@ -1016,8 +1020,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
10161020
[124] = _TAIL_CALL_UNKNOWN_OPCODE,
10171021
[125] = _TAIL_CALL_UNKNOWN_OPCODE,
10181022
[127] = _TAIL_CALL_UNKNOWN_OPCODE,
1019-
[217] = _TAIL_CALL_UNKNOWN_OPCODE,
1020-
[218] = _TAIL_CALL_UNKNOWN_OPCODE,
10211023
[219] = _TAIL_CALL_UNKNOWN_OPCODE,
10221024
[220] = _TAIL_CALL_UNKNOWN_OPCODE,
10231025
[221] = _TAIL_CALL_UNKNOWN_OPCODE,
@@ -1229,7 +1231,9 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
12291231
[RETURN_GENERATOR] = _TAIL_CALL_TRACE_RECORD,
12301232
[RETURN_VALUE] = _TAIL_CALL_TRACE_RECORD,
12311233
[SEND] = _TAIL_CALL_TRACE_RECORD,
1234+
[SEND_ASYNC_GEN] = _TAIL_CALL_TRACE_RECORD,
12321235
[SEND_GEN] = _TAIL_CALL_TRACE_RECORD,
1236+
[SEND_VIRTUAL] = _TAIL_CALL_TRACE_RECORD,
12331237
[SETUP_ANNOTATIONS] = _TAIL_CALL_TRACE_RECORD,
12341238
[SET_ADD] = _TAIL_CALL_TRACE_RECORD,
12351239
[SET_FUNCTION_ATTRIBUTE] = _TAIL_CALL_TRACE_RECORD,
@@ -1274,8 +1278,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
12741278
[124] = _TAIL_CALL_UNKNOWN_OPCODE,
12751279
[125] = _TAIL_CALL_UNKNOWN_OPCODE,
12761280
[127] = _TAIL_CALL_UNKNOWN_OPCODE,
1277-
[217] = _TAIL_CALL_UNKNOWN_OPCODE,
1278-
[218] = _TAIL_CALL_UNKNOWN_OPCODE,
12791281
[219] = _TAIL_CALL_UNKNOWN_OPCODE,
12801282
[220] = _TAIL_CALL_UNKNOWN_OPCODE,
12811283
[221] = _TAIL_CALL_UNKNOWN_OPCODE,

0 commit comments

Comments
 (0)