about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-07-14 11:47:20 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-07-14 11:47:20 -0700
commite76f44453b00235b7a1b2154c240aedc2e24d3f6 (patch)
tree72bcc18a5c57622169a2edc492645bfcb42765af /src
parent4038010bc658c75b8f6efa99790e611c29e84763 (diff)
downloadrust-e76f44453b00235b7a1b2154c240aedc2e24d3f6.tar.gz
rust-e76f44453b00235b7a1b2154c240aedc2e24d3f6.zip
rustc: First stab at interior string literals, untested as of yet
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs82
-rw-r--r--src/comp/middle/trans_alt.rs16
2 files changed, 86 insertions, 12 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 90473857dec..094223c9ce6 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -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");
         }
diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs
index c5fded689b6..9bd453943fb 100644
--- a/src/comp/middle/trans_alt.rs
+++ b/src/comp/middle/trans_alt.rs
@@ -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);
             }