parent
a25119b0c5
commit
e3626c9405
@ -2208,7 +2208,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
|
|||||||
let llety = T_ptr(type_of(ccx, e_sp, e_ty));
|
let llety = T_ptr(type_of(ccx, e_sp, e_ty));
|
||||||
body = PointerCast(bcx, body, llety);
|
body = PointerCast(bcx, body, llety);
|
||||||
}
|
}
|
||||||
bcx = trans_expr_save_in(bcx, e, body);
|
bcx = trans_expr_save_in(bcx, e, body, INIT);
|
||||||
revoke_clean(bcx, box);
|
revoke_clean(bcx, box);
|
||||||
ret store_in_dest(bcx, box, dest);
|
ret store_in_dest(bcx, box, dest);
|
||||||
}
|
}
|
||||||
@ -4033,7 +4033,7 @@ fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
|
|||||||
}
|
}
|
||||||
save_in(pos) { (pos, none) }
|
save_in(pos) { (pos, none) }
|
||||||
overwrite(pos, _) {
|
overwrite(pos, _) {
|
||||||
let scratch = alloca(bcx, val_ty(pos));
|
let scratch = alloca(bcx, llvm::LLVMGetElementType(val_ty(pos)));
|
||||||
(scratch, some(pos))
|
(scratch, some(pos))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4041,7 +4041,7 @@ fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
|
|||||||
for e in elts {
|
for e in elts {
|
||||||
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
|
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
|
||||||
let e_ty = ty::expr_ty(bcx_tcx(bcx), e);
|
let e_ty = ty::expr_ty(bcx_tcx(bcx), e);
|
||||||
bcx = trans_expr_save_in(dst.bcx, e, dst.val);
|
bcx = trans_expr_save_in(dst.bcx, e, dst.val, INIT);
|
||||||
add_clean_temp_mem(bcx, dst.val, e_ty);
|
add_clean_temp_mem(bcx, dst.val, e_ty);
|
||||||
temp_cleanups += [dst.val];
|
temp_cleanups += [dst.val];
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -4072,7 +4072,7 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
|
|||||||
// The expressions that populate the fields might still use the old
|
// The expressions that populate the fields might still use the old
|
||||||
// record, so we build the new on in a scratch area
|
// record, so we build the new on in a scratch area
|
||||||
overwrite(pos, _) {
|
overwrite(pos, _) {
|
||||||
let scratch = alloca(bcx, val_ty(pos));
|
let scratch = alloca(bcx, llvm::LLVMGetElementType(val_ty(pos)));
|
||||||
(scratch, some(pos))
|
(scratch, some(pos))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4096,7 +4096,7 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
|
|||||||
fn test(n: str, f: ast::field) -> bool { str::eq(f.node.ident, n) }
|
fn test(n: str, f: ast::field) -> bool { str::eq(f.node.ident, n) }
|
||||||
alt vec::find(bind test(tf.ident, _), fields) {
|
alt vec::find(bind test(tf.ident, _), fields) {
|
||||||
some(f) {
|
some(f) {
|
||||||
bcx = trans_expr_save_in(bcx, f.node.expr, dst.val);
|
bcx = trans_expr_save_in(bcx, f.node.expr, dst.val, INIT);
|
||||||
}
|
}
|
||||||
none. {
|
none. {
|
||||||
let base = GEP_tup_like_1(bcx, t, base_val, [0, i]);
|
let base = GEP_tup_like_1(bcx, t, base_val, [0, i]);
|
||||||
@ -4198,20 +4198,17 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME add support for INIT/DROP_EXISTING
|
fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef,
|
||||||
fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef)
|
kind: copy_action) -> @block_ctxt {
|
||||||
-> @block_ctxt {
|
|
||||||
let tcx = bcx_tcx(bcx), t = ty::expr_ty(tcx, e);
|
let tcx = bcx_tcx(bcx), t = ty::expr_ty(tcx, e);
|
||||||
if ty::type_is_bot(tcx, t) || ty::type_is_nil(tcx, t) {
|
let dst = if ty::type_is_bot(tcx, t) || ty::type_is_nil(tcx, t) {
|
||||||
ret trans_expr_dps(bcx, e, ignore);
|
ignore
|
||||||
} else if type_is_immediate(bcx_ccx(bcx), t) {
|
} else if kind == INIT {
|
||||||
let cell = empty_dest_cell();
|
save_in(dest)
|
||||||
bcx = trans_expr_dps(bcx, e, by_val(cell));
|
|
||||||
Store(bcx, *cell, dest);
|
|
||||||
ret bcx;
|
|
||||||
} else {
|
} else {
|
||||||
ret trans_expr_dps(bcx, e, save_in(dest));
|
overwrite(dest, t)
|
||||||
}
|
};
|
||||||
|
ret trans_expr_dps(bcx, e, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_expr_by_ref(bcx: @block_ctxt, e: @ast::expr) -> result {
|
fn trans_expr_by_ref(bcx: @block_ctxt, e: @ast::expr) -> result {
|
||||||
@ -4338,13 +4335,9 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
|
|||||||
}
|
}
|
||||||
ast::expr_assign(dst, src) {
|
ast::expr_assign(dst, src) {
|
||||||
assert dest == ignore;
|
assert dest == ignore;
|
||||||
let lhs_res = trans_lval(bcx, dst);
|
let {bcx, val: lhs_addr, is_mem} = trans_lval(bcx, dst);
|
||||||
assert (lhs_res.is_mem);
|
assert is_mem;
|
||||||
let rhs = trans_lval(lhs_res.bcx, src);
|
ret trans_expr_save_in(bcx, src, lhs_addr, DROP_EXISTING);
|
||||||
let t = ty::expr_ty(bcx_tcx(bcx), src);
|
|
||||||
// FIXME: calculate copy init-ness in typestate.
|
|
||||||
ret move_val_if_temp(rhs.bcx, DROP_EXISTING, lhs_res.val,
|
|
||||||
rhs, t);
|
|
||||||
}
|
}
|
||||||
ast::expr_swap(dst, src) {
|
ast::expr_swap(dst, src) {
|
||||||
assert dest == ignore;
|
assert dest == ignore;
|
||||||
@ -4650,7 +4643,7 @@ fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt {
|
|||||||
Store(cx, val, bcx.fcx.llretptr);
|
Store(cx, val, bcx.fcx.llretptr);
|
||||||
bcx = cx;
|
bcx = cx;
|
||||||
} else {
|
} else {
|
||||||
bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr);
|
bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr, INIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
@ -4694,13 +4687,9 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
|
|||||||
some(init) {
|
some(init) {
|
||||||
alt init.op {
|
alt init.op {
|
||||||
ast::init_assign. {
|
ast::init_assign. {
|
||||||
// Use the type of the RHS because if it's _|_, the LHS
|
bcx = trans_expr_save_in(bcx, init.expr, llptr, INIT);
|
||||||
// type might be something else, but we don't want to copy
|
|
||||||
// the value.
|
|
||||||
ty = node_id_type(bcx_ccx(bcx), init.expr.id);
|
|
||||||
let sub = trans_lval(bcx, init.expr);
|
|
||||||
bcx = move_val_if_temp(sub.bcx, INIT, llptr, sub, ty);
|
|
||||||
}
|
}
|
||||||
|
// FIXME[DPS] do a save_in when expr isn't lval
|
||||||
ast::init_move. {
|
ast::init_move. {
|
||||||
let sub = trans_lval(bcx, init.expr);
|
let sub = trans_lval(bcx, init.expr);
|
||||||
bcx = move_val(sub.bcx, INIT, llptr, sub, ty);
|
bcx = move_val(sub.bcx, INIT, llptr, sub, ty);
|
||||||
|
@ -30,7 +30,7 @@ fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr,
|
|||||||
check type_is_unique_box(bcx, uniq_ty);
|
check type_is_unique_box(bcx, uniq_ty);
|
||||||
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
||||||
add_clean_free(bcx, llptr, true);
|
add_clean_free(bcx, llptr, true);
|
||||||
bcx = trans::trans_expr_save_in(bcx, contents, llptr);
|
bcx = trans::trans_expr_save_in(bcx, contents, llptr, INIT);
|
||||||
revoke_clean(bcx, llptr);
|
revoke_clean(bcx, llptr);
|
||||||
ret trans::store_in_dest(bcx, llptr, dest);
|
ret trans::store_in_dest(bcx, llptr, dest);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,11 @@ fn get_alloc(bcx: @block_ctxt, vptrptr: ValueRef) -> ValueRef {
|
|||||||
}
|
}
|
||||||
fn get_dataptr(bcx: @block_ctxt, vptrptr: ValueRef, unit_ty: TypeRef) ->
|
fn get_dataptr(bcx: @block_ctxt, vptrptr: ValueRef, unit_ty: TypeRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
let ptr = GEPi(bcx, Load(bcx, vptrptr), [0, abi::vec_elt_elems as int]);
|
ret get_dataptr_simple(bcx, Load(bcx, vptrptr), unit_ty);
|
||||||
|
}
|
||||||
|
fn get_dataptr_simple(bcx: @block_ctxt, vptr: ValueRef, unit_ty: TypeRef)
|
||||||
|
-> ValueRef {
|
||||||
|
let ptr = GEPi(bcx, vptr, [0, abi::vec_elt_elems as int]);
|
||||||
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +53,7 @@ type alloc_result =
|
|||||||
llunitsz: ValueRef,
|
llunitsz: ValueRef,
|
||||||
llunitty: TypeRef};
|
llunitty: TypeRef};
|
||||||
|
|
||||||
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint, dest: dest)
|
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
|
||||||
-> alloc_result {
|
|
||||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||||
let llvecty = T_vec(llunitty);
|
let llvecty = T_vec(llunitty);
|
||||||
@ -61,11 +64,8 @@ fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint, dest: dest)
|
|||||||
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
||||||
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
||||||
|
|
||||||
let vptrptr = alt dest { trans::save_in(a) { a } };
|
|
||||||
Store(bcx, vptr, vptrptr);
|
|
||||||
// add_clean_temp(bcx, vptrptr, vec_ty);
|
|
||||||
ret {bcx: bcx,
|
ret {bcx: bcx,
|
||||||
val: vptrptr,
|
val: vptr,
|
||||||
unit_ty: unit_ty,
|
unit_ty: unit_ty,
|
||||||
llunitsz: unit_sz,
|
llunitsz: unit_sz,
|
||||||
llunitty: llunitty};
|
llunitty: llunitty};
|
||||||
@ -110,16 +110,15 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
|||||||
}
|
}
|
||||||
let vec_ty = node_id_type(bcx_ccx(bcx), id);
|
let vec_ty = node_id_type(bcx_ccx(bcx), id);
|
||||||
let {bcx: bcx,
|
let {bcx: bcx,
|
||||||
val: vptrptr,
|
val: vptr,
|
||||||
llunitsz: llunitsz,
|
llunitsz: llunitsz,
|
||||||
unit_ty: unit_ty,
|
unit_ty: unit_ty,
|
||||||
llunitty: llunitty} =
|
llunitty: llunitty} =
|
||||||
alloc(bcx, vec_ty, vec::len(args), dest);
|
alloc(bcx, vec_ty, vec::len(args));
|
||||||
|
|
||||||
let vptr = Load(bcx, vptrptr);
|
|
||||||
add_clean_free(bcx, vptr, true);
|
add_clean_free(bcx, vptr, true);
|
||||||
// Store the individual elements.
|
// Store the individual elements.
|
||||||
let dataptr = get_dataptr(bcx, vptrptr, llunitty);
|
let dataptr = get_dataptr_simple(bcx, vptr, llunitty);
|
||||||
let i = 0u, temp_cleanups = [vptr];
|
let i = 0u, temp_cleanups = [vptr];
|
||||||
for e in args {
|
for e in args {
|
||||||
let lv = trans_lval(bcx, e);
|
let lv = trans_lval(bcx, e);
|
||||||
@ -133,17 +132,28 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
|||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
for clean in temp_cleanups { revoke_clean(bcx, clean); }
|
for clean in temp_cleanups { revoke_clean(bcx, clean); }
|
||||||
|
let vptrptr = alt dest {
|
||||||
|
trans::save_in(a) { a }
|
||||||
|
trans::overwrite(a, t) { bcx = trans::drop_ty(bcx, a, t); a }
|
||||||
|
};
|
||||||
|
Store(bcx, vptr, vptrptr);
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
|
fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
|
||||||
let veclen = std::str::byte_len(s) + 1u; // +1 for \0
|
let veclen = std::str::byte_len(s) + 1u; // +1 for \0
|
||||||
let {bcx: bcx, val: sptrptr, _} =
|
let {bcx: bcx, val: sptr, _} =
|
||||||
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen, dest);
|
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen);
|
||||||
|
|
||||||
let llcstr = C_cstr(bcx_ccx(bcx), s);
|
let llcstr = C_cstr(bcx_ccx(bcx), s);
|
||||||
let bcx =
|
let bcx =
|
||||||
call_memmove(bcx, get_dataptr(bcx, sptrptr, T_i8()), llcstr,
|
call_memmove(bcx, get_dataptr_simple(bcx, sptr, T_i8()), llcstr,
|
||||||
C_uint(veclen)).bcx;
|
C_uint(veclen)).bcx;
|
||||||
|
let sptrptr = alt dest {
|
||||||
|
trans::save_in(a) { a }
|
||||||
|
trans::overwrite(a, t) { bcx = trans::drop_ty(bcx, a, t); a }
|
||||||
|
};
|
||||||
|
Store(bcx, sptr, sptrptr);
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,11 +247,9 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
|||||||
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
||||||
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);
|
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);
|
||||||
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(llunitty)));
|
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(llunitty)));
|
||||||
let new_vec_ptr_ptr = alt dest { trans::save_in(a) { a } };
|
|
||||||
Store(bcx, new_vec_ptr, new_vec_ptr_ptr);
|
|
||||||
|
|
||||||
let write_ptr_ptr =
|
let write_ptr_ptr = do_spill_noroot
|
||||||
do_spill_noroot(bcx, get_dataptr(bcx, new_vec_ptr_ptr, llunitty));
|
(bcx, get_dataptr_simple(bcx, new_vec_ptr, llunitty));
|
||||||
let copy_fn =
|
let copy_fn =
|
||||||
bind fn (bcx: @block_ctxt, addr: ValueRef, _ty: ty::t,
|
bind fn (bcx: @block_ctxt, addr: ValueRef, _ty: ty::t,
|
||||||
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
||||||
@ -259,7 +267,15 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
|||||||
}(_, _, _, write_ptr_ptr, unit_ty, llunitsz);
|
}(_, _, _, write_ptr_ptr, unit_ty, llunitsz);
|
||||||
|
|
||||||
let bcx = iter_vec_raw(bcx, lhsptr, vec_ty, lhs_fill, copy_fn);
|
let bcx = iter_vec_raw(bcx, lhsptr, vec_ty, lhs_fill, copy_fn);
|
||||||
ret iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
|
bcx = iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
|
||||||
|
alt dest {
|
||||||
|
trans::save_in(a) { Store(bcx, new_vec_ptr, a); }
|
||||||
|
trans::overwrite(a, t) {
|
||||||
|
bcx = trans::drop_ty(bcx, a, t);
|
||||||
|
Store(bcx, new_vec_ptr, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
type val_and_ty_fn = fn(@block_ctxt, ValueRef, ty::t) -> result;
|
type val_and_ty_fn = fn(@block_ctxt, ValueRef, ty::t) -> result;
|
||||||
|
Loading…
Reference in New Issue
Block a user