Skip to content

Commit 86f16b9

Browse files
committed
Support type parameters in resources
Some rather dodgy code was added to trans in the process. I'd love to discuss it with someone who knows more about types during translation.
1 parent 31ec26d commit 86f16b9

File tree

8 files changed

+164
-66
lines changed

8 files changed

+164
-66
lines changed

src/comp/lib/llvm.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,13 @@ fn type_to_str_inner(type_names names,
15701570
}
15711571
}
15721572

1573+
fn fn_ty_param_tys(TypeRef fn_ty) -> vec[TypeRef] {
1574+
auto args = vec::init_elt(0 as TypeRef, llvm::LLVMCountParamTypes(fn_ty));
1575+
llvm::LLVMGetParamTypes(fn_ty, vec::buf(args));
1576+
ret args;
1577+
}
1578+
1579+
15731580
/* Memory-managed interface to target data. */
15741581

15751582
obj target_data_dtor(TargetDataRef TD) {

src/comp/metadata/tydecode.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,13 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
257257
ret ty::mk_obj(st.tcx, methods);
258258
}
259259
case ('r') {
260+
assert (next(st) as char == '[');
260261
auto def = parse_def(st, sd);
261262
auto inner = parse_ty(st, sd);
262-
ret ty::mk_res(st.tcx, def, inner);
263+
let vec[ty::t] params = [];
264+
while (peek(st) as char != ']') { params += [parse_ty(st, sd)]; }
265+
st.pos = st.pos + 1u;
266+
ret ty::mk_res(st.tcx, def, inner, params);
263267
}
264268
case ('X') { ret ty::mk_var(st.tcx, parse_int(st)); }
265269
case ('E') { ret ty::mk_native(st.tcx); }

src/comp/metadata/tyencode.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,13 @@ fn enc_sty(&io::writer w, &@ctxt cx, &ty::sty st) {
172172
}
173173
w.write_char(']');
174174
}
175-
case (ty::ty_res(?def, ?ty)) {
176-
w.write_char('r');
175+
case (ty::ty_res(?def, ?ty, ?tps)) {
176+
w.write_str("r[");
177177
w.write_str(cx.ds(def));
178178
w.write_char('|');
179179
enc_ty(w, cx, ty);
180+
for (ty::t t in tps) { enc_ty(w, cx, t); }
181+
w.write_char(']');
180182
}
181183
case (ty::ty_var(?id)) {
182184
w.write_char('X');

src/comp/middle/alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) ->
556556
kind=unbox,
557557
outer_t=base_t));
558558
}
559-
case (ty::ty_res(_, ?inner)) {
559+
case (ty::ty_res(_, ?inner, _)) {
560560
vec::push(ds, rec(mut=false,
561561
kind=unbox,
562562
outer_t=base_t));

src/comp/middle/trans.rs

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,9 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
876876
abs_pair = llvm::LLVMResolveTypeHandle(th.llth);
877877
llty = abs_pair;
878878
}
879-
case (ty::ty_res(_, ?sub)) {
880-
ret T_struct([T_i32(), type_of_inner(cx, sp, sub)]);
879+
case (ty::ty_res(_, ?sub, ?tps)) {
880+
auto sub1 = ty::substitute_type_params(cx.tcx, tps, sub);
881+
ret T_struct([T_i32(), type_of_inner(cx, sp, sub1)]);
881882
}
882883
case (ty::ty_var(_)) {
883884
cx.tcx.sess.span_fatal(sp, "trans::type_of called on ty_var");
@@ -1220,9 +1221,10 @@ fn simplify_type(&@crate_ctxt ccx, &ty::t typ) -> ty::t {
12201221
ty::mk_imm_box(ccx.tcx,
12211222
ty::mk_nil(ccx.tcx))]);
12221223
}
1223-
case (ty::ty_res(_, ?sub)) {
1224+
case (ty::ty_res(_, ?sub, ?tps)) {
1225+
auto sub1 = ty::substitute_type_params(ccx.tcx, tps, sub);
12241226
ret ty::mk_imm_tup(ccx.tcx, [ty::mk_int(ccx.tcx),
1225-
simplify_type(ccx, sub)]);
1227+
simplify_type(ccx, sub1)]);
12261228
}
12271229
case (_) { ret typ; }
12281230
}
@@ -1716,8 +1718,7 @@ fn get_tydesc(&@block_ctxt cx, &ty::t t, bool escapes,
17161718
}
17171719
// Otherwise, generate a tydesc if necessary, and return it.
17181720

