Skip to content

Commit 8176424

Browse files
committed
---
yaml --- r: 1280 b: refs/heads/master c: 90e329d h: refs/heads/master v: v3
1 parent 74f4be3 commit 8176424

File tree

3 files changed

+76
-27
lines changed

3 files changed

+76
-27
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: c72d6a3e7a605d67ceff701465eff77b95dc2d32
2+
refs/heads/master: 90e329da6b263cde1fc286e2c4aa6d062a6acf8a

trunk/src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
432432
cast.rs \
433433
char.rs \
434434
complex.rs \
435+
const.rs \
435436
dead-code-one-arm-if.rs \
436437
deep.rs \
437438
deref.rs \

trunk/src/comp/middle/trans.rs

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ state type crate_ctxt = rec(session.session sess,
7070
hashmap[ast.def_id, @ast.item] items,
7171
hashmap[ast.def_id, @tag_info] tags,
7272
hashmap[ast.def_id, ValueRef] fn_pairs,
73+
hashmap[ast.def_id, ValueRef] consts,
7374
hashmap[ast.def_id,()] obj_methods,
7475
hashmap[@ty.t, ValueRef] tydescs,
7576
vec[ast.obj_field] obj_fields,
@@ -527,7 +528,9 @@ fn C_int(int i) -> ValueRef {
527528
ret C_integral(i, T_int());
528529
}
529530

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 {
531534
auto sc = llvm.LLVMConstString(_str.buf(s), _str.byte_len(s), False);
532535
auto g = llvm.LLVMAddGlobal(cx.llmod, val_ty(sc),
533536
_str.buf(cx.names.next("str")));
@@ -538,6 +541,23 @@ fn C_str(@crate_ctxt cx, str s) -> ValueRef {
538541
ret g;
539542
}
540543

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 + 1u as int), // 'alloc'
549+
C_int(len + 1u 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+
541561
fn C_zero_byte_arr(uint size) -> ValueRef {
542562
auto i = 0u;
543563
let vec[ValueRef] elts = vec();
@@ -1504,13 +1524,13 @@ fn copy_ty(@block_ctxt cx,
15041524
fail;
15051525
}
15061526

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 {
15081528
alt (lit.node) {
15091529
case (ast.lit_int(?i)) {
1510-
ret res(cx, C_int(i));
1530+
ret C_int(i);
15111531
}
15121532
case (ast.lit_uint(?u)) {
1513-
ret res(cx, C_int(u as int));
1533+
ret C_int(u as int);
15141534
}
15151535
case (ast.lit_mach_int(?tm, ?i)) {
15161536
// 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 {
15271547
case (common.ty_i16) { t = T_i16(); }
15281548
case (common.ty_i32) { t = T_i32(); }
15291549
case (common.ty_i64) { t = T_i64(); }
1530-
case (_) {
1531-
cx.fcx.ccx.sess.bug("bad mach int literal type");
1532-
}
15331550
}
1534-
ret res(cx, C_integral(i, t));
1551+
ret C_integral(i, t);
15351552
}
15361553
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());
15381555
}
15391556
case (ast.lit_bool(?b)) {
1540-
ret res(cx, C_bool(b));
1557+
ret C_bool(b);
15411558
}
15421559
case (ast.lit_nil) {
1543-
ret res(cx, C_nil());
1560+
ret C_nil();
15441561
}
15451562
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);
15561564
}
15571565
}
15581566
}
@@ -2087,6 +2095,10 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
20872095
ret lval_val(cx, cx.fcx.ccx.item_ids.get(vid));
20882096
}
20892097
}
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+
}
20902102
case (_) {
20912103
cx.fcx.ccx.sess.unimpl("def variant in trans");
20922104
}
@@ -2155,8 +2167,8 @@ fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
21552167
ix.bcx.build.CondBr(bounds_check, next_cx.llbb, fail_cx.llbb);
21562168

21572169
// 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));
21602172
auto V_line = sp.lo.line as int;
21612173
auto args = vec(V_expr_str, V_filename, C_int(V_line));
21622174
auto fail_res = trans_upcall(fail_cx, "upcall_fail", args);
@@ -2667,7 +2679,7 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
26672679
fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
26682680
alt (e.node) {
26692681
case (ast.expr_lit(?lit, ?ann)) {
2670-
ret trans_lit(cx, *lit, ann);
2682+
ret res(cx, trans_lit(cx.fcx.ccx, *lit, ann));
26712683
}
26722684

26732685
case (ast.expr_unary(?op, ?x, ?ann)) {
@@ -2806,8 +2818,8 @@ fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result {
28062818
auto cond_res = trans_expr(cx, e);
28072819

28082820
// 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));
28112823
auto V_line = e.span.lo.line as int;
28122824
auto args = vec(V_expr_str, V_filename, C_int(V_line));
28132825

@@ -3495,6 +3507,37 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
34953507
bcx.build.Ret(lltagval);
34963508
}
34973509

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+
34983541
fn trans_item(@crate_ctxt cx, &ast.item item) {
34993542
alt (item.node) {
35003543
case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
@@ -3518,6 +3561,10 @@ fn trans_item(@crate_ctxt cx, &ast.item item) {
35183561
i += 1;
35193562
}
35203563
}
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+
}
35213568
case (_) { /* fall through */ }
35223569
}
35233570
}
@@ -4055,6 +4102,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
40554102
items = new_def_hash[@ast.item](),
40564103
tags = new_def_hash[@tag_info](),
40574104
fn_pairs = new_def_hash[ValueRef](),
4105+
consts = new_def_hash[ValueRef](),
40584106
obj_methods = new_def_hash[()](),
40594107
tydescs = tydescs,
40604108
obj_fields = obj_fields,

0 commit comments

Comments
 (0)