@@ -73,6 +73,7 @@ tag cleanup {
73
73
state type block_ctxt = rec ( BasicBlockRef llbb,
74
74
builder build,
75
75
block_parent parent,
76
+ bool is_scope,
76
77
mutable vec[ cleanup] cleanups,
77
78
@fn_ctxt fcx) ;
78
79
@@ -450,15 +451,30 @@ fn trans_non_gc_free(@block_ctxt cx, ValueRef v) -> result {
450
451
C_int ( 0 ) ) ) ;
451
452
}
452
453
454
+ fn find_scope_cx ( @block_ctxt cx ) -> @block_ctxt {
455
+ if ( cx. is_scope ) {
456
+ ret cx;
457
+ }
458
+ alt ( cx. parent ) {
459
+ case ( parent_some ( ?b) ) {
460
+ be find_scope_cx ( b) ;
461
+ }
462
+ case ( parent_none) {
463
+ fail;
464
+ }
465
+ }
466
+ }
467
+
453
468
fn trans_malloc ( @block_ctxt cx , @typeck. ty t ) -> result {
469
+ auto scope_cx = find_scope_cx ( cx) ;
454
470
auto ptr_ty = type_of ( cx. fcx . ccx , t) ;
455
471
auto body_ty = lib. llvm . llvm . LLVMGetElementType ( ptr_ty) ;
456
472
// FIXME: need a table to collect tydesc globals.
457
473
auto tydesc = C_int ( 0 ) ;
458
474
auto sz = cx. build . IntCast ( lib. llvm . llvm . LLVMSizeOf ( body_ty) , T_int ( ) ) ;
459
475
auto sub = trans_upcall ( cx, "upcall_malloc" , vec ( sz, tydesc) ) ;
460
476
sub. val = sub. bcx . build . IntToPtr ( sub. val , ptr_ty) ;
461
- sub . bcx . cleanups += clean ( bind drop_ty ( _, sub. val , t) ) ;
477
+ scope_cx . cleanups += clean ( bind drop_ty ( _, sub. val , t) ) ;
462
478
ret sub;
463
479
}
464
480
@@ -575,8 +591,8 @@ fn iter_sequence(@block_ctxt cx,
575
591
576
592
auto r = res ( cx, C_nil ( ) ) ;
577
593
578
- auto cond_cx = new_sub_block_ctxt ( cx, "sequence-iter cond" ) ;
579
- auto body_cx = new_sub_block_ctxt ( cx, "sequence-iter body" ) ;
594
+ auto cond_cx = new_scope_block_ctxt ( cx, "sequence-iter cond" ) ;
595
+ auto body_cx = new_scope_block_ctxt ( cx, "sequence-iter body" ) ;
580
596
auto next_cx = new_sub_block_ctxt ( cx, "next" ) ;
581
597
582
598
auto ix = cond_cx. build . Phi ( T_int ( ) , vec ( C_int ( 0 ) ) , vec ( cx. llbb ) ) ;
@@ -1081,10 +1097,10 @@ impure fn trans_if(@block_ctxt cx, @ast.expr cond,
1081
1097
1082
1098
auto cond_res = trans_expr ( cx, cond) ;
1083
1099
1084
- auto then_cx = new_sub_block_ctxt ( cx, "then" ) ;
1100
+ auto then_cx = new_scope_block_ctxt ( cx, "then" ) ;
1085
1101
auto then_res = trans_block ( then_cx, thn) ;
1086
1102
1087
- auto else_cx = new_sub_block_ctxt ( cx, "else" ) ;
1103
+ auto else_cx = new_scope_block_ctxt ( cx, "else" ) ;
1088
1104
auto else_res = res ( else_cx, C_nil ( ) ) ;
1089
1105
1090
1106
alt ( els) {
@@ -1106,8 +1122,8 @@ impure fn trans_if(@block_ctxt cx, @ast.expr cond,
1106
1122
impure fn trans_while ( @block_ctxt cx, @ast. expr cond,
1107
1123
& ast. block body) -> result {
1108
1124
1109
- auto cond_cx = new_sub_block_ctxt ( cx, "while cond" ) ;
1110
- auto body_cx = new_sub_block_ctxt ( cx, "while loop body" ) ;
1125
+ auto cond_cx = new_scope_block_ctxt ( cx, "while cond" ) ;
1126
+ auto body_cx = new_scope_block_ctxt ( cx, "while loop body" ) ;
1111
1127
auto next_cx = new_sub_block_ctxt ( cx, "next" ) ;
1112
1128
1113
1129
auto body_res = trans_block ( body_cx, body) ;
@@ -1125,7 +1141,7 @@ impure fn trans_while(@block_ctxt cx, @ast.expr cond,
1125
1141
impure fn trans_do_while ( @block_ctxt cx, & ast. block body,
1126
1142
@ast. expr cond) -> result {
1127
1143
1128
- auto body_cx = new_sub_block_ctxt ( cx, "do-while loop body" ) ;
1144
+ auto body_cx = new_scope_block_ctxt ( cx, "do-while loop body" ) ;
1129
1145
auto next_cx = new_sub_block_ctxt ( cx, "next" ) ;
1130
1146
1131
1147
auto body_res = trans_block ( body_cx, body) ;
@@ -1353,7 +1369,7 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
1353
1369
}
1354
1370
1355
1371
case ( ast. expr_block( ?blk, _) ) {
1356
- auto sub_cx = new_sub_block_ctxt ( cx, "block-expr body" ) ;
1372
+ auto sub_cx = new_scope_block_ctxt ( cx, "block-expr body" ) ;
1357
1373
auto next_cx = new_sub_block_ctxt( cx, "next" ) ;
1358
1374
auto sub = trans_block( sub_cx, blk) ;
1359
1375
@@ -1542,36 +1558,45 @@ fn new_builder(BasicBlockRef llbb, str name) -> builder {
1542
1558
// You probably don't want to use this one. See the
1543
1559
// next three functions instead.
1544
1560
fn new_block_ctxt( @fn_ctxt cx, block_parent parent,
1545
- vec [ cleanup ] cleanups ,
1561
+ bool is_scope ,
1546
1562
str name) -> @block_ctxt {
1563
+ let vec[ cleanup] cleanups = vec( ) ;
1547
1564
let BasicBlockRef llbb =
1548
1565
llvm. LLVMAppendBasicBlock ( cx. llfn,
1549
1566
_str. buf( cx. ccx. names. next( name) ) ) ;
1550
1567
1551
1568
ret @rec( llbb=llbb,
1552
1569
build=new_builder( llbb, name) ,
1553
1570
parent=parent,
1571
+ is_scope=is_scope,
1554
1572
mutable cleanups=cleanups,
1555
1573
fcx=cx) ;
1556
1574
}
1557
1575
1558
1576
// Use this when you're at the top block of a function or the like.
1559
1577
fn new_top_block_ctxt( @fn_ctxt fcx) -> @block_ctxt {
1560
- let vec [ cleanup ] cleanups = vec ( ) ;
1561
- ret new_block_ctxt ( fcx , parent_none , cleanups , "function top level" ) ;
1578
+ ret new_block_ctxt ( fcx , parent_none , true , "function top level" ) ;
1579
+ }
1562
1580
1581
+ // Use this when you're at a curly-brace or similar lexical scope.
1582
+ fn new_scope_block_ctxt( @block_ctxt bcx, str n) -> @block_ctxt {
1583
+ ret new_block_ctxt( bcx. fcx, parent_some( bcx) , true, n) ;
1563
1584
}
1564
1585
1565
- // Use this when you're making a block- within-a-block .
1586
+ // Use this when you're making a general CFG BB within a scope .
1566
1587
fn new_sub_block_ctxt( @block_ctxt bcx, str n) -> @block_ctxt {
1567
- let vec[ cleanup] cleanups = vec( ) ;
1568
- ret new_block_ctxt( bcx. fcx, parent_some( bcx) , cleanups, n) ;
1588
+ ret new_block_ctxt( bcx. fcx, parent_some( bcx) , false, n) ;
1569
1589
}
1570
1590
1571
1591
1572
1592
fn trans_block_cleanups( @block_ctxt cx,
1573
1593
@block_ctxt cleanup_cx) -> @block_ctxt {
1574
1594
auto bcx = cx;
1595
+
1596
+ if ( !cleanup_cx. is_scope) {
1597
+ check ( _vec. len[ cleanup] ( cleanup_cx. cleanups) == 0 u) ;
1598
+ }
1599
+
1575
1600
for ( cleanup c in cleanup_cx. cleanups) {
1576
1601
alt ( c) {
1577
1602
case ( clean( ?cfn) ) {
0 commit comments