@@ -70,6 +70,7 @@ state type crate_ctxt = rec(session.session sess,
70
70
hashmap[ ast. def_id , @ast. item ] items,
71
71
hashmap[ ast. def_id , @tag_info] tags,
72
72
hashmap[ ast. def_id , ValueRef ] fn_pairs,
73
+ hashmap[ ast. def_id , ValueRef ] consts,
73
74
hashmap[ ast. def_id , ( ) ] obj_methods,
74
75
hashmap[ @ty. t , ValueRef ] tydescs,
75
76
vec[ ast. obj_field ] obj_fields,
@@ -527,7 +528,9 @@ fn C_int(int i) -> ValueRef {
527
528
ret C_integral ( i, T_int ( ) ) ;
528
529
}
529
530
530
- fn C_str ( @crate_ctxt cx , str s) -> ValueRef {
531
+ // This is a 'c-like' raw string, which differs from
532
+ // our boxed-and-length-annotated strings.
533
+ fn C_cstr ( @crate_ctxt cx , str s) -> ValueRef {
531
534
auto sc = llvm. LLVMConstString ( _str. buf ( s) , _str. byte_len ( s) , False ) ;
532
535
auto g = llvm. LLVMAddGlobal ( cx. llmod , val_ty ( sc) ,
533
536
_str. buf ( cx. names . next ( "str" ) ) ) ;
@@ -538,6 +541,23 @@ fn C_str(@crate_ctxt cx, str s) -> ValueRef {
538
541
ret g;
539
542
}
540
543
544
+ // A rust boxed-and-length-annotated string.
545
+ fn C_str ( @crate_ctxt cx , str s) -> ValueRef {
546
+ auto len = _str. byte_len ( s) ;
547
+ auto box = C_struct ( vec ( C_int ( abi. const_refcount as int ) ,
548
+ C_int ( len + 1 u as int ) , // 'alloc'
549
+ C_int ( len + 1 u as int ) , // 'fill'
550
+ llvm. LLVMConstString ( _str. buf ( s) ,
551
+ len, False ) ) ) ;
552
+ auto g = llvm. LLVMAddGlobal ( cx. llmod , val_ty ( box) ,
553
+ _str. buf ( cx. names . next ( "str" ) ) ) ;
554
+ llvm. LLVMSetInitializer ( g, box) ;
555
+ llvm. LLVMSetGlobalConstant ( g, True ) ;
556
+ llvm. LLVMSetLinkage ( g, lib. llvm . LLVMPrivateLinkage
557
+ as llvm . Linkage ) ;
558
+ ret llvm. LLVMConstPointerCast ( g, T_ptr ( T_str ( ) ) ) ;
559
+ }
560
+
541
561
fn C_zero_byte_arr ( uint size) -> ValueRef {
542
562
auto i = 0 u;
543
563
let vec[ ValueRef ] elts = vec ( ) ;
@@ -1504,13 +1524,13 @@ fn copy_ty(@block_ctxt cx,
1504
1524
fail;
1505
1525
}
1506
1526
1507
- fn trans_lit( @block_ctxt cx, & ast. lit lit, & ast. ann ann) -> result {
1527
+ fn trans_lit( @crate_ctxt cx, & ast. lit lit, & ast. ann ann) -> ValueRef {
1508
1528
alt ( lit. node) {
1509
1529
case ( ast. lit_int( ?i) ) {
1510
- ret res ( cx , C_int( i) ) ;
1530
+ ret C_int ( i) ;
1511
1531
}
1512
1532
case ( ast. lit_uint( ?u) ) {
1513
- ret res ( cx , C_int ( u as int) ) ;
1533
+ ret C_int ( u as int) ;
1514
1534
}
1515
1535
case ( ast. lit_mach_int( ?tm, ?i) ) {
1516
1536
// FIXME: the entire handling of mach types falls apart
@@ -1527,32 +1547,20 @@ fn trans_lit(@block_ctxt cx, &ast.lit lit, &ast.ann ann) -> result {
1527
1547
case ( common. ty_i16) { t = T_i16 ( ) ; }
1528
1548
case ( common. ty_i32) { t = T_i32 ( ) ; }
1529
1549
case ( common. ty_i64) { t = T_i64 ( ) ; }
1530
- case ( _) {
1531
- cx. fcx. ccx. sess. bug( "bad mach int literal type" ) ;
1532
- }
1533
1550
}
1534
- ret res ( cx , C_integral ( i, t) ) ;
1551
+ ret C_integral ( i, t) ;
1535
1552
}
1536
1553
case ( ast. lit_char( ?c) ) {
1537
- ret res ( cx , C_integral ( c as int, T_char ( ) ) ) ;
1554
+ ret C_integral ( c as int, T_char ( ) ) ;
1538
1555
}
1539
1556
case ( ast. lit_bool( ?b) ) {
1540
- ret res ( cx , C_bool ( b) ) ;
1557
+ ret C_bool ( b) ;
1541
1558
}
1542
1559
case ( ast. lit_nil) {
1543
- ret res ( cx , C_nil ( ) ) ;
1560
+ ret C_nil ( ) ;
1544
1561
}
1545
1562
case ( ast. lit_str( ?s) ) {
1546
- auto len = ( _str. byte_len( s) as int) + 1 ;
1547
- auto sub = trans_upcall( cx, "upcall_new_str" ,
1548
- vec( p2i( C_str ( cx. fcx. ccx, s) ) ,
1549
- C_int ( len) ) ) ;
1550
- auto val = sub. bcx. build. IntToPtr ( sub. val,
1551
- T_ptr ( T_str ( ) ) ) ;
1552
- auto t = node_ann_type( cx. fcx. ccx, ann) ;
1553
- find_scope_cx( cx) . cleanups +=
1554
- clean( bind drop_ty( _, val, t) ) ;
1555
- ret res( sub. bcx, val) ;
1563
+ ret C_str ( cx, s) ;
1556
1564
}
1557
1565
}
1558
1566
}
@@ -2087,6 +2095,10 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
2087
2095
ret lval_val( cx, cx. fcx. ccx. item_ids. get( vid) ) ;
2088
2096
}
2089
2097
}
2098
+ case ( ast. def_const( ?did) ) {
2099
+ check ( cx. fcx. ccx. consts. contains_key( did) ) ;
2100
+ ret lval_mem( cx, cx. fcx. ccx. consts. get( did) ) ;
2101
+ }
2090
2102
case ( _) {
2091
2103
cx. fcx. ccx. sess. unimpl( "def variant in trans" ) ;
2092
2104
}
@@ -2155,8 +2167,8 @@ fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
2155
2167
ix. bcx. build. CondBr ( bounds_check, next_cx. llbb, fail_cx. llbb) ;
2156
2168
2157
2169
// fail: bad bounds check.
2158
- auto V_expr_str = p2i( C_str ( cx. fcx. ccx, "out-of-bounds access" ) ) ;
2159
- auto V_filename = p2i( C_str ( cx. fcx. ccx, sp. filename) ) ;
2170
+ auto V_expr_str = p2i( C_cstr ( cx. fcx. ccx, "out-of-bounds access" ) ) ;
2171
+ auto V_filename = p2i( C_cstr ( cx. fcx. ccx, sp. filename) ) ;
2160
2172
auto V_line = sp. lo. line as int;
2161
2173
auto args = vec( V_expr_str , V_filename , C_int ( V_line ) ) ;
2162
2174
auto fail_res = trans_upcall( fail_cx, "upcall_fail" , args) ;
@@ -2667,7 +2679,7 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
2667
2679
fn trans_expr( @block_ctxt cx, @ast. expr e) -> result {
2668
2680
alt ( e. node) {
2669
2681
case ( ast. expr_lit( ?lit, ?ann) ) {
2670
- ret trans_lit( cx, * lit, ann) ;
2682
+ ret res ( cx , trans_lit( cx. fcx . ccx , * lit, ann) ) ;
2671
2683
}
2672
2684
2673
2685
case ( ast. expr_unary( ?op, ?x, ?ann) ) {
@@ -2806,8 +2818,8 @@ fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result {
2806
2818
auto cond_res = trans_expr( cx, e) ;
2807
2819
2808
2820
// FIXME: need pretty-printer.
2809
- auto V_expr_str = p2i( C_str ( cx. fcx. ccx, "<expr>") ) ;
2810
- auto V_filename = p2i( C_str ( cx. fcx. ccx, e. span. filename) ) ;
2821
+ auto V_expr_str = p2i( C_cstr ( cx. fcx. ccx, "<expr>") ) ;
2822
+ auto V_filename = p2i( C_cstr ( cx. fcx. ccx, e. span. filename) ) ;
2811
2823
auto V_line = e. span. lo. line as int;
2812
2824
auto args = vec( V_expr_str, V_filename, C_int ( V_line ) ) ;
2813
2825
@@ -3495,6 +3507,37 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
3495
3507
bcx. build. Ret ( lltagval) ;
3496
3508
}
3497
3509
3510
+ // FIXME: this should do some structural hash-consing to avoid
3511
+ // duplicate constants. I think. Maybe LLVM has a magical mode
3512
+ // that does so later on?
3513
+
3514
+ fn trans_const_expr( @crate_ctxt cx, @ast. expr e) -> ValueRef {
3515
+ alt ( e. node) {
3516
+ case ( ast. expr_lit( ?lit, ?ann) ) {
3517
+ ret trans_lit( cx, * lit, ann) ;
3518
+ }
3519
+ }
3520
+ }
3521
+
3522
+ fn trans_const( @crate_ctxt cx, @ast. expr e,
3523
+ & ast. def_id cid, & ast. ann ann) {
3524
+ auto t = node_ann_type( cx, ann) ;
3525
+ auto v = trans_const_expr( cx, e) ;
3526
+ if ( ty. type_is_scalar( t) ) {
3527
+ // The scalars come back as 1st class LLVM vals
3528
+ // which we have to stick into global constants.
3529
+ auto g = llvm. LLVMAddGlobal ( cx. llmod, val_ty( v) ,
3530
+ _str. buf( cx. names. next( cx. path) ) ) ;
3531
+ llvm. LLVMSetInitializer ( g, v) ;
3532
+ llvm. LLVMSetGlobalConstant ( g, True ) ;
3533
+ llvm. LLVMSetLinkage ( g, lib. llvm. LLVMPrivateLinkage
3534
+ as llvm. Linkage ) ;
3535
+ cx. consts. insert( cid, g) ;
3536
+ } else {
3537
+ cx. consts. insert( cid, v) ;
3538
+ }
3539
+ }
3540
+
3498
3541
fn trans_item( @crate_ctxt cx, & ast. item item) {
3499
3542
alt ( item. node) {
3500
3543
case ( ast. item_fn( ?name, ?f, ?tps, ?fid, ?ann) ) {
@@ -3518,6 +3561,10 @@ fn trans_item(@crate_ctxt cx, &ast.item item) {
3518
3561
i += 1 ;
3519
3562
}
3520
3563
}
3564
+ case ( ast. item_const( ?name, _, ?expr, ?cid, ?ann) ) {
3565
+ auto sub_cx = @rec( path=cx. path + "." + name with * cx) ;
3566
+ trans_const( sub_cx, expr, cid, ann) ;
3567
+ }
3521
3568
case ( _) { /* fall through */ }
3522
3569
}
3523
3570
}
@@ -4055,6 +4102,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
4055
4102
items = new_def_hash[ @ast. item ] ( ) ,
4056
4103
tags = new_def_hash[ @tag_info] ( ) ,
4057
4104
fn_pairs = new_def_hash[ ValueRef ] ( ) ,
4105
+ consts = new_def_hash[ ValueRef ] ( ) ,
4058
4106
obj_methods = new_def_hash[ ( ) ] ( ) ,
4059
4107
tydescs = tydescs,
4060
4108
obj_fields = obj_fields,
0 commit comments