diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs index 2f4718223c41..7c54bde66b32 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 3d2dd1bbe563..5833be8aaff5 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::, mutable free_glue: none::, mutable cmp_glue: none::, - 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 563ee322e6cd..ce49024a88b5 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, mutable free_glue: option::t, mutable cmp_glue: option::t, - 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 99eacedaf3b3..5688048085d1 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