Various changes for self-describing vecs
This commit is contained in:
parent
846dfbc922
commit
09a1b94907
@ -13,7 +13,7 @@ command_line_args : public kernel_owned<command_line_args>
|
||||
char **argv;
|
||||
|
||||
// [str] passed to rust_task::start.
|
||||
rust_vec *args;
|
||||
rust_vec_box *args;
|
||||
|
||||
command_line_args(rust_task *task,
|
||||
int sys_argc,
|
||||
@ -47,7 +47,7 @@ command_line_args : public kernel_owned<command_line_args>
|
||||
|
||||
~command_line_args() {
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
rust_vec *s = ((rust_vec**)&args->data)[i];
|
||||
rust_vec *s = ((rust_vec**)&args->body.data)[i];
|
||||
kernel->free(s);
|
||||
}
|
||||
kernel->free(args);
|
||||
|
@ -85,7 +85,7 @@ rust_getcwd() {
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
extern "C" CDECL rust_vec *
|
||||
extern "C" CDECL rust_vec_box *
|
||||
rust_env_pairs() {
|
||||
rust_task *task = rust_get_current_task();
|
||||
size_t envc = 0;
|
||||
@ -102,7 +102,7 @@ rust_env_pairs() {
|
||||
for (size_t i = 0; i < envc; ++i) {
|
||||
size_t n = strlen(c);
|
||||
rust_str *str = make_str(task->kernel, c, n, "str");
|
||||
((rust_str**)&v->data)[i] = str;
|
||||
((rust_str**)&v->body.data)[i] = str;
|
||||
c += n + 1;
|
||||
}
|
||||
if (ch) {
|
||||
@ -111,7 +111,7 @@ rust_env_pairs() {
|
||||
return v;
|
||||
}
|
||||
#else
|
||||
extern "C" CDECL rust_vec *
|
||||
extern "C" CDECL rust_vec_box *
|
||||
rust_env_pairs() {
|
||||
rust_task *task = rust_get_current_task();
|
||||
#ifdef __APPLE__
|
||||
@ -140,14 +140,14 @@ unsupervise() {
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
vec_reserve_shared(type_desc* ty, rust_vec** vp,
|
||||
vec_reserve_shared(type_desc* ty, rust_vec_box** vp,
|
||||
size_t n_elts) {
|
||||
rust_task *task = rust_get_current_task();
|
||||
reserve_vec_exact(task, vp, n_elts * ty->size);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
str_reserve_shared(rust_vec** sp,
|
||||
str_reserve_shared(rust_vec_box** sp,
|
||||
size_t n_elts) {
|
||||
rust_task *task = rust_get_current_task();
|
||||
reserve_vec_exact(task, sp, n_elts + 1);
|
||||
@ -169,13 +169,13 @@ vec_from_buf_shared(type_desc *ty, void *ptr, size_t count) {
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
rust_str_push(rust_vec** sp, uint8_t byte) {
|
||||
rust_str_push(rust_vec_box** sp, uint8_t byte) {
|
||||
rust_task *task = rust_get_current_task();
|
||||
size_t fill = (*sp)->fill;
|
||||
size_t fill = (*sp)->body.fill;
|
||||
reserve_vec(task, sp, fill + 1);
|
||||
(*sp)->data[fill-1] = byte;
|
||||
(*sp)->data[fill] = 0;
|
||||
(*sp)->fill = fill + 1;
|
||||
(*sp)->body.data[fill-1] = byte;
|
||||
(*sp)->body.data[fill] = 0;
|
||||
(*sp)->body.fill = fill + 1;
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_vec*
|
||||
@ -373,7 +373,7 @@ rust_list_files(rust_str *path) {
|
||||
array_list<rust_str*> strings;
|
||||
#if defined(__WIN32__)
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind = FindFirstFile((char*)path->data, &FindFileData);
|
||||
HANDLE hFind = FindFirstFile((char*)path->body.data, &FindFileData);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
rust_str *str = make_str(task->kernel, FindFileData.cFileName,
|
||||
@ -384,13 +384,13 @@ rust_list_files(rust_str *path) {
|
||||
FindClose(hFind);
|
||||
}
|
||||
#else
|
||||
DIR *dirp = opendir((char*)path->data);
|
||||
DIR *dirp = opendir((char*)path->body.data);
|
||||
if (dirp) {
|
||||
struct dirent *dp;
|
||||
while ((dp = readdir(dirp))) {
|
||||
rust_vec *str = make_str(task->kernel, dp->d_name,
|
||||
strlen(dp->d_name),
|
||||
"list_files_str");
|
||||
rust_vec_box *str = make_str(task->kernel, dp->d_name,
|
||||
strlen(dp->d_name),
|
||||
"list_files_str");
|
||||
strings.push(str);
|
||||
}
|
||||
closedir(dirp);
|
||||
@ -520,9 +520,9 @@ void tm_to_rust_tm(tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
|
||||
if (zone != NULL) {
|
||||
size_t size = strlen(zone);
|
||||
str_reserve_shared(&out_tm->tm_zone, size);
|
||||
memcpy(out_tm->tm_zone->data, zone, size);
|
||||
out_tm->tm_zone->fill = size + 1;
|
||||
out_tm->tm_zone->data[size] = '\0';
|
||||
memcpy(out_tm->tm_zone->body.data, zone, size);
|
||||
out_tm->tm_zone->body.fill = size + 1;
|
||||
out_tm->tm_zone->body.data[size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1110,9 +1110,9 @@ data<T,U>::walk_variant1(tag_info &tinfo, tag_variant_t variant_id) {
|
||||
template<typename T,typename U>
|
||||
std::pair<uint8_t *,uint8_t *>
|
||||
data<T,U>::get_vec_data_range(ptr dp) {
|
||||
rust_vec* ptr = bump_dp<rust_vec*>(dp);
|
||||
uint8_t* data = &ptr->data[0];
|
||||
return std::make_pair(data, data + ptr->fill);
|
||||
rust_vec_box* ptr = bump_dp<rust_vec_box*>(dp);
|
||||
uint8_t* data = &ptr->body.data[0];
|
||||
return std::make_pair(data, data + ptr->body.fill);
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
|
@ -445,10 +445,10 @@ upcall_s_str_new_shared(s_str_new_shared_args *args) {
|
||||
vec_size<char>(str_fill),
|
||||
"str_new_shared");
|
||||
rust_str *str = (rust_str *)box_body(args->retval);
|
||||
str->fill = str_fill;
|
||||
str->alloc = str_alloc;
|
||||
memcpy(&str->data, args->cstr, args->len);
|
||||
str->data[args->len] = '\0';
|
||||
str->body.fill = str_fill;
|
||||
str->body.alloc = str_alloc;
|
||||
memcpy(&str->body.data, args->cstr, args->len);
|
||||
str->body.data[args->len] = '\0';
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_opaque_box*
|
||||
@ -460,7 +460,7 @@ upcall_str_new_shared(const char *cstr, size_t len) {
|
||||
|
||||
|
||||
struct s_vec_grow_args {
|
||||
rust_vec** vp;
|
||||
rust_vec_box** vp;
|
||||
size_t new_sz;
|
||||
};
|
||||
|
||||
@ -469,37 +469,38 @@ upcall_s_vec_grow(s_vec_grow_args *args) {
|
||||
rust_task *task = rust_get_current_task();
|
||||
LOG_UPCALL_ENTRY(task);
|
||||
reserve_vec(task, args->vp, args->new_sz);
|
||||
(*args->vp)->fill = args->new_sz;
|
||||
(*args->vp)->body.fill = args->new_sz;
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
upcall_vec_grow(rust_vec** vp, size_t new_sz) {
|
||||
upcall_vec_grow(rust_vec_box** vp, size_t new_sz) {
|
||||
s_vec_grow_args args = {vp, new_sz};
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow);
|
||||
}
|
||||
|
||||
struct s_str_concat_args {
|
||||
rust_vec* lhs;
|
||||
rust_vec* rhs;
|
||||
rust_vec* retval;
|
||||
rust_vec_box* lhs;
|
||||
rust_vec_box* rhs;
|
||||
rust_vec_box* retval;
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
upcall_s_str_concat(s_str_concat_args *args) {
|
||||
rust_vec *lhs = args->lhs;
|
||||
rust_vec *rhs = args->rhs;
|
||||
rust_vec *lhs = &args->lhs->body;
|
||||
rust_vec *rhs = &args->rhs->body;
|
||||
rust_task *task = rust_get_current_task();
|
||||
size_t fill = lhs->fill + rhs->fill - 1;
|
||||
rust_vec* v = (rust_vec*)task->kernel->malloc(fill + sizeof(rust_vec),
|
||||
"str_concat");
|
||||
v->fill = v->alloc = fill;
|
||||
memmove(&v->data[0], &lhs->data[0], lhs->fill - 1);
|
||||
memmove(&v->data[lhs->fill - 1], &rhs->data[0], rhs->fill);
|
||||
rust_vec_box* v = (rust_vec_box*)
|
||||
task->kernel->malloc(fill + sizeof(rust_vec_box),
|
||||
"str_concat");
|
||||
v->body.fill = v->body.alloc = fill;
|
||||
memmove(&v->body.data[0], &lhs->data[0], lhs->fill - 1);
|
||||
memmove(&v->body.data[lhs->fill - 1], &rhs->data[0], rhs->fill);
|
||||
args->retval = v;
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_vec*
|
||||
upcall_str_concat(rust_vec* lhs, rust_vec* rhs) {
|
||||
extern "C" CDECL rust_vec_box*
|
||||
upcall_str_concat(rust_vec_box* lhs, rust_vec_box* rhs) {
|
||||
s_str_concat_args args = {lhs, rhs, 0};
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_str_concat);
|
||||
return args.retval;
|
||||
|
@ -42,9 +42,16 @@ rust_vec
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
struct
|
||||
rust_vec_box
|
||||
{
|
||||
rust_opaque_box header;
|
||||
rust_vec body;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline size_t vec_size(size_t elems) {
|
||||
return sizeof(rust_vec) + sizeof(T) * elems;
|
||||
return sizeof(rust_vec_box) + sizeof(T) * elems;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -53,19 +60,20 @@ vec_data(rust_vec *v) {
|
||||
return reinterpret_cast<T*>(v->data);
|
||||
}
|
||||
|
||||
inline void reserve_vec_exact(rust_task* task, rust_vec** vpp, size_t size) {
|
||||
if (size > (*vpp)->alloc) {
|
||||
*vpp = (rust_vec*)task->kernel
|
||||
->realloc(*vpp, size + sizeof(rust_vec));
|
||||
(*vpp)->alloc = size;
|
||||
inline void reserve_vec_exact(rust_task* task, rust_vec_box** vpp,
|
||||
size_t size) {
|
||||
if (size > (*vpp)->body.alloc) {
|
||||
*vpp = (rust_vec_box*)task->kernel
|
||||
->realloc(*vpp, size + sizeof(rust_vec_box));
|
||||
(*vpp)->body.alloc = size;
|
||||
}
|
||||
}
|
||||
|
||||
inline void reserve_vec(rust_task* task, rust_vec** vpp, size_t size) {
|
||||
inline void reserve_vec(rust_task* task, rust_vec_box** vpp, size_t size) {
|
||||
reserve_vec_exact(task, vpp, next_power_of_two(size));
|
||||
}
|
||||
|
||||
typedef rust_vec rust_str;
|
||||
typedef rust_vec_box rust_str;
|
||||
|
||||
inline rust_str *
|
||||
make_str(rust_kernel* kernel, const char* c, size_t strlen,
|
||||
@ -74,24 +82,24 @@ make_str(rust_kernel* kernel, const char* c, size_t strlen,
|
||||
size_t str_alloc = str_fill;
|
||||
rust_str *str = (rust_str *)
|
||||
kernel->malloc(vec_size<char>(str_fill), name);
|
||||
str->fill = str_fill;
|
||||
str->alloc = str_alloc;
|
||||
memcpy(&str->data, c, strlen);
|
||||
str->data[strlen] = '\0';
|
||||
str->body.fill = str_fill;
|
||||
str->body.alloc = str_alloc;
|
||||
memcpy(&str->body.data, c, strlen);
|
||||
str->body.data[strlen] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
inline rust_vec *
|
||||
inline rust_vec_box *
|
||||
make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) {
|
||||
rust_vec *v = (rust_vec *)
|
||||
kernel->malloc(vec_size<rust_vec*>(nstrs),
|
||||
rust_vec_box *v = (rust_vec_box *)
|
||||
kernel->malloc(vec_size<rust_vec_box*>(nstrs),
|
||||
"str vec interior");
|
||||
v->fill = v->alloc = sizeof(rust_vec*) * nstrs;
|
||||
v->body.fill = v->body.alloc = sizeof(rust_vec_box*) * nstrs;
|
||||
for (size_t i = 0; i < nstrs; ++i) {
|
||||
rust_str *str = make_str(kernel, strs[i],
|
||||
strlen(strs[i]),
|
||||
"str");
|
||||
((rust_str**)&v->data)[i] = str;
|
||||
((rust_str**)&v->body.data)[i] = str;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ import driver::session;
|
||||
import middle::trans::base;
|
||||
import middle::trans::common::{T_fn, T_i1, T_i8, T_i32,
|
||||
T_int, T_nil,
|
||||
T_opaque_vec, T_ptr,
|
||||
T_size_t, T_void};
|
||||
T_opaque_vec, T_ptr, T_unique_ptr,
|
||||
T_size_t, T_void, T_vec2};
|
||||
import lib::llvm::{type_names, ModuleRef, ValueRef, TypeRef};
|
||||
|
||||
type upcalls =
|
||||
@ -13,6 +13,7 @@ type upcalls =
|
||||
malloc: ValueRef,
|
||||
free: ValueRef,
|
||||
exchange_malloc: ValueRef,
|
||||
exchange_malloc_dyn: ValueRef,
|
||||
exchange_free: ValueRef,
|
||||
validate_box: ValueRef,
|
||||
shared_malloc: ValueRef,
|
||||
@ -51,7 +52,6 @@ fn declare_upcalls(targ_cfg: @session::config,
|
||||
|
||||
let int_t = T_int(targ_cfg);
|
||||
let size_t = T_size_t(targ_cfg);
|
||||
let opaque_vec_t = T_opaque_vec(targ_cfg);
|
||||
|
||||
ret @{_fail: dv("fail", [T_ptr(T_i8()),
|
||||
T_ptr(T_i8()),
|
||||
@ -67,6 +67,10 @@ fn declare_upcalls(targ_cfg: @session::config,
|
||||
exchange_malloc:
|
||||
nothrow(d("exchange_malloc", [T_ptr(tydesc_type)],
|
||||
T_ptr(T_i8()))),
|
||||
exchange_malloc_dyn:
|
||||
nothrow(d("exchange_malloc_dyn",
|
||||
[T_ptr(tydesc_type), int_t],
|
||||
T_ptr(T_i8()))),
|
||||
exchange_free:
|
||||
nothrow(dv("exchange_free", [T_ptr(T_i8())])),
|
||||
validate_box:
|
||||
@ -81,17 +85,17 @@ fn declare_upcalls(targ_cfg: @session::config,
|
||||
mark:
|
||||
d("mark", [T_ptr(T_i8())], int_t),
|
||||
vec_grow:
|
||||
nothrow(dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)), int_t])),
|
||||
nothrow(dv("vec_grow", [T_ptr(T_ptr(T_i8())), int_t])),
|
||||
str_new_uniq:
|
||||
nothrow(d("str_new_uniq", [T_ptr(T_i8()), int_t],
|
||||
T_ptr(opaque_vec_t))),
|
||||
T_ptr(T_i8()))),
|
||||
str_new_shared:
|
||||
nothrow(d("str_new_shared", [T_ptr(T_i8()), int_t],
|
||||
T_ptr(T_i8()))),
|
||||
str_concat:
|
||||
nothrow(d("str_concat", [T_ptr(opaque_vec_t),
|
||||
T_ptr(opaque_vec_t)],
|
||||
T_ptr(opaque_vec_t))),
|
||||
nothrow(d("str_concat", [T_ptr(T_i8()),
|
||||
T_ptr(T_i8())],
|
||||
T_ptr(T_i8()))),
|
||||
cmp_type:
|
||||
dv("cmp_type",
|
||||
[T_ptr(T_i1()), T_ptr(tydesc_type),
|
||||
|
@ -417,6 +417,33 @@ fn malloc_unique(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
|
||||
ret {box: box, body: body};
|
||||
}
|
||||
|
||||
fn malloc_unique_dyn_raw(bcx: block, t: ty::t, size: ValueRef) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("malloc_unique_box_raw");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
// Grab the TypeRef type of box_ptr, because that's what trans_raw_malloc
|
||||
// wants.
|
||||
let box_ptr = ty::mk_imm_uniq(ccx.tcx, t);
|
||||
let llty = type_of(ccx, box_ptr);
|
||||
|
||||
// Get the tydesc for the body:
|
||||
let mut static_ti = none;
|
||||
let lltydesc = get_tydesc(ccx, t, static_ti);
|
||||
lazily_emit_all_tydesc_glue(ccx, static_ti);
|
||||
|
||||
// Allocate space:
|
||||
let rval = Call(bcx, ccx.upcalls.exchange_malloc_dyn, [lltydesc, size]);
|
||||
ret PointerCast(bcx, rval, llty);
|
||||
}
|
||||
|
||||
fn malloc_unique_dyn(bcx: block, t: ty::t, size: ValueRef
|
||||
) -> {box: ValueRef, body: ValueRef} {
|
||||
let _icx = bcx.insn_ctxt("malloc_unique_box");
|
||||
let box = malloc_unique_dyn_raw(bcx, t, size);
|
||||
let body = GEPi(bcx, box, [0u, abi::box_field_body]);
|
||||
ret {box: box, body: body};
|
||||
}
|
||||
|
||||
// Type descriptor and type glue stuff
|
||||
|
||||
fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef {
|
||||
@ -560,7 +587,9 @@ fn make_generic_glue_inner(ccx: @crate_ctxt, t: ty::t,
|
||||
// the caller has no idea if it's dealing with something that can be
|
||||
// passed by value.
|
||||
|
||||
#error("%?", ty::get(t));
|
||||
let llty = T_ptr(type_of(ccx, t));
|
||||
#error("%?", ty_str(ccx.tn, llty));
|
||||
|
||||
let bcx = top_scope_block(fcx, none);
|
||||
let lltop = bcx.llbb;
|
||||
|
@ -21,6 +21,24 @@ fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) {
|
||||
fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc]))
|
||||
}
|
||||
|
||||
fn get_bodyptr(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> ValueRef {
|
||||
let ccx = bcx.ccx();
|
||||
alt ty::get(vec_ty).struct {
|
||||
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq)
|
||||
| ty::ty_vec(_) | ty::ty_str {
|
||||
let boxptr = PointerCast(bcx, vptr, T_ptr(T_box_header(ccx)));
|
||||
let bodyptr = GEPi(bcx, boxptr, [1u]);
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
let llunit_ty = type_of::type_of(ccx, unit_ty);
|
||||
PointerCast(bcx, bodyptr, T_ptr(T_vec(ccx, llunit_ty)))
|
||||
}
|
||||
_ {
|
||||
vptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dataptr(bcx: block, vptr: ValueRef, unit_ty: TypeRef)
|
||||
-> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("tvec::get_dataptr");
|
||||
@ -35,41 +53,55 @@ fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
||||
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
|
||||
}
|
||||
|
||||
fn alloc_uniq_raw(bcx: block, fill: ValueRef, alloc: ValueRef) -> result {
|
||||
fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
|
||||
fill: ValueRef, alloc: ValueRef) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq_raw");
|
||||
let ccx = bcx.ccx();
|
||||
let llvecty = ccx.opaque_vec_type;
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
let llvecty = T_vec(ccx, llunitty);
|
||||
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
|
||||
let vecptr = shared_malloc(bcx, T_ptr(llvecty), vecsize);
|
||||
Store(bcx, fill, GEPi(bcx, vecptr, [0u, abi::vec_elt_fill]));
|
||||
Store(bcx, alloc, GEPi(bcx, vecptr, [0u, abi::vec_elt_alloc]));
|
||||
ret {bcx: bcx, val: vecptr};
|
||||
let vecbodyty = unit_ty; // FIXME: This is not the correct type
|
||||
let {box, body} = base::malloc_unique_dyn(bcx, vecbodyty, vecsize);
|
||||
let boxptr = PointerCast(bcx, box,
|
||||
T_unique_ptr(T_unique(bcx.ccx(), llvecty)));
|
||||
let bodyptr = PointerCast(bcx, body, T_ptr(llvecty));
|
||||
Store(bcx, fill, GEPi(bcx, bodyptr, [0u, abi::vec_elt_fill]));
|
||||
Store(bcx, alloc, GEPi(bcx, bodyptr, [0u, abi::vec_elt_alloc]));
|
||||
ret {bcx: bcx, val: boxptr};
|
||||
}
|
||||
|
||||
fn alloc_uniq(bcx: block, llunitty: TypeRef, elts: uint) -> result {
|
||||
fn alloc_uniq(bcx: block, unit_ty: ty::t, elts: uint) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
let llvecty = T_vec(ccx, llunitty);
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
let unit_sz = llsize_of(ccx, llunitty);
|
||||
|
||||
let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
|
||||
let alloc = if elts < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
|
||||
else { fill };
|
||||
let {bcx: bcx, val: vptr} = alloc_uniq_raw(bcx, fill, alloc);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
||||
|
||||
let {bcx: bcx, val: vptr} = alloc_uniq_raw(bcx, unit_ty, fill, alloc);
|
||||
ret {bcx: bcx, val: vptr};
|
||||
}
|
||||
|
||||
fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||
let _icx = bcx.insn_ctxt("tvec::duplicate_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
let fill = get_fill(bcx, vptr);
|
||||
let body_ptr = get_bodyptr(bcx, vptr, vec_ty);
|
||||
let fill = get_fill(bcx, body_ptr);
|
||||
let size = Add(bcx, fill, llsize_of(ccx, ccx.opaque_vec_type));
|
||||
let newptr = shared_malloc(bcx, val_ty(vptr), size);
|
||||
call_memmove(bcx, newptr, vptr, size);
|
||||
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
Store(bcx, fill, GEPi(bcx, newptr, [0u, abi::vec_elt_alloc]));
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
let llvecty = T_vec(ccx, llunitty);
|
||||
let vecbodyty = unit_ty; // FIXME: This is not the correct type
|
||||
let {box: newptr, body: new_body_ptr} =
|
||||
base::malloc_unique_dyn(bcx, vecbodyty, size);
|
||||
let newptr = PointerCast(bcx, newptr,
|
||||
T_unique_ptr(T_unique(bcx.ccx(), llvecty)));
|
||||
let new_body_ptr = PointerCast(bcx, new_body_ptr, T_ptr(llvecty));
|
||||
call_memmove(bcx, new_body_ptr, body_ptr, size);
|
||||
|
||||
Store(bcx, fill, GEPi(bcx, new_body_ptr, [0u, abi::vec_elt_alloc]));
|
||||
let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) {
|
||||
iter_vec(bcx, newptr, vec_ty, base::take_ty)
|
||||
} else { bcx };
|
||||
@ -133,9 +165,10 @@ fn trans_evec(bcx: block, args: [@ast::expr],
|
||||
{bcx: bcx, val: p, dataptr: vp}
|
||||
}
|
||||
ast::vstore_uniq {
|
||||
let {bcx, val} = alloc_uniq(bcx, llunitty, args.len());
|
||||
let {bcx, val} = alloc_uniq(bcx, unit_ty, args.len());
|
||||
add_clean_free(bcx, val, true);
|
||||
let dataptr = get_dataptr(bcx, val, llunitty);
|
||||
let body = get_bodyptr(bcx, val, vec_ty);
|
||||
let dataptr = get_dataptr(bcx, body, llunitty);
|
||||
{bcx: bcx, val: val, dataptr: dataptr}
|
||||
}
|
||||
ast::vstore_box {
|
||||
@ -216,8 +249,9 @@ fn get_base_and_len(cx: block, v: ValueRef, e_ty: ty::t)
|
||||
(base, len)
|
||||
}
|
||||
ty::vstore_uniq {
|
||||
let base = tvec::get_dataptr(cx, v, llunitty);
|
||||
let len = tvec::get_fill(cx, v);
|
||||
let body = tvec::get_bodyptr(cx, v, vec_ty);
|
||||
let base = tvec::get_dataptr(cx, body, llunitty);
|
||||
let len = tvec::get_fill(cx, body);
|
||||
(base, len)
|
||||
}
|
||||
ty::vstore_box {
|
||||
@ -249,7 +283,9 @@ fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
|
||||
ast::vstore_uniq {
|
||||
let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
|
||||
let len = C_uint(ccx, str::len(s));
|
||||
Call(bcx, ccx.upcalls.str_new_uniq, [cs, len])
|
||||
let c = Call(bcx, ccx.upcalls.str_new_uniq, [cs, len]);
|
||||
PointerCast(bcx, c,
|
||||
T_unique_ptr(T_unique(ccx, T_vec(ccx, T_i8()))))
|
||||
}
|
||||
|
||||
ast::vstore_box {
|
||||
@ -274,19 +310,23 @@ fn trans_append(bcx: block, vec_ty: ty::t, lhsptr: ValueRef,
|
||||
|
||||
let lhs = Load(bcx, lhsptr);
|
||||
let self_append = ICmp(bcx, lib::llvm::IntEQ, lhs, rhs);
|
||||
let lfill = get_fill(bcx, lhs);
|
||||
let rfill = get_fill(bcx, rhs);
|
||||
let lbody = get_bodyptr(bcx, lhs, vec_ty);
|
||||
let rbody = get_bodyptr(bcx, rhs, vec_ty);
|
||||
let lfill = get_fill(bcx, lbody);
|
||||
let rfill = get_fill(bcx, rbody);
|
||||
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(ccx.opaque_vec_type)));
|
||||
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 lhs_data = get_dataptr(bcx, lhs, llunitty);
|
||||
let lbody = get_bodyptr(bcx, lhs, vec_ty);
|
||||
|
||||
let lhs_data = get_dataptr(bcx, lbody, llunitty);
|
||||
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);
|
||||
@ -311,18 +351,18 @@ fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
let scratch = base::alloca(bcx, elt_llty);
|
||||
for vec::each(vals) {|val|
|
||||
bcx = base::trans_expr_save_in(bcx, val, scratch);
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
let vptr = get_bodyptr(bcx, Load(bcx, vptrptr), vec_ty);
|
||||
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 = base::with_cond(bcx, do_grow) {|bcx|
|
||||
let pt = PointerCast(bcx, vptrptr,
|
||||
T_ptr(T_ptr(ccx.opaque_vec_type)));
|
||||
T_ptr(T_ptr(T_i8())));
|
||||
Call(bcx, ccx.upcalls.vec_grow, [pt, new_fill]);
|
||||
bcx
|
||||
};
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
let vptr = get_bodyptr(bcx, Load(bcx, vptrptr), vec_ty);
|
||||
set_fill(bcx, vptr, new_fill);
|
||||
let targetptr = pointer_add(bcx, get_dataptr(bcx, vptr, elt_llty),
|
||||
old_fill);
|
||||
@ -336,23 +376,30 @@ fn trans_add(bcx: block, vec_ty: ty::t, lhs: ValueRef,
|
||||
let _icx = bcx.insn_ctxt("tvec::trans_add");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
if ty::get(vec_ty).struct == ty::ty_str {
|
||||
let n = Call(bcx, ccx.upcalls.str_concat, [lhs, rhs]);
|
||||
ret base::store_in_dest(bcx, n, dest);
|
||||
}
|
||||
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
|
||||
let lhs_fill = get_fill(bcx, lhs);
|
||||
let rhs_fill = get_fill(bcx, rhs);
|
||||
if ty::get(vec_ty).struct == ty::ty_str {
|
||||
let lhs = PointerCast(bcx, lhs, T_ptr(T_i8()));
|
||||
let rhs = PointerCast(bcx, rhs, T_ptr(T_i8()));
|
||||
let n = Call(bcx, ccx.upcalls.str_concat, [lhs, rhs]);
|
||||
let n = PointerCast(
|
||||
bcx, n, T_unique_ptr(T_unique(ccx, T_vec(ccx, llunitty))));
|
||||
ret base::store_in_dest(bcx, n, dest);
|
||||
}
|
||||
|
||||
let lhs_body = get_bodyptr(bcx, lhs, vec_ty);
|
||||
let rhs_body = get_bodyptr(bcx, rhs, vec_ty);
|
||||
|
||||
let lhs_fill = get_fill(bcx, lhs_body);
|
||||
let rhs_fill = get_fill(bcx, rhs_body);
|
||||
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
||||
let mut {bcx: bcx, val: new_vec_ptr} =
|
||||
alloc_uniq_raw(bcx, new_fill, new_fill);
|
||||
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(ccx, llunitty)));
|
||||
alloc_uniq_raw(bcx, unit_ty, new_fill, new_fill);
|
||||
|
||||
let new_vec_body_ptr = get_bodyptr(bcx, new_vec_ptr, vec_ty);
|
||||
let write_ptr_ptr = do_spill_noroot
|
||||
(bcx, get_dataptr(bcx, new_vec_ptr, llunitty));
|
||||
(bcx, get_dataptr(bcx, new_vec_body_ptr, llunitty));
|
||||
let copy_fn = fn@(bcx: block, addr: ValueRef,
|
||||
_ty: ty::t) -> block {
|
||||
let ccx = bcx.ccx();
|
||||
@ -408,16 +455,17 @@ fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||
let ccx = bcx.ccx();
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(T_vec(ccx, llunitty)));
|
||||
let data_ptr = get_dataptr(bcx, vptr, llunitty);
|
||||
let body_ptr = get_bodyptr(bcx, vptr, vec_ty);
|
||||
let data_ptr = get_dataptr(bcx, body_ptr, llunitty);
|
||||
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
|
||||
}
|
||||
|
||||
fn iter_vec(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||
f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec");
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(bcx.ccx().opaque_vec_type));
|
||||
ret iter_vec_uniq(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
||||
let body_ptr = get_bodyptr(bcx, vptr, vec_ty);
|
||||
let fill = get_fill(bcx, body_ptr);
|
||||
ret iter_vec_uniq(bcx, vptr, vec_ty, fill, f);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -85,7 +85,9 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
ty::ty_uint(t) { T_uint_ty(cx, t) }
|
||||
ty::ty_float(t) { T_float_ty(cx, t) }
|
||||
ty::ty_estr(ty::vstore_uniq) |
|
||||
ty::ty_str { T_ptr(T_vec(cx, T_i8())) }
|
||||
ty::ty_str {
|
||||
T_unique_ptr(T_unique(cx, T_vec(cx, T_i8())))
|
||||
}
|
||||
ty::ty_enum(did, _) { type_of_enum(cx, did, t) }
|
||||
ty::ty_estr(ty::vstore_box) { T_box_ptr(T_box(cx, T_i8())) }
|
||||
ty::ty_evec(mt, ty::vstore_box) |
|
||||
@ -93,7 +95,9 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
ty::ty_opaque_box { T_box_ptr(T_box(cx, T_i8())) }
|
||||
ty::ty_uniq(mt) { T_unique_ptr(T_unique(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_evec(mt, ty::vstore_uniq) |
|
||||
ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_vec(mt) {
|
||||
T_unique_ptr(T_unique(cx, T_vec(cx, type_of(cx, mt.ty))))
|
||||
}
|
||||
ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) }
|
||||
ty::ty_rptr(_, mt) { T_ptr(type_of(cx, mt.ty)) }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user