@@ -756,6 +756,11 @@ dummy_func(
756756 goto resume_frame ;
757757 }
758758 _Py_LeaveRecursiveCallTstate (tstate );
759+ if (frame -> owner == FRAME_OWNED_BY_GENERATOR ) {
760+ PyGenObject * gen = _PyFrame_GetGenerator (frame );
761+ tstate -> exc_info = gen -> gi_exc_state .previous_item ;
762+ gen -> gi_exc_state .previous_item = NULL ;
763+ }
759764 /* Restore previous cframe and return. */
760765 tstate -> cframe = cframe .previous ;
761766 tstate -> cframe -> use_tracing = cframe .use_tracing ;
@@ -895,7 +900,6 @@ dummy_func(
895900
896901 // error: SEND stack effect depends on jump flag
897902 inst (SEND ) {
898- assert (frame -> is_entry );
899903 assert (STACK_LEVEL () >= 2 );
900904 PyObject * v = POP ();
901905 PyObject * receiver = TOP ();
@@ -960,13 +964,21 @@ dummy_func(
960964 // The compiler treats any exception raised here as a failed close()
961965 // or throw() call.
962966 assert (oparg == STACK_LEVEL ());
963- assert (frame -> is_entry );
964967 PyObject * retval = POP ();
965- _PyFrame_GetGenerator (frame )-> gi_frame_state = FRAME_SUSPENDED ;
968+ PyGenObject * gen = _PyFrame_GetGenerator (frame );
969+ gen -> gi_frame_state = FRAME_SUSPENDED ;
966970 _PyFrame_SetStackPointer (frame , stack_pointer );
967971 TRACE_FUNCTION_EXIT ();
968972 DTRACE_FUNCTION_EXIT ();
973+ tstate -> exc_info = gen -> gi_exc_state .previous_item ;
974+ gen -> gi_exc_state .previous_item = NULL ;
969975 _Py_LeaveRecursiveCallPy (tstate );
976+ if (!frame -> is_entry ) {
977+ frame = cframe .current_frame = frame -> previous ;
978+ frame -> prev_instr -= frame -> yield_offset ;
979+ _PyFrame_StackPush (frame , retval );
980+ goto resume_frame ;
981+ }
970982 _Py_LeaveRecursiveCallTstate (tstate );
971983 /* Restore previous cframe and return. */
972984 tstate -> cframe = cframe .previous ;
@@ -2788,7 +2800,7 @@ dummy_func(
27882800 _PyForIterCache * cache = (_PyForIterCache * )next_instr ;
27892801 if (ADAPTIVE_COUNTER_IS_ZERO (cache )) {
27902802 next_instr -- ;
2791- _Py_Specialize_ForIter (TOP (), next_instr );
2803+ _Py_Specialize_ForIter (TOP (), next_instr , oparg );
27922804 DISPATCH_SAME_OPARG ();
27932805 }
27942806 else {
@@ -2844,6 +2856,30 @@ dummy_func(
28442856 JUMPBY (INLINE_CACHE_ENTRIES_FOR_ITER + 1 );
28452857 }
28462858
2859+ inst (FOR_ITER_GEN ) {
2860+ assert (cframe .use_tracing == 0 );
2861+ PyGenObject * gen = (PyGenObject * )TOP ();
2862+ DEOPT_IF (Py_TYPE (gen ) != & PyGen_Type , FOR_ITER );
2863+ DEOPT_IF (gen -> gi_frame_state >= FRAME_EXECUTING , FOR_ITER );
2864+ STAT_INC (FOR_ITER , hit );
2865+ _PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
2866+ _PyFrame_SetStackPointer (frame , stack_pointer );
2867+ frame -> yield_offset = oparg ;
2868+ JUMPBY (INLINE_CACHE_ENTRIES_FOR_ITER + oparg );
2869+ assert (_Py_OPCODE (* next_instr ) == END_FOR );
2870+ frame -> prev_instr = next_instr - 1 ;
2871+ Py_INCREF (Py_None );
2872+ _PyFrame_StackPush (gen_frame , Py_None );
2873+ gen -> gi_frame_state = FRAME_EXECUTING ;
2874+ gen -> gi_exc_state .previous_item = tstate -> exc_info ;
2875+ tstate -> exc_info = & gen -> gi_exc_state ;
2876+ gen_frame -> previous = frame ;
2877+ gen_frame -> is_entry = false;
2878+ frame = cframe .current_frame = gen_frame ;
2879+ goto start_frame ;
2880+ }
2881+
2882+
28472883 // stack effect: ( -- __0)
28482884 inst (BEFORE_ASYNC_WITH ) {
28492885 PyObject * mgr = TOP ();
0 commit comments