aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-10 16:10:35 -0800
committerGraydon Hoare <[email protected]>2010-12-10 16:10:35 -0800
commit865c06c1f9766495dafc519c0d4b8160f0b12df8 (patch)
tree731b23591f6a9feca2059e0c16e502d14957fec2 /src
parentrustc: Move refcount decrement-and-free (drop) logic out-of-line (diff)
downloadrust-865c06c1f9766495dafc519c0d4b8160f0b12df8.tar.xz
rust-865c06c1f9766495dafc519c0d4b8160f0b12df8.zip
Preliminary translation of expr_index.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 2dce726a..e37d2c28 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1349,6 +1349,40 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
fail;
}
+fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
+ @ast.expr idx, &ast.ann ann) -> tup(result, bool) {
+
+ auto lv = trans_lval(cx, base);
+ auto ix = trans_expr(lv._0.bcx, idx);
+ auto v = lv._0.val;
+
+ auto llunit_ty = node_type(cx.fcx.ccx, ann);
+ auto unit_sz = ix.bcx.build.IntCast(lib.llvm.llvm.LLVMSizeOf(llunit_ty),
+ T_int());
+ auto scaled_ix = ix.bcx.build.Mul(ix.val, unit_sz);
+
+ auto lim = ix.bcx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_fill)));
+ lim = ix.bcx.build.Load(lim);
+ auto bounds_check = ix.bcx.build.ICmp(lib.llvm.LLVMIntULT,
+ scaled_ix, lim);
+
+ auto fail_cx = new_sub_block_ctxt(ix.bcx, "fail");
+ auto next_cx = new_sub_block_ctxt(ix.bcx, "next");
+ ix.bcx.build.CondBr(bounds_check, next_cx.llbb, fail_cx.llbb);
+
+ // fail: bad bounds check.
+ auto V_expr_str = p2i(C_str(cx.fcx.ccx, "out-of-bounds access"));
+ auto V_filename = p2i(C_str(cx.fcx.ccx, sp.filename));
+ auto V_line = sp.lo.line as int;
+ auto args = vec(V_expr_str, V_filename, C_int(V_line));
+ auto fail_res = trans_upcall(fail_cx, "upcall_fail", args);
+ fail_res.bcx.build.Br(next_cx.llbb);
+
+ auto body = next_cx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_data)));
+ auto elt = next_cx.build.GEP(body, vec(C_int(0), ix.val));
+ ret tup(res(next_cx, elt), lv._1);
+}
+
// 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).
@@ -1361,6 +1395,9 @@ fn trans_lval(@block_ctxt cx, @ast.expr e) -> tup(result, bool) {
case (ast.expr_field(?base, ?ident, ?ann)) {
ret trans_field(cx, e.span, base, ident, ann);
}
+ case (ast.expr_index(?base, ?idx, ?ann)) {
+ ret trans_index(cx, e.span, base, idx, ann);
+ }
case (_) { cx.fcx.ccx.sess.unimpl("expr variant in trans_lval"); }
}
fail;