Skip to content

Commit 93d2a4f

Browse files
committed
Add support for basic return-by-alias to trans
Issue #918
1 parent 9a69ee7 commit 93d2a4f

File tree

4 files changed

+75
-58
lines changed

4 files changed

+75
-58
lines changed

src/comp/middle/trans.rs

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,18 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
6161

6262
// NB: must keep 4 fns in sync:
6363
//
64-
// - type_of_fn_full
64+
// - type_of_fn
6565
// - create_llargs_for_fn_args.
6666
// - new_fn_ctxt
6767
// - trans_args
68-
fn type_of_fn_full(cx: @crate_ctxt, sp: span, proto: ast::proto,
69-
is_method: bool, inputs: [ty::arg], output: ty::t,
70-
ty_param_count: uint) -> TypeRef {
68+
fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto,
69+
is_method: bool, ret_ref: bool, inputs: [ty::arg],
70+
output: ty::t, ty_param_count: uint) -> TypeRef {
7171
let atys: [TypeRef] = [];
7272

7373
// Arg 0: Output pointer.
74-
atys += [T_ptr(type_of_inner(cx, sp, output))];
74+
let out_ty = T_ptr(type_of_inner(cx, sp, output));
75+
atys += [ret_ref ? T_ptr(out_ty) : out_ty];
7576

7677
// Arg 1: task pointer.
7778
atys += [T_taskptr(*cx)];
@@ -97,17 +98,13 @@ fn type_of_fn_full(cx: @crate_ctxt, sp: span, proto: ast::proto,
9798
ret T_fn(atys, llvm::LLVMVoidType());
9899
}
99100

100-
fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto, inputs: [ty::arg],
101-
output: ty::t, ty_param_count: uint) -> TypeRef {
102-
ret type_of_fn_full(cx, sp, proto, false, inputs, output, ty_param_count);
103-
}
104-
105101
// Given a function type and a count of ty params, construct an llvm type
106102
fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
107103
ty_param_count: uint) -> TypeRef {
104+
let by_ref = ty::ty_fn_ret_style(cx.tcx, fty) == ast::return_ref;
108105
ret type_of_fn(cx, sp, ty::ty_fn_proto(cx.tcx, fty),
109-
ty::ty_fn_args(cx.tcx, fty), ty::ty_fn_ret(cx.tcx, fty),
110-
ty_param_count);
106+
false, by_ref, ty::ty_fn_args(cx.tcx, fty),
107+
ty::ty_fn_ret(cx.tcx, fty), ty_param_count);
111108
}
112109

