Added string duplication to deep_copy. Closes #520.

This commit is contained in:
Eric Holk 2011-06-20 13:46:44 -07:00
parent c051501784
commit a2dcd08cc2
6 changed files with 59 additions and 25 deletions

View File

@ -49,6 +49,7 @@
ValueRef free,
ValueRef mark,
ValueRef new_str,
ValueRef dup_str,
ValueRef new_vec,
ValueRef vec_append,
ValueRef get_type_desc,
@ -101,6 +102,8 @@ fn decl(type_names tn, ModuleRef llmod, str name, vec[TypeRef] tys,
mark=d("mark", [T_ptr(T_i8())], T_int()),
new_str=d("new_str", [T_ptr(T_i8()), T_size_t()],
T_ptr(T_str())),
dup_str=d("dup_str", [T_ptr(T_str())],
T_ptr(T_str())),
new_vec=d("new_vec", [T_size_t(), T_ptr(T_tydesc(tn))],
T_opaque_vec_ptr()),
vec_append=d("vec_append",

View File

@ -6340,28 +6340,13 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
if(ty::type_is_scalar(tcx, t)) {
ret res(bcx, v);
}
else if(ty::type_is_str(tcx, t)) {
ret res(bcx,
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str,
[bcx.fcx.lltaskptr, v]));
}
else if(ty::type_is_chan(tcx, t)) {
// If this is a channel, we need to clone it.
/*
log_err "Generating clone call for channel argument.";
log_err #fmt("ty(clone_chan) = %s",
val_str(bcx.fcx.lcx.ccx.tn,
bcx.fcx.lcx.ccx.upcalls.clone_chan));
log_err #fmt("ty(lltaskptr) = %s",
val_str(bcx.fcx.lcx.ccx.tn,
bcx.fcx.lltaskptr));
log_err #fmt("ty(target_task) = %s",
val_str(bcx.fcx.lcx.ccx.tn,
target_task));
log_err #fmt("ty(chan) = %s",
val_str(bcx.fcx.lcx.ccx.tn,
v));
*/
auto chan_ptr = bcx.build.PointerCast(v, T_opaque_chan_ptr());
auto chan_raw_val =
@ -6386,8 +6371,8 @@ fn inner_deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t) -> result {
}
else {
bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
"trans::deep_copy: " +
ty_to_str(tcx, t));
"trans::deep_copy: " +
ty_to_str(tcx, t));
}
}

View File

@ -168,6 +168,7 @@
export type_is_signed;
export type_is_structural;
export type_is_tup_like;
export type_is_str;
export type_owns_heap_mem;
export type_param;
export unify;
@ -899,6 +900,13 @@ fn type_is_sequence(&ctxt cx, &t ty) -> bool {
}
}
fn type_is_str(&ctxt cx, &t ty) -> bool {
alt (struct(cx, ty)) {
case (ty_str) { ret true; }
case (_) { ret false; }
}
}
fn sequence_is_interior(&ctxt cx, &t ty) -> bool {
alt (struct(cx, ty)) {
case (

View File

@ -315,9 +315,7 @@ upcall_mark(rust_task *task, void* ptr) {
return 0;
}
extern "C" CDECL rust_str *
upcall_new_str(rust_task *task, char const *s, size_t fill) {
LOG_UPCALL_ENTRY(task);
rust_str *make_str(rust_task *task, char const *s, size_t fill) {
rust_dom *dom = task->dom;
size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
void *mem = task->malloc(alloc);
@ -332,6 +330,20 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) {
return st;
}
extern "C" CDECL rust_str *
upcall_new_str(rust_task *task, char const *s, size_t fill) {
LOG_UPCALL_ENTRY(task);
return make_str(task, s, fill);
}
extern "C" CDECL rust_str *
upcall_dup_str(rust_task *task, rust_str *str) {
LOG_UPCALL_ENTRY(task);
return make_str(task, (char const *)str->data, str->fill);
}
extern "C" CDECL rust_vec *
upcall_new_vec(rust_task *task, size_t fill, type_desc *td) {
LOG_UPCALL_ENTRY(task);

View File

@ -47,6 +47,7 @@ unsupervise
upcall_clone_chan
upcall_del_chan
upcall_del_port
upcall_dup_str
upcall_exit
upcall_fail
upcall_flush_chan

View File

@ -0,0 +1,25 @@
/*
Make sure we can spawn tasks that take different types of
parameters. This is based on a test case for #520 provided by Rob
Arnold.
*/
// xfail-stage0
// xfail-stage1
// xfail-stage2
// xfail-stage3
use std;
import std::str;
type ctx = chan[int];
fn iotask(ctx cx, str ip) {
assert(str::eq(ip, "localhost"));
}
fn main() {
let port[int] p = port();
spawn iotask(chan(p), "localhost");
}