about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-09-22 16:10:48 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-09-22 16:13:03 -0700
commite372f943e2f84beef81fde6b7e1260fc710529c6 (patch)
treeb8a120a72dab926eed34b015266ab85ba0448251
parentdfa5bd111404102a561ee2a05e4aa1676363d6ad (diff)
downloadrust-e372f943e2f84beef81fde6b7e1260fc710529c6.tar.gz
rust-e372f943e2f84beef81fde6b7e1260fc710529c6.zip
rustc: Write raw type parameters instead of linearized type parameters in object body shapes
-rw-r--r--src/comp/middle/shape.rs50
-rw-r--r--src/comp/middle/trans.rs26
-rw-r--r--src/comp/middle/trans_common.rs3
-rw-r--r--src/comp/middle/trans_objects.rs18
4 files changed, 61 insertions, 36 deletions
diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs
index 2f4718223c4..7c54bde66b3 100644
--- a/src/comp/middle/shape.rs
+++ b/src/comp/middle/shape.rs
@@ -274,7 +274,8 @@ fn add_substr(&dest: [u8], src: [u8]) {
     dest += src;
 }
 
-fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
+fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint],
+            is_obj_body: bool) -> [u8] {
     let s = [];
 
     alt ty::struct(ccx.tcx, t) {
@@ -320,7 +321,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
         s += [shape_vec];
         add_bool(s, true); // type is POD
         let unit_ty = ty::mk_mach(ccx.tcx, ast::ty_u8);
-        add_substr(s, shape_of(ccx, unit_ty, ty_param_map));
+        add_substr(s, shape_of(ccx, unit_ty, ty_param_map, is_obj_body));
       }
 
 
@@ -352,7 +353,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
 
             add_u16(sub, vec::len(tps) as u16);
             for tp: ty::t in tps {
-                let subshape = shape_of(ccx, tp, ty_param_map);
+                let subshape = shape_of(ccx, tp, ty_param_map, is_obj_body);
                 add_u16(sub, vec::len(subshape) as u16);
                 sub += subshape;
             }
@@ -368,29 +369,31 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
 
       ty::ty_box(mt) {
         s += [shape_box];
-        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
       }
       ty::ty_uniq(mt) {
         s += [shape_uniq];
-        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
       }
       ty::ty_vec(mt) {
         s += [shape_vec];
         add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
-        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
       }
       ty::ty_rec(fields) {
         s += [shape_struct];
         let sub = [];
         for f: field in fields {
-            sub += shape_of(ccx, f.mt.ty, ty_param_map);
+            sub += shape_of(ccx, f.mt.ty, ty_param_map, is_obj_body);
         }
         add_substr(s, sub);
       }
       ty::ty_tup(elts) {
         s += [shape_struct];
         let sub = [];
-        for elt in elts { sub += shape_of(ccx, elt, ty_param_map); }
+        for elt in elts {
+            sub += shape_of(ccx, elt, ty_param_map, is_obj_body);
+        }
         add_substr(s, sub);
       }
 
@@ -417,9 +420,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
         add_u16(s, id as u16);
         add_u16(s, vec::len(tps) as u16);
         for tp: ty::t in tps {
-            add_substr(s, shape_of(ccx, tp, ty_param_map));
+            add_substr(s, shape_of(ccx, tp, ty_param_map, is_obj_body));
         }
-        add_substr(s, shape_of(ccx, subt, ty_param_map));
+        add_substr(s, shape_of(ccx, subt, ty_param_map, is_obj_body));
 
       }
 
@@ -434,18 +437,23 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
 
 
       ty::ty_param(n, _) {
-        // Find the type parameter in the parameter list.
-        let found = false;
-        let i = 0u;
-        while i < vec::len(ty_param_map) {
-            if n == ty_param_map[i] {
-                s += [shape_var, i as u8];
-                found = true;
-                break;
+        if is_obj_body {
+            // Just write in the parameter number.
+            s += [shape_var, n as u8];
+        } else {
+            // Find the type parameter in the parameter list.
+            let found = false;
+            let i = 0u;
+            while i < vec::len(ty_param_map) {
+                if n == ty_param_map[i] {
+                    s += [shape_var, i as u8];
+                    found = true;
+                    break;
+                }
+                i += 1u;
             }
-            i += 1u;
+            assert (found);
         }
-        assert (found);
       }
     }
 
@@ -460,7 +468,7 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info,
     while i < ty_param_count { ty_param_map += [i]; i += 1u; }
 
     let s = [];
-    for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map); }
+    for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map, false); }
     ret s;
 }
 
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 3d2dd1bbe56..5833be8aaff 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -951,10 +951,16 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
       none. {/* fall through */ }
     }
 
