]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-145667: Merge `GET_ITER` and `GET_YIELD_FROM_ITER` (GH-146120)
authorMark Shannon <Mark.Shannon@arm.com>
Sat, 21 Mar 2026 10:48:13 +0000 (10:48 +0000)
committerGitHub <noreply@github.com>
Sat, 21 Mar 2026 10:48:13 +0000 (10:48 +0000)
* Merge GET_ITER and GET_YIELD_FROM_ITER. Modify SEND to make it a bit more like FOR_ITER

30 files changed:
Include/internal/pycore_ceval.h
Include/internal/pycore_interpframe.h
Include/internal/pycore_magic_number.h
Include/internal/pycore_opcode_metadata.h
Include/internal/pycore_opcode_utils.h
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h
Include/opcode_ids.h
Lib/_opcode_metadata.py
Lib/test/test_dis.py
Lib/test/test_peepholer.py
Misc/NEWS.d/next/Core_and_Builtins/2026-03-20-11-34-17.gh-issue-145667._Agp9o.rst [new file with mode: 0644]
Modules/_remote_debugging/asyncio.c
Modules/_testinternalcapi/test_cases.c.h
Modules/_testinternalcapi/test_targets.h
Objects/codeobject.c
Objects/genobject.c
Programs/test_frozenmain.h
Python/bytecodes.c
Python/ceval.c
Python/codegen.c
Python/executor_cases.c.h
Python/flowgraph.c
Python/generated_cases.c.h
Python/opcode_targets.h
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h
Python/record_functions.c.h
Python/specialize.c
Tools/cases_generator/analyzer.py

index f27ec4350bb2c834f5d1c299520625633e8659fa..16913289a02f59a51bb7a0e10c3582c1c84db526 100644 (file)
@@ -342,6 +342,7 @@ PyAPI_FUNC(PyObject *) _PyEval_GetAwaitable(PyObject *iterable, int oparg);
 PyAPI_FUNC(PyObject *) _PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *name);
 PyAPI_FUNC(int)
 _Py_Check_ArgsIterable(PyThreadState *tstate, PyObject *func, PyObject *args);
+PyAPI_FUNC(_PyStackRef) _PyEval_GetIter(_PyStackRef iterable, _PyStackRef *null_or_index, int yield_from);
 
 /*
  * Indicate whether a special method of given 'oparg' can use the (improved)
index 14e2f245834dca0d1a4c4416f0c4f8f4ae1ef32b..8db1aebdc1140130e10e53c796ac24ab40b13587 100644 (file)
@@ -102,10 +102,10 @@ static inline _PyStackRef *_PyFrame_Stackbase(_PyInterpreterFrame *f) {
     return (f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus);
 }
 
-static inline _PyStackRef _PyFrame_StackPeek(_PyInterpreterFrame *f) {
+static inline _PyStackRef _PyFrame_StackPeek(_PyInterpreterFrame *f, int depth) {
     assert(f->stackpointer > _PyFrame_Stackbase(f));
-    assert(!PyStackRef_IsNull(f->stackpointer[-1]));
-    return f->stackpointer[-1];
+    assert(!PyStackRef_IsNull(f->stackpointer[-depth]));
+    return f->stackpointer[-depth];
 }
 
 static inline _PyStackRef _PyFrame_StackPop(_PyInterpreterFrame *f) {
index ec9cfe432371c76594736a5039463d5e51638ecd..9d36165c8a8ffb77fc52cd6aad25f26cc66982ce 100644 (file)
@@ -292,7 +292,8 @@ Known values:
     Python 3.15a4 3659 (Add CALL_FUNCTION_EX specialization)
     Python 3.15a4 3660 (Change generator preamble code)
     Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes)
-    Python 3.15a6 3662 (Add counter to RESUME)
+    Python 3.15a8 3662 (Add counter to RESUME)
+    Python 3.15a8 3663 (Merge GET_ITER and GET_YIELD_FROM_ITER. Modify SEND to make it a bit more like FOR_ITER)
 
 
     Python 3.16 will start with 3700
@@ -306,7 +307,7 @@ PC/launcher.c must also be updated.
 
 */
 
-#define PYC_MAGIC_NUMBER 3662
+#define PYC_MAGIC_NUMBER 3663
 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
    (little-endian) and then appending b'\r\n'. */
 #define PYC_MAGIC_NUMBER_TOKEN \
index 2ff6e75e28a74ceffd7918e1d381a8e8a27bef93..3260806f3222d6f4d6977f59f6384d8055c849d4 100644 (file)
@@ -157,7 +157,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case CHECK_EXC_MATCH:
             return 2;
         case CLEANUP_THROW:
-            return 3;
+            return 4;
         case COMPARE_OP:
             return 2;
         case COMPARE_OP_FLOAT:
@@ -199,7 +199,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case END_FOR:
             return 1;
         case END_SEND:
-            return 2;
+            return 3;
         case ENTER_EXECUTOR:
             return 0;
         case EXIT_INIT_CHECK:
@@ -230,8 +230,6 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
             return 1;
         case GET_LEN:
             return 1;
-        case GET_YIELD_FROM_ITER:
-            return 1;
         case IMPORT_FROM:
             return 1;
         case IMPORT_NAME:
@@ -247,7 +245,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case INSTRUMENTED_END_FOR:
             return 3;
         case INSTRUMENTED_END_SEND:
-            return 2;
+            return 3;
         case INSTRUMENTED_FOR_ITER:
             return 2;
         case INSTRUMENTED_INSTRUCTION:
@@ -433,9 +431,9 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case RETURN_VALUE:
             return 1;
         case SEND:
-            return 2;
+            return 3;
         case SEND_GEN:
-            return 2;
+            return 3;
         case SETUP_ANNOTATIONS:
             return 0;
         case SETUP_CLEANUP:
@@ -650,7 +648,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case CHECK_EXC_MATCH:
             return 2;
         case CLEANUP_THROW:
-            return 2;
+            return 3;
         case COMPARE_OP:
             return 1;
         case COMPARE_OP_FLOAT:
@@ -723,8 +721,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
             return 2;
         case GET_LEN:
             return 2;
-        case GET_YIELD_FROM_ITER:
-            return 1;
         case IMPORT_FROM:
             return 2;
         case IMPORT_NAME:
@@ -926,9 +922,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case RETURN_VALUE:
             return 1;
         case SEND:
-            return 2;
+            return 3;
         case SEND_GEN:
-            return 1;
+            return 2;
         case SETUP_ANNOTATIONS:
             return 0;
         case SETUP_CLEANUP:
