Skip to content

Commit 82727b9

Browse files
committed
Get explicit unique estrs working.
1 parent dea8ae4 commit 82727b9

File tree

8 files changed

+86
-29
lines changed

8 files changed

+86
-29
lines changed

src/rt/rust_upcall.cpp

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,23 +290,66 @@ upcall_shared_realloc(void *ptr, size_t size) {
290290

291291
/**********************************************************************/
292292

293-
struct s_str_new_args {
293+
struct s_str_new_uniq_args {
294294
const char *cstr;
295295
size_t len;
296296
rust_str *retval;
297297
};
298298

299299
extern "C" CDECL void
300-
upcall_s_str_new(s_str_new_args *args) {
300+
upcall_s_str_new_uniq(s_str_new_uniq_args *args) {
301301
rust_task *task = rust_get_current_task();
302302
LOG_UPCALL_ENTRY(task);
303-
args->retval = make_str(task->kernel, args->cstr, args->len, "str_new");
303+
args->retval = make_str(task->kernel, args->cstr, args->len,
304+
"str_new_uniq");
304305
}
305306

307+
extern "C" CDECL rust_str*
308+
upcall_str_new_uniq(const char *cstr, size_t len) {
309+
s_str_new_uniq_args args = { cstr, len, 0 };
310+
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_uniq);
311+
return args.retval;
312+
}
313+
314+
// FIXME: this is an old compatibility-name for upcall_str_new_uniq
315+
// can remove after next snapshot.
306316
extern "C" CDECL rust_str*
307317
upcall_str_new(const char *cstr, size_t len) {
308-
s_str_new_args args = { cstr, len, 0 };
309-
UPCALL_SWITCH_STACK(&args, upcall_s_str_new);
318+
s_str_new_uniq_args args = { cstr, len, 0 };
319+
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_uniq);
320+
return args.retval;
321+
}
322+
323+
324+
325+
struct s_str_new_shared_args {
326+
const char *cstr;
327+
size_t len;
328+
rust_opaque_box *retval;
329+
};
330+
331+
extern "C" CDECL void
332+
upcall_s_str_new_shared(s_str_new_shared_args *args) {
333+
rust_task *task = rust_get_current_task();
334+
LOG_UPCALL_ENTRY(task);
335+
336+
size_t str_fill = args->len + 1;
337+
size_t str_alloc = str_fill;
338+
args->retval = (rust_opaque_box *)
339+
task->kernel->malloc(sizeof(rust_opaque_box) +
340+
vec_size<char>(str_fill),
341+
"str_new_shared");
342+
rust_str *str = (rust_str *)box_body(args->retval);
343+
str->fill = str_fill;
344+
str->alloc = str_alloc;
345+
memcpy(&str->data, args->cstr, args->len);
346+
str->data[args->len] = '\0';
347+
}
348+
349+
extern "C" CDECL rust_opaque_box*
350+
upcall_str_new_shared(const char *cstr, size_t len) {
351+
s_str_new_shared_args args = { cstr, len, 0 };
352+
UPCALL_SWITCH_STACK(&args, upcall_s_str_new_shared);
310353
return args.retval;
311354
}
312355

src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ upcall_shared_free
7676
upcall_shared_realloc
7777
upcall_vec_grow
7878
upcall_str_new
79+
upcall_str_new_uniq
80+
upcall_str_new_shared
7981
upcall_str_concat
8082
upcall_call_shim_on_c_stack
8183
upcall_call_shim_on_rust_stack

src/rustc/back/abi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ const vec_elt_alloc: int = 1;
7171

7272
const vec_elt_elems: int = 2;
7373

74+
const slice_elt_base: int = 0;
75+
const slice_elt_len: int = 1;
76+
7477
const worst_case_glue_call_args: int = 7;
7578

7679
const abi_version: uint = 1u;

src/rustc/back/upcall.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ type upcalls =
1717
shared_realloc: ValueRef,
1818
mark: ValueRef,
1919
vec_grow: ValueRef,
20-
str_new: ValueRef,
20+
str_new_uniq: ValueRef,
21+
str_new_shared: ValueRef,
2122
str_concat: ValueRef,
2223
cmp_type: ValueRef,
2324
log_type: ValueRef,
@@ -65,8 +66,10 @@ fn declare_upcalls(targ_cfg: @session::config,
6566
d("mark", [T_ptr(T_i8())], int_t),
6667
vec_grow:
6768
dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)), int_t]),
68-
str_new:
69-
d("str_new", [T_ptr(T_i8()), int_t], T_ptr(opaque_vec_t)),
69+
str_new_uniq:
70+
d("str_new_uniq", [T_ptr(T_i8()), int_t], T_ptr(opaque_vec_t)),
71+
str_new_shared:
72+
d("str_new_shared", [T_ptr(T_i8()), int_t], T_ptr(T_i8())),
7073
str_concat:
7174
d("str_concat", [T_ptr(opaque_vec_t), T_ptr(opaque_vec_t)],
7275
T_ptr(opaque_vec_t)),

