Skip to content

Commit fae6870

Browse files
committed
rustc: Make populate_fn_ctxt_from_llself() generic-aware
1 parent 5876da0 commit fae6870

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

src/comp/middle/trans.rs

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -401,20 +401,19 @@ fn T_captured_tydescs(type_names tn, uint n) -> TypeRef {
401401
ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc(tn)), n));
402402
}
403403

404-
fn T_obj(type_names tn, uint n_captured_tydescs,
405-
TypeRef llfields_ty) -> TypeRef {
406-
ret T_struct(vec(T_ptr(T_tydesc(tn)),
407-
T_captured_tydescs(tn, n_captured_tydescs),
408-
llfields_ty));
409-
}
404+
fn T_obj_ptr(type_names tn, uint n_captured_tydescs) -> TypeRef {
405+
// This function is not publicly exposed because it returns an incomplete
406+
// type. The dynamically-sized fields follow the captured tydescs.
407+
fn T_obj(type_names tn, uint n_captured_tydescs) -> TypeRef {
408+
ret T_struct(vec(T_ptr(T_tydesc(tn)),
409+
T_captured_tydescs(tn, n_captured_tydescs)));
410+
}
410411

411-
fn T_obj_ptr(type_names tn, uint n_captured_tydescs,
412-
TypeRef llfields_ty) -> TypeRef {
413-
ret T_ptr(T_box(T_obj(tn, n_captured_tydescs, llfields_ty)));
412+
ret T_ptr(T_box(T_obj(tn, n_captured_tydescs)));
414413
}
415414

416415
fn T_opaque_obj_ptr(type_names tn) -> TypeRef {
417-
ret T_obj_ptr(tn, 0u, T_nil());
416+
ret T_obj_ptr(tn, 0u);
418417
}
419418

420419

@@ -4265,56 +4264,73 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
42654264
ret ret_ty_of_fn_ty(ty.ann_to_type(ann));
42664265
}
42674266

4268-
fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) {
4267+
fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) -> result {
4268+
auto bcx = cx;
42694269

4270-
let vec[TypeRef] llfield_tys = vec();
4270+
let vec[@ty.t] field_tys = vec();
42714271

4272-
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
4273-
llfield_tys += node_type(cx.fcx.ccx, f.ann);
4272+
for (ast.obj_field f in bcx.fcx.ccx.obj_fields) {
4273+
field_tys += vec(node_ann_type(bcx.fcx.ccx, f.ann));
42744274
}
42754275

4276-
auto n_typarams = _vec.len[ast.ty_param](cx.fcx.ccx.obj_typarams);
4277-
let TypeRef llobj_box_ty = T_obj_ptr(cx.fcx.ccx.tn, n_typarams,
4278-
T_struct(llfield_tys));
4276+
// Synthesize a tuple type for the fields so that GEP_tup_like() can work
4277+
// its magic.
4278+
auto fields_tup_ty = ty.plain_ty(ty.ty_tup(field_tys));
4279+
4280+
auto n_typarams = _vec.len[ast.ty_param](bcx.fcx.ccx.obj_typarams);
4281+
let TypeRef llobj_box_ty = T_obj_ptr(bcx.fcx.ccx.tn, n_typarams);
42794282

42804283
auto box_cell =
4281-
cx.build.GEP(llself,
4282-
vec(C_int(0),
4283-
C_int(abi.obj_field_box)));
4284+
bcx.build.GEP(llself,
4285+
vec(C_int(0),
4286+
C_int(abi.obj_field_box)));
42844287

4285-
auto box_ptr = cx.build.Load(box_cell);
4288+
auto box_ptr = bcx.build.Load(box_cell);
42864289

4287-
box_ptr = cx.build.PointerCast(box_ptr, llobj_box_ty);
4290+
box_ptr = bcx.build.PointerCast(box_ptr, llobj_box_ty);
42884291

4289-
auto obj_typarams = cx.build.GEP(box_ptr,
4292+
auto obj_typarams = bcx.build.GEP(box_ptr,
42904293
vec(C_int(0),
42914294
C_int(abi.box_rc_field_body),
42924295
C_int(abi.obj_body_elt_typarams)));
42934296

4294-
auto obj_fields = cx.build.GEP(box_ptr,
4295-
vec(C_int(0),
4296-
C_int(abi.box_rc_field_body),
4297-
C_int(abi.obj_body_elt_fields)));
4297+
// The object fields immediately follow the type parameters, so we skip
4298+
// over them to get the pointer.
4299+
auto obj_fields = bcx.build.Add(vp2i(bcx, obj_typarams),
4300+
llsize_of(llvm.LLVMGetElementType(val_ty(obj_typarams))));
4301+
4302+
// If we can (i.e. the type is statically sized), then cast the resulting
4303+
// fields pointer to the appropriate LLVM type. If not, just leave it as
4304+
// i8 *.
4305+
if (!ty.type_has_dynamic_size(fields_tup_ty)) {
4306+
auto llfields_ty = type_of(bcx.fcx.ccx, fields_tup_ty);
4307+
obj_fields = vi2p(bcx, obj_fields, T_ptr(llfields_ty));
4308+
} else {
4309+
obj_fields = vi2p(bcx, obj_fields, T_ptr(T_i8()));
4310+
}
4311+
42984312

42994313
let int i = 0;
43004314

4301-
for (ast.ty_param p in cx.fcx.ccx.obj_typarams) {
4302-
let ValueRef lltyparam = cx.build.GEP(obj_typarams,
4303-
vec(C_int(0),
4304-
C_int(i)));
4305-
lltyparam = cx.build.Load(lltyparam);
4306-
cx.fcx.lltydescs.insert(p.id, lltyparam);
4315+
for (ast.ty_param p in bcx.fcx.ccx.obj_typarams) {
4316+
let ValueRef lltyparam = bcx.build.GEP(obj_typarams,
4317+
vec(C_int(0),
4318+
C_int(i)));
4319+
lltyparam = bcx.build.Load(lltyparam);
4320+
bcx.fcx.lltydescs.insert(p.id, lltyparam);
43074321
i += 1;
43084322
}
43094323

43104324
i = 0;
4311-
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
4312-
let ValueRef llfield = cx.build.GEP(obj_fields,
4313-
vec(C_int(0),
4314-
C_int(i)));
4325+
for (ast.obj_field f in bcx.fcx.ccx.obj_fields) {
4326+
auto rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, vec(0, i));
4327+
bcx = rslt.bcx;
4328+
auto llfield = rslt.val;
43154329
cx.fcx.llobjfields.insert(f.id, llfield);
43164330
i += 1;
43174331
}
4332+
4333+
ret res(bcx, C_nil());
43184334
}
43194335

43204336
fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
@@ -4335,7 +4351,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
43354351

43364352
alt (fcx.llself) {
43374353
case (some[ValueRef](?llself)) {
4338-
populate_fn_ctxt_from_llself(bcx, llself);
4354+
bcx = populate_fn_ctxt_from_llself(bcx, llself).bcx;
43394355
}
43404356
case (_) {
43414357
}

0 commit comments

Comments
 (0)