aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-11-09 17:49:20 -0800
committerGraydon Hoare <[email protected]>2010-11-09 17:50:31 -0800
commita404e542614c0848931544eb0281fd546a62a971 (patch)
tree9b6437fbbc6632d9b68c80df69d74a0e589e9297 /src
parentImplement a map2() function in std._vec (diff)
downloadrust-a404e542614c0848931544eb0281fd546a62a971.tar.xz
rust-a404e542614c0848931544eb0281fd546a62a971.zip
Teach rustc about const tag value, begin work on trans_copy_ty, make uint's to_str routine less clever and thereby resist overflow.
Diffstat (limited to 'src')
-rw-r--r--src/comp/back/abi.rs3
-rw-r--r--src/comp/middle/trans.rs78
-rw-r--r--src/lib/_uint.rs28
3 files changed, 84 insertions, 25 deletions
diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs
index 5e00ff32..d6926f34 100644
--- a/src/comp/back/abi.rs
+++ b/src/comp/back/abi.rs
@@ -1,6 +1,9 @@
const int rc_base_field_refcnt = 0;
+// FIXME: import from std.dbg when imported consts work.
+const uint const_refcount = 0x7bad_face_u;
+
const int task_field_refcnt = 0;
const int task_field_stk = 2;
const int task_field_runtime_sp = 3;
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 79ffc3e0..65dd2938 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -394,6 +394,25 @@ fn trans_non_gc_free(@block_ctxt cx, ValueRef v) -> result {
C_int(0)));
}
+fn incr_refcnt(@block_ctxt cx, ValueRef box_ptr) -> result {
+ auto rc_ptr = cx.build.GEP(box_ptr, vec(C_int(0),
+ C_int(abi.box_rc_field_refcnt)));
+ auto rc = cx.build.Load(rc_ptr);
+
+ auto next_cx = new_extension_block_ctxt(cx);
+ auto rc_adj_cx = new_empty_block_ctxt(cx.fcx);
+
+ auto const_test = cx.build.ICmp(lib.llvm.LLVMIntEQ,
+ C_int(abi.const_refcount as int), rc);
+ cx.build.CondBr(const_test, next_cx.llbb, rc_adj_cx.llbb);
+
+ rc = rc_adj_cx.build.Add(rc, C_int(1));
+ rc_adj_cx.build.Store(rc, rc_ptr);
+ rc_adj_cx.build.Br(next_cx.llbb);
+
+ ret res(next_cx, C_nil());
+}
+
fn decr_refcnt_and_if_zero(@block_ctxt cx,
ValueRef box_ptr,
fn(@block_ctxt cx) -> result inner,
@@ -401,20 +420,66 @@ fn decr_refcnt_and_if_zero(@block_ctxt cx,
auto rc_ptr = cx.build.GEP(box_ptr, vec(C_int(0),
C_int(abi.box_rc_field_refcnt)));
auto rc = cx.build.Load(rc_ptr);
- rc = cx.build.Sub(rc, C_int(1));
- cx.build.Store(rc, rc_ptr);
- auto test = cx.build.ICmp(lib.llvm.LLVMIntEQ, C_int(0), rc);
+
+ auto rc_adj_cx = new_empty_block_ctxt(cx.fcx);
auto next_cx = new_extension_block_ctxt(cx);
+
+ auto const_test = cx.build.ICmp(lib.llvm.LLVMIntEQ,
+ C_int(abi.const_refcount as int), rc);
+ cx.build.CondBr(const_test, next_cx.llbb, rc_adj_cx.llbb);
+
+ rc = rc_adj_cx.build.Sub(rc, C_int(1));
+ rc_adj_cx.build.Store(rc, rc_ptr);
+
+ auto zero_test = rc_adj_cx.build.ICmp(lib.llvm.LLVMIntEQ, C_int(0), rc);
+
auto then_cx = new_empty_block_ctxt(cx.fcx);
auto then_res = inner(then_cx);
then_res.bcx.build.Br(next_cx.llbb);
- cx.build.CondBr(test, then_res.bcx.llbb, next_cx.llbb);
+ rc_adj_cx.build.CondBr(zero_test, then_res.bcx.llbb, next_cx.llbb);
auto phi = next_cx.build.Phi(t_else,
- vec(v_else, then_res.val),
- vec(cx.llbb, then_res.bcx.llbb));
+ vec(v_else, v_else, then_res.val),
+ vec(cx.llbb,
+ rc_adj_cx.llbb,
+ then_res.bcx.llbb));
ret res(next_cx, phi);
}
+fn type_is_scalar(@ast.ty t) -> bool {
+ alt (t.node) {
+ case (ast.ty_nil) { ret true; }
+ case (ast.ty_bool) { ret true; }
+ case (ast.ty_int) { ret true; }
+ case (ast.ty_uint) { ret true; }
+ case (ast.ty_machine(_)) { ret true; }
+ case (ast.ty_char) { ret true; }
+ }
+ ret false;
+}
+
+fn trans_copy_ty(@block_ctxt cx,
+ bool is_init,
+ ValueRef dst,
+ ValueRef src,
+ @ast.ty t) -> result {
+ if (type_is_scalar(t)) {
+ ret res(cx, cx.build.Store(src, dst));
+ }
+
+ alt (t.node) {
+ case (ast.ty_str) {
+ let result r = res(cx, C_nil());
+ if (is_init) {
+ r = trans_drop_str(cx, dst);
+ }
+ r = incr_refcnt(r.bcx, src);
+ ret res(r.bcx, r.bcx.build.Store(src, dst));
+ }
+ }
+ cx.fcx.tcx.sess.unimpl("ty variant in trans_copy_ty");
+ fail;
+}
+
fn trans_drop_str(@block_ctxt cx, ValueRef v) -> result {
ret decr_refcnt_and_if_zero(cx, v,
bind trans_non_gc_free(_, v),
@@ -825,6 +890,7 @@ impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
auto lhs_res = trans_lval(cx, *dst);
check (lhs_res._1);
auto rhs_res = trans_expr(lhs_res._0.bcx, *src);
+ // FIXME: call trans_copy_ty once we have a ty here.
ret res(rhs_res.bcx,
rhs_res.bcx.build.Store(rhs_res.val, lhs_res._0.val));
}
diff --git a/src/lib/_uint.rs b/src/lib/_uint.rs
index 0930cadc..7fa4ea02 100644
--- a/src/lib/_uint.rs
+++ b/src/lib/_uint.rs
@@ -59,30 +59,20 @@ fn to_str(mutable uint n, uint radix) -> str
if (n == 0u) { ret "0"; }
- let uint r = 1u;
- if (n > r) {
- while ((r*radix) <= n) {
- r *= radix;
- }
- }
-
let str s = "";
- while (n > 0u) {
-
- auto i = n/r;
-
- n -= (i * r);
- r /= radix;
-
- s += digit(i) as u8;
+ while (n != 0u) {
+ s += digit(n % radix) as u8;
+ n /= radix;
}
- while (r > 0u) {
- s += '0' as u8;
- r /= radix;
+ let str s1 = "";
+ let uint len = _str.byte_len(s);
+ while (len != 0u) {
+ len -= 1u;
+ s1 += s.(len);
}
+ ret s1;
- ret s;
}
// Local Variables: