@@ -1045,8 +1045,6 @@ stack_effect(int opcode, int oparg, int jump)
10451045 return 0 ;
10461046 case YIELD_VALUE :
10471047 return 0 ;
1048- case YIELD_FROM :
1049- return -1 ;
10501048 case POP_BLOCK :
10511049 return 0 ;
10521050 case POP_EXCEPT :
@@ -1065,7 +1063,8 @@ stack_effect(int opcode, int oparg, int jump)
10651063 case FOR_ITER :
10661064 /* -1 at end of iterator, 1 if continue iterating. */
10671065 return jump > 0 ? -1 : 1 ;
1068-
1066+ case SEND :
1067+ return jump > 0 ? -1 : 0 ;
10691068 case STORE_ATTR :
10701069 return -2 ;
10711070 case DELETE_ATTR :
@@ -1667,6 +1666,9 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b)
16671666 the ASDL name to synthesize the name of the C type and the visit function.
16681667*/
16691668
1669+ #define ADD_YIELD_FROM (C ) \
1670+ RETURN_IF_FALSE(compiler_add_yield_from((C)))
1671+
16701672#define VISIT (C , TYPE , V ) {\
16711673 if (!compiler_visit_ ## TYPE((C), (V))) \
16721674 return 0; \
@@ -1819,6 +1821,24 @@ compiler_call_exit_with_nones(struct compiler *c) {
18191821 return 1 ;
18201822}
18211823
1824+ static int
1825+ compiler_add_yield_from (struct compiler * c )
1826+ {
1827+ basicblock * start , * jump , * exit ;
1828+ start = compiler_new_block (c );
1829+ jump = compiler_new_block (c );
1830+ exit = compiler_new_block (c );
1831+ if (start == NULL || jump == NULL || exit == NULL ) {
1832+ return 0 ;
1833+ }
1834+ compiler_use_next_block (c , start );
1835+ ADDOP_JUMP (c , SEND , exit );
1836+ compiler_use_next_block (c , jump );
1837+ ADDOP_JUMP (c , JUMP_ABSOLUTE , start );
1838+ compiler_use_next_block (c , exit );
1839+ return 1 ;
1840+ }
1841+
18221842/* Unwind a frame block. If preserve_tos is true, the TOS before
18231843 * popping the blocks will be restored afterwards, unless another
18241844 * return, break or continue is found. In which case, the TOS will
@@ -1893,7 +1913,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
18931913 if (info -> fb_type == ASYNC_WITH ) {
18941914 ADDOP (c , GET_AWAITABLE );
18951915 ADDOP_LOAD_CONST (c , Py_None );
1896- ADDOP ( c , YIELD_FROM );
1916+ ADD_YIELD_FROM ( c );
18971917 }
18981918 ADDOP (c , POP_TOP );
18991919 /* The exit block should appear to execute after the
@@ -3006,7 +3026,7 @@ compiler_async_for(struct compiler *c, stmt_ty s)
30063026 ADDOP_JUMP (c , SETUP_FINALLY , except );
30073027 ADDOP (c , GET_ANEXT );
30083028 ADDOP_LOAD_CONST (c , Py_None );
3009- ADDOP ( c , YIELD_FROM );
3029+ ADD_YIELD_FROM ( c );
30103030 ADDOP (c , POP_BLOCK ); /* for SETUP_FINALLY */
30113031
30123032 /* Success block for __anext__ */
@@ -5192,7 +5212,7 @@ compiler_async_comprehension_generator(struct compiler *c,
51925212 ADDOP_JUMP (c , SETUP_FINALLY , except );
51935213 ADDOP (c , GET_ANEXT );
51945214 ADDOP_LOAD_CONST (c , Py_None );
5195- ADDOP ( c , YIELD_FROM );
5215+ ADD_YIELD_FROM ( c );
51965216 ADDOP (c , POP_BLOCK );
51975217 VISIT (c , expr , gen -> target );
51985218
@@ -5342,7 +5362,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
53425362 if (is_async_generator && type != COMP_GENEXP ) {
53435363 ADDOP (c , GET_AWAITABLE );
53445364 ADDOP_LOAD_CONST (c , Py_None );
5345- ADDOP ( c , YIELD_FROM );
5365+ ADD_YIELD_FROM ( c );
53465366 }
53475367
53485368 return 1 ;
@@ -5493,7 +5513,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
54935513 ADDOP (c , BEFORE_ASYNC_WITH );
54945514 ADDOP (c , GET_AWAITABLE );
54955515 ADDOP_LOAD_CONST (c , Py_None );
5496- ADDOP ( c , YIELD_FROM );
5516+ ADD_YIELD_FROM ( c );
54975517
54985518 ADDOP_JUMP (c , SETUP_WITH , final );
54995519
@@ -5530,7 +5550,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
55305550 return 0 ;
55315551 ADDOP (c , GET_AWAITABLE );
55325552 ADDOP_LOAD_CONST (c , Py_None );
5533- ADDOP ( c , YIELD_FROM );
5553+ ADD_YIELD_FROM ( c );
55345554
55355555 ADDOP (c , POP_TOP );
55365556
@@ -5544,7 +5564,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
55445564 ADDOP (c , WITH_EXCEPT_START );
55455565 ADDOP (c , GET_AWAITABLE );
55465566 ADDOP_LOAD_CONST (c , Py_None );
5547- ADDOP ( c , YIELD_FROM );
5567+ ADD_YIELD_FROM ( c );
55485568 compiler_with_except_finish (c , cleanup );
55495569
55505570 compiler_use_next_block (c , exit );
@@ -5701,7 +5721,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
57015721 VISIT (c , expr , e -> v .YieldFrom .value );
57025722 ADDOP (c , GET_YIELD_FROM_ITER );
57035723 ADDOP_LOAD_CONST (c , Py_None );
5704- ADDOP ( c , YIELD_FROM );
5724+ ADD_YIELD_FROM ( c );
57055725 break ;
57065726 case Await_kind :
57075727 if (!IS_TOP_LEVEL_AWAIT (c )){
@@ -5718,7 +5738,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
57185738 VISIT (c , expr , e -> v .Await .value );
57195739 ADDOP (c , GET_AWAITABLE );
57205740 ADDOP_LOAD_CONST (c , Py_None );
5721- ADDOP ( c , YIELD_FROM );
5741+ ADD_YIELD_FROM ( c );
57225742 break ;
57235743 case Compare_kind :
57245744 return compiler_compare (c , e );
@@ -7544,10 +7564,13 @@ normalize_jumps(struct assembler *a)
75447564 continue ;
75457565 }
75467566 struct instr * last = & b -> b_instr [b -> b_iused - 1 ];
7547- if (last -> i_opcode == JUMP_ABSOLUTE &&
7548- last -> i_target -> b_visited == 0
7549- ) {
7550- last -> i_opcode = JUMP_FORWARD ;
7567+ if (last -> i_opcode == JUMP_ABSOLUTE ) {
7568+ if (last -> i_target -> b_visited == 0 ) {
7569+ last -> i_opcode = JUMP_FORWARD ;
7570+ }
7571+ else if (b -> b_iused >= 2 && b -> b_instr [b -> b_iused - 2 ].i_opcode == SEND ) {
7572+ last -> i_opcode = JUMP_ABSOLUTE_QUICK ;
7573+ }
75517574 }
75527575 }
75537576}
0 commit comments