+    let is_obj_body;
+    alt storage {
+        tps_normal. { is_obj_body = false; }
+        tps_obj(_) | tps_fn(_) { is_obj_body = true; }
+    }
+
     bcx_ccx(cx).stats.n_derived_tydescs += 1u;
     let bcx = new_raw_block_ctxt(cx.fcx, cx.fcx.llderivedtydescs);
     let tys = linearize_ty_params(bcx, t);
-    let root_ti = get_static_tydesc(bcx, t, tys.params);
+    let root_ti = get_static_tydesc(bcx, t, tys.params, is_obj_body);
     static_ti = some::<@tydesc_info>(root_ti);
     lazily_emit_all_tydesc_glue(cx, static_ti);
     let root = root_ti.tydesc;
@@ -1048,13 +1054,13 @@ fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
              result: get_derived_tydesc(cx, t, escapes, storage, static_ti)};
     }
     // Otherwise, generate a tydesc if necessary, and return it.
-    let info = get_static_tydesc(cx, t, []);
+    let info = get_static_tydesc(cx, t, [], false);
     static_ti = some::<@tydesc_info>(info);
     ret {kind: tk_static, result: rslt(cx, info.tydesc)};
 }
 
-fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint]) ->
-   @tydesc_info {
+fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint],
+                     is_obj_body: bool) -> @tydesc_info {
     let t = ty::strip_cname(bcx_tcx(cx), orig_t);
 
 
@@ -1062,7 +1068,8 @@ fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint]) ->
       some(info) { ret info; }
       none. {
         bcx_ccx(cx).stats.n_static_tydescs += 1u;
-        let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params);
+        let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params,
+                                  is_obj_body);
         bcx_ccx(cx).tydescs.insert(t, info);
         ret info;
       }
@@ -1097,7 +1104,8 @@ fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) {
 
 
 // Generates the declaration for (but doesn't emit) a type descriptor.
-fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
+fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint],
+                  is_obj_body: bool) ->
    @tydesc_info {
     log "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
     let ccx = cx.ccx;
@@ -1133,7 +1141,8 @@ fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
           mutable drop_glue: none::<ValueRef>,
           mutable free_glue: none::<ValueRef>,
           mutable cmp_glue: none::<ValueRef>,
-          ty_params: ty_params};
+          ty_params: ty_params,
+          is_obj_body: is_obj_body};
     log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
     ret info;
 }
@@ -1249,7 +1258,8 @@ fn emit_tydescs(ccx: @crate_ctxt) {
               some(v) { ccx.stats.n_real_glues += 1u; v }
             };
 
-        let shape = shape::shape_of(ccx, pair.key, ti.ty_params);
+        let shape = shape::shape_of(ccx, pair.key, ti.ty_params,
+                                    ti.is_obj_body);
         let shape_tables =
             llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables,
                                        T_ptr(T_i8()));
diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs
index 563ee322e6c..ce49024a88b 100644
--- a/src/comp/middle/trans_common.rs
+++ b/src/comp/middle/trans_common.rs
@@ -58,7 +58,8 @@ type tydesc_info =
      mutable drop_glue: option::t<ValueRef>,
      mutable free_glue: option::t<ValueRef>,
      mutable cmp_glue: option::t<ValueRef>,
-     ty_params: [uint]};
+     ty_params: [uint],
+     is_obj_body: bool};
 
 /*
  * A note on nomenclature of linking: "upcall", "extern" and "native".
diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs
index 99eacedaf3b..5688048085d 100644
--- a/src/comp/middle/trans_objects.rs
+++ b/src/comp/middle/trans_objects.rs
@@ -108,6 +108,18 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         // refcount.
         let body_ty: ty::t =
             create_object_body_type(ccx.tcx, obj_fields, tps, none);
+
+        // We have to get this type descriptor now so that
+        // trans_malloc_boxed() doesn't generate a type descriptor with the
+        // wrong storage type and override the type descriptor we're about to
+        // generate.
+        let ti = none;
+        let storage = tps_obj(vec::len(ty_params));
+        let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
+        bcx = body_td.bcx;
+        lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
+        lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
+
         let box = trans_malloc_boxed(bcx, body_ty);
         bcx = box.bcx;
         let body = box.body;
@@ -126,7 +138,6 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         let body_tydesc =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
         bcx = body_tydesc.bcx;
-        let ti = none;
 
         check type_is_tup_like(bcx, body_ty);
         let r =
@@ -134,11 +145,6 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         bcx = r.bcx;
         let body_typarams = r.val;
 
-        let storage = tps_obj(vec::len(ty_params));
-        let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
-        lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
-        lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
-        bcx = body_td.bcx;
         Store(bcx, body_td.val, body_tydesc.val);
 
         // Copy the object's type parameters and fields into the space we