Skip to content

Commit 4b8779e

Browse files
committed
Pass tydescs to parametric fns, along with (dummy, presently) retptr when needed. Can call simple parametric fn now.
1 parent d55bee4 commit 4b8779e

File tree

1 file changed

+82
-66
lines changed

1 file changed

+82
-66
lines changed

src/comp/middle/trans.rs

Lines changed: 82 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ fn T_taskptr() -> TypeRef {
288288
ret T_ptr(T_task());
289289
}
290290

291+
fn T_typaram_ptr() -> TypeRef {
292+
ret T_ptr(T_i8());
293+
}
294+
291295
fn T_closure_ptr(TypeRef lltarget_ty,
292296
TypeRef llbindings_ty) -> TypeRef {
293297
ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc()),
@@ -311,7 +315,7 @@ fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
311315
ret llty;
312316
}
313317

314-
// NB: this function must match the ABI assumptions of trans_args.
318+
// NB: this must match trans_args and create_llargs_for_fn_args.
315319
fn type_of_fn_full(@crate_ctxt cx,
316320
option.t[TypeRef] obj_self,
317321
vec[ty.arg] inputs,
@@ -326,6 +330,10 @@ fn type_of_fn_full(@crate_ctxt cx,
326330
i += 1u;
327331
}
328332

333+
if (ty.type_has_dynamic_size(output)) {
334+
atys += T_typaram_ptr();
335+
}
336+
329337
alt (obj_self) {
330338
case (some[TypeRef](?t)) {
331339
check (t as int != 0);
@@ -336,19 +344,20 @@ fn type_of_fn_full(@crate_ctxt cx,
336344
}
337345
}
338346

339-
if (ty.type_has_dynamic_size(output)) {
340-
atys += T_ptr(type_of(cx, output));
341-
}
342-
343347
for (ty.arg arg in inputs) {
344-
let TypeRef t = type_of(cx, arg.ty);
345-
alt (arg.mode) {
346-
case (ast.alias) {
347-
t = T_ptr(t);
348+
if (ty.type_has_dynamic_size(arg.ty)) {
349+
check (arg.mode == ast.alias);
350+
atys += T_typaram_ptr();
351+
} else {
352+
let TypeRef t = type_of(cx, arg.ty);
353+
alt (arg.mode) {
354+
case (ast.alias) {
355+
t = T_ptr(t);
356+
}
357+
case (_) { /* fall through */ }
348358
}
349-
case (_) { /* fall through */ }
359+
atys += t;
350360
}
351-
atys += t;
352361
}
353362

354363
auto ret_ty;
@@ -441,7 +450,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
441450
fail;
442451
}
443452
case (ty.ty_param(_)) {
444-
ret T_ptr(T_i8());
453+
ret T_typaram_ptr();
445454
}
446455
}
447456
fail;
@@ -797,7 +806,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
797806
vec(C_int(0),
798807
C_int(abi.box_rc_field_body)));
799808

800-
auto body_val = load_non_structural(cx, body, body_ty);
809+
auto body_val = load_scalar_or_boxed(cx, body, body_ty);
801810
auto res = drop_ty(cx, body_val, body_ty);
802811
// FIXME: switch gc/non-gc on layer of the type.
803812
ret trans_non_gc_free(res.bcx, v);
@@ -1001,7 +1010,7 @@ fn iter_structural_ty(@block_ctxt cx,
10011010
for (@ty.t arg in args) {
10021011
auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
10031012
r = f(r.bcx,
1004-
load_non_structural(r.bcx, elt, arg),
1013+
load_scalar_or_boxed(r.bcx, elt, arg),
10051014
arg);
10061015
i += 1;
10071016
}
@@ -1011,7 +1020,7 @@ fn iter_structural_ty(@block_ctxt cx,
10111020
for (ty.field fld in fields) {
10121021
auto llfld = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
10131022
r = f(r.bcx,
1014-
load_non_structural(r.bcx, llfld, fld.ty),
1023+
load_scalar_or_boxed(r.bcx, llfld, fld.ty),
10151024
fld.ty);
10161025
i += 1;
10171026
}
@@ -1073,7 +1082,7 @@ fn iter_structural_ty(@block_ctxt cx,
10731082
auto llfldp = variant_cx.build.GEP(llvarp,
10741083
vec(C_int(0), C_int(j as int)));
10751084
auto llfld =
1076-
load_non_structural(variant_cx,
1085+
load_scalar_or_boxed(variant_cx,
10771086
llfldp, a.ty);
10781087

10791088
auto res = f(variant_cx, llfld, a.ty);
@@ -1161,7 +1170,7 @@ fn iter_sequence(@block_ctxt cx,
11611170

11621171
auto elt = body_cx.build.GEP(p0, vec(C_int(0), ix));
11631172
auto body_res = f(body_cx,
1164-
load_non_structural(body_cx, elt, elt_ty),
1173+
load_scalar_or_boxed(body_cx, elt, elt_ty),
11651174
elt_ty);
11661175
auto next_ix = body_res.bcx.build.Add(ix, C_int(1));
11671176
auto next_scaled_ix = body_res.bcx.build.Add(scaled_ix, unit_sz);
@@ -1206,7 +1215,7 @@ fn incr_all_refcnts(@block_ctxt cx,
12061215
fn drop_slot(@block_ctxt cx,
12071216
ValueRef slot,
12081217
@ty.t t) -> result {
1209-
auto llptr = load_non_structural(cx, slot, t);
1218+
auto llptr = load_scalar_or_boxed(cx, slot, t);
12101219
auto re = drop_ty(cx, llptr, t);
12111220

12121221
auto llty = val_ty(slot);
@@ -1668,7 +1677,7 @@ impure fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
16681677
auto llsubvalptr = matched_cx.build.GEP(llunionptr,
16691678
vec(C_int(0),
16701679
C_int(i)));
1671-
auto llsubval = load_non_structural(matched_cx,
1680+
auto llsubval = load_scalar_or_boxed(matched_cx,
16721681
llsubvalptr,
16731682
pat_ty(subpat));
16741683
auto subpat_res = trans_pat_match(matched_cx, subpat,
@@ -1709,7 +1718,7 @@ impure fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
17091718
for (@ast.pat subpat in subpats) {
17101719
auto llsubvalptr = this_cx.build.GEP(llunionptr,
17111720
vec(C_int(0), C_int(i)));
1712-
auto llsubval = load_non_structural(this_cx, llsubvalptr,
1721+
auto llsubval = load_scalar_or_boxed(this_cx, llsubvalptr,
17131722
pat_ty(subpat));
17141723
auto subpat_res = trans_pat_binding(this_cx, subpat,
17151724
llsubval);
@@ -1757,7 +1766,7 @@ impure fn trans_alt(@block_ctxt cx, @ast.expr expr, vec[ast.arm] arms)
17571766
ret res(last_cx, C_nil());
17581767
}
17591768

1760-
type generic_info = rec(@ty.t monotype,
1769+
type generic_info = rec(@ty.t item_type,
17611770
vec[ValueRef] tydescs);
17621771

17631772
type lval_result = rec(result res,
@@ -1815,7 +1824,7 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
18151824
append[ValueRef](tydescs,
18161825
get_tydesc(cx, t));
18171826
}
1818-
auto gen = rec( monotype = monoty,
1827+
auto gen = rec( item_type = ty.item_ty(fn_item)._1,
18191828
tydescs = tydescs );
18201829
lv = rec(generic = some[generic_info](gen)
18211830
with lv);
@@ -1969,7 +1978,7 @@ impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result {
19691978
}
19701979

19711980

1972-
// NB: this function must match the ABI assumptions of type_of_fn_full.
1981+
// NB: this must match type_of_fn_full and create_llargs_for_fn_args.
19731982
impure fn trans_args(@block_ctxt cx,
19741983
ValueRef llclosure,
19751984
option.t[ValueRef] llobj,
@@ -1980,17 +1989,19 @@ impure fn trans_args(@block_ctxt cx,
19801989
let vec[ValueRef] vs = vec(cx.fcx.lltaskptr);
19811990
let @block_ctxt bcx = cx;
19821991

1983-
let vec[ty.arg] args = vec(); // FIXME: typestate bug
1984-
alt (fn_ty.struct) {
1985-
case (ty.ty_fn(?a, _)) { args = a; }
1986-
case (_) { fail; }
1987-
}
1992+
let vec[ty.arg] args = ty.ty_fn_args(fn_ty);
19881993

19891994
alt (gen) {
19901995
case (some[generic_info](?g)) {
19911996
for (ValueRef t in g.tydescs) {
19921997
vs += t;
19931998
}
1999+
args = ty.ty_fn_args(g.item_type);
2000+
if (ty.type_has_dynamic_size(ty.ty_fn_ret(g.item_type))) {
2001+
// FIXME: allocate real outptr in caller,
2002+
// pass in to here.
2003+
vs += C_null(T_typaram_ptr());
2004+
}
19942005
}
19952006
case (_) { }
19962007
}
@@ -2019,29 +2030,33 @@ impure fn trans_args(@block_ctxt cx,
20192030
// we are now passing it as an arg, so need to load it.
20202031
re.val = re.bcx.build.Load(re.val);
20212032
}
2022-
} else {
2023-
if (mode == ast.alias) {
2024-
let lval_result lv;
2025-
if (ty.is_lval(e)) {
2026-
lv = trans_lval(bcx, e);
2027-
} else {
2028-
auto r = trans_expr(bcx, e);
2029-
lv = lval_val(r.bcx, r.val);
2030-
}
2033+
} else if (mode == ast.alias) {
2034+
let lval_result lv;
2035+
if (ty.is_lval(e)) {
2036+
lv = trans_lval(bcx, e);
2037+
} else {
2038+
auto r = trans_expr(bcx, e);
2039+
lv = lval_val(r.bcx, r.val);
2040+
}
20312041

2032-
if (!lv.is_mem) {
2033-
// Non-mem but we're trying to alias; synthesize an
2034-
// alloca, spill to it and pass its address.
2035-
auto llty = val_ty(lv.res.val);
2036-
auto llptr = lv.res.bcx.build.Alloca(llty);
2037-
lv.res.bcx.build.Store(lv.res.val, llptr);
2038-
re = res(lv.res.bcx, llptr);
2039-
} else {
2040-
re = lv.res;
2041-
}
2042+
if (!lv.is_mem) {
2043+
// Non-mem but we're trying to alias; synthesize an
2044+
// alloca, spill to it and pass its address.
2045+
auto llty = val_ty(lv.res.val);
2046+
auto llptr = lv.res.bcx.build.Alloca(llty);
2047+
lv.res.bcx.build.Store(lv.res.val, llptr);
2048+
re = res(lv.res.bcx, llptr);
20422049
} else {
2043-
re = trans_expr(bcx, e);
2050+
re = lv.res;
20442051
}
2052+
2053+
} else {
2054+
re = trans_expr(bcx, e);
2055+
}
2056+
2057+
if (ty.type_has_dynamic_size(args.(i).ty)) {
2058+
re.val = re.bcx.build.PointerCast(re.val,
2059+
T_typaram_ptr());
20452060
}
20462061

20472062
vs += re.val;
@@ -2444,7 +2459,7 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
24442459
auto t = node_ann_type(cx.fcx.ccx, ann);
24452460
auto lhs_res = trans_lval(cx, dst);
24462461
check (lhs_res.is_mem);
2447-
auto lhs_val = load_non_structural(lhs_res.res.bcx,
2462+
auto lhs_val = load_scalar_or_boxed(lhs_res.res.bcx,
24482463
lhs_res.res.val, t);
24492464
auto rhs_res = trans_expr(lhs_res.res.bcx, src);
24502465
auto v = trans_eager_binop(rhs_res.bcx, op, lhs_val, rhs_res.val);
@@ -2483,24 +2498,24 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
24832498
auto t = ty.expr_ty(e);
24842499
auto sub = trans_lval(cx, e);
24852500
ret res(sub.res.bcx,
2486-
load_non_structural(sub.res.bcx, sub.res.val, t));
2501+
load_scalar_or_boxed(sub.res.bcx, sub.res.val, t));
24872502
}
24882503
}
24892504
cx.fcx.ccx.sess.unimpl("expr variant in trans_expr");
24902505
fail;
24912506
}
24922507

24932508
// We pass structural values around the compiler "by pointer" and
2494-
// non-structural values "by value". This function selects whether
2495-
// to load a pointer or pass it.
2509+
// non-structural values (scalars and boxes) "by value". This function selects
2510+
// whether to load a pointer or pass it.
24962511

2497-
fn load_non_structural(@block_ctxt cx,
2498-
ValueRef v,
2499-
@ty.t t) -> ValueRef {
2500-
if (ty.type_is_structural(t)) {
2501-
ret v;
2502-
} else {
2512+
fn load_scalar_or_boxed(@block_ctxt cx,
2513+
ValueRef v,
2514+
@ty.t t) -> ValueRef {
2515+
if (ty.type_is_scalar(t) || ty.type_is_boxed(t)) {
25032516
ret cx.build.Load(v);
2517+
} else {
2518+
ret v;
25042519
}
25052520
}
25062521

@@ -2591,7 +2606,8 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
25912606

25922607
alt (cx.fcx.llretptr) {
25932608
case (some[ValueRef](?llptr)) {
2594-
r.bcx.build.Store(r.val, llptr);
2609+
// FIXME: Generic return: Needs to use tydesc.
2610+
// r.bcx.build.Store(r.val, llptr);
25952611
r.bcx.build.RetVoid();
25962612
}
25972613
case (none[ValueRef]) {
@@ -2801,7 +2817,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
28012817
ccx=cx);
28022818
}
28032819

2804-
2820+
// NB: this must match trans_args and type_of_fn_full.
28052821
fn create_llargs_for_fn_args(&@fn_ctxt cx,
28062822
option.t[TypeRef] ty_self,
28072823
@ty.t ret_ty,
@@ -2816,6 +2832,11 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
28162832
arg_n += 1u;
28172833
}
28182834

2835+
if (ty.type_has_dynamic_size(ret_ty)) {
2836+
cx.llretptr = some[ValueRef](llvm.LLVMGetParam(cx.llfn, arg_n));
2837+
arg_n += 1u;
2838+
}
2839+
28192840
alt (ty_self) {
28202841
case (some[TypeRef](_)) {
28212842
auto llself = llvm.LLVMGetParam(cx.llfn, arg_n);
@@ -2829,11 +2850,6 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
28292850
}
28302851
}
28312852

2832-
if (ty.type_has_dynamic_size(ret_ty)) {
2833-
cx.llretptr = some[ValueRef](llvm.LLVMGetParam(cx.llfn, arg_n));
2834-
arg_n += 1u;
2835-
}
2836-
28372853
for (ast.arg arg in args) {
28382854
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
28392855
check (llarg as int != 0);
@@ -3106,7 +3122,7 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
31063122
let int i = 0;
31073123
for (ast.obj_field f in ob.fields) {
31083124
auto arg = r.bcx.fcx.llargs.get(f.id);
3109-
arg = load_non_structural(r.bcx, arg, arg_tys.(i).ty);
3125+
arg = load_scalar_or_boxed(r.bcx, arg, arg_tys.(i).ty);
31103126
auto field = r.bcx.build.GEP(body_fields,
31113127
vec(C_int(0),C_int(i)));
31123128
r = copy_ty(r.bcx, true, field, arg, arg_tys.(i).ty);

0 commit comments

Comments
 (0)