Rip out a bunch more append code from trans.
This commit is contained in:
parent
702f0cd734
commit
9e6b43fb33
@ -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);
|
||||
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,
|
||||
op, Load(bcx, lhs_res.val), t, rhs_val, t,
|
||||
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)
|
||||
}
|
||||
|
||||
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 iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
||||
|
Loading…
Reference in New Issue
Block a user