Skip to content

Commit 007ec66

Browse files
committed
Reorganize translation of expr_field
Issue #667
1 parent 6e65258 commit 007ec66

File tree

1 file changed

+54
-56
lines changed

1 file changed

+54
-56
lines changed

src/comp/middle/trans.rs

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,7 +2366,6 @@ fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
23662366
_ { }
23672367
}
23682368
}
2369-
23702369
ret trans_eager_binop(bcx, op, Load(bcx, lhs_res.val), t, rhs_val, t,
23712370
save_in(lhs_res.val));
23722371
}
@@ -3149,54 +3148,49 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
31493148
}
31503149
}
31513150

3152-
fn trans_field(cx: @block_ctxt, sp: span, base: @ast::expr,
3153-
field: ast::ident) -> lval_maybe_callee {
3154-
let {bcx, val} = trans_expr(cx, base);
3155-
ret trans_field_inner(bcx, sp, val, ty::expr_ty(bcx_tcx(cx), base),
3156-
field);
3151+
fn trans_object_field(bcx: @block_ctxt, o: @ast::expr, field: ast::ident)
3152+
-> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} {
3153+
let {bcx, val} = trans_expr(bcx, o);
3154+
let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), o));
3155+
ret trans_object_field_inner(bcx, val, field, ty);
31573156
}
31583157

3159-
fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
3160-
field: ast::ident) -> lval_maybe_callee {
3161-
let r = autoderef(cx, v, t0);
3162-
let t = r.ty;
3163-
alt ty::struct(bcx_tcx(cx), t) {
3164-
ty::ty_rec(fields) {
3165-
let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields);
3166-
let r_bcx = r.bcx;
3167-
// Silly check
3168-
check type_is_tup_like(r_bcx, t);
3169-
let v = GEP_tup_like(r_bcx, t, r.val, [0, ix as int]);
3170-
ret lval_no_env(v.bcx, v.val, true);
3171-
}
3172-
ty::ty_obj(methods) {
3173-
let ix: uint = ty::method_idx(bcx_ccx(cx).sess, sp, field, methods);
3174-
let vtbl = GEP(r.bcx, r.val, [C_int(0), C_int(abi::obj_field_vtbl)]);
3175-
vtbl = Load(r.bcx, vtbl);
3158+
fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
3159+
field: ast::ident, o_ty: ty::t)
3160+
-> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} {
3161+
let ccx = bcx_ccx(bcx), tcx = ccx.tcx;
3162+
let mths = alt ty::struct(tcx, o_ty) { ty::ty_obj(ms) { ms } };
31763163

3177-
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
3178-
vtbl = PointerCast(cx, vtbl, vtbl_type);
3164+
let ix = ty::method_idx(ccx.sess, bcx.sp, field, mths);
3165+
let vtbl = Load(bcx, GEP(bcx, o, [C_int(0), C_int(abi::obj_field_vtbl)]));
3166+
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
3167+
vtbl = PointerCast(bcx, vtbl, vtbl_type);
31793168

3180-
let v = GEP(r.bcx, vtbl, [C_int(0), C_int(ix as int)]);
3181-
let tcx = bcx_tcx(cx);
3182-
let ccx = bcx_ccx(cx);
3169+
let v = GEP(bcx, vtbl, [C_int(0), C_int(ix as int)]);
3170+
let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, mths[ix]);
3171+
let ret_ty = ty::ty_fn_ret(tcx, fn_ty);
3172+
let ret_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_ty));
3173+
// FIXME: constrain ty_obj?
3174+
check non_ty_var(ccx, ret_ty);
31833175

3184-
let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, methods[ix]);
3185-
let ret_ty = ty::ty_fn_ret(tcx, fn_ty);
3186-
let ret_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_ty));
3187-
// FIXME: constrain ty_obj?
3188-
check non_ty_var(ccx, ret_ty);
3176+
let ll_fn_ty = type_of_fn(ccx, bcx.sp, ty::ty_fn_proto(tcx, fn_ty),
3177+
true, ret_ref, ty::ty_fn_args(tcx, fn_ty),
3178+
ret_ty, 0u);
3179+
v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
3180+
ret {bcx: bcx, mthptr: v, objptr: o};
3181+
}
31893182

