Get explicit unique estrs working.

This commit is contained in:
Graydon Hoare 2012-04-16 16:17:51 -07:00
parent dea8ae4e6f
commit 82727b926f
8 changed files with 86 additions and 29 deletions

View file

@ -290,23 +290,66 @@ upcall_shared_realloc(void *ptr, size_t size) {
/**********************************************************************/
struct s_str_new_args {
struct s_str_new_uniq_args {
const char *cstr;
size_t len;
rust_str *retval;
};
extern "C" CDECL void
upcall_s_str_new(s_str_new_args *args) {
upcall_s_str_new_uniq(s_str_new_uniq_args *args) {
rust_task *task = rust_get_current_task();
LOG_UPCALL_ENTRY(task);
args->retval = make_str(task->kernel, args->cstr, args->len, "str_new");
args->retval = make_str(task->kernel, args->cstr, args->len,
"str_new_uniq");
}
extern "C" CDECL rust_str*
upcall_str_new_uniq(const char *cstr, size_t len) {
s_str_new_uniq_args args = { cstr, len, 0 };
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_uniq);
return args.retval;
}
// FIXME: this is an old compatibility-name for upcall_str_new_uniq
// can remove after next snapshot.
extern "C" CDECL rust_str*
upcall_str_new(const char *cstr, size_t len) {
s_str_new_args args = { cstr, len, 0 };
UPCALL_SWITCH_STACK(&args, upcall_s_str_new);
s_str_new_uniq_args args = { cstr, len, 0 };
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_uniq);
return args.retval;
}
struct s_str_new_shared_args {
const char *cstr;
size_t len;
rust_opaque_box *retval;
};
extern "C" CDECL void
upcall_s_str_new_shared(s_str_new_shared_args *args) {
rust_task *task = rust_get_current_task();
LOG_UPCALL_ENTRY(task);
size_t str_fill = args->len + 1;
size_t str_alloc = str_fill;
args->retval = (rust_opaque_box *)
task->kernel->malloc(sizeof(rust_opaque_box) +
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';
}
extern "C" CDECL rust_opaque_box*
upcall_str_new_shared(const char *cstr, size_t len) {
s_str_new_shared_args args = { cstr, len, 0 };
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_shared);
return args.retval;
}

View file

@ -76,6 +76,8 @@ upcall_shared_free
upcall_shared_realloc
upcall_vec_grow
upcall_str_new
upcall_str_new_uniq
upcall_str_new_shared
upcall_str_concat
upcall_call_shim_on_c_stack
upcall_call_shim_on_rust_stack

View file

@ -71,6 +71,9 @@ const vec_elt_alloc: int = 1;
const vec_elt_elems: int = 2;
const slice_elt_base: int = 0;
const slice_elt_len: int = 1;
const worst_case_glue_call_args: int = 7;
const abi_version: uint = 1u;

View file

@ -17,7 +17,8 @@ type upcalls =
shared_realloc: ValueRef,
mark: ValueRef,
vec_grow: ValueRef,
str_new: ValueRef,
str_new_uniq: ValueRef,
str_new_shared: ValueRef,
str_concat: ValueRef,
cmp_type: ValueRef,
log_type: ValueRef,
@ -65,8 +66,10 @@ fn declare_upcalls(targ_cfg: @session::config,
d("mark", [T_ptr(T_i8())], int_t),
vec_grow:
dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)), int_t]),
str_new:
d("str_new", [T_ptr(T_i8()), int_t], T_ptr(opaque_vec_t)),
str_new_uniq:
d("str_new_uniq", [T_ptr(T_i8()), int_t], T_ptr(opaque_vec_t)),
str_new_shared:
d("str_new_shared", [T_ptr(T_i8()), int_t], T_ptr(T_i8())),
str_concat:
d("str_concat", [T_ptr(opaque_vec_t), T_ptr(opaque_vec_t)],
T_ptr(opaque_vec_t)),

View file

