Skip to content

Commit e372f94

Browse files
committed
rustc: Write raw type parameters instead of linearized type parameters in object body shapes
1 parent dfa5bd1 commit e372f94

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed

src/comp/middle/shape.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ fn add_substr(&dest: [u8], src: [u8]) {
274274
dest += src;
275275
}
276276

277-
fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
277+
fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint],
278+
is_obj_body: bool) -> [u8] {
278279
let s = [];
279280

280281
alt ty::struct(ccx.tcx, t) {
@@ -320,7 +321,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
320321
s += [shape_vec];
321322
add_bool(s, true); // type is POD
322323
let unit_ty = ty::mk_mach(ccx.tcx, ast::ty_u8);
323-
add_substr(s, shape_of(ccx, unit_ty, ty_param_map));
324+
add_substr(s, shape_of(ccx, unit_ty, ty_param_map, is_obj_body));
324325
}
325326

326327

@@ -352,7 +353,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
352353

353354
add_u16(sub, vec::len(tps) as u16);
354355
for tp: ty::t in tps {
355-
let subshape = shape_of(ccx, tp, ty_param_map);
356+
let subshape = shape_of(ccx, tp, ty_param_map, is_obj_body);
356357
add_u16(sub, vec::len(subshape) as u16);
357358
sub += subshape;
358359
}
@@ -368,29 +369,31 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
368369

369370
ty::ty_box(mt) {
370371
s += [shape_box];
371-
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
372+
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
372373
}
373374
ty::ty_uniq(mt) {
374375
s += [shape_uniq];
375-
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
376+
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
376377
}
377378
ty::ty_vec(mt) {
378379
s += [shape_vec];
379380
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
380-
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
381+
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
381382
}
382383
ty::ty_rec(fields) {
383384
s += [shape_struct];
384385
let sub = [];
385386
for f: field in fields {
386-
sub += shape_of(ccx, f.mt.ty, ty_param_map);
387+
sub += shape_of(ccx, f.mt.ty, ty_param_map, is_obj_body);
387388
}
388389
add_substr(s, sub);
389390
}
390391
ty::ty_tup(elts) {
391392
s += [shape_struct];
392393
let sub = [];
393-
for elt in elts { sub += shape_of(ccx, elt, ty_param_map); }
394+
for elt in elts {
395+
sub += shape_of(ccx, elt, ty_param_map, is_obj_body);
396+
}
394397
add_substr(s, sub);
395398
}
396399

@@ -417,9 +420,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
417420
add_u16(s, id as u16);
418421
add_u16(s, vec::len(tps) as u16);
419422
for tp: ty::t in tps {
420-
add_substr(s, shape_of(ccx, tp, ty_param_map));
423+
add_substr(s, shape_of(ccx, tp, ty_param_map, is_obj_body));
421424
}
422-
add_substr(s, shape_of(ccx, subt, ty_param_map));
425+
add_substr(s, shape_of(ccx, subt, ty_param_map, is_obj_body));
423426

424427
}
425428

@@ -434,18 +437,23 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
434437

435438

436439
ty::ty_param(n, _) {
437-
// Find the type parameter in the parameter list.
438-
let found = false;
439-
let i = 0u;
440-
while i < vec::len(ty_param_map) {
441-
if n == ty_param_map[i] {
442-
s += [shape_var, i as u8];
443-
found = true;
444-
break;
440+
if is_obj_body {
441+
// Just write in the parameter number.
442+
s += [shape_var, n as u8];
443+
} else {
444+
// Find the type parameter in the parameter list.
445+
let found = false;
446+
let i = 0u;
447+
while i < vec::len(ty_param_map) {
448+
if n == ty_param_map[i] {
449+
s += [shape_var, i as u8];
450+
found = true;
451+
break;
452+
}
453+
i += 1u;
445454
}
446-
i += 1u;
455+
assert (found);
447456
}
448-
assert (found);
449457
}
450458
}
451459

@@ -460,7 +468,7 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info,
460468
while i < ty_param_count { ty_param_map += [i]; i += 1u; }
461469

462470
let s = [];
463-
for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map); }
471+
for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map, false); }
464472
ret s;
465473
}
466474

src/comp/middle/trans.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -951,10 +951,16 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
951951
none. {/* fall through */ }
952952
}
953953

