diff options
| author | Graydon Hoare <[email protected]> | 2010-12-10 16:10:35 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-12-10 16:10:35 -0800 |
| commit | 865c06c1f9766495dafc519c0d4b8160f0b12df8 (patch) | |
| tree | 731b23591f6a9feca2059e0c16e502d14957fec2 /src | |
| parent | rustc: Move refcount decrement-and-free (drop) logic out-of-line (diff) | |
| download | rust-865c06c1f9766495dafc519c0d4b8160f0b12df8.tar.xz rust-865c06c1f9766495dafc519c0d4b8160f0b12df8.zip | |
Preliminary translation of expr_index.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 37 |
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; |