diff options
| author | Roy Frostig <[email protected]> | 2010-07-22 17:47:32 -0700 |
|---|---|---|
| committer | Roy Frostig <[email protected]> | 2010-07-22 17:47:32 -0700 |
| commit | 1730d2e037fc41f31d0a90b2fde477f02f0fc798 (patch) | |
| tree | 4e920841841b4cbf35862f3db41db7f688ffffa9 | |
| parent | A certain incomplete quantity of wrestling with "INIT" statements that don't ... (diff) | |
| download | rust-1730d2e037fc41f31d0a90b2fde477f02f0fc798.tar.xz rust-1730d2e037fc41f31d0a90b2fde477f02f0fc798.zip | |
Notify copy glue of dst-initialization and fix _vec.alloc issues in lib and runtime. Closes #109.
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/boot/be/abi.ml | 5 | ||||
| -rw-r--r-- | src/boot/me/trans.ml | 31 | ||||
| -rw-r--r-- | src/lib/_vec.rs | 7 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 10 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 1 | ||||
| -rw-r--r-- | src/test/run-pass/vec-alloc-append.rs | 2 |
7 files changed, 41 insertions, 16 deletions
diff --git a/src/Makefile b/src/Makefile index 84f3a2b2..08992377 100644 --- a/src/Makefile +++ b/src/Makefile @@ -364,7 +364,6 @@ TEST_XFAILS_X86 := test/run-pass/bind-obj-ctor.rs \ test/run-pass/mutable-vec-drop.rs \ test/run-pass/obj-as.rs \ test/run-pass/task-comm.rs \ - test/run-pass/vec-alloc-append.rs \ test/run-pass/vec-slice.rs \ test/run-pass/task-comm-2.rs \ test/run-pass/task-comm-3.rs \ diff --git a/src/boot/be/abi.ml b/src/boot/be/abi.ml index e4bb3c9c..8084c7cf 100644 --- a/src/boot/be/abi.ml +++ b/src/boot/be/abi.ml @@ -77,8 +77,9 @@ let tydesc_field_free_glue = 5;; let tydesc_field_sever_glue = 6;; let tydesc_field_mark_glue = 7;; let tydesc_field_obj_drop_glue = 8;; -let tydesc_field_cmp_glue = 9;; -let tydesc_field_hash_glue = 10;; +let tydesc_field_cmp_glue = 9;; (* FIXME these two aren't in the *) +let tydesc_field_hash_glue = 10;; (* runtime's type_desc struct. *) +let tydesc_field_stateflag = 11;; let vec_elt_rc = 0;; let vec_elt_alloc = 1;; diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index cd59ff5d..78a3257e 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -1112,8 +1112,9 @@ let trans_visitor let fix fixup = fixup_rel_word tydesc_fixup fixup in - log cx "tydesc for %a has sz=%Ld, align=%Ld" - Ast.sprintf_ty t sz align; + let is_stateful = if type_has_state t then 1L else 0L in + log cx "tydesc for %a has sz=%Ld, align=%Ld, is_stateful=%Ld" + Ast.sprintf_ty t sz align is_stateful; Asm.DEF (tydesc_fixup, Asm.SEQ @@ -1145,6 +1146,7 @@ let trans_visitor Asm.WORD (word_ty_mach, Asm.IMM 0L); end end; + Asm.WORD (word_ty_mach, Asm.IMM is_stateful); |]) end @@ -1715,13 +1717,23 @@ let trans_visitor let dst = deref out_ptr in let ty_params = deref (get_element_ptr args 0) in let src = deref (get_element_ptr args 1) in - trans_copy_ty ty_params false dst ty src ty curr_iso + + (* Translate copy code for the dst-initializing and + * dst-non-initializing cases and branch accordingly. *) + let initflag = get_element_ptr args 2 in + let jmps = trans_compare_simple Il.JNE (Il.Cell initflag) one in + trans_copy_ty ty_params true dst ty src ty curr_iso; + let skip_noninit_jmp = mark() in + emit (Il.jmp Il.JMP Il.CodeNone); + List.iter patch jmps; + trans_copy_ty ty_params false dst ty src ty curr_iso; + patch skip_noninit_jmp; in let ty_params_ptr = ty_params_covering ty in let fty = mk_ty_fn (local_slot ty) - [| ty_params_ptr; alias_slot ty |] + [| ty_params_ptr; alias_slot ty; word_slot |] in get_typed_mem_glue g fty inner @@ -3198,6 +3210,8 @@ let trans_visitor iflog (fun _ -> annotate (Printf.sprintf "copy_ty: parametric copy %#d" i)); + let initflag = if initializing then one else zero in + let initflag = Il.Reg (force_to_reg initflag) in aliasing false src begin fun src -> @@ -3206,7 +3220,7 @@ let trans_visitor trans_call_dynamic_glue td Abi.tydesc_field_copy_glue (Some dst) - [| ty_params_ptr; src; |] + [| ty_params_ptr; src; initflag |] None end @@ -4299,7 +4313,12 @@ let trans_visitor [| vr; fp |] None - and trans_vec_append dst_cell dst_ty src_oper src_ty = + and trans_vec_append + (dst_cell:Il.cell) + (dst_ty:Ast.ty) + (src_oper:Il.operand) + (src_ty:Ast.ty) + : unit = let elt_ty = seq_unit_ty dst_ty in let trim_trailing_null = dst_ty = Ast.TY_str in assert (simplified_ty src_ty = simplified_ty dst_ty); diff --git a/src/lib/_vec.rs b/src/lib/_vec.rs index c0555bf1..849e750a 100644 --- a/src/lib/_vec.rs +++ b/src/lib/_vec.rs @@ -5,12 +5,15 @@ native "rust" mod rustrt { type vbuf; fn vec_buf[T](vec[T] v) -> vbuf; fn vec_len[T](vec[T] v) -> uint; - fn vec_alloc[T](uint n_elts) -> vec[T]; + /* The T in vec_alloc[T, U] is the type of the vec to allocate. The + * U is the type of an element in the vec. So to allocate a vec[U] we + * want to invoke this as vec_alloc[vec[U], U]. */ + fn vec_alloc[T, U](uint n_elts) -> vec[U]; fn refcount[T](vec[T] v) -> uint; } fn alloc[T](uint n_elts) -> vec[T] { - ret rustrt.vec_alloc[T](n_elts); + ret rustrt.vec_alloc[vec[T], T](n_elts); } type init_op[T] = fn(uint i) -> T; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 0b492de8..99fa9535 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -92,15 +92,15 @@ unsupervise(rust_task *task) { } extern "C" CDECL rust_vec* -vec_alloc(rust_task *task, type_desc *t, size_t n_elts) +vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts) { rust_dom *dom = task->dom; task->log(rust_log::MEM, - "vec_alloc %" PRIdPTR " elements of size %" PRIdPTR, - n_elts, t->size); - size_t fill = n_elts * t->size; + "vec_alloc %" PRIdPTR " elements of size %" PRIdPTR, + n_elts, elem_t->size); + size_t fill = n_elts * elem_t->size; size_t alloc = next_power_of_two(sizeof(rust_vec) + fill); - void *mem = dom->malloc(alloc); + void *mem = task->malloc(alloc, t->is_stateful ? t : NULL); if (!mem) { task->fail(3); return NULL; diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index d962e894..78ba85e8 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -274,6 +274,7 @@ struct type_desc { uintptr_t sever_glue_off; // For GC. uintptr_t mark_glue_off; // For GC. uintptr_t obj_drop_glue_off; // For custom destructors. + uintptr_t is_stateful; // Residual fields past here are known only to runtime. UT_hash_handle hh; diff --git a/src/test/run-pass/vec-alloc-append.rs b/src/test/run-pass/vec-alloc-append.rs index 2b4a2b20..63d0ee98 100644 --- a/src/test/run-pass/vec-alloc-append.rs +++ b/src/test/run-pass/vec-alloc-append.rs @@ -4,7 +4,9 @@ use std; fn slice[T](vec[T] e) { let vec[T] result = std._vec.alloc[T](uint(1)); + log "alloced"; result += e; + log "appended"; } fn main() { |