1719-
let vec[uint] tps = [];
1720-
auto info = get_static_tydesc(cx, t, tps);
1721+
auto info = get_static_tydesc(cx, t, []);
17211722
static_ti = some[@tydesc_info](info);
17221723
ret rslt(cx, info.tydesc);
17231724
}
@@ -2089,8 +2090,8 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
20892090
cx.build.GEP(v0, [C_int(0), C_int(abi::obj_field_box)]);
20902091
decr_refcnt_maybe_free(cx, box_cell, v0, t)
20912092
}
2092-
case (ty::ty_res(?did, ?inner)) {
2093-
trans_res_drop(cx, v0, did, inner)
2093+
case (ty::ty_res(?did, ?inner, ?tps)) {
2094+
trans_res_drop(cx, v0, did, inner, tps)
20942095
}
20952096
case (ty::ty_fn(_, _, _, _, _)) {
20962097
auto box_cell =
@@ -2108,9 +2109,11 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
21082109
}
21092110

21102111
fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did,
2111-
ty::t inner_t) -> result {
2112+
ty::t inner_t, &vec[ty::t] tps) -> result {
21122113
auto ccx = cx.fcx.lcx.ccx;
2113-
auto tup_ty = ty::mk_imm_tup(ccx.tcx, [ty::mk_int(ccx.tcx), inner_t]);
2114+
2115+
auto inner_t_s = ty::substitute_type_params(ccx.tcx, tps, inner_t);
2116+
auto tup_ty = ty::mk_imm_tup(ccx.tcx, [ty::mk_int(ccx.tcx), inner_t_s]);
21142117
auto drop_cx = new_sub_block_ctxt(cx, "drop res");
21152118
auto next_cx = new_sub_block_ctxt(cx, "next");
21162119

@@ -2120,6 +2123,8 @@ fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did,
21202123
cx.build.CondBr(null_test, next_cx.llbb, drop_cx.llbb);
21212124
cx = drop_cx;
21222125

2126+
auto val = GEP_tup_like(cx, tup_ty, rs, [0, 1]);
2127+
cx = val.bcx;
21232128
// Find and call the actual destructor.
21242129
auto dtor_pair = if (did._0 == ast::local_crate) {
21252130
ccx.fn_pairs.get(did._1)
@@ -2136,15 +2141,25 @@ fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did,
21362141
(cx.build.GEP(dtor_pair, [C_int(0), C_int(abi::fn_field_code)]));
21372142
auto dtor_env = cx.build.Load
21382143
(cx.build.GEP(dtor_pair, [C_int(0), C_int(abi::fn_field_box)]));
2139-
auto val = GEP_tup_like(cx, tup_ty, rs, [0, 1]);
2140-
cx = val.bcx;
2141-
cx.build.FastCall(dtor_addr, [cx.fcx.llretptr, cx.fcx.lltaskptr, dtor_env]
2142-
+ cx.fcx.lltydescs + [val.val]);
2143-
2144-
cx = drop_slot(cx, val.val, inner_t).bcx;
2144+
auto args = [cx.fcx.llretptr, cx.fcx.lltaskptr, dtor_env];
2145+
for (ty::t tp in tps) {
2146+
let option::t[@tydesc_info] ti = none;
2147+
auto td = get_tydesc(cx, tp, false, ti);
2148+
args += [td.val];
2149+
cx = td.bcx;
2150+
}
2151+
// Kludge to work around the fact that we know the precise type of the
2152+
// value here, but the dtor expects a type that still has opaque pointers
2153+
// for type variables.
2154+
auto val_llty = lib::llvm::fn_ty_param_tys
2155+
(llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)))
2156+
.(vec::len(args));
2157+
auto val_cast = cx.build.BitCast(val.val, val_llty);
2158+
cx.build.FastCall(dtor_addr, args + [val_cast]);
2159+
2160+
cx = drop_slot(cx, val.val, inner_t_s).bcx;
21452161
cx.build.Store(C_int(0), drop_flag.val);
21462162
cx.build.Br(next_cx.llbb);
2147-
21482163
ret rslt(next_cx, C_nil());
21492164
}
21502165

