rustc: First stab at interior string literals, untested as of yet

This commit is contained in:
Patrick Walton 2011-07-14 11:47:20 -07:00
parent 4038010bc6
commit e76f44453b
2 changed files with 86 additions and 12 deletions

View File

@ -3244,7 +3244,9 @@ fn memmove_ty(&@block_ctxt cx, ValueRef dst, ValueRef src, &ty::t t) ->
if (ty::type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, t)) {
auto llsz = size_of(cx, t);
ret call_memmove(llsz.bcx, dst, src, llsz.val);
} else { ret rslt(cx, cx.build.Store(cx.build.Load(src), dst)); }
} else {
ret rslt(cx, cx.build.Store(cx.build.Load(src), dst));
}
}
// Duplicates any heap-owned memory owned by a value of the given type.
@ -3365,7 +3367,65 @@ fn move_val_if_temp(@block_ctxt cx, copy_action action, ValueRef dst,
}
}
fn trans_lit(&@crate_ctxt cx, &ast::lit lit) -> ValueRef {
fn trans_lit_istr(&@block_ctxt cx, str s) -> result {
auto llstackpart = alloca(cx, T_ivec(T_i8()));
auto len = str::byte_len(s);
auto bcx;
if (len < 3u) { // 3 because of the \0
cx.build.Store(C_uint(len + 1u),
cx.build.InBoundsGEP(llstackpart,
~[C_int(0), C_int(0)]));
cx.build.Store(C_int(4),
cx.build.InBoundsGEP(llstackpart,
~[C_int(0), C_int(1)]));
auto i = 0u;
while (i < len) {
cx.build.Store(C_u8(s.(i) as uint),
cx.build.InBoundsGEP(llstackpart,
~[C_int(0), C_int(2),
C_uint(i)]));
i += 1u;
}
cx.build.Store(C_u8(0u),
cx.build.InBoundsGEP(llstackpart,
~[C_int(0), C_int(2),
C_uint(len)]));
bcx = cx;
} else {
auto r =
trans_shared_malloc(cx, T_ptr(T_ivec_heap_part(T_i8())),
llsize_of(T_struct(~[T_int(),
T_array(T_i8(),
len + 1u)])));
bcx = r.bcx;
auto llheappart = r.val;
bcx.build.Store(C_uint(len + 1u),
bcx.build.InBoundsGEP(llheappart,
~[C_int(0), C_int(0)]));
bcx.build.Store(llvm::LLVMConstString(str::buf(s), len, False),
bcx.build.InBoundsGEP(llheappart,
~[C_int(0), C_int(1)]));
auto llspilledstackpart = bcx.build.PointerCast(llstackpart,
T_ptr(T_ivec_heap(T_i8())));
bcx.build.Store(C_int(0),
bcx.build.InBoundsGEP(llspilledstackpart,
~[C_int(0), C_int(0)]));
bcx.build.Store(C_uint(len + 1u),
bcx.build.InBoundsGEP(llspilledstackpart,
~[C_int(0), C_int(1)]));
bcx.build.Store(llheappart,
bcx.build.InBoundsGEP(llspilledstackpart,
~[C_int(0), C_int(2)]));
}
ret rslt(bcx, llstackpart);
}
fn trans_crate_lit(&@crate_ctxt cx, &ast::lit lit) -> ValueRef {
alt (lit.node) {
case (ast::lit_int(?i)) { ret C_int(i); }
case (ast::lit_uint(?u)) { ret C_int(u as int); }
@ -3402,7 +3462,17 @@ fn trans_lit(&@crate_ctxt cx, &ast::lit lit) -> ValueRef {
}
case (ast::lit_bool(?b)) { ret C_bool(b); }
case (ast::lit_nil) { ret C_nil(); }
case (ast::lit_str(?s, _)) { ret C_str(cx, s); }
case (ast::lit_str(?s, ast::sk_rc)) { ret C_str(cx, s); }
case (ast::lit_str(?s, ast::sk_unique)) {
cx.sess.span_unimpl(lit.span, "unique string in this context");
}
}
}
fn trans_lit(&@block_ctxt cx, &ast::lit lit) -> result {
alt (lit.node) {
ast::lit_str(?s, ast::sk_unique) { ret trans_lit_istr(cx, s); }
_ { ret rslt(cx, trans_crate_lit(cx.fcx.lcx.ccx, lit)); }
}
}
@ -6018,9 +6088,7 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
result {
// FIXME Fill in cx.sp
alt (e.node) {
case (ast::expr_lit(?lit)) {
ret rslt(cx, trans_lit(cx.fcx.lcx.ccx, *lit));
}
case (ast::expr_lit(?lit)) { ret trans_lit(cx, *lit); }
case (ast::expr_unary(?op, ?x)) {
if (op != ast::deref) { ret trans_unary(cx, op, x, e.id); }
}
@ -8484,7 +8552,7 @@ fn trans_tag_variant(@local_ctxt cx, ast::node_id tag_id,
// that does so later on?
fn trans_const_expr(&@crate_ctxt cx, @ast::expr e) -> ValueRef {
alt (e.node) {
case (ast::expr_lit(?lit)) { ret trans_lit(cx, *lit); }
case (ast::expr_lit(?lit)) { ret trans_crate_lit(cx, *lit); }
case (_) {
cx.sess.span_unimpl(e.span, "consts that's not a plain literal");
}

View File

@ -41,10 +41,10 @@ fn opt_eq(&opt a, &opt b) -> bool {
}
}
}
fn trans_opt(&@crate_ctxt ccx, &opt o) -> ValueRef {
fn trans_opt(&@block_ctxt bcx, &opt o) -> result {
alt (o) {
lit(?l) { ret trans::trans_lit(ccx, *l); }
var(?id, _) { ret C_int(id as int); }
lit(?l) { ret trans::trans_lit(bcx, *l); }
var(?id, _) { ret rslt(bcx, C_int(id as int)); }
}
}
@ -344,11 +344,17 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
auto opt_cx = new_sub_block_ctxt(bcx, "match_case");
alt (kind) {
single { bcx.build.Br(opt_cx.llbb); }
switch { llvm::LLVMAddCase(sw, trans_opt(ccx, opt), opt_cx.llbb);}
switch {
auto r = trans_opt(bcx, opt);
bcx = r.bcx;
llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
}
compare {
auto r = trans_opt(bcx, opt);
bcx = r.bcx;
auto t = ty::node_id_to_type(ccx.tcx, pat_id);
auto eq = trans::trans_compare(bcx, ast::eq, t, test_val,
trans_opt(ccx, opt));
r.val);
bcx = new_sub_block_ctxt(bcx, "next");
eq.bcx.build.CondBr(eq.val, opt_cx.llbb, bcx.llbb);
}