@@ -264,6 +264,15 @@ typedef struct basicblock_ {
264264 unsigned b_return : 1 ;
265265} basicblock ;
266266
267+
268+ static struct instr *
269+ basicblock_last_instr (basicblock * b ) {
270+ if (b -> b_iused ) {
271+ return & b -> b_instr [b -> b_iused - 1 ];
272+ }
273+ return NULL ;
274+ }
275+
267276/* fblockinfo tracks the current frame block.
268277
269278A frame block is used to handle loops, try/except, and try/finally.
@@ -331,9 +340,6 @@ struct compiler_unit {
331340 int u_col_offset ; /* the offset of the current stmt */
332341 int u_end_lineno ; /* the end line of the current stmt */
333342 int u_end_col_offset ; /* the end offset of the current stmt */
334-
335- /* true if we need to create an implicit basicblock before the next instr */
336- int u_need_new_implicit_block ;
337343};
338344
339345/* This struct captures the global state of a compilation.
@@ -389,10 +395,11 @@ typedef struct {
389395 Py_ssize_t on_top ;
390396} pattern_context ;
391397
398+ static int basicblock_next_instr (basicblock * );
399+
392400static int compiler_enter_scope (struct compiler * , identifier , int , void * , int );
393401static void compiler_free (struct compiler * );
394402static basicblock * compiler_new_block (struct compiler * );
395- static int compiler_next_instr (basicblock * );
396403static int compiler_addop (struct compiler * , int );
397404static int compiler_addop_i (struct compiler * , int , Py_ssize_t );
398405static int compiler_addop_j (struct compiler * , int , basicblock * );
@@ -830,7 +837,6 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
830837 assert (block != NULL );
831838 c -> u -> u_curblock -> b_next = block ;
832839 c -> u -> u_curblock = block ;
833- c -> u -> u_need_new_implicit_block = 0 ;
834840 return block ;
835841}
836842
@@ -846,7 +852,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
846852 return NULL ;
847853 }
848854 for (int i = 0 ; i < block -> b_iused ; i ++ ) {
849- int n = compiler_next_instr (result );
855+ int n = basicblock_next_instr (result );
850856 if (n < 0 ) {
851857 return NULL ;
852858 }
@@ -863,7 +869,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
863869*/
864870
865871static int
866- compiler_next_instr (basicblock * b )
872+ basicblock_next_instr (basicblock * b )
867873{
868874 assert (b != NULL );
869875 if (b -> b_instr == NULL ) {
@@ -1206,7 +1212,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
12061212 return stack_effect (opcode , oparg , -1 );
12071213}
12081214
1209- static int is_end_of_basic_block (struct instr * instr )
1215+ static int
1216+ is_end_of_basic_block (struct instr * instr )
12101217{
12111218 int opcode = instr -> i_opcode ;
12121219
@@ -1219,7 +1226,8 @@ static int is_end_of_basic_block(struct instr *instr)
12191226static int
12201227compiler_use_new_implicit_block_if_needed (struct compiler * c )
12211228{
1222- if (c -> u -> u_need_new_implicit_block ) {
1229+ basicblock * b = c -> u -> u_curblock ;
1230+ if (b -> b_iused && is_end_of_basic_block (basicblock_last_instr (b ))) {
12231231 basicblock * b = compiler_new_block (c );
12241232 if (b == NULL ) {
12251233 return -1 ;
@@ -1229,32 +1237,19 @@ compiler_use_new_implicit_block_if_needed(struct compiler *c)
12291237 return 0 ;
12301238}
12311239
1232- static void
1233- compiler_check_if_end_of_block (struct compiler * c , struct instr * instr )
1234- {
1235- if (is_end_of_basic_block (instr )) {
1236- c -> u -> u_need_new_implicit_block = 1 ;
1237- }
1238- }
1239-
12401240/* Add an opcode with no argument.
12411241 Returns 0 on failure, 1 on success.
12421242*/
12431243
12441244static int
1245- compiler_addop_line ( struct compiler * c , int opcode , int line ,
1246- int end_line , int col_offset , int end_col_offset )
1245+ basicblock_addop_line ( basicblock * b , int opcode , int line ,
1246+ int end_line , int col_offset , int end_col_offset )
12471247{
12481248 assert (IS_WITHIN_OPCODE_RANGE (opcode ));
12491249 assert (!IS_ASSEMBLER_OPCODE (opcode ));
12501250 assert (!HAS_ARG (opcode ) || IS_ARTIFICIAL (opcode ));
12511251
1252- if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1253- return -1 ;
1254- }
1255-
1256- basicblock * b = c -> u -> u_curblock ;
1257- int off = compiler_next_instr (b );
1252+ int off = basicblock_next_instr (b );
12581253 if (off < 0 ) {
12591254 return 0 ;
12601255 }
@@ -1269,21 +1264,26 @@ compiler_addop_line(struct compiler *c, int opcode, int line,
12691264 i -> i_col_offset = col_offset ;
12701265 i -> i_end_col_offset = end_col_offset ;
12711266
1272- compiler_check_if_end_of_block (c , i );
12731267 return 1 ;
12741268}
12751269
12761270static int
12771271compiler_addop (struct compiler * c , int opcode )
12781272{
1279- return compiler_addop_line (c , opcode , c -> u -> u_lineno , c -> u -> u_end_lineno ,
1280- c -> u -> u_col_offset , c -> u -> u_end_col_offset );
1273+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1274+ return -1 ;
1275+ }
1276+ return basicblock_addop_line (c -> u -> u_curblock , opcode , c -> u -> u_lineno , c -> u -> u_end_lineno ,
1277+ c -> u -> u_col_offset , c -> u -> u_end_col_offset );
12811278}
12821279
12831280static int
12841281compiler_addop_noline (struct compiler * c , int opcode )
12851282{
1286- return compiler_addop_line (c , opcode , -1 , 0 , 0 , 0 );
1283+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1284+ return -1 ;
1285+ }
1286+ return basicblock_addop_line (c -> u -> u_curblock , opcode , -1 , 0 , 0 , 0 );
12871287}
12881288
12891289
@@ -1477,9 +1477,9 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
14771477*/
14781478
14791479static int
1480- compiler_addop_i_line ( struct compiler * c , int opcode , Py_ssize_t oparg ,
1481- int lineno , int end_lineno ,
1482- int col_offset , int end_col_offset )
1480+ basicblock_addop_i_line ( basicblock * b , int opcode , Py_ssize_t oparg ,
1481+ int lineno , int end_lineno ,
1482+ int col_offset , int end_col_offset )
14831483{
14841484 /* oparg value is unsigned, but a signed C int is usually used to store
14851485 it in the C code (like Python/ceval.c).
@@ -1494,12 +1494,7 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
14941494 assert (HAS_ARG (opcode ));
14951495 assert (0 <= oparg && oparg <= 2147483647 );
14961496
1497- if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1498- return -1 ;
1499- }
1500-
1501- basicblock * b = c -> u -> u_curblock ;
1502- int off = compiler_next_instr (b );
1497+ int off = basicblock_next_instr (b );
15031498 if (off < 0 ) {
15041499 return 0 ;
15051500 }
@@ -1511,40 +1506,41 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
15111506 i -> i_col_offset = col_offset ;
15121507 i -> i_end_col_offset = end_col_offset ;
15131508
1514- compiler_check_if_end_of_block (c , i );
15151509 return 1 ;
15161510}
15171511
15181512static int
15191513compiler_addop_i (struct compiler * c , int opcode , Py_ssize_t oparg )
15201514{
1521- return compiler_addop_i_line (c , opcode , oparg ,
1522- c -> u -> u_lineno , c -> u -> u_end_lineno ,
1523- c -> u -> u_col_offset , c -> u -> u_end_col_offset );
1515+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1516+ return -1 ;
1517+ }
1518+ return basicblock_addop_i_line (c -> u -> u_curblock , opcode , oparg ,
1519+ c -> u -> u_lineno , c -> u -> u_end_lineno ,
1520+ c -> u -> u_col_offset , c -> u -> u_end_col_offset );
15241521}
15251522
15261523static int
15271524compiler_addop_i_noline (struct compiler * c , int opcode , Py_ssize_t oparg )
15281525{
1529- return compiler_addop_i_line (c , opcode , oparg , -1 , 0 , 0 , 0 );
1526+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1527+ return -1 ;
1528+ }
1529+ return basicblock_addop_i_line (c -> u -> u_curblock , opcode , oparg , -1 , 0 , 0 , 0 );
15301530}
15311531
1532- static int add_jump_to_block (struct compiler * c , int opcode ,
1533- int lineno , int end_lineno ,
1534- int col_offset , int end_col_offset ,
1535- basicblock * target )
1532+ static int
1533+ basicblock_add_jump (basicblock * b , int opcode ,
1534+ int lineno , int end_lineno ,
1535+ int col_offset , int end_col_offset ,
1536+ basicblock * target )
15361537{
15371538 assert (IS_WITHIN_OPCODE_RANGE (opcode ));
15381539 assert (!IS_ASSEMBLER_OPCODE (opcode ));
15391540 assert (HAS_ARG (opcode ) || IS_VIRTUAL_OPCODE (opcode ));
15401541 assert (target != NULL );
15411542
1542- if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1543- return -1 ;
1544- }
1545-
1546- basicblock * b = c -> u -> u_curblock ;
1547- int off = compiler_next_instr (b );
1543+ int off = basicblock_next_instr (b );
15481544 struct instr * i = & b -> b_instr [off ];
15491545 if (off < 0 ) {
15501546 return 0 ;
@@ -1556,22 +1552,27 @@ static int add_jump_to_block(struct compiler *c, int opcode,
15561552 i -> i_col_offset = col_offset ;
15571553 i -> i_end_col_offset = end_col_offset ;
15581554
1559- compiler_check_if_end_of_block (c , i );
15601555 return 1 ;
15611556}
15621557
15631558static int
15641559compiler_addop_j (struct compiler * c , int opcode , basicblock * b )
15651560{
1566- return add_jump_to_block (c , opcode , c -> u -> u_lineno ,
1567- c -> u -> u_end_lineno , c -> u -> u_col_offset ,
1568- c -> u -> u_end_col_offset , b );
1561+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1562+ return -1 ;
1563+ }
1564+ return basicblock_add_jump (c -> u -> u_curblock , opcode , c -> u -> u_lineno ,
1565+ c -> u -> u_end_lineno , c -> u -> u_col_offset ,
1566+ c -> u -> u_end_col_offset , b );
15691567}
15701568
15711569static int
15721570compiler_addop_j_noline (struct compiler * c , int opcode , basicblock * b )
15731571{
1574- return add_jump_to_block (c , opcode , -1 , 0 , 0 , 0 , b );
1572+ if (compiler_use_new_implicit_block_if_needed (c ) < 0 ) {
1573+ return -1 ;
1574+ }
1575+ return basicblock_add_jump (c -> u -> u_curblock , opcode , -1 , 0 , 0 , 0 , b );
15751576}
15761577
15771578#define ADDOP (C , OP ) { \
@@ -8085,7 +8086,7 @@ build_cellfixedoffsets(struct compiler *c)
80858086
80868087static inline int
80878088insert_instruction (basicblock * block , int pos , struct instr * instr ) {
8088- if (compiler_next_instr (block ) < 0 ) {
8089+ if (basicblock_next_instr (block ) < 0 ) {
80898090 return -1 ;
80908091 }
80918092 for (int i = block -> b_iused - 1 ; i > pos ; i -- ) {
@@ -8971,7 +8972,7 @@ extend_block(basicblock *bb) {
89718972 basicblock * to_copy = last -> i_target ;
89728973 last -> i_opcode = NOP ;
89738974 for (int i = 0 ; i < to_copy -> b_iused ; i ++ ) {
8974- int index = compiler_next_instr (bb );
8975+ int index = basicblock_next_instr (bb );
89758976 if (index < 0 ) {
89768977 return -1 ;
89778978 }
0 commit comments