113110
fn type_of_native_fn(cx: @crate_ctxt, sp: span, abi: ast::native_abi,
@@ -2970,12 +2967,13 @@ fn trans_field(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
29702967
vtbl = PointerCast(cx, vtbl, vtbl_type);
29712968

29722969
let v = GEP(r.bcx, vtbl, [C_int(0), C_int(ix as int)]);
2973-
let fn_ty: ty::t = ty::method_ty_to_fn_ty(bcx_tcx(cx), methods[ix]);
29742970
let tcx = bcx_tcx(cx);
2971+
let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, methods[ix]);
2972+
let ret_ref = ty::ty_fn_ret_style(tcx, fn_ty) == ast::return_ref;
29752973
let ll_fn_ty =
2976-
type_of_fn_full(bcx_ccx(cx), sp, ty::ty_fn_proto(tcx, fn_ty),
2977-
true, ty::ty_fn_args(tcx, fn_ty),
2978-
ty::ty_fn_ret(tcx, fn_ty), 0u);
2974+
type_of_fn(bcx_ccx(cx), sp, ty::ty_fn_proto(tcx, fn_ty),
2975+
true, ret_ref, ty::ty_fn_args(tcx, fn_ty),
2976+
ty::ty_fn_ret(tcx, fn_ty), 0u);
29792977
v = PointerCast(r.bcx, v, T_ptr(T_ptr(ll_fn_ty)));
29802978
let lvo = lval_mem(r.bcx, v);
29812979
ret {llobj: some::<ValueRef>(r.val), method_ty: some::<ty::t>(fn_ty)
@@ -3513,26 +3511,28 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
35133511

35143512
// NB: must keep 4 fns in sync:
35153513
//
3516-
// - type_of_fn_full
3514+
// - type_of_fn
35173515
// - create_llargs_for_fn_args.
35183516
// - new_fn_ctxt
35193517
// - trans_args
35203518
fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
35213519
lliterbody: option::t<ValueRef>, es: [@ast::expr], fn_ty: ty::t)
3522-
->
3523-
{bcx: @block_ctxt,
3524-
args: [ValueRef],
3525-
retslot: ValueRef,
3526-
to_zero: [{v: ValueRef, t: ty::t}],
3527-
to_revoke: [{v: ValueRef, t: ty::t}]} {
3520+
-> {bcx: @block_ctxt,
3521+
args: [ValueRef],
3522+
retslot: ValueRef,
3523+
to_zero: [{v: ValueRef, t: ty::t}],
3524+
to_revoke: [{v: ValueRef, t: ty::t}],
3525+
by_ref: bool} {
35283526

35293527
let args: [ty::arg] = ty::ty_fn_args(bcx_tcx(cx), fn_ty);
35303528
let llargs: [ValueRef] = [];
35313529
let lltydescs: [ValueRef] = [];
35323530
let to_zero = [];
35333531
let to_revoke = [];
35343532

3533+
let tcx = bcx_tcx(cx);
35353534
let bcx: @block_ctxt = cx;
3535+
let by_ref = ty::ty_fn_ret_style(tcx, fn_ty) == ast::return_ref;
35363536
// Arg 0: Output pointer.
35373537

35383538
// FIXME: test case looks like
@@ -3544,22 +3544,25 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
35443544
args: [],
35453545
retslot: C_nil(),
35463546
to_zero: to_zero,
3547-
to_revoke: to_revoke};
3547+
to_revoke: to_revoke,
3548+
by_ref: by_ref};
35483549
}
3549-
let retty = ty::ty_fn_ret(bcx_tcx(cx), fn_ty);
3550-
let llretslot_res = alloc_ty(bcx, retty);
3550+
let retty = ty::ty_fn_ret(tcx, fn_ty);
3551+
let llretslot_res = if by_ref {
3552+
rslt(cx, alloca(cx, T_ptr(type_of_or_i8(cx, retty))))
3553+
} else { alloc_ty(bcx, retty) };
35513554
bcx = llretslot_res.bcx;
35523555
let llretslot = llretslot_res.val;
35533556
alt gen {
35543557
some(g) {
35553558
lazily_emit_all_generic_info_tydesc_glues(cx, g);
35563559
lltydescs = g.tydescs;
3557-
args = ty::ty_fn_args(bcx_tcx(cx), g.item_type);
3558-
retty = ty::ty_fn_ret(bcx_tcx(cx), g.item_type);
3560+
args = ty::ty_fn_args(tcx, g.item_type);
3561+
retty = ty::ty_fn_ret(tcx, g.item_type);
35593562
}
35603563
_ { }
35613564
}
3562-
if ty::type_contains_params(bcx_tcx(cx), retty) {
3565+
if ty::type_contains_params(tcx, retty) {
35633566
// It's possible that the callee has some generic-ness somewhere in
35643567
// its return value -- say a method signature within an obj or a fn
35653568
// type deep in a structure -- which the caller has a concrete view
@@ -3583,8 +3586,8 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
35833586
none. { }
35843587
some(lli) {
35853588
let lli =
3586-
if ty::type_contains_params(bcx_tcx(cx), retty) {
3587-
let body_ty = ty::mk_iter_body_fn(bcx_tcx(cx), retty);
3589+
if ty::type_contains_params(tcx, retty) {
3590+
let body_ty = ty::mk_iter_body_fn(tcx, retty);
35883591
let body_llty = type_of_inner(bcx_ccx(cx), cx.sp, body_ty);
35893592
PointerCast(bcx, lli, T_ptr(body_llty))
35903593
} else { lli };
@@ -3615,7 +3618,8 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
36153618
args: llargs,
36163619
retslot: llretslot,
36173620
to_zero: to_zero,
3618-
to_revoke: to_revoke};
3621+
to_revoke: to_revoke,
3622+
by_ref: by_ref};
36193623
}
36203624

36213625
fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
@@ -3686,11 +3690,16 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
36863690
alt lliterbody {
36873691
none. {
36883692
if !ty::type_is_nil(bcx_tcx(cx), ret_ty) {
3689-
retval = load_if_immediate(bcx, llretslot, ret_ty);
3690-
// Retval doesn't correspond to anything really tangible
3691-
// in the frame, but it's a ref all the same, so we put a
3692-
// note here to drop it when we're done in this scope.
3693-
add_clean_temp(in_cx, retval, ret_ty);
3693+
if args_res.by_ref {
3694+
let retptr = Load(bcx, llretslot);
3695+
retval = load_if_immediate(bcx, retptr, ret_ty);
3696+
} else {
3697+
retval = load_if_immediate(bcx, llretslot, ret_ty);
3698+
// Retval doesn't correspond to anything really tangible
3699+
// in the frame, but it's a ref all the same, so we put a
3700+
// note here to drop it when we're done in this scope.
3701+
add_clean_temp(in_cx, retval, ret_ty);
3702+
}
36943703
}
36953704
}
36963705
some(_) {
@@ -4386,7 +4395,7 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
43864395
bcx = lv.res.bcx;
43874396
if cx.fcx.ret_style == ast::return_ref {
43884397
assert lv.is_mem;
4389-
Store(bcx, cx.fcx.llretptr, lv.res.val);
4398+
Store(bcx, lv.res.val, cx.fcx.llretptr);
43904399
} else {
43914400
let is_local = alt x.node {
43924401
ast::expr_path(p) {
@@ -4824,7 +4833,7 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
48244833

48254834
// NB: must keep 4 fns in sync:
48264835
//
4827-
// - type_of_fn_full
4836+
// - type_of_fn
48284837
// - create_llargs_for_fn_args.
48294838
// - new_fn_ctxt
48304839
// - trans_args
@@ -4864,7 +4873,7 @@ fn new_fn_ctxt(cx: @local_ctxt, sp: span, llfndecl: ValueRef) -> @fn_ctxt {
48644873

48654874
// NB: must keep 4 fns in sync:
48664875
//
4867-
// - type_of_fn_full
4876+
// - type_of_fn
48684877
// - create_llargs_for_fn_args.
48694878
// - new_fn_ctxt
48704879
// - trans_args
@@ -5355,10 +5364,10 @@ fn decl_fn_and_pair_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
53555364
let llfty =
53565365
type_of_fn_from_ty(ccx, sp, node_type, std::vec::len(ty_params));
53575366
alt ty::struct(ccx.tcx, node_type) {
5358-
ty::ty_fn(proto, inputs, output, _, _) {
5359-
llfty =
5360-
type_of_fn(ccx, sp, proto, inputs, output,
5361-
std::vec::len::<ast::ty_param>(ty_params));
5367+
ty::ty_fn(proto, inputs, output, rs, _) {
5368+
llfty = type_of_fn(ccx, sp, proto, false,
5369+
rs == ast::return_ref, inputs, output,
5370+
vec::len(ty_params));
53625371
}
53635372
_ { ccx.sess.bug("decl_fn_and_pair(): fn item doesn't have fn type!"); }
53645373
}
@@ -5396,9 +5405,8 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
53965405
let vecarg_ty: ty::arg =
53975406
{mode: ast::by_ref,
53985407
ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mut: ast::imm})};
5399-
let llfty =
5400-
type_of_fn(ccx, sp, ast::proto_fn, [vecarg_ty],
5401-
ty::mk_nil(ccx.tcx), 0u);
5408+
let llfty = type_of_fn(ccx, sp, ast::proto_fn, false, false,
5409+
[vecarg_ty], ty::mk_nil(ccx.tcx), 0u);
54025410
let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty);
54035411

54045412
let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl);
@@ -5499,7 +5507,8 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
54995507
x: ty::t) -> TypeRef {
55005508
alt ty::struct(cx.tcx, x) {
55015509
ty::ty_native_fn(abi, args, out) {
5502-
ret type_of_fn(cx, sp, ast::proto_fn, args, out, ty_param_count);
5510+
ret type_of_fn(cx, sp, ast::proto_fn, false, false, args, out,
5511+
ty_param_count);
55035512
}
55045513
}
55055514
}

src/comp/middle/trans_common.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import syntax::print::pprust::{expr_to_str, path_to_str};
3333
import bld = trans_build;
3434

3535
// FIXME: These should probably be pulled in here too.
36-
import trans::{type_of_fn_full, drop_ty};
36+
import trans::{type_of_fn, drop_ty};
3737

3838
obj namegen(mutable i: int) {
3939
fn next(prefix: str) -> str { i += 1; ret prefix + int::str(i); }
@@ -336,10 +336,9 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t)
336336
}
337337

338338
let params = csearch::get_type_param_count(ccx.sess.get_cstore(), did);
339-
let f_t =
340-
trans::type_of_fn(ccx, sp, ast::proto_fn,
341-
[{mode: ast::by_ref, ty: inner_t}],
342-
ty::mk_nil(ccx.tcx), params);
339+
let f_t = type_of_fn(ccx, sp, ast::proto_fn, false, false,
340+
[{mode: ast::by_ref, ty: inner_t}],
341+
ty::mk_nil(ccx.tcx), params);
343342
ret trans::get_extern_const(ccx.externs, ccx.llmod,
344343
csearch::get_symbol(ccx.sess.get_cstore(),
345344
did),

src/comp/middle/trans_objects.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -880,9 +880,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
880880

881881
let llfnty = T_nil();
882882
alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.node.id)) {
883-
ty::ty_fn(proto, inputs, output, _, _) {
884-
llfnty =
885-
type_of_fn_full(cx.ccx, m.span, proto, true, inputs, output,
883+
ty::ty_fn(proto, inputs, output, rs, _) {
884+
llfnty = type_of_fn(cx.ccx, m.span, proto, true,
885+
rs == ast::return_ref, inputs, output,
886886
vec::len(ty_params));
887887
}
888888
}
@@ -933,8 +933,8 @@ fn populate_self_stack(bcx: @block_ctxt, self_stack: ValueRef,
933933

934934
fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method,
935935
tps: [ast::ty_param]) -> TypeRef {
936-
type_of_fn_full(ccx, sp, m.proto, true, m.inputs, m.output,
937-
vec::len(tps))
936+
type_of_fn(ccx, sp, m.proto, true, m.cf == ast::return_ref,
937+
m.inputs, m.output, vec::len(tps))
938938
}
939939

940940
//

src/comp/middle/ty.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export ty_fn;
118118
export ty_fn_abi;
119119
export ty_fn_proto;
120120
export ty_fn_ret;
121+
export ty_fn_ret_style;
121122
export ty_int;
122123
export ty_str;
123124
export ty_vec;
@@ -1609,6 +1610,14 @@ fn ty_fn_ret(cx: ctxt, fty: t) -> t {
16091610
}
16101611
}
16111612

1613+
fn ty_fn_ret_style(cx: ctxt, fty: t) -> ast::ret_style {
1614+
alt struct(cx, fty) {
1615+
ty::ty_fn(_, _, _, rs, _) { rs }
1616+
ty::ty_native_fn(_, _, _) { ast::return_val }
1617+
_ { cx.sess.bug("ty_fn_ret_style() called on non-fn type"); }
1618+
}
1619+
}
1620+
16121621
fn is_fn_ty(cx: ctxt, fty: t) -> bool {
16131622
alt struct(cx, fty) {
16141623
ty::ty_fn(_, _, _, _, _) { ret true; }

0 commit comments

Comments
 (0)