@ -49,7 +49,7 @@ fn trans_opt(bcx: block, o: opt) -> opt_result {
ast::expr_lit(@{node: ast::lit_str(s), _}) {
let strty = ty::mk_str(bcx.tcx());
let cell = empty_dest_cell();
bcx = tvec::trans_str(bcx, s, by_val(cell));
bcx = tvec::trans_estr(bcx, s, ast::vstore_uniq, by_val(cell));
add_clean_temp(bcx, *cell, strty);
ret single_result(rslt(bcx, *cell));
}

View file

@ -673,10 +673,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
let ccx = bcx.ccx();
let bcx = alt ty::get(t).struct {
ty::ty_box(_) | ty::ty_opaque_box |
ty::ty_estr(ty::vstore_box) {
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) {
decr_refcnt_maybe_free(bcx, Load(bcx, v0), t)
}
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str {
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str |
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) {
free_ty(bcx, Load(bcx, v0), t)
}
ty::ty_res(did, inner, tps) {
@ -1328,7 +1329,7 @@ fn trans_lit(cx: block, lit: ast::lit, dest: dest) -> block {
let _icx = cx.insn_ctxt("trans_lit");
if dest == ignore { ret cx; }
alt lit.node {
ast::lit_str(s) { tvec::trans_str(cx, s, dest) }
ast::lit_str(s) { tvec::trans_estr(cx, s, ast::vstore_uniq, dest) }
_ {
store_in_dest(cx, trans_crate_lit(cx.ccx(), lit), dest)
}
@ -2294,16 +2295,18 @@ fn trans_index(cx: block, ex: @ast::expr, base: @ast::expr,
let body = GEPi(bcx, v, [0, 0]);
(lim, body)
}
ty::ty_estr(ty::vstore_slice(_)) |
ty::ty_evec(_, ty::vstore_slice(_)) {
let body = Load(bcx, GEPi(bcx, v, [0, 0]));
let lim = Load(bcx, GEPi(bcx, v, [0, 1]));
let body = Load(bcx, GEPi(bcx, v, [0, abi::slice_elt_base]));
let lim = Load(bcx, GEPi(bcx, v, [0, abi::slice_elt_len]));
(lim, body)
}
ty::ty_estr(_) | ty::ty_evec(_, _) {
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) {
bcx.sess().unimpl(#fmt("unsupported evec/estr type trans_index"));
}
_ {
let lim = tvec::get_fill(bcx, v);
let body = tvec::get_dataptr(bcx, v, type_of(ccx, unit_ty));

View file

@ -134,7 +134,7 @@ fn trans_vstore(bcx: block, e: @ast::expr,
v: ast::vstore, dest: dest) -> block {
alt e.node {
ast::expr_lit(@{node: ast::lit_str(s), span: _}) {
ret trans_estr(bcx, s, v, e.span, dest);
ret trans_estr(bcx, s, v, dest);
}
ast::expr_vec(es, mutbl) {
bcx.ccx().sess.span_unimpl(e.span, "unhandled tvec::trans_vstore");
@ -146,7 +146,7 @@ fn trans_vstore(bcx: block, e: @ast::expr,
}
fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
sp: span, dest: dest) -> block {
dest: dest) -> block {
let _icx = bcx.insn_ctxt("tvec::trans_estr");
let ccx = bcx.ccx();
@ -165,8 +165,16 @@ fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
C_struct([cs, C_uint(ccx, str::len(s))])
}
_ {
bcx.ccx().sess.span_unimpl(sp, "unhandled tvec::trans_estr");
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])
}
ast::vstore_box {
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_shared, [cs, len])
}
};
@ -174,15 +182,6 @@ fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
base::store_in_dest(bcx, c, dest)
}
fn trans_str(bcx: block, s: str, dest: dest) -> block {
let _icx = bcx.insn_ctxt("tvec::trans_str");
let ccx = bcx.ccx();
let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
let len = C_uint(ccx, str::len(s));
let n = Call(bcx, ccx.upcalls.str_new, [cs, len]);
ret base::store_in_dest(bcx, n, dest);
}
fn trans_append(bcx: block, vec_ty: ty::t, lhsptr: ValueRef,
rhs: ValueRef) -> block {
let _icx = bcx.insn_ctxt("tvec::trans_append");

View file

@ -1,4 +1,8 @@
// xfail-test
fn main() {
let x : str/~ = "hello"/~;
let _y : str/~ = "there"/~;
let mut z = "thing"/~;
z = x;
assert z[0] == ('h' as u8);
assert z[4] == ('o' as u8);
}