Skip to content

Commit a2dcd08

Browse files
author
Eric Holk
committed
Added string duplication to deep_copy. Closes #520.
1 parent c051501 commit a2dcd08

File tree

6 files changed

+59
-25
lines changed

6 files changed

+59
-25
lines changed

src/comp/back/upcall.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type upcalls =
4949
ValueRef free,
5050
ValueRef mark,
5151
ValueRef new_str,
52+
ValueRef dup_str,
5253
ValueRef new_vec,
5354
ValueRef vec_append,
5455
ValueRef get_type_desc,
@@ -101,6 +102,8 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls {
101102
mark=d("mark", [T_ptr(T_i8())], T_int()),
102103
new_str=d("new_str", [T_ptr(T_i8()), T_size_t()],
103104
T_ptr(T_str())),
105+
dup_str=d("dup_str", [T_ptr(T_str())],
106+
T_ptr(T_str())),
104107
new_vec=d("new_vec", [T_size_t(), T_ptr(T_tydesc(tn))],
105108
T_opaque_vec_ptr()),
106109
vec_append=d("vec_append",

src/comp/middle/trans.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6340,28 +6340,13 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
63406340
if(ty::type_is_scalar(tcx, t)) {
63416341
ret res(bcx, v);
63426342
}
6343+
else if(ty::type_is_str(tcx, t)) {
6344+
ret res(bcx,
6345+
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str,
6346+
[bcx.fcx.lltaskptr, v]));
6347+
}
63436348
else if(ty::type_is_chan(tcx, t)) {
63446349
// If this is a channel, we need to clone it.
6345-
/*
6346-
log_err "Generating clone call for channel argument.";
6347-
6348-
log_err #fmt("ty(clone_chan) = %s",
6349-
val_str(bcx.fcx.lcx.ccx.tn,
6350-
bcx.fcx.lcx.ccx.upcalls.clone_chan));
6351-
6352-
log_err #fmt("ty(lltaskptr) = %s",
6353-
val_str(bcx.fcx.lcx.ccx.tn,
6354-
bcx.fcx.lltaskptr));
6355-
6356-
log_err #fmt("ty(target_task) = %s",
6357-
val_str(bcx.fcx.lcx.ccx.tn,
6358-
target_task));
6359-
6360-
log_err #fmt("ty(chan) = %s",
6361-
val_str(bcx.fcx.lcx.ccx.tn,
6362-
v));
6363-
*/
6364-
63656350
auto chan_ptr = bcx.build.PointerCast(v, T_opaque_chan_ptr());
63666351

63676352
auto chan_raw_val =
@@ -6386,8 +6371,8 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
63866371
}
63876372
else {
63886373
bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
6389-
"trans::deep_copy: " +
6390-
ty_to_str(tcx, t));
6374+
"trans::deep_copy: " +
6375+
ty_to_str(tcx, t));
63916376
}
63926377
}
63936378

src/comp/middle/ty.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export type_is_sequence;
168168
export type_is_signed;
169169
export type_is_structural;
170170
export type_is_tup_like;
171+
export type_is_str;
171172
export type_owns_heap_mem;
172173
export type_param;
173174
export unify;
@@ -899,6 +900,13 @@ fn type_is_sequence(&ctxt cx, &t ty) -> bool {
899900
}
900901
}
901902

903+
fn type_is_str(&ctxt cx, &t ty) -> bool {
904+
alt (struct(cx, ty)) {
905+
case (ty_str) { ret true; }
906+
case (_) { ret false; }
907+
}
908+
}
909+
902910
fn sequence_is_interior(&ctxt cx, &t ty) -> bool {
903911
alt (struct(cx, ty)) {
904912
case (

src/rt/rust_upcall.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,7 @@ upcall_mark(rust_task *task, void* ptr) {
315315
return 0;
316316
}
317317

318-
extern "C" CDECL rust_str *
319-
upcall_new_str(rust_task *task, char const *s, size_t fill) {
320-
LOG_UPCALL_ENTRY(task);
318+
rust_str *make_str(rust_task *task, char const *s, size_t fill) {
321319
rust_dom *dom = task->dom;
322320
size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
323321
void *mem = task->malloc(alloc);
@@ -332,6 +330,20 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) {
332330
return st;
333331
}
334332

333+
extern "C" CDECL rust_str *
334+
upcall_new_str(rust_task *task, char const *s, size_t fill) {
335+
LOG_UPCALL_ENTRY(task);
336+
337+
return make_str(task, s, fill);
338+
}
339+
340+
extern "C" CDECL rust_str *
341+
upcall_dup_str(rust_task *task, rust_str *str) {
342+
LOG_UPCALL_ENTRY(task);
343+
344+
return make_str(task, (char const *)str->data, str->fill);
345+
}
346+
335347
extern "C" CDECL rust_vec *
336348
upcall_new_vec(rust_task *task, size_t fill, type_desc *td) {
337349
LOG_UPCALL_ENTRY(task);

src/rt/rustrt.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ unsupervise
4747
upcall_clone_chan
4848
upcall_del_chan
4949
upcall_del_port
50+
upcall_dup_str
5051
upcall_exit
5152
upcall_fail
5253
upcall_flush_chan

src/test/run-pass/spawn-types.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Make sure we can spawn tasks that take different types of
3+
parameters. This is based on a test case for #520 provided by Rob
4+
Arnold.
5+
*/
6+
7+
// xfail-stage0
8+
// xfail-stage1
9+
// xfail-stage2
10+
// xfail-stage3
11+
12+
use std;
13+
14+
import std::str;
15+
16+
type ctx = chan[int];
17+
18+
fn iotask(ctx cx, str ip) {
19+
assert(str::eq(ip, "localhost"));
20+
}
21+
22+
fn main() {
23+
let port[int] p = port();
24+
spawn iotask(chan(p), "localhost");
25+
}

0 commit comments

Comments
 (0)