Skip to content

Commit 3003c2d

Browse files
committed
---
yaml --- r: 3087 b: refs/heads/master c: 95def69 h: refs/heads/master i: 3085: 893c78c 3083: 08eb4f3 3079: 8b9ec32 3071: fa4a634 v: v3
1 parent 557190c commit 3003c2d

File tree

5 files changed

+56
-3
lines changed

5 files changed

+56
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 491d1106454c9ffa3950afe27ea3488ef5c19e32
2+
refs/heads/master: 95def699f10b9ec92721d6057a86c454c3c64122

trunk/src/comp/back/upcall.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import trans::decl_cdecl_fn;
55
import trans::T_f32;
66
import trans::T_f64;
77
import trans::T_fn;
8+
import trans::T_bool;
89
import trans::T_i8;
910
import trans::T_i32;
1011
import trans::T_int;
@@ -53,6 +54,7 @@ type upcalls = rec(
5354
ValueRef new_str,
5455
ValueRef new_vec,
5556
ValueRef vec_grow,
57+
ValueRef vec_append,
5658
ValueRef get_type_desc,
5759
ValueRef new_task,
5860
ValueRef start_task,
@@ -111,6 +113,9 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls {
111113
vec_grow=d("vec_grow", [T_opaque_vec_ptr(), T_size_t(),
112114
T_ptr(T_int()), T_ptr(T_tydesc(tn))],
113115
T_opaque_vec_ptr()),
116+
vec_append=d("vec_append", [T_ptr(T_tydesc(tn)), T_ptr(T_tydesc(tn)),
117+
T_ptr(T_opaque_vec_ptr()),
118+
T_opaque_vec_ptr(), T_bool()], T_void()),
114119
get_type_desc=d("get_type_desc",
115120
[T_ptr(T_nil()), T_size_t(), T_size_t(),
116121
T_size_t(), T_ptr(T_ptr(T_tydesc(tn)))],

trunk/src/comp/middle/trans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3681,7 +3681,7 @@ fn trans_vec_append(&@block_ctxt cx, &ty::t t,
36813681
auto dst = bcx.build.PointerCast(lhs, T_ptr(T_opaque_vec_ptr()));
36823682
auto src = bcx.build.PointerCast(rhs, T_opaque_vec_ptr());
36833683

3684-
ret res(bcx, bcx.build.FastCall(cx.fcx.lcx.ccx.glues.vec_append_glue,
3684+
ret res(bcx, bcx.build.Call(cx.fcx.lcx.ccx.upcalls.vec_append,
36853685
[cx.fcx.lltaskptr,
36863686
llvec_tydesc.val,
36873687
llelt_tydesc.val,

trunk/src/rt/rust_upcall.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ upcall_vec_grow(rust_task *task,
415415
*
416416
* Step 3 is a bit tricky. We don't know how to properly copy the
417417
* elements in the runtime (all we have are bits in a buffer; no
418-
* type infromation and no copy glue). What we do instead is set the
418+
* type information and no copy glue). What we do instead is set the
419419
* need_copy outparam flag to indicate to our caller (vec-copy glue)
420420
* that we need the copies performed for us.
421421
*/
@@ -436,6 +436,53 @@ upcall_vec_grow(rust_task *task,
436436
return v;
437437
}
438438

439+
// Copy elements from one vector to another,
440+
// dealing with reference counts
441+
static inline void
442+
copy_elements(rust_task *task, type_desc *elem_t,
443+
void *pdst, void *psrc, size_t n)
444+
{
445+
char *dst = (char *)pdst, *src = (char *)psrc;
446+
447+
// increment the refcount of each element of the vector
448+
if (elem_t->take_glue) {
449+
glue_fn *take_glue = elem_t->take_glue;
450+
size_t elem_size = elem_t->size;
451+
const type_desc **tydescs = elem_t->first_param;
452+
for (char *p = src; p < src+n; p += elem_size) {
453+
take_glue(NULL, task, NULL, tydescs, p);
454+
}
455+
}
456+
memmove(dst, src, n);
457+
}
458+
459+
extern "C" CDECL void
460+
upcall_vec_append(rust_task *task, type_desc *t, type_desc *elem_t,
461+
rust_vec **dst_ptr, rust_vec *src, bool skip_null)
462+
{
463+
LOG_UPCALL_ENTRY(task);
464+
rust_vec *dst = *dst_ptr;
465+
uintptr_t need_copy;
466+
size_t n_src_bytes = skip_null ? src->fill - 1 : src->fill;
467+
size_t n_dst_bytes = skip_null ? dst->fill - 1 : dst->fill;
468+
rust_vec *new_vec = upcall_vec_grow(task, dst, n_src_bytes,
469+
&need_copy, t);
470+
471+
if (need_copy) {
472+
// Copy any dst elements in, omitting null if doing str.
473+
copy_elements(task, elem_t, &new_vec->data, &dst->data, n_dst_bytes);
474+
}
475+
476+
// Copy any src elements in, carrying along null if doing str.
477+
void *new_end = (void *)((char *)new_vec->data + n_dst_bytes);
478+
copy_elements(task, elem_t, new_end, &src->data, src->fill);
479+
new_vec->fill = n_dst_bytes + src->fill;
480+
481+
// Write new_vec back through the alias we were given.
482+
*dst_ptr = new_vec;
483+
}
484+
485+
439486
extern "C" CDECL type_desc *
440487
upcall_get_type_desc(rust_task *task,
441488
void *curr_crate, // ignored, legacy compat.

trunk/src/rt/rustrt.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ upcall_start_thread
7373
upcall_trace_str
7474
upcall_trace_word
7575
upcall_vec_grow
76+
upcall_vec_append
7677
upcall_yield
7778
vec_alloc
7879
vec_alloc_mut

0 commit comments

Comments
 (0)