Rip out a bunch more append code from trans.
This commit is contained in:
@@ -1755,28 +1755,7 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
|
|||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for `+= ~[x]`
|
|
||||||
alt ty::get(t).struct {
|
|
||||||
ty::ty_vec(_) {
|
|
||||||
alt src.node {
|
|
||||||
ast::expr_vec(args, _) {
|
|
||||||
ret tvec::trans_append_literal(lhs_res.bcx,
|
|
||||||
lhs_res.val, t, args);
|
|
||||||
}
|
|
||||||
_ { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ { }
|
|
||||||
}
|
|
||||||
let {bcx, val: rhs_val} = trans_temp_expr(lhs_res.bcx, src);
|
let {bcx, val: rhs_val} = trans_temp_expr(lhs_res.bcx, src);
|
||||||
if ty::type_is_sequence(t) {
|
|
||||||
alt op {
|
|
||||||
ast::add {
|
|
||||||
ret tvec::trans_append(bcx, t, lhs_res.val, rhs_val);
|
|
||||||
}
|
|
||||||
_ { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret trans_eager_binop(bcx, ex.span,
|
ret trans_eager_binop(bcx, ex.span,
|
||||||
op, Load(bcx, lhs_res.val), t, rhs_val, t,
|
op, Load(bcx, lhs_res.val), t, rhs_val, t,
|
||||||
save_in(lhs_res.val));
|
save_in(lhs_res.val));
|
||||||
|
|||||||
@@ -306,75 +306,6 @@ fn trans_estr(bcx: block, s: @str, vstore: ast::vstore,
|
|||||||
base::store_in_dest(bcx, c, dest)
|
base::store_in_dest(bcx, c, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_append(bcx: block, vec_ty: ty::t, lhsptr: ValueRef,
|
|
||||||
rhs: ValueRef) -> block {
|
|
||||||
let _icx = bcx.insn_ctxt("tvec::trans_append");
|
|
||||||
// Cast to opaque interior vector types if necessary.
|
|
||||||
let ccx = bcx.ccx();
|
|
||||||
let unit_ty = ty::sequence_element_type(ccx.tcx, vec_ty);
|
|
||||||
let strings = ty::type_is_str(vec_ty);
|
|
||||||
|
|
||||||
let lhs = Load(bcx, lhsptr);
|
|
||||||
let self_append = ICmp(bcx, lib::llvm::IntEQ, lhs, rhs);
|
|
||||||
let lfill = get_fill(bcx, get_bodyptr(bcx, lhs));
|
|
||||||
let rfill = get_fill(bcx, get_bodyptr(bcx, rhs));
|
|
||||||
let mut new_fill = Add(bcx, lfill, rfill);
|
|
||||||
if strings { new_fill = Sub(bcx, new_fill, C_int(ccx, 1)); }
|
|
||||||
let opaque_lhs = PointerCast(bcx, lhsptr,
|
|
||||||
T_ptr(T_ptr(T_i8())));
|
|
||||||
Call(bcx, ccx.upcalls.vec_grow,
|
|
||||||
~[opaque_lhs, new_fill]);
|
|
||||||
// Was overwritten if we resized
|
|
||||||
let lhs = Load(bcx, lhsptr);
|
|
||||||
let rhs = Select(bcx, self_append, lhs, rhs);
|
|
||||||
|
|
||||||
let lbody = get_bodyptr(bcx, lhs);
|
|
||||||
|
|
||||||
let lhs_data = get_dataptr(bcx, lbody);
|
|
||||||
let mut lhs_off = lfill;
|
|
||||||
if strings { lhs_off = Sub(bcx, lhs_off, C_int(ccx, 1)); }
|
|
||||||
let write_ptr = pointer_add(bcx, lhs_data, lhs_off);
|
|
||||||
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
|
|
||||||
iter_vec_uniq(bcx, rhs, vec_ty, rfill, |bcx, addr, _ty| {
|
|
||||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
|
||||||
let bcx = copy_val(bcx, INIT, write_ptr,
|
|
||||||
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
|
||||||
Store(bcx, InBoundsGEP(bcx, write_ptr, ~[C_int(ccx, 1)]),
|
|
||||||
write_ptr_ptr);
|
|
||||||
bcx
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t,
|
|
||||||
vals: ~[@ast::expr]) -> block {
|
|
||||||
let _icx = bcx.insn_ctxt("tvec::trans_append_literal");
|
|
||||||
let mut bcx = bcx, ccx = bcx.ccx();
|
|
||||||
let elt_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
|
||||||
let elt_llty = type_of::type_of(ccx, elt_ty);
|
|
||||||
let elt_sz = shape::llsize_of(ccx, elt_llty);
|
|
||||||
let scratch = base::alloca(bcx, elt_llty);
|
|
||||||
for vec::each(vals) |val| {
|
|
||||||
bcx = base::trans_expr_save_in(bcx, val, scratch);
|
|
||||||
let vptr = get_bodyptr(bcx, Load(bcx, vptrptr));
|
|
||||||
let old_fill = get_fill(bcx, vptr);
|
|
||||||
let new_fill = Add(bcx, old_fill, elt_sz);
|
|
||||||
let do_grow = ICmp(bcx, lib::llvm::IntUGT, new_fill,
|
|
||||||
get_alloc(bcx, vptr));
|
|
||||||
bcx = do base::with_cond(bcx, do_grow) |bcx| {
|
|
||||||
let pt = PointerCast(bcx, vptrptr,
|
|
||||||
T_ptr(T_ptr(T_i8())));
|
|
||||||
Call(bcx, ccx.upcalls.vec_grow, ~[pt, new_fill]);
|
|
||||||
bcx
|
|
||||||
};
|
|
||||||
let vptr = get_bodyptr(bcx, Load(bcx, vptrptr));
|
|
||||||
set_fill(bcx, vptr, new_fill);
|
|
||||||
let targetptr = pointer_add(bcx, get_dataptr(bcx, vptr),
|
|
||||||
old_fill);
|
|
||||||
call_memmove(bcx, targetptr, scratch, elt_sz);
|
|
||||||
}
|
|
||||||
bcx
|
|
||||||
}
|
|
||||||
|
|
||||||
type val_and_ty_fn = fn@(block, ValueRef, ty::t) -> result;
|
type val_and_ty_fn = fn@(block, ValueRef, ty::t) -> result;
|
||||||
|
|
||||||
type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
||||||
|
|||||||
Reference in New Issue
Block a user