954+
let is_obj_body;
955+
alt storage {
956+
tps_normal. { is_obj_body = false; }
957+
tps_obj(_) | tps_fn(_) { is_obj_body = true; }
958+
}
959+
954960
bcx_ccx(cx).stats.n_derived_tydescs += 1u;
955961
let bcx = new_raw_block_ctxt(cx.fcx, cx.fcx.llderivedtydescs);
956962
let tys = linearize_ty_params(bcx, t);
957-
let root_ti = get_static_tydesc(bcx, t, tys.params);
963+
let root_ti = get_static_tydesc(bcx, t, tys.params, is_obj_body);
958964
static_ti = some::<@tydesc_info>(root_ti);
959965
lazily_emit_all_tydesc_glue(cx, static_ti);
960966
let root = root_ti.tydesc;
@@ -1048,21 +1054,22 @@ fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
10481054
result: get_derived_tydesc(cx, t, escapes, storage, static_ti)};
10491055
}
10501056
// Otherwise, generate a tydesc if necessary, and return it.
1051-
let info = get_static_tydesc(cx, t, []);
1057+
let info = get_static_tydesc(cx, t, [], false);
10521058
static_ti = some::<@tydesc_info>(info);
10531059
ret {kind: tk_static, result: rslt(cx, info.tydesc)};
10541060
}
10551061

1056-
fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint]) ->
1057-
@tydesc_info {
1062+
fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint],
1063+
is_obj_body: bool) -> @tydesc_info {
10581064
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
10591065

10601066

10611067
alt bcx_ccx(cx).tydescs.find(t) {
10621068
some(info) { ret info; }
10631069
none. {
10641070
bcx_ccx(cx).stats.n_static_tydescs += 1u;
1065-
let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params);
1071+
let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params,
1072+
is_obj_body);
10661073
bcx_ccx(cx).tydescs.insert(t, info);
10671074
ret info;
10681075
}
@@ -1097,7 +1104,8 @@ fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) {
10971104

10981105

10991106
// Generates the declaration for (but doesn't emit) a type descriptor.
1100-
fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
1107+
fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint],
1108+
is_obj_body: bool) ->
11011109
@tydesc_info {
11021110
log "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
11031111
let ccx = cx.ccx;
@@ -1133,7 +1141,8 @@ fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
11331141
mutable drop_glue: none::<ValueRef>,
11341142
mutable free_glue: none::<ValueRef>,
11351143
mutable cmp_glue: none::<ValueRef>,
1136-
ty_params: ty_params};
1144+
ty_params: ty_params,
1145+
is_obj_body: is_obj_body};
11371146
log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
11381147
ret info;
11391148
}
@@ -1249,7 +1258,8 @@ fn emit_tydescs(ccx: @crate_ctxt) {
12491258
some(v) { ccx.stats.n_real_glues += 1u; v }
12501259
};
12511260

1252-
let shape = shape::shape_of(ccx, pair.key, ti.ty_params);
1261+
let shape = shape::shape_of(ccx, pair.key, ti.ty_params,
1262+
ti.is_obj_body);
12531263
let shape_tables =
12541264
llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables,
12551265
T_ptr(T_i8()));

src/comp/middle/trans_common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ type tydesc_info =
5858
mutable drop_glue: option::t<ValueRef>,
5959
mutable free_glue: option::t<ValueRef>,
6060
mutable cmp_glue: option::t<ValueRef>,
61-
ty_params: [uint]};
61+
ty_params: [uint],
62+
is_obj_body: bool};
6263

6364
/*
6465
* A note on nomenclature of linking: "upcall", "extern" and "native".

src/comp/middle/trans_objects.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
108108
// refcount.
109109
let body_ty: ty::t =
110110
create_object_body_type(ccx.tcx, obj_fields, tps, none);
111+
112+
// We have to get this type descriptor now so that
113+
// trans_malloc_boxed() doesn't generate a type descriptor with the
114+
// wrong storage type and override the type descriptor we're about to
115+
// generate.
116+
let ti = none;
117+
let storage = tps_obj(vec::len(ty_params));
118+
let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
119+
bcx = body_td.bcx;
120+
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
121+
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
122+
111123
let box = trans_malloc_boxed(bcx, body_ty);
112124
bcx = box.bcx;
113125
let body = box.body;
@@ -126,19 +138,13 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
126138
let body_tydesc =
127139
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
128140
bcx = body_tydesc.bcx;
129-
let ti = none;
130141

131142
check type_is_tup_like(bcx, body_ty);
132143
let r =
133144
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]);
134145
bcx = r.bcx;
135146
let body_typarams = r.val;
136147

137-
let storage = tps_obj(vec::len(ty_params));
138-
let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
139-
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
140-
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
141-
bcx = body_td.bcx;
142148
Store(bcx, body_td.val, body_tydesc.val);
143149

144150
// Copy the object's type parameters and fields into the space we

0 commit comments

Comments
 (0)