@@ -2611,13 +2626,15 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
26112626
i += 1;
26122627
}
26132628
}
2614-
case (ty::ty_res(_, ?inner)) {
2629+
case (ty::ty_res(_, ?inner, ?tps)) {
2630+
auto inner1 = ty::substitute_type_params(cx.fcx.lcx.ccx.tcx,
2631+
tps, inner);
26152632
r = GEP_tup_like(r.bcx, t, av, [0, 1]);
26162633
auto llfld_a = r.val;
26172634
r = GEP_tup_like(r.bcx, t, bv, [0, 1]);
26182635
auto llfld_b = r.val;
2619-
f(r.bcx, load_if_immediate(r.bcx, llfld_a, inner),
2620-
load_if_immediate(r.bcx, llfld_b, inner), inner);
2636+
f(r.bcx, load_if_immediate(r.bcx, llfld_a, inner1),
2637+
load_if_immediate(r.bcx, llfld_b, inner1), inner1);
26212638
}
26222639
case (ty::ty_tag(?tid, ?tps)) {
26232640
auto variants = ty::tag_variants(cx.fcx.lcx.ccx.tcx, tid);
@@ -2891,9 +2908,9 @@ fn lazily_emit_tydesc_glue(&@block_ctxt cx, int field,
28912908
T_glue_fn(lcx.ccx.tn),
28922909
"drop");
28932910
ti.drop_glue = some[ValueRef](glue_fn);
2894-
auto dg = make_drop_glue;
28952911
make_generic_glue(lcx, cx.sp, ti.ty, glue_fn,
2896-
mgghf_single(dg), ti.ty_params);
2912+
mgghf_single(make_drop_glue),
2913+
ti.ty_params);
28972914
log #fmt("--- lazily_emit_tydesc_glue DROP %s",
28982915
ty_to_str(cx.fcx.lcx.ccx.tcx, ti.ty));
28992916
}
@@ -5026,7 +5043,7 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result {
50265043
auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, base);
50275044
auto offset = alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
50285045
case (ty::ty_box(_)) { abi::box_rc_field_body }
5029-
case (ty::ty_res(_, _)) { 1 }
5046+
case (ty::ty_res(_, _, _)) { 1 }
50305047
};
50315048
auto val = sub.bcx.build.GEP(sub.val, [C_int(0), C_int(offset)]);
50325049
ret lval_mem(sub.bcx, val);
@@ -7850,10 +7867,17 @@ fn trans_res_ctor(@local_ctxt cx, &span sp, &ast::_fn dtor,
78507867
auto tup_t = ty::mk_imm_tup(cx.ccx.tcx, [ty::mk_int(cx.ccx.tcx), arg_t]);
78517868
auto arg = load_if_immediate
78527869
(bcx, fcx.llargs.get(dtor.decl.inputs.(0).id), arg_t);
7853-
auto dst = GEP_tup_like(bcx, tup_t, fcx.llretptr, [0, 1]);
7870+
7871+
auto llretptr = fcx.llretptr;
7872+
if (ty::type_has_dynamic_size(cx.ccx.tcx, ret_t)) {
7873+
auto llret_t = T_ptr(T_struct([T_i32(), llvm::LLVMTypeOf(arg)]));
7874+
llretptr = bcx.build.BitCast(llretptr, llret_t);
7875+
}
7876+
7877+
auto dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
78547878
bcx = dst.bcx;
78557879
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t).bcx;
7856-
auto flag = GEP_tup_like(bcx, tup_t, fcx.llretptr, [0, 0]);
7880+
auto flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
78577881
bcx = flag.bcx;
78587882
bcx.build.Store(C_int(1), flag.val);
78597883
bcx.build.RetVoid();
@@ -7973,7 +7997,7 @@ fn trans_item(@local_ctxt cx, &ast::item item) {
79737997
trans_res_ctor(cx, item.span, dtor, ctor_id, tps);
79747998
// Create a function for the destructor
79757999
auto lldtor_decl = cx.ccx.item_ids.get(item.id);
7976-
trans_fn(cx, item.span, dtor, lldtor_decl, none, tps, dtor_id);
8000+
trans_fn(cx, item.span, dtor, lldtor_decl, none, tps, dtor_id)
79778001
}
79788002
case (ast::item_mod(?m)) {
79798003
auto sub_cx =

0 commit comments

Comments
 (0)