Revert "Revert "Reorganize translation of expr_field""

This reverts commit 11e407aaa9.
This commit is contained in:
Marijn Haverbeke 2011-10-05 10:21:57 +02:00
parent c33e61e75c
commit babd1ff3c7

View File

@ -2366,7 +2366,6 @@ fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
_ { } _ { }
} }
} }
ret trans_eager_binop(bcx, op, Load(bcx, lhs_res.val), t, rhs_val, t, ret trans_eager_binop(bcx, op, Load(bcx, lhs_res.val), t, rhs_val, t,
save_in(lhs_res.val)); save_in(lhs_res.val));
} }
@ -3149,54 +3148,49 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
} }
} }
fn trans_field(cx: @block_ctxt, sp: span, base: @ast::expr, fn trans_object_field(bcx: @block_ctxt, o: @ast::expr, field: ast::ident)
field: ast::ident) -> lval_maybe_callee { -> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} {
let {bcx, val} = trans_expr(cx, base); let {bcx, val} = trans_expr(bcx, o);
ret trans_field_inner(bcx, sp, val, ty::expr_ty(bcx_tcx(cx), base), let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), o));
field); ret trans_object_field_inner(bcx, val, field, ty);
} }
fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t, fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
field: ast::ident) -> lval_maybe_callee { field: ast::ident, o_ty: ty::t)
let r = autoderef(cx, v, t0); -> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} {
let t = r.ty; let ccx = bcx_ccx(bcx), tcx = ccx.tcx;
alt ty::struct(bcx_tcx(cx), t) { let mths = alt ty::struct(tcx, o_ty) { ty::ty_obj(ms) { ms } };
ty::ty_rec(fields) {
let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields);
let r_bcx = r.bcx;
// Silly check
check type_is_tup_like(r_bcx, t);
let v = GEP_tup_like(r_bcx, t, r.val, [0, ix as int]);
ret lval_no_env(v.bcx, v.val, true);
}
ty::ty_obj(methods) {
let ix: uint = ty::method_idx(bcx_ccx(cx).sess, sp, field, methods);
let vtbl = GEP(r.bcx, r.val, [C_int(0), C_int(abi::obj_field_vtbl)]);
vtbl = Load(r.bcx, vtbl);
let ix = ty::method_idx(ccx.sess, bcx.sp, field, mths);
let vtbl = Load(bcx, GEP(bcx, o, [C_int(0), C_int(abi::obj_field_vtbl)]));
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u)); let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
vtbl = PointerCast(cx, vtbl, vtbl_type); vtbl = PointerCast(bcx, vtbl, vtbl_type);
let v = GEP(r.bcx, vtbl, [C_int(0), C_int(ix as int)]); let v = GEP(bcx, vtbl, [C_int(0), C_int(ix as int)]);
let tcx = bcx_tcx(cx); let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, mths[ix]);
let ccx = bcx_ccx(cx);
let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, methods[ix]);
let ret_ty = ty::ty_fn_ret(tcx, fn_ty); let ret_ty = ty::ty_fn_ret(tcx, fn_ty);
let ret_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_ty)); let ret_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_ty));
// FIXME: constrain ty_obj? // FIXME: constrain ty_obj?
check non_ty_var(ccx, ret_ty); check non_ty_var(ccx, ret_ty);
let ll_fn_ty = let ll_fn_ty = type_of_fn(ccx, bcx.sp, ty::ty_fn_proto(tcx, fn_ty),
type_of_fn(ccx, sp, ty::ty_fn_proto(tcx, fn_ty),
true, ret_ref, ty::ty_fn_args(tcx, fn_ty), true, ret_ref, ty::ty_fn_args(tcx, fn_ty),
ret_ty, 0u); ret_ty, 0u);
v = Load(r.bcx, PointerCast(r.bcx, v, T_ptr(T_ptr(ll_fn_ty)))); v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
ret {bcx: r.bcx, val: v, is_mem: true, ret {bcx: bcx, mthptr: v, objptr: o};
env: obj_env(r.val), generic: none};
}
_ { bcx_ccx(cx).sess.unimpl("field variant in trans_field"); }
} }
fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr,
field: ast::ident) -> lval_result {
let {bcx, val} = trans_expr(bcx, base);
let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), base));
let fields = alt ty::struct(bcx_tcx(bcx), ty) { ty::ty_rec(fs) { fs } };
let ix = ty::field_idx(bcx_ccx(bcx).sess, bcx.sp, field, fields);
// Silly check
check type_is_tup_like(bcx, ty);
let {bcx, val} = GEP_tup_like(bcx, ty, val, [0, ix as int]);
ret {bcx: bcx, val: val, is_mem: true};
} }
fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr, fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
@ -3248,25 +3242,31 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
ret lval_mem(next_cx, elt); ret lval_mem(next_cx, elt);
} }
fn trans_callee(cx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee { fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
alt e.node { alt e.node {
ast::expr_path(p) { ret trans_path(cx, p, e.id); } ast::expr_path(p) { ret trans_path(bcx, p, e.id); }
ast::expr_field(base, ident) { ast::expr_field(base, ident) {
ret trans_field(cx, e.span, base, ident); // Lval means record field, so not a method
if !expr_is_lval(bcx_tcx(bcx), e) {
let of = trans_object_field(bcx, base, ident);
ret {bcx: of.bcx, val: of.mthptr, is_mem: true,
env: obj_env(of.objptr), generic: none};
}
} }
ast::expr_self_method(ident) { ast::expr_self_method(ident) {
alt cx.fcx.llself { alt bcx.fcx.llself {
some(pair) { some(pair) {
ret trans_field_inner(cx, e.span, pair.v, pair.t, ident); let fld = trans_object_field_inner(bcx, pair.v, ident, pair.t);
ret {bcx: fld.bcx, val: fld.mthptr, is_mem: true,
env: obj_env(fld.objptr), generic: none};
} }
} }
} }
_ { _ {}
let lv = trans_lval(cx, e); }
let lv = trans_lval(bcx, e);
ret lval_no_env(lv.bcx, lv.val, lv.is_mem); ret lval_no_env(lv.bcx, lv.val, lv.is_mem);
} }
}
}
fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool { fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool {
alt e.node { alt e.node {
@ -3298,8 +3298,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
ret lval_maybe_callee_to_lval(v, ty::expr_ty(bcx_tcx(cx), e)); ret lval_maybe_callee_to_lval(v, ty::expr_ty(bcx_tcx(cx), e));
} }
ast::expr_field(base, ident) { ast::expr_field(base, ident) {
let f = trans_field(cx, e.span, base, ident); ret trans_rec_field(cx, base, ident);
ret lval_maybe_callee_to_lval(f, ty::expr_ty(bcx_tcx(cx), e));
} }
ast::expr_index(base, idx) { ast::expr_index(base, idx) {
ret trans_index(cx, e.span, base, idx, e.id); ret trans_index(cx, e.span, base, idx, e.id);
@ -4339,9 +4338,8 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
ast::expr_call(f, args) { ast::expr_call(f, args) {
ret trans_call(bcx, f, none, args, e.id, dest); ret trans_call(bcx, f, none, args, e.id, dest);
} }
// FIXME[DPS] untangle non-lval fields from trans_lval
ast::expr_field(_, _) { ast::expr_field(_, _) {
ret lval_to_dps(bcx, e, dest); fail "Taking the value of a method does not work yet (issue #435)";
} }
// These return nothing // These return nothing