@@ -60,6 +60,10 @@ type glue_fns = rec(ValueRef activate_glue,
60
60
ValueRef bzero_glue ,
61
61
ValueRef vec_append_glue ) ;
62
62
63
+ type tydesc_info = rec ( ValueRef tydesc,
64
+ ValueRef take_glue ,
65
+ ValueRef drop_glue ) ;
66
+
63
67
state type crate_ctxt = rec ( session. session sess,
64
68
ModuleRef llmod,
65
69
target_data td,
@@ -78,7 +82,7 @@ state type crate_ctxt = rec(session.session sess,
78
82
hashmap[ ast. def_id , ValueRef ] fn_pairs,
79
83
hashmap[ ast. def_id , ValueRef ] consts,
80
84
hashmap[ ast. def_id , ( ) ] obj_methods,
81
- hashmap[ @ty. t , ValueRef ] tydescs,
85
+ hashmap[ @ty. t , @tydesc_info ] tydescs,
82
86
vec[ ast. ty_param ] obj_typarams,
83
87
vec[ ast. obj_field ] obj_fields,
84
88
@glue_fns glues,
@@ -1291,10 +1295,11 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
1291
1295
check ( n_params == _vec. len [ ValueRef ] ( tys. _1 ) ) ;
1292
1296
1293
1297
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 ) ;
1295
1300
}
1296
1301
1297
- auto root = cx. fcx . ccx . tydescs . get ( t) ;
1302
+ auto root = cx. fcx . ccx . tydescs . get ( t) . tydesc ;
1298
1303
1299
1304
auto tydescs = cx. build . Alloca ( T_array ( T_ptr ( T_tydesc ( cx. fcx . ccx . tn ) ) ,
1300
1305
n_params) ) ;
@@ -1329,16 +1334,18 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
1329
1334
// Otherwise, generate a tydesc if necessary, and return it.
1330
1335
if ( !cx. fcx. ccx. tydescs. contains_key( t) ) {
1331
1336
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) ;
1333
1339
}
1334
- ret res( cx, cx. fcx. ccx. tydescs. get( t) ) ;
1340
+ ret res( cx, cx. fcx. ccx. tydescs. get( t) . tydesc ) ;
1335
1341
}
1336
1342
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" ) ;
1342
1349
1343
1350
auto llsize;
1344
1351
auto llalign;
@@ -1383,18 +1390,40 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
1383
1390
llvm. LLVMSetGlobalConstant ( gvar, True ) ;
1384
1391
llvm. LLVMSetLinkage ( gvar, lib. llvm. LLVMPrivateLinkage
1385
1392
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) ;
1387
1401
}
1388
1402
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 {
1392
1417
auto llfnty = T_glue_fn ( cx. tn) ;
1393
1418
1394
1419
auto fn_name = cx. names. next( "_rust_" + name) + sep( ) + ty. ty_to_str( t) ;
1395
1420
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
+ }
1397
1423
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 {
1398
1427
auto fcx = new_fn_ctxt( cx, llfn) ;
1399
1428
auto bcx = new_top_block_ctxt( fcx) ;
1400
1429
@@ -5508,7 +5537,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
5508
5537
auto hasher = ty. hash_ty ;
5509
5538
auto eqer = ty. eq_ty ;
5510
5539
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) ;
5512
5541
let vec[ ast. ty_param ] obj_typarams = vec ( ) ;
5513
5542
let vec[ ast. obj_field ] obj_fields = vec ( ) ;
5514
5543
0 commit comments