Skip to content

Commit 1dc6bdf

Browse files
committed
rustc: Don't recurse forever if type glue needs to refer to its own type descriptor
1 parent 0aa7482 commit 1dc6bdf

File tree

1 file changed

+45
-16
lines changed

1 file changed

+45
-16
lines changed

src/comp/middle/trans.rs

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ type glue_fns = rec(ValueRef activate_glue,
6060
ValueRef bzero_glue,
6161
ValueRef vec_append_glue);
6262

63+
type tydesc_info = rec(ValueRef tydesc,
64+
ValueRef take_glue,
65+
ValueRef drop_glue);
66+
6367
state type crate_ctxt = rec(session.session sess,
6468
ModuleRef llmod,
6569
target_data td,
@@ -78,7 +82,7 @@ state type crate_ctxt = rec(session.session sess,
7882
hashmap[ast.def_id, ValueRef] fn_pairs,
7983
hashmap[ast.def_id, ValueRef] consts,
8084
hashmap[ast.def_id,()] obj_methods,
81-
hashmap[@ty.t, ValueRef] tydescs,
85+
hashmap[@ty.t, @tydesc_info] tydescs,
8286
vec[ast.ty_param] obj_typarams,
8387
vec[ast.obj_field] obj_fields,
8488
@glue_fns glues,
@@ -1291,10 +1295,11 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
12911295
check (n_params == _vec.len[ValueRef](tys._1));
12921296

12931297
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
1294-
make_tydesc(cx.fcx.ccx, t, tys._0);
1298+
declare_tydesc(cx.fcx.ccx, t);
1299+
define_tydesc(cx.fcx.ccx, t, tys._0);
12951300
}
12961301

1297-
auto root = cx.fcx.ccx.tydescs.get(t);
1302+
auto root = cx.fcx.ccx.tydescs.get(t).tydesc;
12981303

12991304
auto tydescs = cx.build.Alloca(T_array(T_ptr(T_tydesc(cx.fcx.ccx.tn)),
13001305
n_params));
@@ -1329,16 +1334,18 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
13291334
// Otherwise, generate a tydesc if necessary, and return it.
13301335
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
13311336
let vec[ast.def_id] defs = vec();
1332-
make_tydesc(cx.fcx.ccx, t, defs);
1337+
declare_tydesc(cx.fcx.ccx, t);
1338+
define_tydesc(cx.fcx.ccx, t, defs);
13331339
}
1334-
ret res(cx, cx.fcx.ccx.tydescs.get(t));
1340+
ret res(cx, cx.fcx.ccx.tydescs.get(t).tydesc);
13351341
}
13361342

1337-
fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
1338-
auto tg = make_take_glue;
1339-
auto take_glue = make_generic_glue(cx, t, "take", tg, typaram_defs);
1340-
auto dg = make_drop_glue;
1341-
auto drop_glue = make_generic_glue(cx, t, "drop", dg, typaram_defs);
1343+
// Generates the declaration for (but doesn't fill in) a type descriptor. This
1344+
// needs to be separate from make_tydesc() below, because sometimes type glue
1345+
// functions needs to refer to their own type descriptors.
1346+
fn declare_tydesc(@crate_ctxt cx, @ty.t t) {
1347+
auto take_glue = declare_generic_glue(cx, t, "take");
1348+
auto drop_glue = declare_generic_glue(cx, t, "drop");
13421349

13431350
auto llsize;
13441351
auto llalign;
@@ -1383,18 +1390,40 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
13831390
llvm.LLVMSetGlobalConstant(gvar, True);
13841391
llvm.LLVMSetLinkage(gvar, lib.llvm.LLVMPrivateLinkage
13851392
as llvm.Linkage);
1386-
cx.tydescs.insert(t, gvar);
1393+
1394+
auto info = rec(
1395+
tydesc=gvar,
1396+
take_glue=take_glue,
1397+
drop_glue=drop_glue
1398+
);
1399+
1400+
cx.tydescs.insert(t, @info);
13871401
}
13881402

1389-
fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name,
1390-
val_and_ty_fn helper,
1391-
vec[ast.def_id] typaram_defs) -> ValueRef {
1403+
// declare_tydesc() above must have been called first.
1404+
fn define_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
1405+
auto info = cx.tydescs.get(t);
1406+
auto gvar = info.tydesc;
1407+
1408+
auto tg = make_take_glue;
1409+
auto take_glue = make_generic_glue(cx, t, info.take_glue, tg,
1410+
typaram_defs);
1411+
auto dg = make_drop_glue;
1412+
auto drop_glue = make_generic_glue(cx, t, info.drop_glue, dg,
1413+
typaram_defs);
1414+
}
1415+
1416+
fn declare_generic_glue(@crate_ctxt cx, @ty.t t, str name) -> ValueRef {
13921417
auto llfnty = T_glue_fn(cx.tn);
13931418

13941419
auto fn_name = cx.names.next("_rust_" + name) + sep() + ty.ty_to_str(t);
13951420
fn_name = sanitize(fn_name);
1396-
auto llfn = decl_fastcall_fn(cx.llmod, fn_name, llfnty);
1421+
ret decl_fastcall_fn(cx.llmod, fn_name, llfnty);
1422+
}
13971423

1424+
fn make_generic_glue(@crate_ctxt cx, @ty.t t, ValueRef llfn,
1425+
val_and_ty_fn helper,
1426+
vec[ast.def_id] typaram_defs) -> ValueRef {
13981427
auto fcx = new_fn_ctxt(cx, llfn);
13991428
auto bcx = new_top_block_ctxt(fcx);
14001429

@@ -5508,7 +5537,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
55085537
auto hasher = ty.hash_ty;
55095538
auto eqer = ty.eq_ty;
55105539
auto tag_sizes = map.mk_hashmap[@ty.t,uint](hasher, eqer);
5511-
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
5540+
auto tydescs = map.mk_hashmap[@ty.t,@tydesc_info](hasher, eqer);
55125541
let vec[ast.ty_param] obj_typarams = vec();
55135542
let vec[ast.obj_field] obj_fields = vec();
55145543

0 commit comments

Comments
 (0)