Skip to content

Commit be97a77

Browse files
committed
Capture typarams into obj, independent of body tydesc.
1 parent ce17fe2 commit be97a77

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

src/comp/back/abi.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ const int obj_field_vtbl = 0;
4444
const int obj_field_box = 1;
4545

4646
const int obj_body_elt_tydesc = 0;
47-
const int obj_body_elt_fields = 1;
47+
const int obj_body_elt_typarams = 1;
48+
const int obj_body_elt_fields = 2;
4849

4950
const int fn_field_code = 0;
5051
const int fn_field_box = 1;

src/comp/middle/trans.rs

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ state type crate_ctxt = rec(session.session sess,
7575
hashmap[ast.def_id, ValueRef] consts,
7676
hashmap[ast.def_id,()] obj_methods,
7777
hashmap[@ty.t, ValueRef] tydescs,
78+
vec[ast.ty_param] obj_typarams,
7879
vec[ast.obj_field] obj_fields,
7980
@glue_fns glues,
8081
namegen names,
@@ -327,6 +328,24 @@ fn T_opaque_closure_ptr() -> TypeRef {
327328
T_nil());
328329
}
329330

331+
fn T_captured_tydescs(uint n) -> TypeRef {
332+
ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc()), n));
333+
}
334+
335+
fn T_obj(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef {
336+
ret T_struct(vec(T_ptr(T_tydesc()),
337+
T_captured_tydescs(n_captured_tydescs),
338+
llfields_ty));
339+
}
340+
341+
fn T_obj_ptr(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef {
342+
ret T_ptr(T_box(T_obj(n_captured_tydescs, llfields_ty)));
343+
}
344+
345+
fn T_opaque_obj_ptr() -> TypeRef {
346+
ret T_obj_ptr(0u, T_nil());
347+
}
348+
330349

331350
fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
332351
let TypeRef llty = type_of_inner(cx, t);
@@ -455,11 +474,9 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
455474
mtys += T_ptr(mty);
456475
}
457476
let TypeRef vtbl = T_struct(mtys);
458-
let TypeRef body = T_struct(vec(T_ptr(T_tydesc()),
459-
T_nil()));
460-
let TypeRef pair =
461-
T_struct(vec(T_ptr(vtbl),
462-
T_ptr(T_box(body))));
477+
let TypeRef pair = T_struct(vec(T_ptr(vtbl),
478+
T_opaque_obj_ptr()));
479+
463480
auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
464481
llvm.LLVMRefineType(abs_pair, pair);
465482
abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
@@ -963,6 +980,7 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
963980
// Is the supplied type a type param? If so, return the passed-in tydesc.
964981
alt (ty.type_param(t)) {
965982
case (some[ast.def_id](?id)) {
983+
check (cx.fcx.lltydescs.contains_key(id));
966984
ret res(cx, cx.fcx.lltydescs.get(id));
967985
}
968986
case (none[ast.def_id]) { /* fall through */ }
@@ -3474,19 +3492,17 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
34743492
ret ret_ty_of_fn_ty(ty.ann_to_type(ann));
34753493
}
34763494

3477-
fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
3495+
fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) {
34783496

34793497
let vec[TypeRef] llfield_tys = vec();
34803498

34813499
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
34823500
llfield_tys += node_type(cx.fcx.ccx, f.ann);
34833501
}
34843502

3485-
let TypeRef llfields_ty = T_struct(llfield_tys);
3486-
let TypeRef lltydesc_ty = T_ptr(T_tydesc());
3487-
let TypeRef llobj_body_ty = T_struct(vec(lltydesc_ty,
3488-
llfields_ty));
3489-
let TypeRef llobj_box_ty = T_ptr(T_box(llobj_body_ty));
3503+
auto n_typarams = _vec.len[ast.ty_param](cx.fcx.ccx.obj_typarams);
3504+
let TypeRef llobj_box_ty = T_obj_ptr(n_typarams,
3505+
T_struct(llfield_tys));
34903506

