@@ -264,6 +264,15 @@ typedef struct basicblock_ {
264
264
unsigned b_return : 1 ;
265
265
} basicblock ;
266
266
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
+
267
276
/* fblockinfo tracks the current frame block.
268
277
269
278
A frame block is used to handle loops, try/except, and try/finally.
@@ -331,9 +340,6 @@ struct compiler_unit {
331
340
int u_col_offset ; /* the offset of the current stmt */
332
341
int u_end_lineno ; /* the end line of the current stmt */
333
342
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 ;
337
343
};
338
344
339
345
/* This struct captures the global state of a compilation.
@@ -389,10 +395,11 @@ typedef struct {
389
395
Py_ssize_t on_top ;
390
396
} pattern_context ;
391
397
398
+ static int basicblock_next_instr (basicblock * );
399
+
392
400
static int compiler_enter_scope (struct compiler * , identifier , int , void * , int );
393
401
static void compiler_free (struct compiler * );
394
402
static basicblock * compiler_new_block (struct compiler * );
395
- static int compiler_next_instr (basicblock * );
396
403
static int compiler_addop (struct compiler * , int );
397
404
static int compiler_addop_i (struct compiler * , int , Py_ssize_t );
398
405
static int compiler_addop_j (struct compiler * , int , basicblock * );
@@ -830,7 +837,6 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
830
837
assert (block != NULL );
831
838
c -> u -> u_curblock -> b_next = block ;
832
839
c -> u -> u_curblock = block ;
833
- c -> u -> u_need_new_implicit_block = 0 ;
834
840
return block ;
835
841
}
836
842
@@ -846,7 +852,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
846
852
return NULL ;
847
853
}
848
854
for (int i = 0 ; i < block -> b_iused ; i ++ ) {
849
- int n = compiler_next_instr (result );
855
+ int n = basicblock_next_instr (result );
850
856
if (n < 0 ) {
851
857
return NULL ;
852
858
}
@@ -863,7 +869,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
863
869
*/
864
870
865
871
static int
866
- compiler_next_instr (basicblock * b )
872
+ basicblock_next_instr (basicblock * b )
867
873
{
868
874
assert (b != NULL );
869
875
if (b -> b_instr == NULL ) {
@@ -1206,7 +1212,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
1206
1212
return stack_effect (opcode , oparg , -1 );
1207
1213
}
1208
1214
1209
- static int is_end_of_basic_block (struct instr * instr )
1215
+ static int
1216
+ is_end_of_basic_block (struct instr * instr )
1210
1217
{
1211
1218
int opcode = instr -> i_opcode ;
1212
1219
@@ -1219,7 +1226,8 @@ static int is_end_of_basic_block(struct instr *instr)
1219
1226
static int
1220
1227
compiler_use_new_implicit_block_if_needed (struct compiler * c )
1221
1228
{
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 ))) {
1223
1231
basicblock * b = compiler_new_block (c );
1224
1232
if (b == NULL ) {
1225
1233
return -1 ;
@@ -1229,32 +1237,19 @@ compiler_use_new_implicit_block_if_needed(struct compiler *c)
1229
1237
return 0 ;
1230
1238
}
1231
1239
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
-
1240
1240
/* Add an opcode with no argument.
1241
1241
Returns 0 on failure, 1 on success.
1242
1242
*/
1243
1243
1244
1244
static 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 )
1247
1247
{
1248
1248
assert (IS_WITHIN_OPCODE_RANGE (opcode ));
1249
1249
assert (!IS_ASSEMBLER_OPCODE (opcode ));
1250
1250
assert (!HAS_ARG (opcode ) || IS_ARTIFICIAL (opcode ));
1251
1251
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 );
1258
1253
if (off < 0 ) {
1259
1254
return 0 ;
1260
1255
}
@@ -1269,21 +1264,26 @@ compiler_addop_line(struct compiler *c, int opcode, int line,
1269
1264
i -> i_col_offset = col_offset ;
1270
1265
i -> i_end_col_offset = end_col_offset ;
1271
1266
1272
- compiler_check_if_end_of_block (c , i );
1273
1267
return 1 ;
1274
1268
}
1275
1269
1276
1270
static int
1277
1271
compiler_addop (struct compiler * c , int opcode )
1278
1272
{
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 );
1281
1278
}
1282
1279
1283
1280
static int
1284
1281
compiler_addop_noline (struct compiler * c , int opcode )
1285
1282
{
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 );
1287
1287
}
1288
1288
1289
1289
@@ -1477,9 +1477,9 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
1477
1477
*/
1478
1478
1479
1479
static 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 )
1483
1483
{
1484
1484
/* oparg value is unsigned, but a signed C int is usually used to store
1485
1485
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,
1494
1494
assert (HAS_ARG (opcode ));
1495
1495
assert (0 <= oparg && oparg <= 2147483647 );
1496
1496
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 );
1503
1498
if (off < 0 ) {
1504
1499
return 0 ;
1505
1500
}
@@ -1511,40 +1506,41 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
1511
1506
i -> i_col_offset = col_offset ;
1512
1507
i -> i_end_col_offset = end_col_offset ;
1513
1508
1514
- compiler_check_if_end_of_block (c , i );
1515
1509
return 1 ;
1516
1510
}
1517
1511
1518
1512
static int
1519
1513
compiler_addop_i (struct compiler * c , int opcode , Py_ssize_t oparg )
1520
1514
{
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 );
1524
1521
}
1525
1522
1526
1523
static int
1527
1524
compiler_addop_i_noline (struct compiler * c , int opcode , Py_ssize_t oparg )
1528
1525
{
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 );
1530
1530
}
1531
1531
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 )
1536
1537
{
1537
1538
assert (IS_WITHIN_OPCODE_RANGE (opcode ));
1538
1539
assert (!IS_ASSEMBLER_OPCODE (opcode ));
1539
1540
assert (HAS_ARG (opcode ) || IS_VIRTUAL_OPCODE (opcode ));
1540
1541
assert (target != NULL );
1541
1542
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 );
1548
1544
struct instr * i = & b -> b_instr [off ];
1549
1545
if (off < 0 ) {
1550
1546
return 0 ;
@@ -1556,22 +1552,27 @@ static int add_jump_to_block(struct compiler *c, int opcode,
1556
1552
i -> i_col_offset = col_offset ;
1557
1553
i -> i_end_col_offset = end_col_offset ;
1558
1554
1559
- compiler_check_if_end_of_block (c , i );
1560
1555
return 1 ;
1561
1556
}
1562
1557
1563
1558
static int
1564
1559
compiler_addop_j (struct compiler * c , int opcode , basicblock * b )
1565
1560
{
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 );
1569
1567
}
1570
1568
1571
1569
static int
1572
1570
compiler_addop_j_noline (struct compiler * c , int opcode , basicblock * b )
1573
1571
{
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 );
1575
1576
}
1576
1577
1577
1578
#define ADDOP (C , OP ) { \
@@ -8085,7 +8086,7 @@ build_cellfixedoffsets(struct compiler *c)
8085
8086
8086
8087
static inline int
8087
8088
insert_instruction (basicblock * block , int pos , struct instr * instr ) {
8088
- if (compiler_next_instr (block ) < 0 ) {
8089
+ if (basicblock_next_instr (block ) < 0 ) {
8089
8090
return -1 ;
8090
8091
}
8091
8092
for (int i = block -> b_iused - 1 ; i > pos ; i -- ) {
@@ -8971,7 +8972,7 @@ extend_block(basicblock *bb) {
8971
8972
basicblock * to_copy = last -> i_target ;
8972
8973
last -> i_opcode = NOP ;
8973
8974
for (int i = 0 ; i < to_copy -> b_iused ; i ++ ) {
8974
- int index = compiler_next_instr (bb );
8975
+ int index = basicblock_next_instr (bb );
8975
8976
if (index < 0 ) {
8976
8977
return -1 ;
8977
8978
}
0 commit comments