about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRoy Frostig <rfrostig@mozilla.com>2010-07-22 17:47:32 -0700
committerRoy Frostig <rfrostig@mozilla.com>2010-07-22 17:47:32 -0700
commit1730d2e037fc41f31d0a90b2fde477f02f0fc798 (patch)
tree4e920841841b4cbf35862f3db41db7f688ffffa9 /src
parentede42cf931dc9cb7c7f4c78d7f9521985c2a8e11 (diff)
downloadrust-1730d2e037fc41f31d0a90b2fde477f02f0fc798.tar.gz
rust-1730d2e037fc41f31d0a90b2fde477f02f0fc798.zip
Notify copy glue of dst-initialization and fix _vec.alloc issues in lib and runtime. Closes #109.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/boot/be/abi.ml5
-rw-r--r--src/boot/me/trans.ml31
-rw-r--r--src/lib/_vec.rs7
-rw-r--r--src/rt/rust_builtin.cpp10
-rw-r--r--src/rt/rust_internal.h1
-rw-r--r--src/test/run-pass/vec-alloc-append.rs2
7 files changed, 41 insertions, 16 deletions
diff --git a/src/Makefile b/src/Makefile
index 84f3a2b2ef2..08992377974 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 e4bb3c9cdea..8084c7cfc05 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 cd59ff5dd2f..78a3257e3f4 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 c0555bf1b03..849e750a4ca 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 0b492de84a1..99fa953580c 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 d962e894153..78ba85e8859 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 2b4a2b204c2..63d0ee98fd5 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() {