Move last remaining expression types out of trans_expr

Issue #667
This commit is contained in:
Marijn Haverbeke 2011-09-29 11:18:40 +02:00
parent f089f533e8
commit d243ea57f5
3 changed files with 58 additions and 79 deletions

View File

@ -2243,10 +2243,7 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
trans_closure(sub_cx, sp, f, llfn, none, [], id, {|_fcx|});
}
};
let addr = alt dest {
save_in(a) { a }
overwrite(a, ty) { bcx = drop_ty(bcx, a, ty); a }
};
let {bcx, val: addr} = get_dest_addr(bcx, dest);
fill_fn_pair(bcx, addr, llfn, env);
ret bcx;
}
@ -2537,6 +2534,13 @@ fn store_in_dest(bcx: @block_ctxt, val: ValueRef, dest: dest) -> @block_ctxt {
ret bcx;
}
fn get_dest_addr(bcx: @block_ctxt, dest: dest) -> result {
alt dest {
save_in(a) { rslt(bcx, a) }
overwrite(a, t) { rslt(drop_ty(bcx, a, t), a) }
}
}
// Wrapper through which legacy non-DPS code can use DPS functions
fn dps_to_result(bcx: @block_ctxt,
work: block(@block_ctxt, dest) -> @block_ctxt,
@ -3675,12 +3679,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
let lv = lval_maybe_callee_to_lval(f_res, pair_ty);
bcx = lv.bcx;
// FIXME[DPS] factor this out
let addr = alt dest {
save_in(a) { a }
overwrite(a, ty) { bcx = drop_ty(bcx, a, ty); a }
};
bcx = memmove_ty(bcx, addr, lv.val, pair_ty);
ret bcx;
let {bcx, val: addr} = get_dest_addr(bcx, dest);
ret memmove_ty(bcx, addr, lv.val, pair_ty);
}
let closure = alt f_res.env {
null_env. { none }
@ -3717,10 +3717,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
closure.ptrty, ty_param_count, target_res);
// Fill the function pair
let addr = alt dest {
save_in(a) { a }
overwrite(a, ty) { bcx = drop_ty(bcx, a, ty); a }
};
let {bcx, val: addr} = get_dest_addr(bcx, dest);
fill_fn_pair(bcx, addr, llthunk.val, closure.ptr);
ret bcx;
}
@ -4186,25 +4183,18 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
ret bcx;
}
// FIXME[DPS] remove this entirely, rename trans_expr_dps to trans_expr
fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
// Fixme Fill in cx.sp
alt e.node {
ast::expr_anon_obj(anon_obj) {
ret trans_anon_obj(cx, e.span, anon_obj, e.id);
}
ast::expr_call(_, _) | ast::expr_field(_, _) | ast::expr_index(_, _) |
ast::expr_path(_) | ast::expr_unary(ast::deref., _) {
if expr_is_lval(bcx_tcx(cx), e) {
let t = ty::expr_ty(bcx_tcx(cx), e);
let sub = trans_lval(cx, e);
let v = sub.val;
if sub.is_mem { v = load_if_immediate(sub.bcx, v, t); }
ret rslt(sub.bcx, v);
}
// Fall through to DPS-style
_ {
} else {
// Fall through to DPS-style
ret dps_to_result(cx, {|bcx, dest| trans_expr_dps(bcx, e, dest)},
ty::expr_ty(bcx_tcx(cx), e));
}
}
}
@ -4234,6 +4224,9 @@ fn trans_expr_by_ref(bcx: @block_ctxt, e: @ast::expr) -> result {
// - exprs returning non-immediates get save_in (or by_ref when lval)
fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
-> @block_ctxt {
let tcx = bcx_tcx(bcx);
if expr_is_lval(tcx, e) { ret lval_to_dps(bcx, e, dest); }
alt e.node {
ast::expr_if(cond, thn, els) | ast::expr_if_check(cond, thn, els) {
ret trans_if(bcx, cond, thn, els, dest);
@ -4261,22 +4254,23 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); }
ast::expr_binary(op, x, y) { ret trans_binary(bcx, op, x, y, dest); }
ast::expr_unary(op, x) {
if op == ast::deref {
ret trans_expr_backwards_compat(bcx, e, dest);
}
assert op != ast::deref; // lvals are handled above
ret trans_unary(bcx, op, x, e.id, dest);
}
ast::expr_fn(f) { ret trans_expr_fn(bcx, f, e.span, e.id, dest); }
ast::expr_bind(f, args) { ret trans_bind(bcx, f, args, e.id, dest); }
ast::expr_copy(a) {
if !expr_is_lval(bcx_tcx(bcx), a) {
ret trans_expr_dps(bcx, a, dest);
} else {
// FIXME[DPS] give this a name that makes more sense
ret trans_expr_backwards_compat(bcx, e, dest);
}
if !expr_is_lval(tcx, a) { ret trans_expr_dps(bcx, a, dest); }
else { ret lval_to_dps(bcx, a, dest); }
}
ast::expr_cast(val, _) { ret trans_cast(bcx, val, e.id, dest); }
ast::expr_anon_obj(anon_obj) {
ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest);
}
// FIXME[DPS] untangle non-lval calls and fields from trans_lval
ast::expr_call(_, _) | ast::expr_field(_, _) {
ret lval_to_dps(bcx, e, dest);
}
// These return nothing
ast::expr_break. {
@ -4366,11 +4360,11 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
let {bcx, val: addr, is_mem} = trans_lval(bcx, dst);
assert is_mem;
// FIXME: calculate copy init-ness in typestate.
if expr_is_lval(bcx_tcx(bcx), src) {
if expr_is_lval(tcx, src) {
ret trans_expr_save_in(bcx, src, addr, DROP_EXISTING);
} else {
let srclv = trans_lval(bcx, src);
let t = ty::expr_ty(bcx_tcx(bcx), src);
let t = ty::expr_ty(tcx, src);
ret move_val(srclv.bcx, DROP_EXISTING, addr, srclv, t);
}
}
@ -4379,7 +4373,7 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
let lhs_res = trans_lval(bcx, dst);
assert (lhs_res.is_mem);
let rhs_res = trans_lval(lhs_res.bcx, src);
let t = ty::expr_ty(bcx_tcx(bcx), src);
let t = ty::expr_ty(tcx, src);
let {bcx: bcx, val: tmp_alloc} = alloc_ty(rhs_res.bcx, t);
// Swap through a temporary.
bcx = move_val(bcx, INIT, tmp_alloc, lhs_res, t);
@ -4390,15 +4384,10 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
assert dest == ignore;
ret trans_assign_op(bcx, op, dst, src);
}
ast::expr_mac(_) { ret bcx_ccx(bcx).sess.bug("unexpanded macro"); }
// Convert back from result to DPS
_ { ret trans_expr_backwards_compat(bcx, e, dest); }
}
}
fn trans_expr_backwards_compat(bcx: @block_ctxt, e: @ast::expr, dest: dest)
-> @block_ctxt {
fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
let lv = trans_lval(bcx, e);
let {bcx, val, is_mem} = lv;
let ty = ty::expr_ty(bcx_tcx(bcx), e);

View File

@ -213,7 +213,13 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
// instead "inlining" the construction of the object and returning the object
// itself.
fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
id: ast::node_id) -> result {
id: ast::node_id, dest: trans::dest) -> @block_ctxt {
if dest == trans::ignore {
alt anon_obj.inner_obj {
some(e) { ret trans::trans_expr_dps(bcx, e, trans::ignore); }
none. { ret bcx; }
}
}
let ccx = bcx_ccx(bcx);
@ -283,43 +289,26 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
}
}
// Allocate the object that we're going to return.
let pair = alloca(bcx, ccx.rust_object_type);
// Take care of cleanups.
let t = node_id_type(ccx, id);
add_clean_temp(bcx, pair, t);
// Grab onto the first and second elements of the pair.
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
Store(bcx, vtbl, pair_vtbl);
// Next we have to take care of the other half of the pair we're
// returning: a boxed (reference-counted) tuple containing a tydesc,
// typarams, fields, and a pointer to our inner_obj.
let llbox_ty: TypeRef = T_ptr(T_empty_struct());
if vec::len(additional_fields) == 0u &&
anon_obj.inner_obj == none {
// If the object we're translating has no fields and no inner_obj,
// there's not much to do.
Store(bcx, C_null(llbox_ty), pair_box);
} else {
let box = C_null(llbox_ty);
if vec::len(additional_fields) > 0u || anon_obj.inner_obj != none {
// Synthesize a type for the object body and hand it off to
// trans_malloc_boxed, which allocates a box, including space for a
// refcount.
let body_ty: ty::t =
create_object_body_type(ccx.tcx, additional_field_tys, [],
some(inner_obj_ty));
let box = trans_malloc_boxed(bcx, body_ty);
bcx = box.bcx;
let body = box.body;
let box_r = trans_malloc_boxed(bcx, body_ty);
box = box_r.box;
bcx = box_r.bcx;
add_clean_free(bcx, box, false);
let body = box_r.body;
// Put together a tydesc for the body, so that the object can later be
// freed by calling through its tydesc.
@ -386,14 +375,15 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
inner_obj_ty);
}
}
// Store box ptr in outer pair.
let p = PointerCast(bcx, box.box, llbox_ty);
Store(bcx, p, pair_box);
revoke_clean(bcx, box);
box = PointerCast(bcx, box, llbox_ty);
}
// return the object we built.
ret rslt(bcx, pair);
let {bcx, val: pair} = trans::get_dest_addr(bcx, dest);
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
Store(bcx, vtbl, pair_vtbl);
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
Store(bcx, box, pair_box);
ret bcx;
}
// Used only inside create_vtbl and create_backwarding_vtbl to distinguish

View File

@ -1299,14 +1299,14 @@ fn vars_in_type(cx: ctxt, ty: t) -> [int] {
}
fn type_autoderef(cx: ctxt, t: ty::t) -> ty::t {
let t1: ty::t = t;
let t1 = t;
while true {
alt struct(cx, t1) {
ty::ty_box(mt) { t1 = mt.ty; }
ty::ty_res(_, inner, tps) {
ty_box(mt) | ty_uniq(mt) { t1 = mt.ty; }
ty_res(_, inner, tps) {
t1 = substitute_type_params(cx, tps, inner);
}
ty::ty_tag(did, tps) {
ty_tag(did, tps) {
let variants = tag_variants(cx, did);
if vec::len(variants) != 1u || vec::len(variants[0].args) != 1u {
break;