aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-11-26 15:54:04 -0800
committerGraydon Hoare <[email protected]>2010-11-26 15:54:04 -0800
commit9f56b0061ce058c0edd614cfdd5cbdb72efcfe08 (patch)
treef1104c3adc0dd3e5a363ff662bb737c0217cd6a9 /src/comp
parentAvoid segfault due to fallthrough in base case of incr_all_refcounts. We coul... (diff)
downloadrust-9f56b0061ce058c0edd614cfdd5cbdb72efcfe08.tar.xz
rust-9f56b0061ce058c0edd614cfdd5cbdb72efcfe08.zip
Pass exprs by @, always treat structural types by pointer, move path and name into trans_lval.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs186
1 files changed, 98 insertions, 88 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 9098d8eb..00e7f69e 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -679,9 +679,10 @@ fn copy_ty(@block_ctxt cx,
if (! is_init) {
r = drop_ty(r.bcx, dst, t);
}
- auto llty = type_of(cx.fcx.ccx, t);
- r = build_memcpy(r.bcx, dst, src, llty);
- ret res(r.bcx, src);
+ // In this one surprising case, we do a load/store on
+ // structure types. This results in a memcpy. Usually
+ // we talk about structures by pointers in this file.
+ ret res(r.bcx, r.bcx.build.Store(r.bcx.build.Load(src), dst));
}
cx.fcx.ccx.sess.bug("unexpected type in trans.copy_ty: " +
@@ -778,7 +779,7 @@ fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
}
impure fn trans_unary(@block_ctxt cx, ast.unop op,
- &ast.expr e, &ast.ann a) -> result {
+ @ast.expr e, &ast.ann a) -> result {
auto sub = trans_expr(cx, e);
@@ -811,7 +812,7 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op,
}
impure fn trans_binary(@block_ctxt cx, ast.binop op,
- &ast.expr a, &ast.expr b) -> result {
+ @ast.expr a, @ast.expr b) -> result {
// First couple cases are lazy:
@@ -997,7 +998,7 @@ fn join_results(@block_ctxt parent_cx,
ret res(join_cx, phi);
}
-impure fn trans_if(@block_ctxt cx, &ast.expr cond,
+impure fn trans_if(@block_ctxt cx, @ast.expr cond,
&ast.block thn, &option.t[ast.block] els) -> result {
auto cond_res = trans_expr(cx, cond);
@@ -1023,7 +1024,7 @@ impure fn trans_if(@block_ctxt cx, &ast.expr cond,
vec(then_res, else_res));
}
-impure fn trans_while(@block_ctxt cx, &ast.expr cond,
+impure fn trans_while(@block_ctxt cx, @ast.expr cond,
&ast.block body) -> result {
auto cond_cx = new_sub_block_ctxt(cx, "while cond");
@@ -1043,7 +1044,7 @@ impure fn trans_while(@block_ctxt cx, &ast.expr cond,
}
impure fn trans_do_while(@block_ctxt cx, &ast.block body,
- &ast.expr cond) -> result {
+ @ast.expr cond) -> result {
auto body_cx = new_sub_block_ctxt(cx, "do-while loop body");
auto next_cx = new_sub_block_ctxt(cx, "next");
@@ -1058,42 +1059,66 @@ impure fn trans_do_while(@block_ctxt cx, &ast.block body,
ret res(next_cx, body_res.val);
}
-// The additional bool returned indicates whether it's a local
-// (that is represented as an alloca, hence needs a 'load' to be
-// used as an rval).
+// The additional bool returned indicates whether it's mem (that is
+// represented as an alloca or heap, hence needs a 'load' to be used as an
+// immediate).
-fn trans_lval(@block_ctxt cx, &ast.expr e)
- -> tup(result, bool, ast.def_id) {
- alt (e.node) {
- case (ast.expr_name(?n, ?dopt, _)) {
- alt (dopt) {
- case (some[ast.def](?def)) {
- alt (def) {
- case (ast.def_arg(?did)) {
- check (cx.fcx.llargs.contains_key(did));
- ret tup(res(cx, cx.fcx.llargs.get(did)),
- false, did);
- }
- case (ast.def_local(?did)) {
- check (cx.fcx.lllocals.contains_key(did));
- ret tup(res(cx, cx.fcx.lllocals.get(did)),
- true, did);
- }
- case (ast.def_fn(?did)) {
- check (cx.fcx.ccx.fn_ids.contains_key(did));
- ret tup(res(cx, cx.fcx.ccx.fn_ids.get(did)),
- false, did);
- }
- case (_) {
- cx.fcx.ccx.sess.unimpl("def variant in trans");
- }
- }
+fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
+ -> tup(result, bool) {
+ alt (dopt) {
+ case (some[ast.def](?def)) {
+ alt (def) {
+ case (ast.def_arg(?did)) {
+ check (cx.fcx.llargs.contains_key(did));
+ ret tup(res(cx, cx.fcx.llargs.get(did)),
+ false);
+ }
+ case (ast.def_local(?did)) {
+ check (cx.fcx.lllocals.contains_key(did));
+ ret tup(res(cx, cx.fcx.lllocals.get(did)),
+ true);
}
- case (none[ast.def]) {
- cx.fcx.ccx.sess.err("unresolved expr_name in trans");
+ case (ast.def_fn(?did)) {
+ check (cx.fcx.ccx.fn_ids.contains_key(did));
+ ret tup(res(cx, cx.fcx.ccx.fn_ids.get(did)),
+ false);
+ }
+ case (_) {
+ cx.fcx.ccx.sess.unimpl("def variant in trans");
}
}
}
+ case (none[ast.def]) {
+ cx.fcx.ccx.sess.err("unresolved expr_name in trans");
+ }
+ }
+ fail;
+}
+
+fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
+ &ast.ident field, &ast.ann ann) -> tup(result, bool) {
+ auto lv = trans_lval(cx, base);
+ auto r = lv._0;
+ auto ty = typeck.expr_ty(base);
+ alt (ty.struct) {
+ case (typeck.ty_tup(?fields)) {
+ let uint ix = typeck.field_num(cx.fcx.ccx.sess, sp, field);
+ auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
+ ret tup(res(r.bcx, v), lv._1);
+ }
+ }
+ cx.fcx.ccx.sess.unimpl("field variant in trans_field");
+ fail;
+}
+
+fn trans_lval(@block_ctxt cx, @ast.expr e) -> tup(result, bool) {
+ alt (e.node) {
+ case (ast.expr_name(?n, ?dopt, _)) {
+ ret trans_name(cx, n, dopt);
+ }
+ case (ast.expr_field(?base, ?ident, ?ann)) {
+ ret trans_field(cx, e.span, base, ident, ann);
+ }
}
cx.fcx.ccx.sess.unimpl("expr variant in trans_lval");
fail;
@@ -1105,7 +1130,7 @@ impure fn trans_exprs(@block_ctxt cx, &vec[@ast.expr] es)
let @block_ctxt bcx = cx;
for (@ast.expr e in es) {
- auto res = trans_expr(bcx, *e);
+ auto res = trans_expr(bcx, e);
vs += res.val;
bcx = res.bcx;
}
@@ -1113,7 +1138,7 @@ impure fn trans_exprs(@block_ctxt cx, &vec[@ast.expr] es)
ret tup(bcx, vs);
}
-impure fn trans_cast(@block_ctxt cx, &ast.expr e, &ast.ann ann) -> result {
+impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result {
auto e_res = trans_expr(cx, e);
auto llsrctype = val_ty(e_res.val);
auto t = node_ann_type(cx.fcx.ccx, ann);
@@ -1144,7 +1169,7 @@ impure fn trans_cast(@block_ctxt cx, &ast.expr e, &ast.ann ann) -> result {
ret e_res;
}
-impure fn trans_call(@block_ctxt cx, &ast.expr f,
+impure fn trans_call(@block_ctxt cx, @ast.expr f,
vec[@ast.expr] args) -> result {
auto f_res = trans_lval(cx, f);
check (! f_res._1);
@@ -1163,7 +1188,7 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(bool, @ast.expr)] args,
auto r = res(cx, C_nil());
for (tup(bool, @ast.expr) arg in args) {
auto t = typeck.expr_ty(arg._1);
- auto src_res = trans_expr(r.bcx, *arg._1);
+ auto src_res = trans_expr(r.bcx, arg._1);
auto dst_elt = r.bcx.build.GEP(tup_val, vec(C_int(0), C_int(i)));
// FIXME: calculate copy init-ness in typestate.
r = copy_ty(src_res.bcx, true, dst_elt, src_res.val, t);
@@ -1173,46 +1198,31 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(bool, @ast.expr)] args,
}
-impure fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
- &ast.ident field, &ast.ann ann) -> result {
- auto r = trans_expr(cx, *base);
- auto ty = typeck.expr_ty(base);
- alt (ty.struct) {
- case (typeck.ty_tup(?fields)) {
- let uint ix = typeck.field_num(cx.fcx.ccx.sess, sp, field);
- auto v = r.bcx.build.GEP(r.val, vec(C_int(ix as int)));
- ret res(r.bcx, v);
- }
- }
- cx.fcx.ccx.sess.unimpl("field variant in trans_field");
- fail;
-}
-
-impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
+impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
alt (e.node) {
case (ast.expr_lit(?lit, _)) {
ret trans_lit(cx, *lit);
}
case (ast.expr_unary(?op, ?x, ?ann)) {
- ret trans_unary(cx, op, *x, ann);
+ ret trans_unary(cx, op, x, ann);
}
case (ast.expr_binary(?op, ?x, ?y, _)) {
- ret trans_binary(cx, op, *x, *y);
+ ret trans_binary(cx, op, x, y);
}
case (ast.expr_if(?cond, ?thn, ?els, _)) {
- ret trans_if(cx, *cond, thn, els);
+ ret trans_if(cx, cond, thn, els);
}
case (ast.expr_while(?cond, ?body, _)) {
- ret trans_while(cx, *cond, body);
+ ret trans_while(cx, cond, body);
}
case (ast.expr_do_while(?body, ?cond, _)) {
- ret trans_do_while(cx, body, *cond);
+ ret trans_do_while(cx, body, cond);
}
case (ast.expr_block(?blk, _)) {
@@ -1226,46 +1236,45 @@ impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
ret res(next_cx, sub.val);
}
- case (ast.expr_name(_,_,_)) {
- auto sub = trans_lval(cx, e);
- if (sub._1) {
- ret res(sub._0.bcx, cx.build.Load(sub._0.val));
- } else {
- ret sub._0;
- }
- }
-
case (ast.expr_assign(?dst, ?src, ?ann)) {
- auto lhs_res = trans_lval(cx, *dst);
+ auto lhs_res = trans_lval(cx, dst);
check (lhs_res._1);
- auto rhs_res = trans_expr(lhs_res._0.bcx, *src);
+ auto rhs_res = trans_expr(lhs_res._0.bcx, src);
auto t = node_ann_type(cx.fcx.ccx, ann);
// FIXME: calculate copy init-ness in typestate.
ret copy_ty(rhs_res.bcx, true, lhs_res._0.val, rhs_res.val, t);
}
case (ast.expr_call(?f, ?args, _)) {
- ret trans_call(cx, *f, args);
+ ret trans_call(cx, f, args);
}
case (ast.expr_cast(?e, _, ?ann)) {
- ret trans_cast(cx, *e, ann);
+ ret trans_cast(cx, e, ann);
}
case (ast.expr_tup(?args, ?ann)) {
ret trans_tup(cx, args, ann);
}
- case (ast.expr_field(?base, ?ident, ?ann)) {
- ret trans_field(cx, e.span, base, ident, ann);
- }
+ // lval cases fall through to trans_lval and then
+ // possibly load the result (if it's non-structural).
+ case (_) {
+ auto t = typeck.expr_ty(e);
+ auto sub = trans_lval(cx, e);
+ if (sub._1 && ! typeck.type_is_structural(t)) {
+ ret res(sub._0.bcx, cx.build.Load(sub._0.val));
+ } else {
+ ret sub._0;
+ }
+ }
}
cx.fcx.ccx.sess.unimpl("expr variant in trans_expr");
fail;
}
-impure fn trans_log(@block_ctxt cx, &ast.expr e) -> result {
+impure fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
alt (e.node) {
case (ast.expr_lit(?lit, _)) {
alt (lit.node) {
@@ -1293,7 +1302,7 @@ impure fn trans_log(@block_ctxt cx, &ast.expr e) -> result {
}
}
-impure fn trans_check_expr(@block_ctxt cx, &ast.expr e) -> result {
+impure fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result {
auto cond_res = trans_expr(cx, e);
// FIXME: need pretty-printer.
@@ -1317,7 +1326,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
auto r = res(cx, C_nil());
alt (e) {
case (some[@ast.expr](?x)) {
- r = trans_expr(cx, *x);
+ r = trans_expr(cx, x);
}
}
@@ -1353,11 +1362,11 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
auto sub = res(cx, C_nil());
alt (s.node) {
case (ast.stmt_log(?a)) {
- sub.bcx = trans_log(cx, *a).bcx;
+ sub.bcx = trans_log(cx, a).bcx;
}
case (ast.stmt_check_expr(?a)) {
- sub.bcx = trans_check_expr(cx, *a).bcx;
+ sub.bcx = trans_check_expr(cx, a).bcx;
}
case (ast.stmt_ret(?e)) {
@@ -1365,7 +1374,7 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
}
case (ast.stmt_expr(?e)) {
- sub.bcx = trans_expr(cx, *e).bcx;
+ sub.bcx = trans_expr(cx, e).bcx;
}
case (ast.stmt_decl(?d)) {
@@ -1375,8 +1384,9 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
case (some[@ast.expr](?e)) {
check (cx.fcx.lllocals.contains_key(local.id));
auto llptr = cx.fcx.lllocals.get(local.id);
- sub = trans_expr(cx, *e);
- sub.val = sub.bcx.build.Store(sub.val, llptr);
+ sub = trans_expr(cx, e);
+ copy_ty(sub.bcx, true, llptr, sub.val,
+ typeck.expr_ty(e));
}
}
}