3190-
let ll_fn_ty =
3191-
type_of_fn(ccx, sp, ty::ty_fn_proto(tcx, fn_ty),
3192-
true, ret_ref, ty::ty_fn_args(tcx, fn_ty),
3193-
ret_ty, 0u);
3194-
v = Load(r.bcx, PointerCast(r.bcx, v, T_ptr(T_ptr(ll_fn_ty))));
3195-
ret {bcx: r.bcx, val: v, is_mem: true,
3196-
env: obj_env(r.val), generic: none};
3197-
}
3198-
_ { bcx_ccx(cx).sess.unimpl("field variant in trans_field"); }
3199-
}
3183+
3184+
fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr,
3185+
field: ast::ident) -> lval_result {
3186+
let {bcx, val} = trans_expr(bcx, base);
3187+
let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), base));
3188+
let fields = alt ty::struct(bcx_tcx(bcx), ty) { ty::ty_rec(fs) { fs } };
3189+
let ix = ty::field_idx(bcx_ccx(bcx).sess, bcx.sp, field, fields);
3190+
// Silly check
3191+
check type_is_tup_like(bcx, ty);
3192+
let {bcx, val} = GEP_tup_like(bcx, ty, val, [0, ix as int]);
3193+
ret {bcx: bcx, val: val, is_mem: true};
32003194
}
32013195

32023196
fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
@@ -3248,24 +3242,30 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
32483242
ret lval_mem(next_cx, elt);
32493243
}
32503244

3251-
fn trans_callee(cx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
3245+
fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
32523246
alt e.node {
3253-
ast::expr_path(p) { ret trans_path(cx, p, e.id); }
3247+
ast::expr_path(p) { ret trans_path(bcx, p, e.id); }
32543248
ast::expr_field(base, ident) {
3255-
ret trans_field(cx, e.span, base, ident);
3249+
// Lval means record field, so not a method
3250+
if !expr_is_lval(bcx_tcx(bcx), e) {
3251+
let of = trans_object_field(bcx, base, ident);
3252+
ret {bcx: of.bcx, val: of.mthptr, is_mem: true,
3253+
env: obj_env(of.objptr), generic: none};
3254+
}
32563255
}
32573256
ast::expr_self_method(ident) {
3258-
alt cx.fcx.llself {
3257+
alt bcx.fcx.llself {
32593258
some(pair) {
3260-
ret trans_field_inner(cx, e.span, pair.v, pair.t, ident);
3259+
let fld = trans_object_field_inner(bcx, pair.v, ident, pair.t);
3260+
ret {bcx: fld.bcx, val: fld.mthptr, is_mem: true,
3261+
env: obj_env(fld.objptr), generic: none};
32613262
}
32623263
}
32633264
}
3264-
_ {
3265-
let lv = trans_lval(cx, e);
3266-
ret lval_no_env(lv.bcx, lv.val, lv.is_mem);
3267-
}
3265+
_ {}
32683266
}
3267+
let lv = trans_lval(bcx, e);
3268+
ret lval_no_env(lv.bcx, lv.val, lv.is_mem);
32693269
}
32703270

32713271
fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool {
@@ -3298,8 +3298,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
32983298
ret lval_maybe_callee_to_lval(v, ty::expr_ty(bcx_tcx(cx), e));
32993299
}
33003300
ast::expr_field(base, ident) {
3301-
let f = trans_field(cx, e.span, base, ident);
3302-
ret lval_maybe_callee_to_lval(f, ty::expr_ty(bcx_tcx(cx), e));
3301+
ret trans_rec_field(cx, base, ident);
33033302
}
33043303
ast::expr_index(base, idx) {
33053304
ret trans_index(cx, e.span, base, idx, e.id);
@@ -4325,9 +4324,8 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
43254324
ast::expr_call(f, args) {
43264325
ret trans_call(bcx, f, none, args, e.id, dest);
43274326
}
4328-
// FIXME[DPS] untangle non-lval fields from trans_lval
43294327
ast::expr_field(_, _) {
4330-
ret lval_to_dps(bcx, e, dest);
4328+
fail "Taking the value of a method does not work yet (issue #435)";
43314329
}
43324330

43334331
// These return nothing

0 commit comments

Comments
 (0)