src/rustc/middle/trans/alt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn trans_opt(bcx: block, o: opt) -> opt_result {
4949
ast::expr_lit(@{node: ast::lit_str(s), _}) {
5050
let strty = ty::mk_str(bcx.tcx());
5151
let cell = empty_dest_cell();
52-
bcx = tvec::trans_str(bcx, s, by_val(cell));
52+
bcx = tvec::trans_estr(bcx, s, ast::vstore_uniq, by_val(cell));
5353
add_clean_temp(bcx, *cell, strty);
5454
ret single_result(rslt(bcx, *cell));
5555
}

src/rustc/middle/trans/base.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -673,10 +673,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
673673
let ccx = bcx.ccx();
674674
let bcx = alt ty::get(t).struct {
675675
ty::ty_box(_) | ty::ty_opaque_box |
676-
ty::ty_estr(ty::vstore_box) {
676+
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) {
677677
decr_refcnt_maybe_free(bcx, Load(bcx, v0), t)
678678
}
679-
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str {
679+
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str |
680+
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) {
680681
free_ty(bcx, Load(bcx, v0), t)
681682
}
682683
ty::ty_res(did, inner, tps) {
@@ -1328,7 +1329,7 @@ fn trans_lit(cx: block, lit: ast::lit, dest: dest) -> block {
13281329
let _icx = cx.insn_ctxt("trans_lit");
13291330
if dest == ignore { ret cx; }
13301331
alt lit.node {
1331-
ast::lit_str(s) { tvec::trans_str(cx, s, dest) }
1332+
ast::lit_str(s) { tvec::trans_estr(cx, s, ast::vstore_uniq, dest) }
13321333
_ {
13331334
store_in_dest(cx, trans_crate_lit(cx.ccx(), lit), dest)
13341335
}
@@ -2294,16 +2295,18 @@ fn trans_index(cx: block, ex: @ast::expr, base: @ast::expr,
22942295
let body = GEPi(bcx, v, [0, 0]);
22952296
(lim, body)
22962297
}
2298+
22972299
ty::ty_estr(ty::vstore_slice(_)) |
22982300
ty::ty_evec(_, ty::vstore_slice(_)) {
2299-
let body = Load(bcx, GEPi(bcx, v, [0, 0]));
2300-
let lim = Load(bcx, GEPi(bcx, v, [0, 1]));
2301+
let body = Load(bcx, GEPi(bcx, v, [0, abi::slice_elt_base]));
2302+
let lim = Load(bcx, GEPi(bcx, v, [0, abi::slice_elt_len]));
23012303
(lim, body)
23022304
}
23032305

2304-
ty::ty_estr(_) | ty::ty_evec(_, _) {
2306+
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) {
23052307
bcx.sess().unimpl(#fmt("unsupported evec/estr type trans_index"));
23062308
}
2309+
23072310
_ {
23082311
let lim = tvec::get_fill(bcx, v);
23092312
let body = tvec::get_dataptr(bcx, v, type_of(ccx, unit_ty));

src/rustc/middle/trans/tvec.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn trans_vstore(bcx: block, e: @ast::expr,
134134
v: ast::vstore, dest: dest) -> block {
135135
alt e.node {
136136
ast::expr_lit(@{node: ast::lit_str(s), span: _}) {
137-
ret trans_estr(bcx, s, v, e.span, dest);
137+
ret trans_estr(bcx, s, v, dest);
138138
}
139139
ast::expr_vec(es, mutbl) {
140140
bcx.ccx().sess.span_unimpl(e.span, "unhandled tvec::trans_vstore");
@@ -146,7 +146,7 @@ fn trans_vstore(bcx: block, e: @ast::expr,
146146
}
147147

148148
fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
149-
sp: span, dest: dest) -> block {
149+
dest: dest) -> block {
150150
let _icx = bcx.insn_ctxt("tvec::trans_estr");
151151
let ccx = bcx.ccx();
152152

@@ -165,24 +165,23 @@ fn trans_estr(bcx: block, s: str, vstore: ast::vstore,
165165
C_struct([cs, C_uint(ccx, str::len(s))])
166166
}
167167

168-
_ {
169-
bcx.ccx().sess.span_unimpl(sp, "unhandled tvec::trans_estr");
168+
ast::vstore_uniq {
169+
let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
170+
let len = C_uint(ccx, str::len(s));
171+
Call(bcx, ccx.upcalls.str_new_uniq, [cs, len])
172+
}
173+
174+
ast::vstore_box {
175+
let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
176+
let len = C_uint(ccx, str::len(s));
177+
Call(bcx, ccx.upcalls.str_new_shared, [cs, len])
170178
}
171179
};
172180

173181
#debug("trans_estr: type: %s", val_str(ccx.tn, c));
174182
base::store_in_dest(bcx, c, dest)
175183
}
176184

177-
fn trans_str(bcx: block, s: str, dest: dest) -> block {
178-
let _icx = bcx.insn_ctxt("tvec::trans_str");
179-
let ccx = bcx.ccx();
180-
let cs = PointerCast(bcx, C_cstr(ccx, s), T_ptr(T_i8()));
181-
let len = C_uint(ccx, str::len(s));
182-
let n = Call(bcx, ccx.upcalls.str_new, [cs, len]);
183-
ret base::store_in_dest(bcx, n, dest);
184-
}
185-
186185
fn trans_append(bcx: block, vec_ty: ty::t, lhsptr: ValueRef,
187186
rhs: ValueRef) -> block {
188187
let _icx = bcx.insn_ctxt("tvec::trans_append");

src/test/run-pass/estr-uniq.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// xfail-test
21
fn main() {
32
let x : str/~ = "hello"/~;
3+
let _y : str/~ = "there"/~;
4+
let mut z = "thing"/~;
5+
z = x;
6+
assert z[0] == ('h' as u8);
7+
assert z[4] == ('o' as u8);
48
}

0 commit comments

Comments
 (0)