parent
f089f533e8
commit
d243ea57f5
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue