@@ -149,12 +149,12 @@ static struct jump_target_label_ NO_LABEL = {NULL};
149
149
#define IS_LABEL (L ) (!SAME_LABEL((L), (NO_LABEL)))
150
150
151
151
#define NEW_JUMP_TARGET_LABEL (C , NAME ) \
152
- jump_target_label NAME = {compiler_new_block(C )}; \
152
+ jump_target_label NAME = {cfg_builder_new_block(CFG_BUILDER(C) )}; \
153
153
if (!IS_LABEL(NAME)) { \
154
154
return 0; \
155
155
}
156
156
157
- #define USE_LABEL (C , LBL ) compiler_use_next_block(C, ( LBL).block )
157
+ #define USE_LABEL (C , LBL ) cfg_builder_use_label(CFG_BUILDER(C), LBL)
158
158
159
159
struct instr {
160
160
int i_opcode ;
@@ -354,6 +354,8 @@ typedef struct cfg_builder_ {
354
354
basicblock * block_list ;
355
355
/* pointer to the block currently being constructed */
356
356
basicblock * curblock ;
357
+ /* label for the next instruction to be placed */
358
+ jump_target_label g_current_label ;
357
359
} cfg_builder ;
358
360
359
361
/* The following items change on entry and exit of code blocks.
@@ -449,6 +451,7 @@ typedef struct {
449
451
450
452
static int basicblock_next_instr (basicblock * );
451
453
454
+ static int cfg_builder_maybe_start_new_block (cfg_builder * g );
452
455
static int cfg_builder_addop_i (cfg_builder * g , int opcode , Py_ssize_t oparg , struct location loc );
453
456
454
457
static void compiler_free (struct compiler * );
@@ -886,16 +889,11 @@ cfg_builder_use_next_block(cfg_builder *g, basicblock *block)
886
889
return block ;
887
890
}
888
891
889
- static basicblock *
890
- compiler_new_block (struct compiler * c )
891
- {
892
- return cfg_builder_new_block (CFG_BUILDER (c ));
893
- }
894
-
895
- static basicblock *
896
- compiler_use_next_block (struct compiler * c , basicblock * block )
892
+ static int
893
+ cfg_builder_use_label (cfg_builder * g , jump_target_label lbl )
897
894
{
898
- return cfg_builder_use_next_block (CFG_BUILDER (c ), block );
895
+ g -> g_current_label = lbl ;
896
+ return cfg_builder_maybe_start_new_block (g );
899
897
}
900
898
901
899
static basicblock *
@@ -1299,18 +1297,43 @@ basicblock_addop(basicblock *b, int opcode, int oparg,
1299
1297
return 1 ;
1300
1298
}
1301
1299
1302
- static int
1303
- cfg_builder_addop (cfg_builder * g , int opcode , int oparg , jump_target_label target ,
1304
- struct location loc )
1300
+ static bool
1301
+ cfg_builder_current_block_is_terminated (cfg_builder * g )
1305
1302
{
1303
+ if (IS_LABEL (g -> g_current_label )) {
1304
+ return true;
1305
+ }
1306
1306
struct instr * last = basicblock_last_instr (g -> curblock );
1307
- if (last && IS_TERMINATOR_OPCODE (last -> i_opcode )) {
1308
- basicblock * b = cfg_builder_new_block (g );
1307
+ return last && IS_TERMINATOR_OPCODE (last -> i_opcode );
1308
+ }
1309
+
1310
+ static int
1311
+ cfg_builder_maybe_start_new_block (cfg_builder * g )
1312
+ {
1313
+ if (cfg_builder_current_block_is_terminated (g )) {
1314
+ basicblock * b ;
1315
+ if (IS_LABEL (g -> g_current_label )) {
1316
+ b = g -> g_current_label .block ;
1317
+ g -> g_current_label = NO_LABEL ;
1318
+ }
1319
+ else {
1320
+ b = cfg_builder_new_block (g );
1321
+ }
1309
1322
if (b == NULL ) {
1310
1323
return -1 ;
1311
1324
}
1312
1325
cfg_builder_use_next_block (g , b );
1313
1326
}
1327
+ return 0 ;
1328
+ }
1329
+
1330
+ static int
1331
+ cfg_builder_addop (cfg_builder * g , int opcode , int oparg , jump_target_label target ,
1332
+ struct location loc )
1333
+ {
1334
+ if (cfg_builder_maybe_start_new_block (g ) != 0 ) {
1335
+ return -1 ;
1336
+ }
1314
1337
return basicblock_addop (g -> curblock , opcode , oparg , target , loc );
1315
1338
}
1316
1339
@@ -1765,6 +1788,7 @@ compiler_enter_scope(struct compiler *c, identifier name,
1765
1788
if (block == NULL )
1766
1789
return 0 ;
1767
1790
g -> curblock = g -> cfg_entryblock = block ;
1791
+ g -> g_current_label = NO_LABEL ;
1768
1792
1769
1793
if (u -> u_scope_type == COMPILER_SCOPE_MODULE ) {
1770
1794
c -> u -> u_loc .lineno = 0 ;
0 commit comments