34913507
auto box_cell =
34923508
cx.build.GEP(llself,
@@ -3497,12 +3513,28 @@ fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
34973513

34983514
box_ptr = cx.build.PointerCast(box_ptr, llobj_box_ty);
34993515

3516+
auto obj_typarams = cx.build.GEP(box_ptr,
3517+
vec(C_int(0),
3518+
C_int(abi.box_rc_field_body),
3519+
C_int(abi.obj_body_elt_typarams)));
3520+
35003521
auto obj_fields = cx.build.GEP(box_ptr,
35013522
vec(C_int(0),
35023523
C_int(abi.box_rc_field_body),
35033524
C_int(abi.obj_body_elt_fields)));
35043525

35053526
let int i = 0;
3527+
3528+
for (ast.ty_param p in cx.fcx.ccx.obj_typarams) {
3529+
let ValueRef lltyparam = cx.build.GEP(obj_typarams,
3530+
vec(C_int(0),
3531+
C_int(i)));
3532+
lltyparam = cx.build.Load(lltyparam);
3533+
cx.fcx.lltydescs.insert(p.id, lltyparam);
3534+
i += 1;
3535+
}
3536+
3537+
i = 0;
35063538
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
35073539
let ValueRef llfield = cx.build.GEP(obj_fields,
35083540
vec(C_int(0),
@@ -3529,7 +3561,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
35293561

35303562
alt (fcx.llself) {
35313563
case (some[ValueRef](?llself)) {
3532-
create_llobjfields_for_fields(bcx, llself);
3564+
populate_fn_ctxt_from_llself(bcx, llself);
35333565
}
35343566
case (_) {
35353567
}
@@ -3623,10 +3655,11 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
36233655
C_int(abi.obj_field_box)));
36243656
bcx.build.Store(vtbl, pair_vtbl);
36253657

3626-
let TypeRef llbox_ty = T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc()),
3627-
T_nil()))));
3628-
if (_vec.len[ty.arg](arg_tys) == 0u) {
3629-
// Store null into pair, if no args.
3658+
let TypeRef llbox_ty = T_opaque_obj_ptr();
3659+
3660+
if (_vec.len[ast.ty_param](ty_params) == 0u &&
3661+
_vec.len[ty.arg](arg_tys) == 0u) {
3662+
// Store null into pair, if no args or typarams.
36303663
bcx.build.Store(C_null(llbox_ty), pair_box);
36313664
} else {
36323665
// Malloc a box for the body and copy args in.
@@ -3636,8 +3669,16 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
36363669
}
36373670

36383671
// Synthesize an obj body type.
3672+
auto tydesc_ty = plain_ty(ty.ty_type);
3673+
let vec[@ty.t] tps = vec();
3674+
for (ast.ty_param tp in ty_params) {
3675+
append[@ty.t](tps, tydesc_ty);
3676+
}
3677+
3678+
let @ty.t typarams_ty = plain_ty(ty.ty_tup(tps));
36393679
let @ty.t fields_ty = plain_ty(ty.ty_tup(obj_fields));
3640-
let @ty.t body_ty = plain_ty(ty.ty_tup(vec(plain_ty(ty.ty_type),
3680+
let @ty.t body_ty = plain_ty(ty.ty_tup(vec(tydesc_ty,
3681+
typarams_ty,
36413682
fields_ty)));
36423683
let @ty.t boxed_body_ty = plain_ty(ty.ty_box(body_ty));
36433684

@@ -3664,13 +3705,28 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
36643705
bcx = body_td.bcx;
36653706
bcx.build.Store(body_td.val, body_tydesc.val);
36663707

3708+
// Copy typarams into captured typarams.
3709+
auto body_typarams =
3710+
GEP_tup_like(bcx, body_ty, body.val,
3711+
vec(0, abi.obj_body_elt_typarams));
3712+
bcx = body_typarams.bcx;
3713+
let int i = 0;
3714+
for (ast.ty_param tp in ty_params) {
3715+
auto typaram = bcx.fcx.lltydescs.get(tp.id);
3716+
auto capture = GEP_tup_like(bcx, typarams_ty, body_typarams.val,
3717+
vec(0, i));
3718+
bcx = capture.bcx;
3719+
bcx = copy_ty(bcx, INIT, capture.val, typaram, tydesc_ty).bcx;
3720+
i += 1;
3721+
}
3722+
36673723
// Copy args into body fields.
36683724
auto body_fields =
36693725
GEP_tup_like(bcx, body_ty, body.val,
36703726
vec(0, abi.obj_body_elt_fields));
36713727
bcx = body_fields.bcx;
36723728

3673-
let int i = 0;
3729+
i = 0;
36743730
for (ast.obj_field f in ob.fields) {
36753731
auto arg = bcx.fcx.llargs.get(f.id);
36763732
arg = load_scalar_or_boxed(bcx, arg, arg_tys.(i).ty);
@@ -3792,6 +3848,7 @@ fn trans_item(@crate_ctxt cx, &ast.item item) {
37923848
}
37933849
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
37943850
auto sub_cx = @rec(path=cx.path + "." + name,
3851+
obj_typarams=tps,
37953852
obj_fields=ob.fields with *cx);
37963853
trans_obj(sub_cx, ob, oid, tps, ann);
37973854
}
@@ -4353,6 +4410,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
43534410
auto hasher = ty.hash_ty;
43544411
auto eqer = ty.eq_ty;
43554412
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
4413+
let vec[ast.ty_param] obj_typarams = vec();
43564414
let vec[ast.obj_field] obj_fields = vec();
43574415

43584416
auto cx = @rec(sess = sess,
@@ -4369,6 +4427,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
43694427
consts = new_def_hash[ValueRef](),
43704428
obj_methods = new_def_hash[()](),
43714429
tydescs = tydescs,
4430+
obj_typarams = obj_typarams,
43724431
obj_fields = obj_fields,
43734432
glues = glues,
43744433
names = namegen(0),

0 commit comments

Comments
 (0)