@@ -1190,9 +1186,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
     [GET_AITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [GET_ANEXT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
     [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [GET_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [GET_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
     [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
@@ -1287,7 +1282,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
     [RESUME_CHECK_JIT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
     [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
     [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
-    [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
+    [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
     [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
     [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1438,7 +1433,6 @@ _PyOpcode_macro_expansion[256] = {
     [GET_AWAITABLE] = { .nuops = 1, .uops = { { _GET_AWAITABLE, OPARG_SIMPLE, 0 } } },
     [GET_ITER] = { .nuops = 1, .uops = { { _GET_ITER, OPARG_SIMPLE, 0 } } },
     [GET_LEN] = { .nuops = 1, .uops = { { _GET_LEN, OPARG_SIMPLE, 0 } } },
-    [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { _GET_YIELD_FROM_ITER, OPARG_SIMPLE, 0 } } },
     [IMPORT_FROM] = { .nuops = 1, .uops = { { _IMPORT_FROM, OPARG_SIMPLE, 0 } } },
     [IMPORT_NAME] = { .nuops = 1, .uops = { { _IMPORT_NAME, OPARG_SIMPLE, 0 } } },
     [IS_OP] = { .nuops = 3, .uops = { { _IS_OP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
@@ -1501,7 +1495,7 @@ _PyOpcode_macro_expansion[256] = {
     [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 1 } } },
     [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } },
     [RETURN_VALUE] = { .nuops = 2, .uops = { { _MAKE_HEAP_SAFE, OPARG_SIMPLE, 0 }, { _RETURN_VALUE, OPARG_SIMPLE, 0 } } },
-    [SEND_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS_GEN_FUNC, OPARG_SIMPLE, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
+    [SEND_GEN] = { .nuops = 4, .uops = { { _RECORD_3OS_GEN_FUNC, OPARG_SIMPLE, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
     [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, OPARG_SIMPLE, 0 } } },
     [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, OPARG_SIMPLE, 0 } } },
     [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, OPARG_SIMPLE, 0 } } },
@@ -1641,7 +1635,6 @@ const char *_PyOpcode_OpName[267] = {
     [GET_AWAITABLE] = "GET_AWAITABLE",
     [GET_ITER] = "GET_ITER",
     [GET_LEN] = "GET_LEN",
-    [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
     [IMPORT_FROM] = "IMPORT_FROM",
     [IMPORT_NAME] = "IMPORT_NAME",
     [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL",
@@ -1818,6 +1811,7 @@ const uint8_t _PyOpcode_Caches[256] = {
 PyAPI_DATA(const uint8_t) _PyOpcode_Deopt[256];
 #ifdef NEED_OPCODE_METADATA
 const uint8_t _PyOpcode_Deopt[256] = {
+    [120] = 120,
     [121] = 121,
     [122] = 122,
     [123] = 123,
@@ -1940,7 +1934,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [GET_AWAITABLE] = GET_AWAITABLE,
     [GET_ITER] = GET_ITER,
     [GET_LEN] = GET_LEN,
-    [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
     [IMPORT_FROM] = IMPORT_FROM,
     [IMPORT_NAME] = IMPORT_NAME,
     [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
@@ -2079,6 +2072,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
 #endif // NEED_OPCODE_METADATA
 
 #define EXTRA_CASES \
+    case 120: \
     case 121: \
     case 122: \
     case 123: \
index e4d859fcc47d02242ef11d62d9822b1773efa90d..69178381993fba1eb2902ffa92ad7a4dfcf8b625 100644 (file)
@@ -86,6 +86,10 @@ extern "C" {
 #define RESUME_OPARG_LOCATION_MASK 0x3
 #define RESUME_OPARG_DEPTH1_MASK 0x4
 
+#define GET_ITER_YIELD_FROM 1
+#define GET_ITER_YIELD_FROM_NO_CHECK 2
+#define GET_ITER_YIELD_FROM_CORO_CHECK 3
+
 #ifdef __cplusplus
 }
 #endif
index 50f137fd49fe7e4180197a4361021d66401930a4..be4e079e5f5b5cf19deb940270e7d8681e40fd74 100644 (file)
@@ -128,7 +128,6 @@ extern "C" {
 #define _GET_AWAITABLE GET_AWAITABLE
 #define _GET_ITER GET_ITER
 #define _GET_LEN GET_LEN
-#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
 #define _GUARD_BINARY_OP_EXTEND 388
 #define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS 389
 #define _GUARD_BIT_IS_SET_POP 390
@@ -333,271 +332,271 @@ extern "C" {
 #define _PY_FRAME_EX 550
 #define _PY_FRAME_GENERAL 551
 #define _PY_FRAME_KW 552
-#define _RECORD_4OS 553
-#define _RECORD_BOUND_METHOD 554
-#define _RECORD_CALLABLE 555
-#define _RECORD_CODE 556
-#define _RECORD_NOS 557
-#define _RECORD_NOS_GEN_FUNC 558
-#define _RECORD_TOS 559
-#define _RECORD_TOS_TYPE 560
-#define _REPLACE_WITH_TRUE 561
-#define _RESUME_CHECK 562
+#define _RECORD_3OS_GEN_FUNC 553
+#define _RECORD_4OS 554
+#define _RECORD_BOUND_METHOD 555
+#define _RECORD_CALLABLE 556
+#define _RECORD_CODE 557
+#define _RECORD_NOS 558
+#define _RECORD_NOS_GEN_FUNC 559
+#define _RECORD_TOS 560
+#define _RECORD_TOS_TYPE 561
+#define _REPLACE_WITH_TRUE 562
+#define _RESUME_CHECK 563
 #define _RETURN_GENERATOR RETURN_GENERATOR
-#define _RETURN_VALUE 563
-#define _SAVE_RETURN_OFFSET 564
-#define _SEND 565
-#define _SEND_GEN_FRAME 566
+#define _RETURN_VALUE 564
+#define _SAVE_RETURN_OFFSET 565
+#define _SEND 566
+#define _SEND_GEN_FRAME 567
 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
 #define _SET_ADD SET_ADD
 #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
-#define _SET_UPDATE 567
-#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 568
-#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 569
-#define _SPILL_OR_RELOAD 570
-#define _START_EXECUTOR 571
-#define _STORE_ATTR 572
-#define _STORE_ATTR_INSTANCE_VALUE 573
-#define _STORE_ATTR_SLOT 574
-#define _STORE_ATTR_WITH_HINT 575
+#define _SET_UPDATE 568
+#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 569
+#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 570
+#define _SPILL_OR_RELOAD 571
+#define _START_EXECUTOR 572
+#define _STORE_ATTR 573
+#define _STORE_ATTR_INSTANCE_VALUE 574
+#define _STORE_ATTR_SLOT 575
+#define _STORE_ATTR_WITH_HINT 576
 #define _STORE_DEREF STORE_DEREF
 #define _STORE_GLOBAL STORE_GLOBAL
 #define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 576
-#define _STORE_SUBSCR 577
-#define _STORE_SUBSCR_DICT 578
-#define _STORE_SUBSCR_LIST_INT 579
-#define _SWAP 580
-#define _SWAP_2 581
-#define _SWAP_3 582
-#define _SWAP_FAST 583
-#define _SWAP_FAST_0 584
-#define _SWAP_FAST_1 585
-#define _SWAP_FAST_2 586
-#define _SWAP_FAST_3 587
-#define _SWAP_FAST_4 588
-#define _SWAP_FAST_5 589
-#define _SWAP_FAST_6 590
-#define _SWAP_FAST_7 591
-#define _TIER2_RESUME_CHECK 592
-#define _TO_BOOL 593
+#define _STORE_SLICE 577
+#define _STORE_SUBSCR 578
+#define _STORE_SUBSCR_DICT 579
+#define _STORE_SUBSCR_LIST_INT 580
+#define _SWAP 581
+#define _SWAP_2 582
+#define _SWAP_3 583
+#define _SWAP_FAST 584
+#define _SWAP_FAST_0 585
+#define _SWAP_FAST_1 586
+#define _SWAP_FAST_2 587
+#define _SWAP_FAST_3 588
+#define _SWAP_FAST_4 589
+#define _SWAP_FAST_5 590
+#define _SWAP_FAST_6 591
+#define _SWAP_FAST_7 592
+#define _TIER2_RESUME_CHECK 593
+#define _TO_BOOL 594
 #define _TO_BOOL_BOOL TO_BOOL_BOOL
-#define _TO_BOOL_INT 594
-#define _TO_BOOL_LIST 595
+#define _TO_BOOL_INT 595
+#define _TO_BOOL_LIST 596
 #define _TO_BOOL_NONE TO_BOOL_NONE
-#define _TO_BOOL_STR 596
+#define _TO_BOOL_STR 597
 #define _TRACE_RECORD TRACE_RECORD
-#define _UNARY_INVERT 597
-#define _UNARY_NEGATIVE 598
+#define _UNARY_INVERT 598
+#define _UNARY_NEGATIVE 599
 #define _UNARY_NOT UNARY_NOT
 #define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 599
-#define _UNPACK_SEQUENCE_LIST 600
-#define _UNPACK_SEQUENCE_TUPLE 601
-#define _UNPACK_SEQUENCE_TWO_TUPLE 602
+#define _UNPACK_SEQUENCE 600
+#define _UNPACK_SEQUENCE_LIST 601
+#define _UNPACK_SEQUENCE_TUPLE 602
+#define _UNPACK_SEQUENCE_TWO_TUPLE 603
 #define _WITH_EXCEPT_START WITH_EXCEPT_START
-#define _YIELD_VALUE 603
-#define MAX_UOP_ID 603
-#define _BINARY_OP_r23 604
-#define _BINARY_OP_ADD_FLOAT_r03 605
-#define _BINARY_OP_ADD_FLOAT_r13 606
-#define _BINARY_OP_ADD_FLOAT_r23 607
-#define _BINARY_OP_ADD_INT_r03 608
-#define _BINARY_OP_ADD_INT_r13 609
-#define _BINARY_OP_ADD_INT_r23 610
-#define _BINARY_OP_ADD_UNICODE_r03 611
-#define _BINARY_OP_ADD_UNICODE_r13 612
-#define _BINARY_OP_ADD_UNICODE_r23 613
-#define _BINARY_OP_EXTEND_r23 614
-#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 615
-#define _BINARY_OP_MULTIPLY_FLOAT_r03 616
-#define _BINARY_OP_MULTIPLY_FLOAT_r13 617
-#define _BINARY_OP_MULTIPLY_FLOAT_r23 618
-#define _BINARY_OP_MULTIPLY_INT_r03 619
-#define _BINARY_OP_MULTIPLY_INT_r13 620
-#define _BINARY_OP_MULTIPLY_INT_r23 621
-#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 622
-#define _BINARY_OP_SUBSCR_DICT_r23 623
-#define _BINARY_OP_SUBSCR_INIT_CALL_r01 624
-#define _BINARY_OP_SUBSCR_INIT_CALL_r11 625
-#define _BINARY_OP_SUBSCR_INIT_CALL_r21 626
-#define _BINARY_OP_SUBSCR_INIT_CALL_r31 627
-#define _BINARY_OP_SUBSCR_LIST_INT_r23 628
-#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 629
-#define _BINARY_OP_SUBSCR_STR_INT_r23 630
-#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 631
-#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 632
-#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 633
-#define _BINARY_OP_SUBSCR_USTR_INT_r23 634
-#define _BINARY_OP_SUBTRACT_FLOAT_r03 635
-#define _BINARY_OP_SUBTRACT_FLOAT_r13 636
-#define _BINARY_OP_SUBTRACT_FLOAT_r23 637
-#define _BINARY_OP_SUBTRACT_INT_r03 638
-#define _BINARY_OP_SUBTRACT_INT_r13 639
-#define _BINARY_OP_SUBTRACT_INT_r23 640
-#define _BINARY_SLICE_r31 641
-#define _BUILD_INTERPOLATION_r01 642
-#define _BUILD_LIST_r01 643
-#define _BUILD_MAP_r01 644
-#define _BUILD_SET_r01 645
-#define _BUILD_SLICE_r01 646
-#define _BUILD_STRING_r01 647
-#define _BUILD_TEMPLATE_r21 648
-#define _BUILD_TUPLE_r01 649
-#define _CALL_BUILTIN_CLASS_r01 650
-#define _CALL_BUILTIN_FAST_r01 651
-#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 652
-#define _CALL_BUILTIN_O_r03 653
-#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 654
-#define _CALL_INTRINSIC_1_r12 655
-#define _CALL_INTRINSIC_2_r21 656
-#define _CALL_ISINSTANCE_r31 657
-#define _CALL_KW_NON_PY_r11 658
-#define _CALL_LEN_r33 659
-#define _CALL_LIST_APPEND_r03 660
-#define _CALL_LIST_APPEND_r13 661
-#define _CALL_LIST_APPEND_r23 662
-#define _CALL_LIST_APPEND_r33 663
-#define _CALL_METHOD_DESCRIPTOR_FAST_r01 664
-#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 665
-#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 666
-#define _CALL_METHOD_DESCRIPTOR_O_r03 667
-#define _CALL_NON_PY_GENERAL_r01 668
-#define _CALL_STR_1_r32 669
-#define _CALL_TUPLE_1_r32 670
-#define _CALL_TYPE_1_r02 671
-#define _CALL_TYPE_1_r12 672
-#define _CALL_TYPE_1_r22 673
-#define _CALL_TYPE_1_r32 674
-#define _CHECK_AND_ALLOCATE_OBJECT_r00 675
-#define _CHECK_ATTR_CLASS_r01 676
-#define _CHECK_ATTR_CLASS_r11 677
-#define _CHECK_ATTR_CLASS_r22 678
-#define _CHECK_ATTR_CLASS_r33 679
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 680
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 681
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 682
-#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 683
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 684
-#define _CHECK_EG_MATCH_r22 685
-#define _CHECK_EXC_MATCH_r22 686
-#define _CHECK_FUNCTION_EXACT_ARGS_r00 687
-#define _CHECK_FUNCTION_VERSION_r00 688
-#define _CHECK_FUNCTION_VERSION_INLINE_r00 689
-#define _CHECK_FUNCTION_VERSION_INLINE_r11 690
-#define _CHECK_FUNCTION_VERSION_INLINE_r22 691
-#define _CHECK_FUNCTION_VERSION_INLINE_r33 692
-#define _CHECK_FUNCTION_VERSION_KW_r11 693
-#define _CHECK_IS_NOT_PY_CALLABLE_r00 694
-#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 695
-#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 696
-#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 697
-#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 698
-#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 699
-#define _CHECK_IS_PY_CALLABLE_EX_r03 700
-#define _CHECK_IS_PY_CALLABLE_EX_r13 701
-#define _CHECK_IS_PY_CALLABLE_EX_r23 702
-#define _CHECK_IS_PY_CALLABLE_EX_r33 703
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 704
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 705
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 706
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 707
-#define _CHECK_METHOD_VERSION_r00 708
-#define _CHECK_METHOD_VERSION_KW_r11 709
-#define _CHECK_PEP_523_r00 710
-#define _CHECK_PEP_523_r11 711
-#define _CHECK_PEP_523_r22 712
-#define _CHECK_PEP_523_r33 713
-#define _CHECK_PERIODIC_r00 714
-#define _CHECK_PERIODIC_AT_END_r00 715
-#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 716
-#define _CHECK_RECURSION_REMAINING_r00 717
-#define _CHECK_RECURSION_REMAINING_r11 718
-#define _CHECK_RECURSION_REMAINING_r22 719
-#define _CHECK_RECURSION_REMAINING_r33 720
-#define _CHECK_STACK_SPACE_r00 721
-#define _CHECK_STACK_SPACE_OPERAND_r00 722
-#define _CHECK_STACK_SPACE_OPERAND_r11 723
-#define _CHECK_STACK_SPACE_OPERAND_r22 724
-#define _CHECK_STACK_SPACE_OPERAND_r33 725
-#define _CHECK_VALIDITY_r00 726
-#define _CHECK_VALIDITY_r11 727
-#define _CHECK_VALIDITY_r22 728
-#define _CHECK_VALIDITY_r33 729
-#define _COLD_DYNAMIC_EXIT_r00 730
-#define _COLD_EXIT_r00 731
-#define _COMPARE_OP_r21 732
-#define _COMPARE_OP_FLOAT_r03 733
-#define _COMPARE_OP_FLOAT_r13 734
-#define _COMPARE_OP_FLOAT_r23 735
-#define _COMPARE_OP_INT_r23 736
-#define _COMPARE_OP_STR_r23 737
-#define _CONTAINS_OP_r23 738
-#define _CONTAINS_OP_DICT_r23 739
-#define _CONTAINS_OP_SET_r23 740
-#define _CONVERT_VALUE_r11 741
-#define _COPY_r01 742
-#define _COPY_1_r02 743
-#define _COPY_1_r12 744
-#define _COPY_1_r23 745
-#define _COPY_2_r03 746
-#define _COPY_2_r13 747
-#define _COPY_2_r23 748
-#define _COPY_3_r03 749
-#define _COPY_3_r13 750
-#define _COPY_3_r23 751
-#define _COPY_3_r33 752
-#define _COPY_FREE_VARS_r00 753
-#define _COPY_FREE_VARS_r11 754
-#define _COPY_FREE_VARS_r22 755
-#define _COPY_FREE_VARS_r33 756
-#define _CREATE_INIT_FRAME_r01 757
-#define _DELETE_ATTR_r10 758
-#define _DELETE_DEREF_r00 759
-#define _DELETE_FAST_r00 760
-#define _DELETE_GLOBAL_r00 761
-#define _DELETE_NAME_r00 762
-#define _DELETE_SUBSCR_r20 763
-#define _DEOPT_r00 764
-#define _DEOPT_r10 765
-#define _DEOPT_r20 766
-#define _DEOPT_r30 767
-#define _DICT_MERGE_r10 768
-#define _DICT_UPDATE_r10 769
-#define _DO_CALL_r01 770
-#define _DO_CALL_FUNCTION_EX_r31 771
-#define _DO_CALL_KW_r11 772
-#define _DYNAMIC_EXIT_r00 773
-#define _DYNAMIC_EXIT_r10 774
-#define _DYNAMIC_EXIT_r20 775
-#define _DYNAMIC_EXIT_r30 776
-#define _END_FOR_r10 777
-#define _END_SEND_r21 778
-#define _ERROR_POP_N_r00 779
-#define _EXIT_INIT_CHECK_r10 780
-#define _EXIT_TRACE_r00 781
-#define _EXIT_TRACE_r10 782
-#define _EXIT_TRACE_r20 783
-#define _EXIT_TRACE_r30 784
-#define _EXPAND_METHOD_r00 785
-#define _EXPAND_METHOD_KW_r11 786
-#define _FATAL_ERROR_r00 787
-#define _FATAL_ERROR_r11 788
-#define _FATAL_ERROR_r22 789
-#define _FATAL_ERROR_r33 790
-#define _FORMAT_SIMPLE_r11 791
-#define _FORMAT_WITH_SPEC_r21 792
-#define _FOR_ITER_r23 793
-#define _FOR_ITER_GEN_FRAME_r03 794
-#define _FOR_ITER_GEN_FRAME_r13 795
-#define _FOR_ITER_GEN_FRAME_r23 796
-#define _FOR_ITER_TIER_TWO_r23 797
-#define _GET_AITER_r11 798
-#define _GET_ANEXT_r12 799
-#define _GET_AWAITABLE_r11 800
-#define _GET_ITER_r12 801
-#define _GET_LEN_r12 802
-#define _GET_YIELD_FROM_ITER_r11 803
+#define _YIELD_VALUE 604
+#define MAX_UOP_ID 604
+#define _BINARY_OP_r23 605
+#define _BINARY_OP_ADD_FLOAT_r03 606
+#define _BINARY_OP_ADD_FLOAT_r13 607
+#define _BINARY_OP_ADD_FLOAT_r23 608
+#define _BINARY_OP_ADD_INT_r03 609
+#define _BINARY_OP_ADD_INT_r13 610
+#define _BINARY_OP_ADD_INT_r23 611
+#define _BINARY_OP_ADD_UNICODE_r03 612
+#define _BINARY_OP_ADD_UNICODE_r13 613
+#define _BINARY_OP_ADD_UNICODE_r23 614
+#define _BINARY_OP_EXTEND_r23 615
+#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 616
+#define _BINARY_OP_MULTIPLY_FLOAT_r03 617
+#define _BINARY_OP_MULTIPLY_FLOAT_r13 618
+#define _BINARY_OP_MULTIPLY_FLOAT_r23 619
+#define _BINARY_OP_MULTIPLY_INT_r03 620
+#define _BINARY_OP_MULTIPLY_INT_r13 621
+#define _BINARY_OP_MULTIPLY_INT_r23 622
+#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 623
+#define _BINARY_OP_SUBSCR_DICT_r23 624
+#define _BINARY_OP_SUBSCR_INIT_CALL_r01 625
+#define _BINARY_OP_SUBSCR_INIT_CALL_r11 626
+#define _BINARY_OP_SUBSCR_INIT_CALL_r21 627
+#define _BINARY_OP_SUBSCR_INIT_CALL_r31 628
+#define _BINARY_OP_SUBSCR_LIST_INT_r23 629
+#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 630
+#define _BINARY_OP_SUBSCR_STR_INT_r23 631
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 632
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 633
+#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 634
+#define _BINARY_OP_SUBSCR_USTR_INT_r23 635
+#define _BINARY_OP_SUBTRACT_FLOAT_r03 636
+#define _BINARY_OP_SUBTRACT_FLOAT_r13 637
+#define _BINARY_OP_SUBTRACT_FLOAT_r23 638
+#define _BINARY_OP_SUBTRACT_INT_r03 639
+#define _BINARY_OP_SUBTRACT_INT_r13 640
+#define _BINARY_OP_SUBTRACT_INT_r23 641
+#define _BINARY_SLICE_r31 642
+#define _BUILD_INTERPOLATION_r01 643
+#define _BUILD_LIST_r01 644
+#define _BUILD_MAP_r01 645
+#define _BUILD_SET_r01 646
+#define _BUILD_SLICE_r01 647
+#define _BUILD_STRING_r01 648
+#define _BUILD_TEMPLATE_r21 649
+#define _BUILD_TUPLE_r01 650
+#define _CALL_BUILTIN_CLASS_r01 651
+#define _CALL_BUILTIN_FAST_r01 652
+#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 653
+#define _CALL_BUILTIN_O_r03 654
+#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 655
+#define _CALL_INTRINSIC_1_r12 656
+#define _CALL_INTRINSIC_2_r21 657
+#define _CALL_ISINSTANCE_r31 658
+#define _CALL_KW_NON_PY_r11 659
+#define _CALL_LEN_r33 660
+#define _CALL_LIST_APPEND_r03 661
+#define _CALL_LIST_APPEND_r13 662
+#define _CALL_LIST_APPEND_r23 663
+#define _CALL_LIST_APPEND_r33 664
+#define _CALL_METHOD_DESCRIPTOR_FAST_r01 665
+#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 666
+#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 667
+#define _CALL_METHOD_DESCRIPTOR_O_r03 668
+#define _CALL_NON_PY_GENERAL_r01 669
+#define _CALL_STR_1_r32 670
+#define _CALL_TUPLE_1_r32 671
+#define _CALL_TYPE_1_r02 672
+#define _CALL_TYPE_1_r12 673
+#define _CALL_TYPE_1_r22 674
+#define _CALL_TYPE_1_r32 675
+#define _CHECK_AND_ALLOCATE_OBJECT_r00 676
+#define _CHECK_ATTR_CLASS_r01 677
+#define _CHECK_ATTR_CLASS_r11 678
+#define _CHECK_ATTR_CLASS_r22 679
+#define _CHECK_ATTR_CLASS_r33 680
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 681
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 682
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 683
+#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 684
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 685
+#define _CHECK_EG_MATCH_r22 686
+#define _CHECK_EXC_MATCH_r22 687
+#define _CHECK_FUNCTION_EXACT_ARGS_r00 688
+#define _CHECK_FUNCTION_VERSION_r00 689
+#define _CHECK_FUNCTION_VERSION_INLINE_r00 690
+#define _CHECK_FUNCTION_VERSION_INLINE_r11 691
+#define _CHECK_FUNCTION_VERSION_INLINE_r22 692
+#define _CHECK_FUNCTION_VERSION_INLINE_r33 693
+#define _CHECK_FUNCTION_VERSION_KW_r11 694
+#define _CHECK_IS_NOT_PY_CALLABLE_r00 695
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 696
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 697
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 698
+#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 699
+#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 700
+#define _CHECK_IS_PY_CALLABLE_EX_r03 701
+#define _CHECK_IS_PY_CALLABLE_EX_r13 702
+#define _CHECK_IS_PY_CALLABLE_EX_r23 703
+#define _CHECK_IS_PY_CALLABLE_EX_r33 704
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 705
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 706
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 707
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 708
+#define _CHECK_METHOD_VERSION_r00 709
+#define _CHECK_METHOD_VERSION_KW_r11 710
+#define _CHECK_PEP_523_r00 711
+#define _CHECK_PEP_523_r11 712
+#define _CHECK_PEP_523_r22 713
+#define _CHECK_PEP_523_r33 714
+#define _CHECK_PERIODIC_r00 715
+#define _CHECK_PERIODIC_AT_END_r00 716
+#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 717
+#define _CHECK_RECURSION_REMAINING_r00 718
+#define _CHECK_RECURSION_REMAINING_r11 719
+#define _CHECK_RECURSION_REMAINING_r22 720
+#define _CHECK_RECURSION_REMAINING_r33 721
+#define _CHECK_STACK_SPACE_r00 722
+#define _CHECK_STACK_SPACE_OPERAND_r00 723
+#define _CHECK_STACK_SPACE_OPERAND_r11 724
+#define _CHECK_STACK_SPACE_OPERAND_r22 725
+#define _CHECK_STACK_SPACE_OPERAND_r33 726
+#define _CHECK_VALIDITY_r00 727
+#define _CHECK_VALIDITY_r11 728
+#define _CHECK_VALIDITY_r22 729
+#define _CHECK_VALIDITY_r33 730
+#define _COLD_DYNAMIC_EXIT_r00 731
+#define _COLD_EXIT_r00 732
+#define _COMPARE_OP_r21 733
+#define _COMPARE_OP_FLOAT_r03 734
+#define _COMPARE_OP_FLOAT_r13 735
+#define _COMPARE_OP_FLOAT_r23 736
+#define _COMPARE_OP_INT_r23 737
+#define _COMPARE_OP_STR_r23 738
+#define _CONTAINS_OP_r23 739
+#define _CONTAINS_OP_DICT_r23 740
+#define _CONTAINS_OP_SET_r23 741
+#define _CONVERT_VALUE_r11 742
+#define _COPY_r01 743
+#define _COPY_1_r02 744
+#define _COPY_1_r12 745
+#define _COPY_1_r23 746
+#define _COPY_2_r03 747
+#define _COPY_2_r13 748
+#define _COPY_2_r23 749
+#define _COPY_3_r03 750
+#define _COPY_3_r13 751
+#define _COPY_3_r23 752
+#define _COPY_3_r33 753
+#define _COPY_FREE_VARS_r00 754
+#define _COPY_FREE_VARS_r11 755
+#define _COPY_FREE_VARS_r22 756
+#define _COPY_FREE_VARS_r33 757
+#define _CREATE_INIT_FRAME_r01 758
+#define _DELETE_ATTR_r10 759
+#define _DELETE_DEREF_r00 760
+#define _DELETE_FAST_r00 761
+#define _DELETE_GLOBAL_r00 762
+#define _DELETE_NAME_r00 763
+#define _DELETE_SUBSCR_r20 764
+#define _DEOPT_r00 765
+#define _DEOPT_r10 766
+#define _DEOPT_r20 767
+#define _DEOPT_r30 768
+#define _DICT_MERGE_r10 769
+#define _DICT_UPDATE_r10 770
+#define _DO_CALL_r01 771
+#define _DO_CALL_FUNCTION_EX_r31 772
+#define _DO_CALL_KW_r11 773
+#define _DYNAMIC_EXIT_r00 774
+#define _DYNAMIC_EXIT_r10 775
+#define _DYNAMIC_EXIT_r20 776
+#define _DYNAMIC_EXIT_r30 777
+#define _END_FOR_r10 778
+#define _END_SEND_r31 779
+#define _ERROR_POP_N_r00 780
+#define _EXIT_INIT_CHECK_r10 781
+#define _EXIT_TRACE_r00 782
+#define _EXIT_TRACE_r10 783
+#define _EXIT_TRACE_r20 784
+#define _EXIT_TRACE_r30 785
+#define _EXPAND_METHOD_r00 786
+#define _EXPAND_METHOD_KW_r11 787
+#define _FATAL_ERROR_r00 788
+#define _FATAL_ERROR_r11 789
+#define _FATAL_ERROR_r22 790
+#define _FATAL_ERROR_r33 791
+#define _FORMAT_SIMPLE_r11 792
+#define _FORMAT_WITH_SPEC_r21 793
+#define _FOR_ITER_r23 794
+#define _FOR_ITER_GEN_FRAME_r03 795
+#define _FOR_ITER_GEN_FRAME_r13 796
+#define _FOR_ITER_GEN_FRAME_r23 797
+#define _FOR_ITER_TIER_TWO_r23 798
+#define _GET_AITER_r11 799
+#define _GET_ANEXT_r12 800
+#define _GET_AWAITABLE_r11 801
+#define _GET_ITER_r12 802
+#define _GET_LEN_r12 803
 #define _GUARD_BINARY_OP_EXTEND_r22 804
 #define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 805
 #define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 806
@@ -1168,8 +1167,8 @@ extern "C" {
 #define _SAVE_RETURN_OFFSET_r11 1371
 #define _SAVE_RETURN_OFFSET_r22 1372
 #define _SAVE_RETURN_OFFSET_r33 1373
-#define _SEND_r22 1374
-#define _SEND_GEN_FRAME_r22 1375
+#define _SEND_r33 1374
+#define _SEND_GEN_FRAME_r33 1375
 #define _SETUP_ANNOTATIONS_r00 1376
 #define _SET_ADD_r10 1377
 #define _SET_FUNCTION_ATTRIBUTE_r01 1378
index 744f6438659db8ace6eade78cbc02c28acd89d14..3fec783ca2de2ed1bc768f12516eb240c4dc24f5 100644 (file)
@@ -229,8 +229,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_MATCH_MAPPING] = 0,
     [_MATCH_SEQUENCE] = 0,
     [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
-    [_GET_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
-    [_GET_YIELD_FROM_ITER] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+    [_GET_ITER] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
     [_FOR_ITER_TIER_TWO] = HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
     [_ITER_CHECK_LIST] = HAS_EXIT_FLAG,
     [_GUARD_NOT_EXHAUSTED_LIST] = HAS_EXIT_FLAG,
@@ -389,6 +388,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_RECORD_TOS_TYPE] = HAS_RECORDS_VALUE_FLAG,
     [_RECORD_NOS] = HAS_RECORDS_VALUE_FLAG,
     [_RECORD_NOS_GEN_FUNC] = HAS_RECORDS_VALUE_FLAG,
+    [_RECORD_3OS_GEN_FUNC] = HAS_RECORDS_VALUE_FLAG,
     [_RECORD_4OS] = HAS_RECORDS_VALUE_FLAG,
     [_RECORD_CALLABLE] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
     [_RECORD_BOUND_METHOD] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
@@ -841,12 +841,12 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
         },
     },
     [_END_SEND] = {
-        .best = { 2, 2, 2, 2 },
+        .best = { 3, 3, 3, 3 },
         .entries = {
             { -1, -1, -1 },
             { -1, -1, -1 },
-            { 1, 2, _END_SEND_r21 },
             { -1, -1, -1 },
+            { 1, 3, _END_SEND_r31 },
         },
     },
     [_UNARY_NEGATIVE] = {
@@ -1417,12 +1417,12 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
         },
     },
     [_SEND_GEN_FRAME] = {
-        .best = { 2, 2, 2, 2 },
+        .best = { 3, 3, 3, 3 },
         .entries = {
             { -1, -1, -1 },
             { -1, -1, -1 },
-            { 2, 2, _SEND_GEN_FRAME_r22 },
             { -1, -1, -1 },
+            { 3, 3, _SEND_GEN_FRAME_r33 },
         },
     },
     [_YIELD_VALUE] = {
@@ -2163,15 +2163,6 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
             { -1, -1, -1 },
         },
     },
-    [_GET_YIELD_FROM_ITER] = {
-        .best = { 1, 1, 1, 1 },
-        .entries = {
-            { -1, -1, -1 },
-            { 1, 1, _GET_YIELD_FROM_ITER_r11 },
-            { -1, -1, -1 },
-            { -1, -1, -1 },
-        },
-    },
     [_FOR_ITER_TIER_TWO] = {
         .best = { 2, 2, 2, 2 },
         .entries = {
@@ -3699,7 +3690,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
     [_PUSH_NULL_r23] = _PUSH_NULL,
     [_END_FOR_r10] = _END_FOR,
     [_POP_ITER_r20] = _POP_ITER,
-    [_END_SEND_r21] = _END_SEND,
+    [_END_SEND_r31] = _END_SEND,
     [_UNARY_NEGATIVE_r12] = _UNARY_NEGATIVE,
     [_UNARY_NOT_r01] = _UNARY_NOT,
     [_UNARY_NOT_r11] = _UNARY_NOT,
@@ -3862,7 +3853,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
     [_GET_AITER_r11] = _GET_AITER,
     [_GET_ANEXT_r12] = _GET_ANEXT,
     [_GET_AWAITABLE_r11] = _GET_AWAITABLE,
-    [_SEND_GEN_FRAME_r22] = _SEND_GEN_FRAME,
+    [_SEND_GEN_FRAME_r33] = _SEND_GEN_FRAME,
     [_YIELD_VALUE_r11] = _YIELD_VALUE,
     [_POP_EXCEPT_r10] = _POP_EXCEPT,
     [_LOAD_COMMON_CONSTANT_r01] = _LOAD_COMMON_CONSTANT,
@@ -3994,7 +3985,6 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
     [_MATCH_SEQUENCE_r23] = _MATCH_SEQUENCE,
     [_MATCH_KEYS_r23] = _MATCH_KEYS,
     [_GET_ITER_r12] = _GET_ITER,
-    [_GET_YIELD_FROM_ITER_r11] = _GET_YIELD_FROM_ITER,
     [_FOR_ITER_TIER_TWO_r23] = _FOR_ITER_TIER_TWO,
     [_ITER_CHECK_LIST_r02] = _ITER_CHECK_LIST,
     [_ITER_CHECK_LIST_r12] = _ITER_CHECK_LIST,
@@ -4667,7 +4657,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
     [_END_FOR] = "_END_FOR",
     [_END_FOR_r10] = "_END_FOR_r10",
     [_END_SEND] = "_END_SEND",
-    [_END_SEND_r21] = "_END_SEND_r21",
+    [_END_SEND_r31] = "_END_SEND_r31",
     [_ERROR_POP_N] = "_ERROR_POP_N",
     [_ERROR_POP_N_r00] = "_ERROR_POP_N_r00",
     [_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
@@ -4706,8 +4696,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
     [_GET_ITER_r12] = "_GET_ITER_r12",
     [_GET_LEN] = "_GET_LEN",
     [_GET_LEN_r12] = "_GET_LEN_r12",
-    [_GET_YIELD_FROM_ITER] = "_GET_YIELD_FROM_ITER",
-    [_GET_YIELD_FROM_ITER_r11] = "_GET_YIELD_FROM_ITER_r11",
     [_GUARD_BINARY_OP_EXTEND] = "_GUARD_BINARY_OP_EXTEND",
     [_GUARD_BINARY_OP_EXTEND_r22] = "_GUARD_BINARY_OP_EXTEND_r22",
     [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS",
@@ -5386,6 +5374,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
     [_PY_FRAME_GENERAL_r01] = "_PY_FRAME_GENERAL_r01",
     [_PY_FRAME_KW] = "_PY_FRAME_KW",
     [_PY_FRAME_KW_r11] = "_PY_FRAME_KW_r11",
+    [_RECORD_3OS_GEN_FUNC] = "_RECORD_3OS_GEN_FUNC",
     [_RECORD_4OS] = "_RECORD_4OS",
     [_RECORD_BOUND_METHOD] = "_RECORD_BOUND_METHOD",
     [_RECORD_CALLABLE] = "_RECORD_CALLABLE",
@@ -5413,7 +5402,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
     [_SAVE_RETURN_OFFSET_r22] = "_SAVE_RETURN_OFFSET_r22",
     [_SAVE_RETURN_OFFSET_r33] = "_SAVE_RETURN_OFFSET_r33",
     [_SEND_GEN_FRAME] = "_SEND_GEN_FRAME",
-    [_SEND_GEN_FRAME_r22] = "_SEND_GEN_FRAME_r22",
+    [_SEND_GEN_FRAME_r33] = "_SEND_GEN_FRAME_r33",
     [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS",
     [_SETUP_ANNOTATIONS_r00] = "_SETUP_ANNOTATIONS_r00",
     [_SET_ADD] = "_SET_ADD",
@@ -5687,7 +5676,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _POP_ITER:
             return 2;
         case _END_SEND:
-            return 2;
+            return 3;
         case _UNARY_NEGATIVE:
             return 1;
         case _UNARY_NOT:
@@ -5980,8 +5969,6 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _GET_ITER:
             return 1;
-        case _GET_YIELD_FROM_ITER:
-            return 1;
         case _FOR_ITER_TIER_TWO:
             return 0;
         case _ITER_CHECK_LIST:
@@ -6298,6 +6285,8 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _RECORD_NOS_GEN_FUNC:
             return 0;
+        case _RECORD_3OS_GEN_FUNC:
+            return 0;
         case _RECORD_4OS:
             return 0;
         case _RECORD_CALLABLE:
index f9173fd83c295e01e8d08d9316472031d81fefe2..ac6d4d964d3b5e833f4dd614bd7e7d25d11bbe60 100644 (file)
@@ -26,111 +26,110 @@ extern "C" {
 #define FORMAT_WITH_SPEC                        13
 #define GET_AITER                               14
 #define GET_ANEXT                               15
-#define GET_ITER                                16
+#define GET_LEN                                 16
 #define RESERVED                                17
-#define GET_LEN                                 18
-#define GET_YIELD_FROM_ITER                     19
-#define INTERPRETER_EXIT                        20
-#define LOAD_BUILD_CLASS                        21
-#define LOAD_LOCALS                             22
-#define MAKE_FUNCTION                           23
-#define MATCH_KEYS                              24
-#define MATCH_MAPPING                           25
-#define MATCH_SEQUENCE                          26
-#define NOP                                     27
-#define NOT_TAKEN                               28
-#define POP_EXCEPT                              29
-#define POP_ITER                                30
-#define POP_TOP                                 31
-#define PUSH_EXC_INFO                           32
-#define PUSH_NULL                               33
-#define RETURN_GENERATOR                        34
-#define RETURN_VALUE                            35
-#define SETUP_ANNOTATIONS                       36
-#define STORE_SLICE                             37
-#define STORE_SUBSCR                            38
-#define TO_BOOL                                 39
-#define UNARY_INVERT                            40
-#define UNARY_NEGATIVE                          41
-#define UNARY_NOT                               42
-#define WITH_EXCEPT_START                       43
-#define BINARY_OP                               44
-#define BUILD_INTERPOLATION                     45
-#define BUILD_LIST                              46
-#define BUILD_MAP                               47
-#define BUILD_SET                               48
-#define BUILD_SLICE                             49
-#define BUILD_STRING                            50
-#define BUILD_TUPLE                             51
-#define CALL                                    52
-#define CALL_INTRINSIC_1                        53
-#define CALL_INTRINSIC_2                        54
-#define CALL_KW                                 55
-#define COMPARE_OP                              56
-#define CONTAINS_OP                             57
-#define CONVERT_VALUE                           58
-#define COPY                                    59
-#define COPY_FREE_VARS                          60
-#define DELETE_ATTR                             61
-#define DELETE_DEREF                            62
-#define DELETE_FAST                             63
-#define DELETE_GLOBAL                           64
-#define DELETE_NAME                             65
-#define DICT_MERGE                              66
-#define DICT_UPDATE                             67
-#define END_ASYNC_FOR                           68
-#define EXTENDED_ARG                            69
-#define FOR_ITER                                70
-#define GET_AWAITABLE                           71
-#define IMPORT_FROM                             72
-#define IMPORT_NAME                             73
-#define IS_OP                                   74
-#define JUMP_BACKWARD                           75
-#define JUMP_BACKWARD_NO_INTERRUPT              76
-#define JUMP_FORWARD                            77
-#define LIST_APPEND                             78
-#define LIST_EXTEND                             79
-#define LOAD_ATTR                               80
-#define LOAD_COMMON_CONSTANT                    81
-#define LOAD_CONST                              82
-#define LOAD_DEREF                              83
-#define LOAD_FAST                               84
-#define LOAD_FAST_AND_CLEAR                     85
-#define LOAD_FAST_BORROW                        86
-#define LOAD_FAST_BORROW_LOAD_FAST_BORROW       87
-#define LOAD_FAST_CHECK                         88
-#define LOAD_FAST_LOAD_FAST                     89
-#define LOAD_FROM_DICT_OR_DEREF                 90
-#define LOAD_FROM_DICT_OR_GLOBALS               91
-#define LOAD_GLOBAL                             92
-#define LOAD_NAME                               93
-#define LOAD_SMALL_INT                          94
-#define LOAD_SPECIAL                            95
-#define LOAD_SUPER_ATTR                         96
-#define MAKE_CELL                               97
-#define MAP_ADD                                 98
-#define MATCH_CLASS                             99
-#define POP_JUMP_IF_FALSE                      100
-#define POP_JUMP_IF_NONE                       101
-#define POP_JUMP_IF_NOT_NONE                   102
-#define POP_JUMP_IF_TRUE                       103
-#define RAISE_VARARGS                          104
-#define RERAISE                                105
-#define SEND                                   106
-#define SET_ADD                                107
-#define SET_FUNCTION_ATTRIBUTE                 108
-#define SET_UPDATE                             109
-#define STORE_ATTR                             110
-#define STORE_DEREF                            111
-#define STORE_FAST                             112
-#define STORE_FAST_LOAD_FAST                   113
-#define STORE_FAST_STORE_FAST                  114
-#define STORE_GLOBAL                           115
-#define STORE_NAME                             116
-#define SWAP                                   117
-#define UNPACK_EX                              118
-#define UNPACK_SEQUENCE                        119
-#define YIELD_VALUE                            120
+#define INTERPRETER_EXIT                        18
+#define LOAD_BUILD_CLASS                        19
+#define LOAD_LOCALS                             20
+#define MAKE_FUNCTION                           21
+#define MATCH_KEYS                              22
+#define MATCH_MAPPING                           23
+#define MATCH_SEQUENCE                          24
+#define NOP                                     25
+#define NOT_TAKEN                               26
+#define POP_EXCEPT                              27
+#define POP_ITER                                28
+#define POP_TOP                                 29
+#define PUSH_EXC_INFO                           30
+#define PUSH_NULL                               31
+#define RETURN_GENERATOR                        32
+#define RETURN_VALUE                            33
+#define SETUP_ANNOTATIONS                       34
+#define STORE_SLICE                             35
+#define STORE_SUBSCR                            36
+#define TO_BOOL                                 37
+#define UNARY_INVERT                            38
+#define UNARY_NEGATIVE                          39
+#define UNARY_NOT                               40
+#define WITH_EXCEPT_START                       41
+#define BINARY_OP                               42
+#define BUILD_INTERPOLATION                     43
+#define BUILD_LIST                              44
+#define BUILD_MAP                               45
+#define BUILD_SET                               46
+#define BUILD_SLICE                             47
+#define BUILD_STRING                            48
+#define BUILD_TUPLE                             49
+#define CALL                                    50
+#define CALL_INTRINSIC_1                        51
+#define CALL_INTRINSIC_2                        52
+#define CALL_KW                                 53
+#define COMPARE_OP                              54
+#define CONTAINS_OP                             55
+#define CONVERT_VALUE                           56
+#define COPY                                    57
+#define COPY_FREE_VARS                          58
+#define DELETE_ATTR                             59
+#define DELETE_DEREF                            60
+#define DELETE_FAST                             61
+#define DELETE_GLOBAL                           62
+#define DELETE_NAME                             63
+#define DICT_MERGE                              64
+#define DICT_UPDATE                             65
+#define END_ASYNC_FOR                           66
+#define EXTENDED_ARG                            67
+#define FOR_ITER                                68
+#define GET_AWAITABLE                           69
+#define GET_ITER                                70
+#define IMPORT_FROM                             71
+#define IMPORT_NAME                             72
+#define IS_OP                                   73
+#define JUMP_BACKWARD                           74
+#define JUMP_BACKWARD_NO_INTERRUPT              75
+#define JUMP_FORWARD                            76
+#define LIST_APPEND                             77
+#define LIST_EXTEND                             78
+#define LOAD_ATTR                               79
+#define LOAD_COMMON_CONSTANT                    80
+#define LOAD_CONST                              81
+#define LOAD_DEREF                              82
+#define LOAD_FAST                               83
+#define LOAD_FAST_AND_CLEAR                     84
+#define LOAD_FAST_BORROW                        85
+#define LOAD_FAST_BORROW_LOAD_FAST_BORROW       86
+#define LOAD_FAST_CHECK                         87
+#define LOAD_FAST_LOAD_FAST                     88
+#define LOAD_FROM_DICT_OR_DEREF                 89
+#define LOAD_FROM_DICT_OR_GLOBALS               90
+#define LOAD_GLOBAL                             91
+#define LOAD_NAME                               92
+#define LOAD_SMALL_INT                          93
+#define LOAD_SPECIAL                            94
+#define LOAD_SUPER_ATTR                         95
+#define MAKE_CELL                               96
+#define MAP_ADD                                 97
+#define MATCH_CLASS                             98
+#define POP_JUMP_IF_FALSE                       99
+#define POP_JUMP_IF_NONE                       100
+#define POP_JUMP_IF_NOT_NONE                   101
+#define POP_JUMP_IF_TRUE                       102
+#define RAISE_VARARGS                          103
+#define RERAISE                                104
+#define SEND                                   105
+#define SET_ADD                                106
+#define SET_FUNCTION_ATTRIBUTE                 107
+#define SET_UPDATE                             108
+#define STORE_ATTR                             109
+#define STORE_DEREF                            110
+#define STORE_FAST                             111
+#define STORE_FAST_LOAD_FAST                   112
+#define STORE_FAST_STORE_FAST                  113
+#define STORE_GLOBAL                           114
+#define STORE_NAME                             115
+#define SWAP                                   116
+#define UNPACK_EX                              117
+#define UNPACK_SEQUENCE                        118
+#define YIELD_VALUE                            119
 #define RESUME                                 128
 #define BINARY_OP_ADD_FLOAT                    129
 #define BINARY_OP_ADD_INT                      130
@@ -252,7 +251,7 @@ extern "C" {
 #define SETUP_WITH                             265
 #define STORE_FAST_MAYBE_NULL                  266
 
-#define HAVE_ARGUMENT                           43
+#define HAVE_ARGUMENT                           41
 #define MIN_SPECIALIZED_OPCODE                 129
 #define MIN_INSTRUMENTED_OPCODE                233
 
index 8d2c1ece8bc6a82c5a4434c46a4909c94042e699..f5954e4372a980a80456019f298e333a850a0e60 100644 (file)
@@ -235,110 +235,109 @@ opmap = frozendict(
     FORMAT_WITH_SPEC=13,
     GET_AITER=14,
     GET_ANEXT=15,
-    GET_ITER=16,
-    GET_LEN=18,
-    GET_YIELD_FROM_ITER=19,
-    INTERPRETER_EXIT=20,
-    LOAD_BUILD_CLASS=21,
-    LOAD_LOCALS=22,
-    MAKE_FUNCTION=23,
-    MATCH_KEYS=24,
-    MATCH_MAPPING=25,
-    MATCH_SEQUENCE=26,
-    NOP=27,
-    NOT_TAKEN=28,
-    POP_EXCEPT=29,
-    POP_ITER=30,
-    POP_TOP=31,
-    PUSH_EXC_INFO=32,
-    PUSH_NULL=33,
-    RETURN_GENERATOR=34,
-    RETURN_VALUE=35,
-    SETUP_ANNOTATIONS=36,
-    STORE_SLICE=37,
-    STORE_SUBSCR=38,
-    TO_BOOL=39,
-    UNARY_INVERT=40,
-    UNARY_NEGATIVE=41,
-    UNARY_NOT=42,
-    WITH_EXCEPT_START=43,
-    BINARY_OP=44,
-    BUILD_INTERPOLATION=45,
-    BUILD_LIST=46,
-    BUILD_MAP=47,
-    BUILD_SET=48,
-    BUILD_SLICE=49,
-    BUILD_STRING=50,
-    BUILD_TUPLE=51,
-    CALL=52,
-    CALL_INTRINSIC_1=53,
-    CALL_INTRINSIC_2=54,
-    CALL_KW=55,
-    COMPARE_OP=56,
-    CONTAINS_OP=57,
-    CONVERT_VALUE=58,
-    COPY=59,
-    COPY_FREE_VARS=60,
-    DELETE_ATTR=61,
-    DELETE_DEREF=62,
-    DELETE_FAST=63,
-    DELETE_GLOBAL=64,
-    DELETE_NAME=65,
-    DICT_MERGE=66,
-    DICT_UPDATE=67,
-    END_ASYNC_FOR=68,
-    EXTENDED_ARG=69,
-    FOR_ITER=70,
-    GET_AWAITABLE=71,
-    IMPORT_FROM=72,
-    IMPORT_NAME=73,
-    IS_OP=74,
-    JUMP_BACKWARD=75,
-    JUMP_BACKWARD_NO_INTERRUPT=76,
-    JUMP_FORWARD=77,
-    LIST_APPEND=78,
-    LIST_EXTEND=79,
-    LOAD_ATTR=80,
-    LOAD_COMMON_CONSTANT=81,
-    LOAD_CONST=82,
-    LOAD_DEREF=83,
-    LOAD_FAST=84,
-    LOAD_FAST_AND_CLEAR=85,
-    LOAD_FAST_BORROW=86,
-    LOAD_FAST_BORROW_LOAD_FAST_BORROW=87,
-    LOAD_FAST_CHECK=88,
-    LOAD_FAST_LOAD_FAST=89,
-    LOAD_FROM_DICT_OR_DEREF=90,
-    LOAD_FROM_DICT_OR_GLOBALS=91,
-    LOAD_GLOBAL=92,
-    LOAD_NAME=93,
-    LOAD_SMALL_INT=94,
-    LOAD_SPECIAL=95,
-    LOAD_SUPER_ATTR=96,
-    MAKE_CELL=97,
-    MAP_ADD=98,
-    MATCH_CLASS=99,
-    POP_JUMP_IF_FALSE=100,
-    POP_JUMP_IF_NONE=101,
-    POP_JUMP_IF_NOT_NONE=102,
-    POP_JUMP_IF_TRUE=103,
-    RAISE_VARARGS=104,
-    RERAISE=105,
-    SEND=106,
-    SET_ADD=107,
-    SET_FUNCTION_ATTRIBUTE=108,
-    SET_UPDATE=109,
-    STORE_ATTR=110,
-    STORE_DEREF=111,
-    STORE_FAST=112,
-    STORE_FAST_LOAD_FAST=113,
-    STORE_FAST_STORE_FAST=114,
-    STORE_GLOBAL=115,
-    STORE_NAME=116,
-    SWAP=117,
-    UNPACK_EX=118,
-    UNPACK_SEQUENCE=119,
-    YIELD_VALUE=120,
+    GET_LEN=16,
+    INTERPRETER_EXIT=18,
+    LOAD_BUILD_CLASS=19,
+    LOAD_LOCALS=20,
+    MAKE_FUNCTION=21,
+    MATCH_KEYS=22,
+    MATCH_MAPPING=23,
+    MATCH_SEQUENCE=24,
+    NOP=25,
+    NOT_TAKEN=26,
+    POP_EXCEPT=27,
+    POP_ITER=28,
+    POP_TOP=29,
+    PUSH_EXC_INFO=30,
+    PUSH_NULL=31,
+    RETURN_GENERATOR=32,
+    RETURN_VALUE=33,
+    SETUP_ANNOTATIONS=34,
+    STORE_SLICE=35,
+    STORE_SUBSCR=36,
+    TO_BOOL=37,
+    UNARY_INVERT=38,
+    UNARY_NEGATIVE=39,
+    UNARY_NOT=40,
+    WITH_EXCEPT_START=41,
+    BINARY_OP=42,
+    BUILD_INTERPOLATION=43,
+    BUILD_LIST=44,
+    BUILD_MAP=45,
+    BUILD_SET=46,
+    BUILD_SLICE=47,
+    BUILD_STRING=48,
+    BUILD_TUPLE=49,
+    CALL=50,
+    CALL_INTRINSIC_1=51,
+    CALL_INTRINSIC_2=52,
+    CALL_KW=53,
+    COMPARE_OP=54,
+    CONTAINS_OP=55,
+    CONVERT_VALUE=56,
+    COPY=57,
+    COPY_FREE_VARS=58,
+    DELETE_ATTR=59,
+    DELETE_DEREF=60,
+    DELETE_FAST=61,
+    DELETE_GLOBAL=62,
+    DELETE_NAME=63,
+    DICT_MERGE=64,
+    DICT_UPDATE=65,
+    END_ASYNC_FOR=66,
+    EXTENDED_ARG=67,
+    FOR_ITER=68,
+    GET_AWAITABLE=69,
+    GET_ITER=70,
+    IMPORT_FROM=71,
+    IMPORT_NAME=72,
+    IS_OP=73,
+    JUMP_BACKWARD=74,
+    JUMP_BACKWARD_NO_INTERRUPT=75,
+    JUMP_FORWARD=76,
+    LIST_APPEND=77,
+    LIST_EXTEND=78,
+    LOAD_ATTR=79,
+    LOAD_COMMON_CONSTANT=80,
+    LOAD_CONST=81,
+    LOAD_DEREF=82,
+    LOAD_FAST=83,
+    LOAD_FAST_AND_CLEAR=84,
+    LOAD_FAST_BORROW=85,
+    LOAD_FAST_BORROW_LOAD_FAST_BORROW=86,
+    LOAD_FAST_CHECK=87,
+    LOAD_FAST_LOAD_FAST=88,
+    LOAD_FROM_DICT_OR_DEREF=89,
+    LOAD_FROM_DICT_OR_GLOBALS=90,
+    LOAD_GLOBAL=91,
+    LOAD_NAME=92,
+    LOAD_SMALL_INT=93,
+    LOAD_SPECIAL=94,
+    LOAD_SUPER_ATTR=95,
+    MAKE_CELL=96,
+    MAP_ADD=97,
+    MATCH_CLASS=98,
+    POP_JUMP_IF_FALSE=99,
+    POP_JUMP_IF_NONE=100,
+    POP_JUMP_IF_NOT_NONE=101,
+    POP_JUMP_IF_TRUE=102,
+    RAISE_VARARGS=103,
+    RERAISE=104,
+    SEND=105,
+    SET_ADD=106,
+    SET_FUNCTION_ATTRIBUTE=107,
+    SET_UPDATE=108,
+    STORE_ATTR=109,
+    STORE_DEREF=110,
+    STORE_FAST=111,
+    STORE_FAST_LOAD_FAST=112,
+    STORE_FAST_STORE_FAST=113,
+    STORE_GLOBAL=114,
+    STORE_NAME=115,
+    SWAP=116,
+    UNPACK_EX=117,
+    UNPACK_SEQUENCE=118,
+    YIELD_VALUE=119,
     INSTRUMENTED_END_FOR=233,
     INSTRUMENTED_POP_ITER=234,
     INSTRUMENTED_END_SEND=235,
@@ -372,5 +371,5 @@ opmap = frozendict(
     STORE_FAST_MAYBE_NULL=266,
 )
 
-HAVE_ARGUMENT = 43
+HAVE_ARGUMENT = 41
 MIN_INSTRUMENTED_OPCODE = 233
index f4210db5bd788ee3c8729d44037d5bc757ad29f3..f8bbcd35ca7c099b6abcc795200d67e2b6a4d40f 100644 (file)
@@ -174,7 +174,7 @@ dis_bug708901 = """\
 %3d           LOAD_SMALL_INT          10
 
 %3d           CALL                     2
-              GET_ITER
+              GET_ITER                 0
       L1:     FOR_ITER                 3 (to L2)
               STORE_FAST               0 (res)
 
@@ -616,6 +616,7 @@ dis_asyncwith = """\
                 LOAD_SPECIAL             2 (__aenter__)
                 CALL                     0
                 GET_AWAITABLE            1
+                PUSH_NULL
                 LOAD_CONST               0 (None)
         L2:     SEND                     4 (to L5)
         L3:     YIELD_VALUE              1
@@ -632,6 +633,7 @@ dis_asyncwith = """\
                 LOAD_CONST               0 (None)
                 CALL                     3
                 GET_AWAITABLE            2
+                PUSH_NULL
                 LOAD_CONST               0 (None)
         L8:     SEND                     4 (to L11)
         L9:     YIELD_VALUE              1
@@ -646,12 +648,13 @@ dis_asyncwith = """\
                 RETURN_VALUE
 
 %4d   L12:     CLEANUP_THROW
-       L13:     JUMP_BACKWARD_NO_INTERRUPT 27 (to L5)
+       L13:     JUMP_BACKWARD_NO_INTERRUPT 28 (to L5)
        L14:     CLEANUP_THROW
        L15:     JUMP_BACKWARD_NO_INTERRUPT 10 (to L11)
        L16:     PUSH_EXC_INFO
                 WITH_EXCEPT_START
                 GET_AWAITABLE            2
+                PUSH_NULL
                 LOAD_CONST               0 (None)
        L17:     SEND                     5 (to L21)
        L18:     YIELD_VALUE              1
@@ -681,15 +684,15 @@ dis_asyncwith = """\
                 RERAISE                  1
 ExceptionTable:
   L1 to L3 -> L27 [0] lasti
-  L3 to L4 -> L12 [4]
+  L3 to L4 -> L12 [5]
   L4 to L6 -> L27 [0] lasti
   L6 to L7 -> L16 [2] lasti
   L7 to L9 -> L27 [0] lasti
-  L9 to L10 -> L14 [2]
+  L9 to L10 -> L14 [3]
   L10 to L13 -> L27 [0] lasti
   L14 to L15 -> L27 [0] lasti
   L16 to L18 -> L26 [4] lasti
-  L18 to L19 -> L20 [7]
+  L18 to L19 -> L20 [8]
   L19 to L22 -> L26 [4] lasti
   L23 to L25 -> L26 [4] lasti
   L25 to L27 -> L27 [0] lasti
@@ -876,7 +879,7 @@ Disassembly of <code object <genexpr> at 0x..., file "%s", line %d>:
   --           COPY_FREE_VARS           1
 
 %4d           LOAD_FAST                0 (.0)
-               GET_ITER
+               GET_ITER                 0
                RETURN_GENERATOR
                POP_TOP
        L1:     RESUME                   0
@@ -933,7 +936,7 @@ dis_loop_test_quickened_code = """\
               LIST_EXTEND              1
               LOAD_SMALL_INT           3
               BINARY_OP                5 (*)
-              GET_ITER
+              GET_ITER                 0
       L1:     FOR_ITER_LIST           14 (to L2)
               STORE_FAST               0 (i)
 
@@ -1035,6 +1038,7 @@ class DisTests(DisTestBase):
         long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT',
                             'LOAD_FAST_BORROW_LOAD_FAST_BORROW',
                             'INSTRUMENTED_CALL_FUNCTION_EX',
+                            'YIELD_FROM_CORO_CHECK',
                             'ANNOTATIONS_PLACEHOLDER'])
         for op, opname in enumerate(dis.opname):
             if opname in long_opcodes or opname.startswith("INSTRUMENTED"):
@@ -1855,7 +1859,7 @@ expected_opinfo_jumpy = [
   make_inst(opname='LOAD_GLOBAL', arg=1, argval='range', argrepr='range + NULL', offset=4, start_offset=4, starts_line=True, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
   make_inst(opname='LOAD_SMALL_INT', arg=10, argval=10, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3),
   make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
-  make_inst(opname='GET_ITER', arg=None, argval=None, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3),
+  make_inst(opname='GET_ITER', arg=0, argval=0, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3),
   make_inst(opname='FOR_ITER', arg=33, argval=96, argrepr='to L4', offset=26, start_offset=26, starts_line=False, line_number=3, label=1, cache_info=[('counter', 1, b'\x00\x00')]),
   make_inst(opname='STORE_FAST', arg=0, argval='i', argrepr='i', offset=30, start_offset=30, starts_line=False, line_number=3),
   make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=32, start_offset=32, starts_line=True, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
index 88d20bbb028d6fd19a61c7bd80977b15da430b08..e0cc010f15513b29ff384a456629f4a928285104 100644 (file)
@@ -1470,7 +1470,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ('LOAD_SMALL_INT', 1, 0),
             ('LOAD_SMALL_INT', 2, 0),
             ('BUILD_LIST', 2, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1483,7 +1483,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
         ]
         after = [
             ('LOAD_CONST', 1, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1501,7 +1501,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ('LOAD_SMALL_INT', 1, 0),
             ('LOAD_NAME', 0, 0),
             ('BUILD_LIST', 2, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1516,7 +1516,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ('LOAD_SMALL_INT', 1, 0),
             ('LOAD_NAME', 0, 0),
             ('BUILD_TUPLE', 2, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1535,7 +1535,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ('LOAD_SMALL_INT', 1, 0),
             ('LOAD_SMALL_INT', 2, 0),
             ('BUILD_SET', 2, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1548,7 +1548,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
         ]
         after = [
             ('LOAD_CONST', 1, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -1567,7 +1567,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ('LOAD_SMALL_INT', 1, 0),
             ('LOAD_NAME', 0, 0),
             ('BUILD_SET', 2, 0),
-            ('GET_ITER', None, 0),
+            ('GET_ITER', 0, 0),
             start := self.Label(),
             ('FOR_ITER', end := self.Label(), 0),
             ('STORE_FAST', 0, 0),
@@ -2356,7 +2356,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ("LOAD_FAST", 1, 4),
             ("LIST_EXTEND", 1, 5),
             ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE, 6),
-            ("GET_ITER", None, 7),
+            ("GET_ITER", 0, 7),
             top := self.Label(),
             ("FOR_ITER", end := self.Label(), 8),
             ("STORE_FAST", 2, 9),
@@ -2374,7 +2374,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
             ("LOAD_FAST_BORROW", 1, 4),
             ("LIST_EXTEND", 1, 5),
             ("NOP", None, 6),  # ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE, 6),
-            ("GET_ITER", None, 7),
+            ("GET_ITER", 0, 7),
             top := self.Label(),
             ("FOR_ITER", end := self.Label(), 8),
             ("STORE_FAST", 2, 9),
@@ -2677,20 +2677,20 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
         self.cfg_optimization_test(insts, expected, consts=[None])
 
     def test_get_yield_from_iter(self):
-        # GET_YIELD_FROM_ITER may leave its operand on the stack
         insts = [
             ("LOAD_FAST", 0, 1),
-            ("GET_YIELD_FROM_ITER", None, 2),
-            ("LOAD_CONST", 0, 3),
+            ("GET_ITER", 1, 2),
+            ("PUSH_NULL", None, 3),
+            ("LOAD_CONST", 0, 4),
             send := self.Label(),
-            ("SEND", end := self.Label(), 5),
-            ("YIELD_VALUE", 1, 6),
-            ("RESUME", 2, 7),
-            ("JUMP", send, 8),
+            ("SEND", end := self.Label(), 6),
+            ("YIELD_VALUE", 1, 7),
+            ("RESUME", 2, 8),
+            ("JUMP", send, 9),
             end,
-            ("END_SEND", None, 9),
-            ("LOAD_CONST", 0, 10),
-            ("RETURN_VALUE", None, 11),
+            ("END_SEND", None, 10),
+            ("LOAD_CONST", 0, 11),
+            ("RETURN_VALUE", None, 12),
         ]
         self.cfg_optimization_test(insts, insts, consts=[None])
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-20-11-34-17.gh-issue-145667._Agp9o.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-20-11-34-17.gh-issue-145667._Agp9o.rst
new file mode 100644 (file)
index 0000000..cedd8bf
--- /dev/null
@@ -0,0 +1,2 @@
+Remove the ``GET_ITER_YIELD_FROM`` instruction, modifying ``SEND`` to pair
+with ``GET_ITER`` when compiling ``yield from`` expressions.
index 69478634de6926201815a70b6514d802c54093b6..67a97a53db6415ce7b181c91acad600e7588d363 100644 (file)
@@ -265,7 +265,7 @@ handle_yield_from_frame(
         uintptr_t gi_await_addr;
         err = read_py_ptr(
             unwinder,
-            stackpointer_addr - sizeof(void*),
+            stackpointer_addr - sizeof(void*) * 2,
             &gi_await_addr);
         if (err) {
             set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read gi_await address");
index 6f2d4c89893547a09c37c728d0c55fcf4db7b5d3..d5b3735eb2b64e9b60dbd5bc9058cf8294eaa62b 100644 (file)
             next_instr += 1;
             INSTRUCTION_STATS(CLEANUP_THROW);
             _PyStackRef sub_iter;
+            _PyStackRef null_in;
             _PyStackRef last_sent_val;
             _PyStackRef exc_value_st;
             _PyStackRef none;
+            _PyStackRef null_out;
             _PyStackRef value;
             exc_value_st = stack_pointer[-1];
             last_sent_val = stack_pointer[-2];
-            sub_iter = stack_pointer[-3];
+            null_in = stack_pointer[-3];
+            sub_iter = stack_pointer[-4];
             PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st);
             #if !_Py_TAIL_CALL_INTERP
             assert(throwflag);
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 _PyStackRef tmp = sub_iter;
                 sub_iter = value;
-                stack_pointer[-3] = sub_iter;
+                stack_pointer[-4] = sub_iter;
                 PyStackRef_CLOSE(tmp);
                 tmp = exc_value_st;
                 exc_value_st = PyStackRef_NULL;
                 last_sent_val = PyStackRef_NULL;
                 stack_pointer[-2] = last_sent_val;
                 PyStackRef_CLOSE(tmp);
+                tmp = null_in;
+                null_in = PyStackRef_NULL;
+                stack_pointer[-3] = null_in;
+                PyStackRef_XCLOSE(tmp);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
-                stack_pointer += -3;
+                stack_pointer += -4;
                 ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                null_out = null_in;
                 none = PyStackRef_None;
             }
             else {
                 JUMP_TO_LABEL(exception_unwind);
             }
             stack_pointer[0] = none;
-            stack_pointer[1] = value;
-            stack_pointer += 2;
+            stack_pointer[1] = null_out;
+            stack_pointer[2] = value;
+            stack_pointer += 3;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             DISPATCH();
         }
             next_instr += 1;
             INSTRUCTION_STATS(END_SEND);
             _PyStackRef receiver;
+            _PyStackRef index_or_null;
             _PyStackRef value;
             _PyStackRef val;
             value = stack_pointer[-1];
-            receiver = stack_pointer[-2];
+            index_or_null = stack_pointer[-2];
+            receiver = stack_pointer[-3];
             val = value;
-            stack_pointer[-2] = val;
-            stack_pointer += -1;
+            (void)index_or_null;
+            stack_pointer[-3] = val;
+            stack_pointer += -2;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             _PyFrame_SetStackPointer(frame, stack_pointer);
             PyStackRef_CLOSE(receiver);
             _PyStackRef index_or_null;
             iterable = stack_pointer[-1];
             #ifdef Py_STATS
-            _PyFrame_SetStackPointer(frame, stack_pointer);
             _Py_GatherStats_GetIter(iterable);
-            stack_pointer = _PyFrame_GetStackPointer(frame);
             #endif
-            PyTypeObject *tp = PyStackRef_TYPE(iterable);
-            if (tp == &PyTuple_Type || tp == &PyList_Type) {
-                iter = iterable;
-                index_or_null = PyStackRef_TagInt(0);
-            }
-            else {
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                stack_pointer += -1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyStackRef_CLOSE(iterable);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    JUMP_TO_LABEL(error);
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                index_or_null = PyStackRef_NULL;
-                stack_pointer += 1;
+            _PyFrame_SetStackPointer(frame, stack_pointer);
+            _PyStackRef result = _PyEval_GetIter(iterable, &index_or_null, oparg);
+            stack_pointer = _PyFrame_GetStackPointer(frame);
+            if (PyStackRef_IsError(result)) {
+                JUMP_TO_LABEL(pop_1_error);
             }
+            iter = result;
             stack_pointer[-1] = iter;
             stack_pointer[0] = index_or_null;
             stack_pointer += 1;
             DISPATCH();
         }
 
-        TARGET(GET_YIELD_FROM_ITER) {
-            #if _Py_TAIL_CALL_INTERP
-            int opcode = GET_YIELD_FROM_ITER;
-            (void)(opcode);
-            #endif
-            frame->instr_ptr = next_instr;
-            next_instr += 1;
-            INSTRUCTION_STATS(GET_YIELD_FROM_ITER);
-            _PyStackRef iterable;
-            _PyStackRef iter;
-            iterable = stack_pointer[-1];
-            PyObject *iterable_o = PyStackRef_AsPyObjectBorrow(iterable);
-            if (PyCoro_CheckExact(iterable_o)) {
-                if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    _PyErr_SetString(tstate, PyExc_TypeError,
-                                     "cannot 'yield from' a coroutine object "
-                                     "in a non-coroutine generator");
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    JUMP_TO_LABEL(error);
-                }
-                iter = iterable;
-            }
-            else if (PyGen_CheckExact(iterable_o)) {
-                iter = iterable;
-            }
-            else {
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(iterable_o);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    JUMP_TO_LABEL(error);
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                _PyStackRef tmp = iterable;
-                iterable = iter;
-                stack_pointer[-1] = iterable;
-                PyStackRef_CLOSE(tmp);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-            }
-            stack_pointer[-1] = iter;
-            DISPATCH();
-        }
-
         TARGET(IMPORT_FROM) {
             #if _Py_TAIL_CALL_INTERP
             int opcode = IMPORT_FROM;
             next_instr += 1;
             INSTRUCTION_STATS(INSTRUMENTED_END_SEND);
             _PyStackRef receiver;
+            _PyStackRef index_or_null;
             _PyStackRef value;
             _PyStackRef val;
             value = stack_pointer[-1];
-            receiver = stack_pointer[-2];
+            index_or_null = stack_pointer[-2];
+            receiver = stack_pointer[-3];
             PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
             if (PyGen_Check(receiver_o) || PyCoro_CheckExact(receiver_o)) {
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 }
             }
             val = value;
-            stack_pointer[-2] = val;
-            stack_pointer += -1;
+            (void)index_or_null;
+            stack_pointer[-3] = val;
+            stack_pointer += -2;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             _PyFrame_SetStackPointer(frame, stack_pointer);
             PyStackRef_CLOSE(receiver);
             _Py_CODEUNIT* const this_instr = next_instr - 2;
             (void)this_instr;
             _PyStackRef receiver;
+            _PyStackRef null_or_index;
             _PyStackRef v;
             _PyStackRef retval;
             // _SPECIALIZE_SEND
             {
-                receiver = stack_pointer[-2];
+                receiver = stack_pointer[-3];
                 uint16_t counter = read_u16(&this_instr[1].cache);
                 (void)counter;
                 #if ENABLE_SPECIALIZATION
             // _SEND
             {
                 v = stack_pointer[-1];
+                null_or_index = stack_pointer[-2];
                 PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
                 PyObject *retval_o;
                 assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
                     gen_frame->previous = frame;
                     DISPATCH_INLINED(gen_frame);
                 }
-                if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
+                if (!PyStackRef_IsNull(null_or_index)) {
                     _PyFrame_SetStackPointer(frame, stack_pointer);
-                    retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
+                    _PyStackRef item = _PyForIter_VirtualIteratorNext(tstate, frame, receiver, &null_or_index);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
+                    if (!PyStackRef_IsValid(item)) {
+                        if (PyStackRef_IsError(item)) {
+                            JUMP_TO_LABEL(error);
+                        }
+                        JUMPBY(oparg);
+                        stack_pointer[-2] = null_or_index;
+                        DISPATCH();
+                    }
+                    retval = item;
                 }
                 else {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    retval_o = PyObject_CallMethodOneArg(receiver_o,
-                        &_Py_ID(send),
-                        PyStackRef_AsPyObjectBorrow(v));
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                }
-                if (retval_o == NULL) {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (matches) {
+                    if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
                         _PyFrame_SetStackPointer(frame, stack_pointer);
-                        _PyEval_MonitorRaise(tstate, frame, this_instr);
+                        retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
                         stack_pointer = _PyFrame_GetStackPointer(frame);
                     }
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    int err = _PyGen_FetchStopIterationValue(&retval_o);
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (err == 0) {
-                        assert(retval_o != NULL);
-                        JUMPBY(oparg);
-                    }
                     else {
-                        stack_pointer += -1;
-                        ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
                         _PyFrame_SetStackPointer(frame, stack_pointer);
-                        PyStackRef_CLOSE(v);
+                        retval_o = PyObject_CallMethodOneArg(receiver_o,
+                            &_Py_ID(send),
+                            PyStackRef_AsPyObjectBorrow(v));
                         stack_pointer = _PyFrame_GetStackPointer(frame);
-                        JUMP_TO_LABEL(error);
                     }
+                    if (retval_o == NULL) {
+                        _PyFrame_SetStackPointer(frame, stack_pointer);
+                        int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
+                        stack_pointer = _PyFrame_GetStackPointer(frame);
+                        if (matches) {
+                            _PyFrame_SetStackPointer(frame, stack_pointer);
+                            _PyEval_MonitorRaise(tstate, frame, this_instr);
+                            stack_pointer = _PyFrame_GetStackPointer(frame);
+                        }
+                        _PyFrame_SetStackPointer(frame, stack_pointer);
+                        int err = _PyGen_FetchStopIterationValue(&retval_o);
+                        stack_pointer = _PyFrame_GetStackPointer(frame);
+                        if (err == 0) {
+                            assert(retval_o != NULL);
+                            JUMPBY(oparg);
+                        }
+                        else {
+                            stack_pointer += -1;
+                            ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                            _PyFrame_SetStackPointer(frame, stack_pointer);
+                            PyStackRef_CLOSE(v);
+                            stack_pointer = _PyFrame_GetStackPointer(frame);
+                            JUMP_TO_LABEL(error);
+                        }
+                    }
+                    retval = PyStackRef_FromPyObjectSteal(retval_o);
                 }
-                stack_pointer += -1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                stack_pointer[-2] = null_or_index;
+                stack_pointer[-1] = retval;
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 PyStackRef_CLOSE(v);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
-                retval = PyStackRef_FromPyObjectSteal(retval_o);
             }
-            stack_pointer[0] = retval;
-            stack_pointer += 1;
-            ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             DISPATCH();
         }
 
             // _SEND_GEN_FRAME
             {
                 v = stack_pointer[-1];
-                receiver = stack_pointer[-2];
+                receiver = stack_pointer[-3];
                 PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
                 if (Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type) {
                     UPDATE_MISS_STATS(SEND);
index def462bacec176d2cb02ab16e559a77e74ac753d..48fe9c14f4e2dda5d9d5bac02f00c2d5b2bc0b22 100644 (file)
@@ -16,10 +16,8 @@ static void *opcode_targets_table[256] = {
     &&TARGET_FORMAT_WITH_SPEC,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
-    &&TARGET_GET_ITER,
-    &&TARGET_RESERVED,
     &&TARGET_GET_LEN,
-    &&TARGET_GET_YIELD_FROM_ITER,
+    &&TARGET_RESERVED,
     &&TARGET_INTERPRETER_EXIT,
     &&TARGET_LOAD_BUILD_CLASS,
     &&TARGET_LOAD_LOCALS,
@@ -72,6 +70,7 @@ static void *opcode_targets_table[256] = {
     &&TARGET_EXTENDED_ARG,
     &&TARGET_FOR_ITER,
     &&TARGET_GET_AWAITABLE,
+    &&TARGET_GET_ITER,
     &&TARGET_IMPORT_FROM,
     &&TARGET_IMPORT_NAME,
     &&TARGET_IS_OP,
@@ -128,6 +127,7 @@ static void *opcode_targets_table[256] = {
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_RESUME,
     &&TARGET_BINARY_OP_ADD_FLOAT,
     &&TARGET_BINARY_OP_ADD_INT,
@@ -379,7 +379,7 @@ static void *opcode_tracing_targets_table[256] = {
     &&TARGET_TRACE_RECORD,
     &&TARGET_TRACE_RECORD,
     &&TARGET_TRACE_RECORD,
-    &&TARGET_TRACE_RECORD,
+    &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
@@ -626,7 +626,6 @@ static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ANEXT(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_AWAITABLE(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ITER(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_LEN(TAIL_CALL_PARAMS);
-static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_YIELD_FROM_ITER(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_FROM(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_NAME(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_CALL(TAIL_CALL_PARAMS);
@@ -868,7 +867,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
     [GET_AWAITABLE] = _TAIL_CALL_GET_AWAITABLE,
     [GET_ITER] = _TAIL_CALL_GET_ITER,
     [GET_LEN] = _TAIL_CALL_GET_LEN,
-    [GET_YIELD_FROM_ITER] = _TAIL_CALL_GET_YIELD_FROM_ITER,
     [IMPORT_FROM] = _TAIL_CALL_IMPORT_FROM,
     [IMPORT_NAME] = _TAIL_CALL_IMPORT_NAME,
     [INSTRUMENTED_CALL] = _TAIL_CALL_INSTRUMENTED_CALL,
@@ -1002,6 +1000,7 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
     [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE,
     [WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START,
     [YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE,
+    [120] = _TAIL_CALL_UNKNOWN_OPCODE,
     [121] = _TAIL_CALL_UNKNOWN_OPCODE,
     [122] = _TAIL_CALL_UNKNOWN_OPCODE,
     [123] = _TAIL_CALL_UNKNOWN_OPCODE,
@@ -1126,7 +1125,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
     [GET_AWAITABLE] = _TAIL_CALL_TRACE_RECORD,
     [GET_ITER] = _TAIL_CALL_TRACE_RECORD,
     [GET_LEN] = _TAIL_CALL_TRACE_RECORD,
-    [GET_YIELD_FROM_ITER] = _TAIL_CALL_TRACE_RECORD,
     [IMPORT_FROM] = _TAIL_CALL_TRACE_RECORD,
     [IMPORT_NAME] = _TAIL_CALL_TRACE_RECORD,
     [INSTRUMENTED_CALL] = _TAIL_CALL_TRACE_RECORD,
@@ -1260,6 +1258,7 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
     [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_TRACE_RECORD,
     [WITH_EXCEPT_START] = _TAIL_CALL_TRACE_RECORD,
     [YIELD_VALUE] = _TAIL_CALL_TRACE_RECORD,
+    [120] = _TAIL_CALL_UNKNOWN_OPCODE,
     [121] = _TAIL_CALL_UNKNOWN_OPCODE,
     [122] = _TAIL_CALL_UNKNOWN_OPCODE,
     [123] = _TAIL_CALL_UNKNOWN_OPCODE,
index fbf0985e9050dd1b3adac4895ce55c65a3ccb74b..84a712b2b2c05d4e5022cf997d44303984938ac0 100644 (file)
@@ -501,7 +501,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
 }
 
 extern void
-_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters);
+_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters, int flags);
 
 #ifdef Py_GIL_DISABLED
 static _PyCodeArray * _PyCodeArray_New(Py_ssize_t size);
@@ -579,11 +579,12 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
         entry_point++;
     }
     co->_co_firsttraceable = entry_point;
+
 #ifdef Py_GIL_DISABLED
     int enable_counters = interp->config.tlbc_enabled && interp->opt_config.specialization_enabled;
-    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), enable_counters);
+    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), enable_counters, co->co_flags);
 #else
-    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), interp->opt_config.specialization_enabled);
+    _PyCode_Quicken(_PyCode_CODE(co), Py_SIZE(co), interp->opt_config.specialization_enabled, co->co_flags);
 #endif
     notify_code_watchers(PY_CODE_EVENT_CREATE, co);
     return 0;
@@ -3460,7 +3461,7 @@ copy_code(PyInterpreterState *interp, _Py_CODEUNIT *dst, PyCodeObject *co)
     for (int i = 0; i < code_len; i += _PyInstruction_GetLength(co, i)) {
         dst[i] = deopt_code_unit(co, i);
     }
-    _PyCode_Quicken(dst, code_len, interp->opt_config.specialization_enabled);
+    _PyCode_Quicken(dst, code_len, interp->opt_config.specialization_enabled, co->co_flags);
 }
 
 static Py_ssize_t
index 9dece8a7700cab0a86da27b55a9bf7a3fa7e8468..2895833b4ff933042ab93f450f95b76224c37cd0 100644 (file)
@@ -490,7 +490,7 @@ gen_close(PyObject *self, PyObject *args)
     int err = 0;
     _PyInterpreterFrame *frame = &gen->gi_iframe;
     if (frame_state == FRAME_SUSPENDED_YIELD_FROM) {
-        PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame));
+        PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame, 2));
         err = gen_close_iter(yf);
         Py_DECREF(yf);
     }
@@ -649,7 +649,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
 
     if (frame_state == FRAME_SUSPENDED_YIELD_FROM) {
         _PyInterpreterFrame *frame = &gen->gi_iframe;
-        PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame));
+        PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame, 2));
         PyObject *ret;
         int err;
         if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&
@@ -898,7 +898,7 @@ gen_getyieldfrom(PyObject *self, void *Py_UNUSED(ignored))
         }
     } while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_SUSPENDED_YIELD_FROM_LOCKED));
 
-    PyObject *result = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(&gen->gi_iframe));
+    PyObject *result = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(&gen->gi_iframe, 2));
     _Py_atomic_store_int8_release(&gen->gi_frame_state, FRAME_SUSPENDED_YIELD_FROM);
     return result;
 #else
@@ -906,7 +906,7 @@ gen_getyieldfrom(PyObject *self, void *Py_UNUSED(ignored))
     if (frame_state != FRAME_SUSPENDED_YIELD_FROM) {
         Py_RETURN_NONE;
     }
-    return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(&gen->gi_iframe));
+    return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(&gen->gi_iframe, 2));
 #endif
 }
 
index 1411eb1718b683be3dd09296dacf21920efeca3b..d550740b1105dd0cca81addd96ca378c8ecdf0b5 100644 (file)
@@ -1,19 +1,19 @@
 // Auto-generated by Programs/freeze_test_frozenmain.py
 unsigned char M_test_frozenmain[] = {
     227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,
-    0,0,0,0,0,243,186,0,0,0,128,0,0,0,94,0,
-    82,1,73,0,116,0,94,0,82,1,73,4,116,1,93,2,
-    33,0,82,2,52,1,0,0,0,0,0,0,31,0,93,2,
-    33,0,82,3,93,0,80,6,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,52,2,0,0,0,0,
-    0,0,31,0,93,1,80,8,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,33,0,52,0,0,0,
-    0,0,0,0,82,4,44,26,0,0,0,0,0,0,0,0,
-    0,0,116,5,82,7,16,0,70,24,0,0,116,6,93,2,
-    33,0,82,5,93,6,12,0,82,6,93,5,93,6,44,26,
-    0,0,0,0,0,0,0,0,0,0,12,0,50,4,52,1,
-    0,0,0,0,0,0,31,0,75,26,0,0,9,0,30,0,
-    82,1,35,0,41,8,233,0,0,0,0,78,122,18,70,114,
+    0,0,0,0,0,243,186,0,0,0,128,0,0,0,93,0,
+    81,1,72,0,115,0,93,0,81,1,72,4,115,1,92,2,
+    31,0,81,2,50,1,0,0,0,0,0,0,29,0,92,2,
+    31,0,81,3,92,0,79,6,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,50,2,0,0,0,0,
+    0,0,29,0,92,1,79,8,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,31,0,50,0,0,0,
+    0,0,0,0,81,4,42,26,0,0,0,0,0,0,0,0,
+    0,0,115,5,81,7,70,0,68,24,0,0,115,6,92,2,
+    31,0,81,5,92,6,12,0,81,6,92,5,92,6,42,26,
+    0,0,0,0,0,0,0,0,0,0,12,0,48,4,50,1,
+    0,0,0,0,0,0,29,0,74,26,0,0,9,0,28,0,
+    81,1,33,0,41,8,233,0,0,0,0,78,122,18,70,114,
     111,122,101,110,32,72,101,108,108,111,32,87,111,114,108,100,
     122,8,115,121,115,46,97,114,103,118,218,6,99,111,110,102,
     105,103,122,7,99,111,110,102,105,103,32,122,2,58,32,41,
index edccb1ea5a0144f58b6c1cdbff9aeb5bdbd92924..a42e6a57abe2bfd46e019cb4a50f17895deb8390 100644 (file)
@@ -425,13 +425,15 @@ dummy_func(
             PyStackRef_CLOSE(iter);
         }
 
-        pure inst(END_SEND, (receiver, value -- val)) {
+        pure inst(END_SEND, (receiver, index_or_null, value -- val)) {
             val = value;
+            (void)index_or_null;
             DEAD(value);
+            DEAD(index_or_null);
             PyStackRef_CLOSE(receiver);
         }
 
-        tier1 inst(INSTRUMENTED_END_SEND, (receiver, value -- val)) {
+        tier1 inst(INSTRUMENTED_END_SEND, (receiver, index_or_null, value -- val)) {
             PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
             if (PyGen_Check(receiver_o) || PyCoro_CheckExact(receiver_o)) {
                 int err = monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value));
@@ -440,6 +442,8 @@ dummy_func(
                 }
             }
             val = value;
+            (void)index_or_null;
+            DEAD(index_or_null);
             DEAD(value);
             PyStackRef_CLOSE(receiver);
         }
@@ -1410,7 +1414,7 @@ dummy_func(
             SEND_GEN,
         };
 
-        specializing op(_SPECIALIZE_SEND, (counter/1, receiver, unused -- receiver, unused)) {
+        specializing op(_SPECIALIZE_SEND, (counter/1, receiver, unused, unused -- receiver, unused, unused)) {
             #if ENABLE_SPECIALIZATION
             if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
                 next_instr = this_instr;
@@ -1422,7 +1426,7 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION */
         }
 
-        op(_SEND, (receiver, v -- receiver, retval)) {
+        op(_SEND, (receiver, null_or_index, v -- receiver, null_or_index, retval)) {
             PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
             PyObject *retval_o;
             assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
@@ -1443,36 +1447,49 @@ dummy_func(
                 gen_frame->previous = frame;
                 DISPATCH_INLINED(gen_frame);
             }
-            if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
-                retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
+            if (!PyStackRef_IsNull(null_or_index)) {
+                _PyStackRef item = _PyForIter_VirtualIteratorNext(tstate, frame, receiver, &null_or_index);
+                if (!PyStackRef_IsValid(item)) {
+                    if (PyStackRef_IsError(item)) {
+                        ERROR_NO_POP();
+                    }
+                    JUMPBY(oparg);
+                    DISPATCH();
+                }
+                retval = item;
             }
             else {
-                retval_o = PyObject_CallMethodOneArg(receiver_o,
-                                                     &_Py_ID(send),
-                                                     PyStackRef_AsPyObjectBorrow(v));
-            }
-            if (retval_o == NULL) {
-                int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
-                if (matches) {
-                    _PyEval_MonitorRaise(tstate, frame, this_instr);
-                }
-                int err = _PyGen_FetchStopIterationValue(&retval_o);
-                if (err == 0) {
-                    assert(retval_o != NULL);
-                    JUMPBY(oparg);
+                if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
+                    retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
                 }
                 else {
-                    PyStackRef_CLOSE(v);
-                    ERROR_IF(true);
+                    retval_o = PyObject_CallMethodOneArg(receiver_o,
+                                                        &_Py_ID(send),
+                                                        PyStackRef_AsPyObjectBorrow(v));
+                }
+                if (retval_o == NULL) {
+                    int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
+                    if (matches) {
+                        _PyEval_MonitorRaise(tstate, frame, this_instr);
+                    }
+                    int err = _PyGen_FetchStopIterationValue(&retval_o);
+                    if (err == 0) {
+                        assert(retval_o != NULL);
+                        JUMPBY(oparg);
+                    }
+                    else {
+                        PyStackRef_CLOSE(v);
+                        ERROR_IF(true);
+                    }
                 }
+                retval = PyStackRef_FromPyObjectSteal(retval_o);
             }
             PyStackRef_CLOSE(v);
-            retval = PyStackRef_FromPyObjectSteal(retval_o);
         }
 
         macro(SEND) = _SPECIALIZE_SEND + _SEND;
 
-        op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) {
+        op(_SEND_GEN_FRAME, (receiver, null, v -- receiver, null, gen_frame)) {
             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
             EXIT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type);
             EXIT_IF(!gen_try_set_executing((PyGenObject *)gen));
@@ -1490,7 +1507,7 @@ dummy_func(
 
         macro(SEND_GEN) =
             unused/1 +
-            _RECORD_NOS_GEN_FUNC +
+            _RECORD_3OS_GEN_FUNC +
             _CHECK_PEP_523 +
             _SEND_GEN_FRAME +
             _PUSH_FRAME;
@@ -1602,17 +1619,17 @@ dummy_func(
 
         macro(END_ASYNC_FOR) = _END_ASYNC_FOR;
 
-        tier1 inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value_st -- none, value)) {
+        tier1 inst(CLEANUP_THROW, (sub_iter, null_in, last_sent_val, exc_value_st -- none, null_out, value)) {
             PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st);
             #if !_Py_TAIL_CALL_INTERP
             assert(throwflag);
             #endif
             assert(exc_value && PyExceptionInstance_Check(exc_value));
-
             int matches = PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration);
             if (matches) {
                 value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value);
                 DECREF_INPUTS();
+                null_out = null_in;
                 none = PyStackRef_None;
             }
             else {
@@ -3335,52 +3352,10 @@ dummy_func(
             #ifdef Py_STATS
             _Py_GatherStats_GetIter(iterable);
             #endif
-            PyTypeObject *tp = PyStackRef_TYPE(iterable);
-            if (tp == &PyTuple_Type || tp == &PyList_Type) {
-                /* Leave iterable on stack and pushed tagged 0 */
-                iter = iterable;
-                DEAD(iterable);
-                index_or_null = PyStackRef_TagInt(0);
-            }
-            else {
-                /* Pop iterable, and push iterator then NULL */
-                PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
-                PyStackRef_CLOSE(iterable);
-                ERROR_IF(iter_o == NULL);
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                index_or_null = PyStackRef_NULL;
-            }
-        }
-
-        inst(GET_YIELD_FROM_ITER, (iterable -- iter)) {
-            /* before: [obj]; after [getiter(obj)] */
-            PyObject *iterable_o = PyStackRef_AsPyObjectBorrow(iterable);
-            if (PyCoro_CheckExact(iterable_o)) {
-                /* `iterable` is a coroutine */
-                if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
-                    /* and it is used in a 'yield from' expression of a
-                       regular generator. */
-                    _PyErr_SetString(tstate, PyExc_TypeError,
-                                     "cannot 'yield from' a coroutine object "
-                                     "in a non-coroutine generator");
-                    ERROR_NO_POP();
-                }
-                iter = iterable;
-                DEAD(iterable);
-            }
-            else if (PyGen_CheckExact(iterable_o)) {
-                iter = iterable;
-                DEAD(iterable);
-            }
-            else {
-                /* `iterable` is not a generator. */
-                PyObject *iter_o = PyObject_GetIter(iterable_o);
-                if (iter_o == NULL) {
-                    ERROR_NO_POP();
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                DECREF_INPUTS();
-            }
+            _PyStackRef result = _PyEval_GetIter(iterable, &index_or_null, oparg);
+            DEAD(iterable);
+            ERROR_IF(PyStackRef_IsError(result));
+            iter = result;
         }
 
         // Most members of this family are "secretly" super-instructions.
@@ -5857,6 +5832,17 @@ dummy_func(
             }
         }
 
+        tier2 op(_RECORD_3OS_GEN_FUNC, (gen, nos, tos -- gen, nos, tos)) {
+            PyObject *obj = PyStackRef_AsPyObjectBorrow(gen);
+            if (PyGen_Check(obj)) {
+                PyGenObject *gen_obj = (PyGenObject *)obj;
+                _PyStackRef func = gen_obj->gi_iframe.f_funcobj;
+                if (!PyStackRef_IsNull(func)) {
+                    RECORD_VALUE(PyStackRef_AsPyObjectBorrow(func));
+                }
+            }
+        }
+
         tier2 op(_RECORD_4OS, (value, _3os, nos, tos -- value, _3os, nos, tos)) {
             RECORD_VALUE(PyStackRef_AsPyObjectBorrow(value));
         }
index 8a6895834cbb7e4c1a7570ba1264e96ceef7c51c..cb25012ceda92cf564237ad7165cc847362831df 100644 (file)
@@ -1165,6 +1165,42 @@ stop_tracing_and_jit(PyThreadState *tstate, _PyInterpreterFrame *frame)
 #include "generated_cases.c.h"
 #endif
 
+
+_PyStackRef
+_PyEval_GetIter(_PyStackRef iterable, _PyStackRef *index_or_null, int yield_from)
+{
+    PyTypeObject *tp = PyStackRef_TYPE(iterable);
+    if (tp == &PyTuple_Type || tp == &PyList_Type) {
+        /* Leave iterable on stack and pushed tagged 0 */
+        *index_or_null = PyStackRef_TagInt(0);
+        return iterable;
+    }
+    *index_or_null = PyStackRef_NULL;
+    if (tp->tp_iter == PyObject_SelfIter) {
+        return iterable;
+    }
+    if (yield_from && tp == &PyCoro_Type) {
+        assert(yield_from != GET_ITER_YIELD_FROM);
+        if (yield_from == GET_ITER_YIELD_FROM_CORO_CHECK) {
+            /* `iterable` is a coroutine and it is used in a 'yield from'
+            * expression of a regular generator. */
+            PyErr_SetString(PyExc_TypeError,
+                            "cannot 'yield from' a coroutine object "
+                            "in a non-coroutine generator");
+            PyStackRef_CLOSE(iterable);
+            return PyStackRef_ERROR;
+        }
+        return iterable;
+    }
+    /* Pop iterable, and push iterator then NULL */
+    PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
+    PyStackRef_CLOSE(iterable);
+    if (iter_o == NULL) {
+        return PyStackRef_ERROR;
+    }
+    return PyStackRef_FromPyObjectSteal(iter_o);
+}
+
 #if (defined(__GNUC__) && __GNUC__ >= 10 && !defined(__clang__)) && defined(__x86_64__)
 /*
  * gh-129987: The SLP autovectorizer can cause poor code generation for
index 5749b615386717cf0f06e411913064a98a66a979..d300d77e0f73b0d7c6b37513062dc2e609a6634f 100644 (file)
@@ -606,6 +606,7 @@ codegen_unwind_fblock(compiler *c, location *ploc,
             RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
             if (info->fb_type == COMPILE_FBLOCK_ASYNC_WITH) {
                 ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
+                ADDOP(c, *ploc, PUSH_NULL);
                 ADDOP_LOAD_CONST(c, *ploc, Py_None);
                 ADD_YIELD_FROM(c, *ploc, 1);
             }
@@ -2124,7 +2125,7 @@ codegen_for(compiler *c, stmt_ty s)
     VISIT(c, expr, s->v.For.iter);
 
     loc = LOC(s->v.For.iter);
-    ADDOP(c, loc, GET_ITER);
+    ADDOP_I(c, loc, GET_ITER, 0);
 
     USE_LABEL(c, start);
     ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
@@ -2175,6 +2176,7 @@ codegen_async_for(compiler *c, stmt_ty s)
     /* SETUP_FINALLY to guard the __anext__ call */
     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
     ADDOP(c, loc, GET_ANEXT);
+    ADDOP(c, loc, PUSH_NULL);
     ADDOP_LOAD_CONST(c, loc, Py_None);
     USE_LABEL(c, send);
     ADD_YIELD_FROM(c, loc, 1);
@@ -4540,7 +4542,7 @@ codegen_sync_comprehension_generator(compiler *c, location loc,
 
     if (IS_JUMP_TARGET_LABEL(start)) {
         if (iter_pos != ITERATOR_ON_STACK) {
-            ADDOP(c, LOC(gen->iter), GET_ITER);
+            ADDOP_I(c, LOC(gen->iter), GET_ITER, 0);
             depth += 1;
         }
         USE_LABEL(c, start);
@@ -4574,7 +4576,7 @@ codegen_sync_comprehension_generator(compiler *c, location loc,
                 NEW_JUMP_TARGET_LABEL(c, unpack_start);
                 NEW_JUMP_TARGET_LABEL(c, unpack_end);
                 VISIT(c, expr, elt->v.Starred.value);
-                ADDOP(c, elt_loc, GET_ITER);
+                ADDOP_I(c, elt_loc, GET_ITER, 0);
                 USE_LABEL(c, unpack_start);
                 ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
                 ADDOP_YIELD(c, elt_loc);
@@ -4686,6 +4688,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
 
     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
     ADDOP(c, loc, GET_ANEXT);
+    ADDOP(c, loc, PUSH_NULL);
     ADDOP_LOAD_CONST(c, loc, Py_None);
     USE_LABEL(c, send);
     ADD_YIELD_FROM(c, loc, 1);
@@ -4716,7 +4719,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
                 NEW_JUMP_TARGET_LABEL(c, unpack_start);
                 NEW_JUMP_TARGET_LABEL(c, unpack_end);
                 VISIT(c, expr, elt->v.Starred.value);
-                ADDOP(c, elt_loc, GET_ITER);
+                ADDOP_I(c, elt_loc, GET_ITER, 0);
                 USE_LABEL(c, unpack_start);
                 ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
                 ADDOP_YIELD(c, elt_loc);
@@ -5039,6 +5042,7 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
 
     if (is_async_comprehension && type != COMP_GENEXP) {
         ADDOP_I(c, loc, GET_AWAITABLE, 0);
+        ADDOP(c, loc, PUSH_NULL);
         ADDOP_LOAD_CONST(c, loc, Py_None);
         ADD_YIELD_FROM(c, loc, 1);
     }
@@ -5178,6 +5182,7 @@ codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
     ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
     ADDOP_I(c, loc, CALL, 0);
     ADDOP_I(c, loc, GET_AWAITABLE, 1);
+    ADDOP(c, loc, PUSH_NULL);
     ADDOP_LOAD_CONST(c, loc, Py_None);
     ADD_YIELD_FROM(c, loc, 1);
 
@@ -5214,6 +5219,7 @@ codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
      */
     RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
     ADDOP_I(c, loc, GET_AWAITABLE, 2);
+    ADDOP(c, loc, PUSH_NULL);
     ADDOP_LOAD_CONST(c, loc, Py_None);
     ADD_YIELD_FROM(c, loc, 1);
 
@@ -5228,6 +5234,7 @@ codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
     ADDOP(c, loc, PUSH_EXC_INFO);
     ADDOP(c, loc, WITH_EXCEPT_START);
     ADDOP_I(c, loc, GET_AWAITABLE, 2);
+    ADDOP(c, loc, PUSH_NULL);
     ADDOP_LOAD_CONST(c, loc, Py_None);
     ADD_YIELD_FROM(c, loc, 1);
     RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
@@ -5408,13 +5415,14 @@ codegen_visit_expr(compiler *c, expr_ty e)
             return _PyCompile_Error(c, loc, "'yield from' inside async function");
         }
         VISIT(c, expr, e->v.YieldFrom.value);
-        ADDOP(c, loc, GET_YIELD_FROM_ITER);
+        ADDOP_I(c, loc, GET_ITER, GET_ITER_YIELD_FROM);
         ADDOP_LOAD_CONST(c, loc, Py_None);
         ADD_YIELD_FROM(c, loc, 0);
         break;
     case Await_kind:
         VISIT(c, expr, e->v.Await.value);
         ADDOP_I(c, loc, GET_AWAITABLE, 0);
+        ADDOP(c, loc, PUSH_NULL);
         ADDOP_LOAD_CONST(c, loc, Py_None);
         ADD_YIELD_FROM(c, loc, 1);
         break;
index fbbfd521e0d74c17ae9558916706089a25a5e1fa..4e8d2a4aab02a970ff0737a79728ae085a8ea33f 100644 (file)
             break;
         }
 
-        case _END_SEND_r21: {
-            CHECK_CURRENT_CACHED_VALUES(2);
+        case _END_SEND_r31: {
+            CHECK_CURRENT_CACHED_VALUES(3);
             assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
             _PyStackRef value;
+            _PyStackRef index_or_null;
             _PyStackRef receiver;
             _PyStackRef val;
             _PyStackRef _stack_item_0 = _tos_cache0;
             _PyStackRef _stack_item_1 = _tos_cache1;
-            value = _stack_item_1;
+            _PyStackRef _stack_item_2 = _tos_cache2;
+            value = _stack_item_2;
+            index_or_null = _stack_item_1;
             receiver = _stack_item_0;
             val = value;
+            (void)index_or_null;
             stack_pointer[0] = val;
             stack_pointer += 1;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
 
         /* _SEND is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
 
-        case _SEND_GEN_FRAME_r22: {
-            CHECK_CURRENT_CACHED_VALUES(2);
+        case _SEND_GEN_FRAME_r33: {
+            CHECK_CURRENT_CACHED_VALUES(3);
             assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
             _PyStackRef v;
             _PyStackRef receiver;
             _PyStackRef gen_frame;
             _PyStackRef _stack_item_0 = _tos_cache0;
             _PyStackRef _stack_item_1 = _tos_cache1;
+            _PyStackRef _stack_item_2 = _tos_cache2;
             oparg = CURRENT_OPARG();
-            v = _stack_item_1;
+            v = _stack_item_2;
             receiver = _stack_item_0;
             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
             if (Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type) {
                 UOP_STAT_INC(uopcode, miss);
-                _tos_cache1 = v;
+                _tos_cache2 = v;
+                _tos_cache1 = _stack_item_1;
                 _tos_cache0 = receiver;
-                SET_CURRENT_CACHED_VALUES(2);
+                SET_CURRENT_CACHED_VALUES(3);
                 JUMP_TO_JUMP_TARGET();
             }
             if (!gen_try_set_executing((PyGenObject *)gen)) {
                 UOP_STAT_INC(uopcode, miss);
-                _tos_cache1 = v;
+                _tos_cache2 = v;
+                _tos_cache1 = _stack_item_1;
                 _tos_cache0 = receiver;
-                SET_CURRENT_CACHED_VALUES(2);
+                SET_CURRENT_CACHED_VALUES(3);
                 JUMP_TO_JUMP_TARGET();
             }
             STAT_INC(SEND, hit);
             frame->return_offset = (uint16_t)( 2u + oparg);
             pushed_frame->previous = frame;
             gen_frame = PyStackRef_Wrap(pushed_frame);
-            _tos_cache1 = gen_frame;
+            _tos_cache2 = gen_frame;
+            _tos_cache1 = _stack_item_1;
             _tos_cache0 = receiver;
-            _tos_cache2 = PyStackRef_ZERO_BITS;
-            SET_CURRENT_CACHED_VALUES(2);
+            SET_CURRENT_CACHED_VALUES(3);
             assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
             break;
         }
             _PyStackRef iter;
             _PyStackRef index_or_null;
             _PyStackRef _stack_item_0 = _tos_cache0;
+            oparg = CURRENT_OPARG();
             iterable = _stack_item_0;
             #ifdef Py_STATS
+            _Py_GatherStats_GetIter(iterable);
+            #endif
             stack_pointer[0] = iterable;
             stack_pointer += 1;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             _PyFrame_SetStackPointer(frame, stack_pointer);
-            _Py_GatherStats_GetIter(iterable);
+            _PyStackRef result = _PyEval_GetIter(iterable, &index_or_null, oparg);
             stack_pointer = _PyFrame_GetStackPointer(frame);
-            stack_pointer += -1;
-            #endif
-            PyTypeObject *tp = PyStackRef_TYPE(iterable);
-            if (tp == &PyTuple_Type || tp == &PyList_Type) {
-                iter = iterable;
-                index_or_null = PyStackRef_TagInt(0);
-            }
-            else {
-                stack_pointer[0] = iterable;
-                stack_pointer += 1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
-                stack_pointer = _PyFrame_GetStackPointer(frame);
+            if (PyStackRef_IsError(result)) {
                 stack_pointer += -1;
                 ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyStackRef_CLOSE(iterable);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    SET_CURRENT_CACHED_VALUES(0);
-                    JUMP_TO_ERROR();
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                index_or_null = PyStackRef_NULL;
+                SET_CURRENT_CACHED_VALUES(0);
+                JUMP_TO_ERROR();
             }
+            iter = result;
             _tos_cache1 = index_or_null;
             _tos_cache0 = iter;
             _tos_cache2 = PyStackRef_ZERO_BITS;
             SET_CURRENT_CACHED_VALUES(2);
-            assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
-            break;
-        }
-
-        case _GET_YIELD_FROM_ITER_r11: {
-            CHECK_CURRENT_CACHED_VALUES(1);
-            assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
-            _PyStackRef iterable;
-            _PyStackRef iter;
-            _PyStackRef _stack_item_0 = _tos_cache0;
-            iterable = _stack_item_0;
-            PyObject *iterable_o = PyStackRef_AsPyObjectBorrow(iterable);
-            if (PyCoro_CheckExact(iterable_o)) {
-                if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
-                    stack_pointer[0] = iterable;
-                    stack_pointer += 1;
-                    ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    _PyErr_SetString(tstate, PyExc_TypeError,
-                                     "cannot 'yield from' a coroutine object "
-                                     "in a non-coroutine generator");
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    SET_CURRENT_CACHED_VALUES(0);
-                    JUMP_TO_ERROR();
-                }
-                iter = iterable;
-            }
-            else if (PyGen_CheckExact(iterable_o)) {
-                iter = iterable;
-            }
-            else {
-                stack_pointer[0] = iterable;
-                stack_pointer += 1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(iterable_o);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    SET_CURRENT_CACHED_VALUES(0);
-                    JUMP_TO_ERROR();
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                _PyStackRef tmp = iterable;
-                iterable = iter;
-                stack_pointer[-1] = iterable;
-                PyStackRef_CLOSE(tmp);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                stack_pointer += -1;
-            }
-            _tos_cache0 = iter;
-            _tos_cache1 = PyStackRef_ZERO_BITS;
-            _tos_cache2 = PyStackRef_ZERO_BITS;
-            SET_CURRENT_CACHED_VALUES(1);
+            stack_pointer += -1;
+            ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
             break;
         }
index 04234a6025468e5151090acded4ac01511b20f71..f446a87ee6943219b0fab9f2de53db79b9e252a0 100644 (file)
@@ -2884,7 +2884,6 @@ optimize_load_fast(cfg_builder *g)
                 case GET_ANEXT:
                 case GET_ITER:
                 case GET_LEN:
-                case GET_YIELD_FROM_ITER:
                 case IMPORT_FROM:
                 case MATCH_KEYS:
                 case MATCH_MAPPING:
@@ -2919,7 +2918,16 @@ optimize_load_fast(cfg_builder *g)
                     break;
                 }
 
-                case END_SEND:
+                case END_SEND: {
+                    assert(_PyOpcode_num_popped(opcode, oparg) == 3);
+                    assert(_PyOpcode_num_pushed(opcode, oparg) == 1);
+                    ref tos = ref_stack_pop(&refs);
+                    ref_stack_pop(&refs);
+                    ref_stack_pop(&refs);
+                    PUSH_REF(tos.instr, tos.local);
+                    break;
+                }
+
                 case SET_FUNCTION_ATTRIBUTE: {
                     assert(_PyOpcode_num_popped(opcode, oparg) == 2);
                     assert(_PyOpcode_num_pushed(opcode, oparg) == 1);
index 0d8686c1b5856a034df0f64e2dc7e48744251b13..e01b9292a5800bb9b6fac01ff7acc351ac98a6a7 100644 (file)
             next_instr += 1;
             INSTRUCTION_STATS(CLEANUP_THROW);
             _PyStackRef sub_iter;
+            _PyStackRef null_in;
             _PyStackRef last_sent_val;
             _PyStackRef exc_value_st;
             _PyStackRef none;
+            _PyStackRef null_out;
             _PyStackRef value;
             exc_value_st = stack_pointer[-1];
             last_sent_val = stack_pointer[-2];
-            sub_iter = stack_pointer[-3];
+            null_in = stack_pointer[-3];
+            sub_iter = stack_pointer[-4];
             PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st);
             #if !_Py_TAIL_CALL_INTERP
             assert(throwflag);
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 _PyStackRef tmp = sub_iter;
                 sub_iter = value;
-                stack_pointer[-3] = sub_iter;
+                stack_pointer[-4] = sub_iter;
                 PyStackRef_CLOSE(tmp);
                 tmp = exc_value_st;
                 exc_value_st = PyStackRef_NULL;
                 last_sent_val = PyStackRef_NULL;
                 stack_pointer[-2] = last_sent_val;
                 PyStackRef_CLOSE(tmp);
+                tmp = null_in;
+                null_in = PyStackRef_NULL;
+                stack_pointer[-3] = null_in;
+                PyStackRef_XCLOSE(tmp);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
-                stack_pointer += -3;
+                stack_pointer += -4;
                 ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                null_out = null_in;
                 none = PyStackRef_None;
             }
             else {
                 JUMP_TO_LABEL(exception_unwind);
             }
             stack_pointer[0] = none;
-            stack_pointer[1] = value;
-            stack_pointer += 2;
+            stack_pointer[1] = null_out;
+            stack_pointer[2] = value;
+            stack_pointer += 3;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             DISPATCH();
         }
             next_instr += 1;
             INSTRUCTION_STATS(END_SEND);
             _PyStackRef receiver;
+            _PyStackRef index_or_null;
             _PyStackRef value;
             _PyStackRef val;
             value = stack_pointer[-1];
-            receiver = stack_pointer[-2];
+            index_or_null = stack_pointer[-2];
+            receiver = stack_pointer[-3];
             val = value;
-            stack_pointer[-2] = val;
-            stack_pointer += -1;
+            (void)index_or_null;
+            stack_pointer[-3] = val;
+            stack_pointer += -2;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             _PyFrame_SetStackPointer(frame, stack_pointer);
             PyStackRef_CLOSE(receiver);
             _PyStackRef index_or_null;
             iterable = stack_pointer[-1];
             #ifdef Py_STATS
-            _PyFrame_SetStackPointer(frame, stack_pointer);
             _Py_GatherStats_GetIter(iterable);
-            stack_pointer = _PyFrame_GetStackPointer(frame);
             #endif
-            PyTypeObject *tp = PyStackRef_TYPE(iterable);
-            if (tp == &PyTuple_Type || tp == &PyList_Type) {
-                iter = iterable;
-                index_or_null = PyStackRef_TagInt(0);
-            }
-            else {
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                stack_pointer += -1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyStackRef_CLOSE(iterable);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    JUMP_TO_LABEL(error);
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                index_or_null = PyStackRef_NULL;
-                stack_pointer += 1;
+            _PyFrame_SetStackPointer(frame, stack_pointer);
+            _PyStackRef result = _PyEval_GetIter(iterable, &index_or_null, oparg);
+            stack_pointer = _PyFrame_GetStackPointer(frame);
+            if (PyStackRef_IsError(result)) {
+                JUMP_TO_LABEL(pop_1_error);
             }
+            iter = result;
             stack_pointer[-1] = iter;
             stack_pointer[0] = index_or_null;
             stack_pointer += 1;
             DISPATCH();
         }
 
-        TARGET(GET_YIELD_FROM_ITER) {
-            #if _Py_TAIL_CALL_INTERP
-            int opcode = GET_YIELD_FROM_ITER;
-            (void)(opcode);
-            #endif
-            frame->instr_ptr = next_instr;
-            next_instr += 1;
-            INSTRUCTION_STATS(GET_YIELD_FROM_ITER);
-            _PyStackRef iterable;
-            _PyStackRef iter;
-            iterable = stack_pointer[-1];
-            PyObject *iterable_o = PyStackRef_AsPyObjectBorrow(iterable);
-            if (PyCoro_CheckExact(iterable_o)) {
-                if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    _PyErr_SetString(tstate, PyExc_TypeError,
-                                     "cannot 'yield from' a coroutine object "
-                                     "in a non-coroutine generator");
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    JUMP_TO_LABEL(error);
-                }
-                iter = iterable;
-            }
-            else if (PyGen_CheckExact(iterable_o)) {
-                iter = iterable;
-            }
-            else {
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                PyObject *iter_o = PyObject_GetIter(iterable_o);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (iter_o == NULL) {
-                    JUMP_TO_LABEL(error);
-                }
-                iter = PyStackRef_FromPyObjectSteal(iter_o);
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                _PyStackRef tmp = iterable;
-                iterable = iter;
-                stack_pointer[-1] = iterable;
-                PyStackRef_CLOSE(tmp);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-            }
-            stack_pointer[-1] = iter;
-            DISPATCH();
-        }
-
         TARGET(IMPORT_FROM) {
             #if _Py_TAIL_CALL_INTERP
             int opcode = IMPORT_FROM;
             next_instr += 1;
             INSTRUCTION_STATS(INSTRUMENTED_END_SEND);
             _PyStackRef receiver;
+            _PyStackRef index_or_null;
             _PyStackRef value;
             _PyStackRef val;
             value = stack_pointer[-1];
-            receiver = stack_pointer[-2];
+            index_or_null = stack_pointer[-2];
+            receiver = stack_pointer[-3];
             PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
             if (PyGen_Check(receiver_o) || PyCoro_CheckExact(receiver_o)) {
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 }
             }
             val = value;
-            stack_pointer[-2] = val;
-            stack_pointer += -1;
+            (void)index_or_null;
+            stack_pointer[-3] = val;
+            stack_pointer += -2;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             _PyFrame_SetStackPointer(frame, stack_pointer);
             PyStackRef_CLOSE(receiver);
             _Py_CODEUNIT* const this_instr = next_instr - 2;
             (void)this_instr;
             _PyStackRef receiver;
+            _PyStackRef null_or_index;
             _PyStackRef v;
             _PyStackRef retval;
             // _SPECIALIZE_SEND
             {
-                receiver = stack_pointer[-2];
+                receiver = stack_pointer[-3];
                 uint16_t counter = read_u16(&this_instr[1].cache);
                 (void)counter;
                 #if ENABLE_SPECIALIZATION
             // _SEND
             {
                 v = stack_pointer[-1];
+                null_or_index = stack_pointer[-2];
                 PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
                 PyObject *retval_o;
                 assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
                     gen_frame->previous = frame;
                     DISPATCH_INLINED(gen_frame);
                 }
-                if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
+                if (!PyStackRef_IsNull(null_or_index)) {
                     _PyFrame_SetStackPointer(frame, stack_pointer);
-                    retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
+                    _PyStackRef item = _PyForIter_VirtualIteratorNext(tstate, frame, receiver, &null_or_index);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
+                    if (!PyStackRef_IsValid(item)) {
+                        if (PyStackRef_IsError(item)) {
+                            JUMP_TO_LABEL(error);
+                        }
+                        JUMPBY(oparg);
+                        stack_pointer[-2] = null_or_index;
+                        DISPATCH();
+                    }
+                    retval = item;
                 }
                 else {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    retval_o = PyObject_CallMethodOneArg(receiver_o,
-                        &_Py_ID(send),
-                        PyStackRef_AsPyObjectBorrow(v));
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                }
-                if (retval_o == NULL) {
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (matches) {
+                    if (PyStackRef_IsNone(v) && PyIter_Check(receiver_o)) {
                         _PyFrame_SetStackPointer(frame, stack_pointer);
-                        _PyEval_MonitorRaise(tstate, frame, this_instr);
+                        retval_o = Py_TYPE(receiver_o)->tp_iternext(receiver_o);
                         stack_pointer = _PyFrame_GetStackPointer(frame);
                     }
-                    _PyFrame_SetStackPointer(frame, stack_pointer);
-                    int err = _PyGen_FetchStopIterationValue(&retval_o);
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (err == 0) {
-                        assert(retval_o != NULL);
-                        JUMPBY(oparg);
-                    }
                     else {
-                        stack_pointer += -1;
-                        ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
                         _PyFrame_SetStackPointer(frame, stack_pointer);
-                        PyStackRef_CLOSE(v);
+                        retval_o = PyObject_CallMethodOneArg(receiver_o,
+                            &_Py_ID(send),
+                            PyStackRef_AsPyObjectBorrow(v));
                         stack_pointer = _PyFrame_GetStackPointer(frame);
-                        JUMP_TO_LABEL(error);
                     }
+                    if (retval_o == NULL) {
+                        _PyFrame_SetStackPointer(frame, stack_pointer);
+                        int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration);
+                        stack_pointer = _PyFrame_GetStackPointer(frame);
+                        if (matches) {
+                            _PyFrame_SetStackPointer(frame, stack_pointer);
+                            _PyEval_MonitorRaise(tstate, frame, this_instr);
+                            stack_pointer = _PyFrame_GetStackPointer(frame);
+                        }
+                        _PyFrame_SetStackPointer(frame, stack_pointer);
+                        int err = _PyGen_FetchStopIterationValue(&retval_o);
+                        stack_pointer = _PyFrame_GetStackPointer(frame);
+                        if (err == 0) {
+                            assert(retval_o != NULL);
+                            JUMPBY(oparg);
+                        }
+                        else {
+                            stack_pointer += -1;
+                            ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                            _PyFrame_SetStackPointer(frame, stack_pointer);
+                            PyStackRef_CLOSE(v);
+                            stack_pointer = _PyFrame_GetStackPointer(frame);
+                            JUMP_TO_LABEL(error);
+                        }
+                    }
+                    retval = PyStackRef_FromPyObjectSteal(retval_o);
                 }
-                stack_pointer += -1;
-                ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+                stack_pointer[-2] = null_or_index;
+                stack_pointer[-1] = retval;
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 PyStackRef_CLOSE(v);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
-                retval = PyStackRef_FromPyObjectSteal(retval_o);
             }
-            stack_pointer[0] = retval;
-            stack_pointer += 1;
-            ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             DISPATCH();
         }
 
             // _SEND_GEN_FRAME
             {
                 v = stack_pointer[-1];
-                receiver = stack_pointer[-2];
+                receiver = stack_pointer[-3];
                 PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
                 if (Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type) {
                     UPDATE_MISS_STATS(SEND);
index def462bacec176d2cb02ab16e559a77e74ac753d..48fe9c14f4e2dda5d9d5bac02f00c2d5b2bc0b22 100644 (file)
@@ -16,10 +16,8 @@ static void *opcode_targets_table[256] = {
     &&TARGET_FORMAT_WITH_SPEC,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
-    &&TARGET_GET_ITER,
-    &&TARGET_RESERVED,
     &&TARGET_GET_LEN,
-    &&TARGET_GET_YIELD_FROM_ITER,
+    &&TARGET_RESERVED,
     &&TARGET_INTERPRETER_EXIT,
     &&TARGET_LOAD_BUILD_CLASS,
     &&TARGET_LOAD_LOCALS,
@@ -72,6 +70,7 @@ static void *opcode_targets_table[256] = {
     &&TARGET_EXTENDED_ARG,
     &&TARGET_FOR_ITER,
     &&TARGET_GET_AWAITABLE,
+    &&TARGET_GET_ITER,
     &&TARGET_IMPORT_FROM,
     &&TARGET_IMPORT_NAME,
     &&TARGET_IS_OP,
@@ -128,6 +127,7 @@ static void *opcode_targets_table[256] = {
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_RESUME,
     &&TARGET_BINARY_OP_ADD_FLOAT,
     &&TARGET_BINARY_OP_ADD_INT,
@@ -379,7 +379,7 @@ static void *opcode_tracing_targets_table[256] = {
     &&TARGET_TRACE_RECORD,
     &&TARGET_TRACE_RECORD,
     &&TARGET_TRACE_RECORD,
-    &&TARGET_TRACE_RECORD,
+    &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
@@ -626,7 +626,6 @@ static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ANEXT(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_AWAITABLE(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ITER(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_LEN(TAIL_CALL_PARAMS);
-static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_YIELD_FROM_ITER(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_FROM(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_NAME(TAIL_CALL_PARAMS);
 static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_CALL(TAIL_CALL_PARAMS);
@@ -868,7 +867,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
     [GET_AWAITABLE] = _TAIL_CALL_GET_AWAITABLE,
     [GET_ITER] = _TAIL_CALL_GET_ITER,
     [GET_LEN] = _TAIL_CALL_GET_LEN,
-    [GET_YIELD_FROM_ITER] = _TAIL_CALL_GET_YIELD_FROM_ITER,
     [IMPORT_FROM] = _TAIL_CALL_IMPORT_FROM,
     [IMPORT_NAME] = _TAIL_CALL_IMPORT_NAME,
     [INSTRUMENTED_CALL] = _TAIL_CALL_INSTRUMENTED_CALL,
@@ -1002,6 +1000,7 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = {
     [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE,
     [WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START,
     [YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE,
+    [120] = _TAIL_CALL_UNKNOWN_OPCODE,
     [121] = _TAIL_CALL_UNKNOWN_OPCODE,
     [122] = _TAIL_CALL_UNKNOWN_OPCODE,
     [123] = _TAIL_CALL_UNKNOWN_OPCODE,
@@ -1126,7 +1125,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
     [GET_AWAITABLE] = _TAIL_CALL_TRACE_RECORD,
     [GET_ITER] = _TAIL_CALL_TRACE_RECORD,
     [GET_LEN] = _TAIL_CALL_TRACE_RECORD,
-    [GET_YIELD_FROM_ITER] = _TAIL_CALL_TRACE_RECORD,
     [IMPORT_FROM] = _TAIL_CALL_TRACE_RECORD,
     [IMPORT_NAME] = _TAIL_CALL_TRACE_RECORD,
     [INSTRUMENTED_CALL] = _TAIL_CALL_TRACE_RECORD,
@@ -1260,6 +1258,7 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = {
     [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_TRACE_RECORD,
     [WITH_EXCEPT_START] = _TAIL_CALL_TRACE_RECORD,
     [YIELD_VALUE] = _TAIL_CALL_TRACE_RECORD,
+    [120] = _TAIL_CALL_UNKNOWN_OPCODE,
     [121] = _TAIL_CALL_UNKNOWN_OPCODE,
     [122] = _TAIL_CALL_UNKNOWN_OPCODE,
     [123] = _TAIL_CALL_UNKNOWN_OPCODE,
index 2364bf75d104def5621ea0a90c5be9be5ef46aad..f2d0e2940d7188772ad4153acd3781c532eccdd8 100644 (file)
@@ -1038,7 +1038,7 @@ dummy_func(void) {
         gen_frame = PyJitRef_WrapInvalid(new_frame);
     }
 
-    op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) {
+    op(_SEND_GEN_FRAME, (receiver, null, v -- receiver, null, gen_frame)) {
         _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, NULL, 0);
         if (new_frame == NULL) {
             ctx->done = true;
@@ -1779,6 +1779,12 @@ dummy_func(void) {
         sym_set_recorded_gen_func(nos, func);
     }
 
+    op(_RECORD_3OS_GEN_FUNC, (gen, nos, tos -- gen, nos, tos)) {
+        PyFunctionObject *func = (PyFunctionObject *)this_instr->operand0;
+        assert(func == NULL || PyFunction_Check(func));
+        sym_set_recorded_gen_func(gen, func);
+    }
+
     op(_GUARD_CODE_VERSION__PUSH_FRAME, (version/2 -- )) {
         PyCodeObject *co = get_current_code_object(ctx);
         if (co->co_version == version) {
index 40938a4411e3ecc5f1a0554efc9fa20da890cb64..860bb02b7a01226401359d74f04f614aa2afb70c 100644 (file)
         case _END_SEND: {
             JitOptRef val;
             val = sym_new_not_null(ctx);
-            CHECK_STACK_BOUNDS(-1);
-            stack_pointer[-2] = val;
-            stack_pointer += -1;
+            CHECK_STACK_BOUNDS(-2);
+            stack_pointer[-3] = val;
+            stack_pointer += -2;
             ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
             break;
         }
             JitOptRef receiver;
             JitOptRef gen_frame;
             v = stack_pointer[-1];
-            receiver = stack_pointer[-2];
+            receiver = stack_pointer[-3];
             _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, NULL, 0);
             if (new_frame == NULL) {
                 ctx->done = true;
             break;
         }
 
-        case _GET_YIELD_FROM_ITER: {
-            JitOptRef iter;
-            iter = sym_new_not_null(ctx);
-            stack_pointer[-1] = iter;
-            break;
-        }
-
         /* _FOR_ITER is not a viable micro-op for tier 2 */
 
         case _FOR_ITER_TIER_TWO: {
             break;
         }
 
+        case _RECORD_3OS_GEN_FUNC: {
+            JitOptRef gen;
+            gen = stack_pointer[-3];
+            PyFunctionObject *func = (PyFunctionObject *)this_instr->operand0;
+            assert(func == NULL || PyFunction_Check(func));
+            sym_set_recorded_gen_func(gen, func);
+            break;
+        }
+
         case _RECORD_4OS: {
             JitOptRef value;
             value = stack_pointer[-4];
index 64cafcb326e11142626af14115973728c9dda606..958cdab34c8ff4a9fd0743e386e0b8e814333a12 100644 (file)
@@ -41,6 +41,20 @@ void _PyOpcode_RecordFunction_NOS_GEN_FUNC(_PyInterpreterFrame *frame, _PyStackR
     }
 }
 
+void _PyOpcode_RecordFunction_3OS_GEN_FUNC(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
+    _PyStackRef gen;
+    gen = stack_pointer[-3];
+    PyObject *obj = PyStackRef_AsPyObjectBorrow(gen);
+    if (PyGen_Check(obj)) {
+        PyGenObject *gen_obj = (PyGenObject *)obj;
+        _PyStackRef func = gen_obj->gi_iframe.f_funcobj;
+        if (!PyStackRef_IsNull(func)) {
+            *recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(func);
+            Py_INCREF(*recorded_value);
+        }
+    }
+}
+
 void _PyOpcode_RecordFunction_4OS(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
     _PyStackRef value;
     value = stack_pointer[-4];
@@ -73,14 +87,15 @@ void _PyOpcode_RecordFunction_CODE(_PyInterpreterFrame *frame, _PyStackRef *stac
 
 #define _RECORD_TOS_TYPE_INDEX 1
 #define _RECORD_NOS_INDEX 2
-#define _RECORD_NOS_GEN_FUNC_INDEX 3
-#define _RECORD_CALLABLE_INDEX 4
-#define _RECORD_BOUND_METHOD_INDEX 5
-#define _RECORD_4OS_INDEX 6
+#define _RECORD_3OS_GEN_FUNC_INDEX 3
+#define _RECORD_NOS_GEN_FUNC_INDEX 4
+#define _RECORD_CALLABLE_INDEX 5
+#define _RECORD_BOUND_METHOD_INDEX 6
+#define _RECORD_4OS_INDEX 7
 const uint8_t _PyOpcode_RecordFunctionIndices[256] = {
         [TO_BOOL_ALWAYS_TRUE] = _RECORD_TOS_TYPE_INDEX,
         [BINARY_OP_SUBSCR_GETITEM] = _RECORD_NOS_INDEX,
-        [SEND_GEN] = _RECORD_NOS_GEN_FUNC_INDEX,
+        [SEND_GEN] = _RECORD_3OS_GEN_FUNC_INDEX,
         [LOAD_ATTR_INSTANCE_VALUE] = _RECORD_TOS_TYPE_INDEX,
         [LOAD_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX,
         [LOAD_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX,
@@ -110,10 +125,11 @@ const uint8_t _PyOpcode_RecordFunctionIndices[256] = {
         [CALL_EX_PY] = _RECORD_4OS_INDEX,
 };
 
-const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[7] = {
+const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[8] = {
         [0] = NULL,
         [_RECORD_TOS_TYPE_INDEX] = _PyOpcode_RecordFunction_TOS_TYPE,
         [_RECORD_NOS_INDEX] = _PyOpcode_RecordFunction_NOS,
+        [_RECORD_3OS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_3OS_GEN_FUNC,
         [_RECORD_NOS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_NOS_GEN_FUNC,
         [_RECORD_CALLABLE_INDEX] = _PyOpcode_RecordFunction_CALLABLE,
         [_RECORD_BOUND_METHOD_INDEX] = _PyOpcode_RecordFunction_BOUND_METHOD,
index 4ef8b27795650ca3a78f3d5499e7b2fde852675a..09ec25767a4c3ff059870fa4d93372d51701bf48 100644 (file)
@@ -41,9 +41,24 @@ do { \
 #  define SPECIALIZATION_FAIL(opcode, kind) ((void)0)
 #endif  // Py_STATS
 
+static void
+fixup_getiter(_Py_CODEUNIT *instruction, int flags)
+{
+    // Compiler can't know if types.coroutine() will be called,
+    // so fix up here
+    if (instruction->op.arg) {
+        if (flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE)) {
+            instruction->op.arg = GET_ITER_YIELD_FROM_NO_CHECK;
+        }
+        else {
+            instruction->op.arg = GET_ITER_YIELD_FROM_CORO_CHECK;
+        }
+    }
+}
+
 // Initialize warmup counters and optimize instructions. This cannot fail.
 void
-_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters)
+_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters, int flags)
 {
     #if ENABLE_SPECIALIZATION
     _Py_BackoffCounter jump_counter, adaptive_counter, resume_counter;
@@ -66,6 +81,9 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
         opcode = instructions[i].op.code;
         int caches = _PyOpcode_Caches[opcode];
         oparg = (oparg << 8) | instructions[i].op.arg;
+        if (opcode == GET_ITER) {
+            fixup_getiter(&instructions[i], flags);
+        }
         if (caches) {
             // The initial value depends on the opcode
             switch (opcode) {
@@ -91,6 +109,13 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
             oparg = 0;
         }
     }
+    #else
+    for (Py_ssize_t i = 0; i < size-1; i++) {
+        if (instructions[i].op.code == GET_ITER) {
+            fixup_getiter(&instructions[i], flags);
+        }
+        i += _PyOpcode_Caches[opcode];
+    }
     #endif /* ENABLE_SPECIALIZATION */
 }
 
index 89f843644329ec6b88c5ac7cb289381c8b56de52..7bb4d725d51a4d6e7cfd6fda8954222ed685239e 100644 (file)
@@ -714,7 +714,7 @@ NON_ESCAPING_FUNCTIONS = (
     "trigger_backoff_counter",
     "_PyThreadState_PopCStackRefSteal",
     "doesnt_escape",
-
+    "_Py_GatherStats_GetIter",
 )