Add support for passing args to fns in rustc.
This commit is contained in:
parent
67477b85ae
commit
3f80e79efc
1 changed files with 49 additions and 18 deletions
|
@ -42,9 +42,9 @@ type glue_fns = rec(ValueRef activate_glue,
|
||||||
|
|
||||||
state type trans_ctxt = rec(session.session sess,
|
state type trans_ctxt = rec(session.session sess,
|
||||||
ModuleRef llmod,
|
ModuleRef llmod,
|
||||||
hashmap[str,ValueRef] upcalls,
|
hashmap[str, ValueRef] upcalls,
|
||||||
hashmap[str,ValueRef] fn_names,
|
hashmap[str, ValueRef] fn_names,
|
||||||
hashmap[ast.def_id,ValueRef] fn_ids,
|
hashmap[ast.def_id, ValueRef] fn_ids,
|
||||||
@glue_fns glues,
|
@glue_fns glues,
|
||||||
namegen names,
|
namegen names,
|
||||||
str path);
|
str path);
|
||||||
|
@ -52,6 +52,7 @@ state type trans_ctxt = rec(session.session sess,
|
||||||
state type fn_ctxt = rec(ValueRef llfn,
|
state type fn_ctxt = rec(ValueRef llfn,
|
||||||
ValueRef lloutptr,
|
ValueRef lloutptr,
|
||||||
ValueRef lltaskptr,
|
ValueRef lltaskptr,
|
||||||
|
hashmap[ast.def_id, ValueRef] llargs,
|
||||||
hashmap[ast.def_id, ValueRef] lllocals,
|
hashmap[ast.def_id, ValueRef] lllocals,
|
||||||
@trans_ctxt tcx);
|
@trans_ctxt tcx);
|
||||||
|
|
||||||
|
@ -659,17 +660,25 @@ fn trans_if(@block_ctxt cx, &ast.expr cond,
|
||||||
ret res(next_cx, phi);
|
ret res(next_cx, phi);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_lval(@block_ctxt cx, &ast.expr e) -> result {
|
// The additional bool returned indicates whether it's a local
|
||||||
|
// (that is represented as an alloca, hence needs a 'load' to be
|
||||||
|
// used as an rval).
|
||||||
|
|
||||||
|
fn trans_lval(@block_ctxt cx, &ast.expr e) -> tup(result, bool) {
|
||||||
alt (e.node) {
|
alt (e.node) {
|
||||||
case (ast.expr_name(?n, ?dopt, _)) {
|
case (ast.expr_name(?n, ?dopt, _)) {
|
||||||
alt (dopt) {
|
alt (dopt) {
|
||||||
case (some[ast.def](?def)) {
|
case (some[ast.def](?def)) {
|
||||||
alt (def) {
|
alt (def) {
|
||||||
|
case (ast.def_arg(?did)) {
|
||||||
|
ret tup(res(cx, cx.fcx.llargs.get(did)), false);
|
||||||
|
}
|
||||||
case (ast.def_local(?did)) {
|
case (ast.def_local(?did)) {
|
||||||
ret res(cx, cx.fcx.lllocals.get(did));
|
ret tup(res(cx, cx.fcx.lllocals.get(did)), true);
|
||||||
}
|
}
|
||||||
case (ast.def_fn(?did)) {
|
case (ast.def_fn(?did)) {
|
||||||
ret res(cx, cx.fcx.tcx.fn_ids.get(did));
|
ret tup(res(cx, cx.fcx.tcx.fn_ids.get(did)),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
cx.fcx.tcx.sess.unimpl("def variant in trans");
|
cx.fcx.tcx.sess.unimpl("def variant in trans");
|
||||||
|
@ -731,24 +740,30 @@ fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
|
||||||
|
|
||||||
case (ast.expr_name(_,_,_)) {
|
case (ast.expr_name(_,_,_)) {
|
||||||
auto sub = trans_lval(cx, e);
|
auto sub = trans_lval(cx, e);
|
||||||
ret res(sub.bcx, cx.build.Load(sub.val));
|
if (sub._1) {
|
||||||
|
ret res(sub._0.bcx, cx.build.Load(sub._0.val));
|
||||||
|
} else {
|
||||||
|
ret sub._0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case (ast.expr_assign(?dst, ?src, _)) {
|
case (ast.expr_assign(?dst, ?src, _)) {
|
||||||
auto lhs_res = trans_lval(cx, *dst);
|
auto lhs_res = trans_lval(cx, *dst);
|
||||||
auto rhs_res = trans_expr(lhs_res.bcx, *src);
|
check (lhs_res._1);
|
||||||
|
auto rhs_res = trans_expr(lhs_res._0.bcx, *src);
|
||||||
ret res(rhs_res.bcx,
|
ret res(rhs_res.bcx,
|
||||||
cx.build.Store(rhs_res.val, lhs_res.val));
|
cx.build.Store(rhs_res.val, lhs_res._0.val));
|
||||||
}
|
}
|
||||||
|
|
||||||
case (ast.expr_call(?f, ?args, _)) {
|
case (ast.expr_call(?f, ?args, _)) {
|
||||||
auto f_res = trans_lval(cx, *f);
|
auto f_res = trans_lval(cx, *f);
|
||||||
auto args_res = trans_exprs(f_res.bcx, args);
|
check (! f_res._1);
|
||||||
|
auto args_res = trans_exprs(f_res._0.bcx, args);
|
||||||
auto llargs = vec(cx.fcx.lloutptr,
|
auto llargs = vec(cx.fcx.lloutptr,
|
||||||
cx.fcx.lltaskptr);
|
cx.fcx.lltaskptr);
|
||||||
llargs += args_res._1;
|
llargs += args_res._1;
|
||||||
ret res(args_res._0,
|
ret res(args_res._0,
|
||||||
cx.build.Call(f_res.val, llargs));
|
cx.build.Call(f_res._0.val, llargs));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -923,31 +938,46 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
|
||||||
|
|
||||||
fn new_fn_ctxt(@trans_ctxt cx,
|
fn new_fn_ctxt(@trans_ctxt cx,
|
||||||
str name,
|
str name,
|
||||||
ast.def_id fid,
|
&ast._fn f,
|
||||||
TypeRef T_out,
|
ast.def_id fid) -> @fn_ctxt {
|
||||||
vec[TypeRef] T_explicit_args) -> @fn_ctxt {
|
|
||||||
let vec[TypeRef] args = vec(T_ptr(T_out), // outptr.
|
let vec[TypeRef] args = vec(T_ptr(type_of(cx, f.output)), // outptr.
|
||||||
T_taskptr() // taskptr
|
T_taskptr() // taskptr
|
||||||
);
|
);
|
||||||
|
let uint arg_n = _vec.len[TypeRef](args);
|
||||||
|
|
||||||
|
let vec[TypeRef] T_explicit_args = vec();
|
||||||
|
for (ast.arg arg in f.inputs) {
|
||||||
|
T_explicit_args += type_of(cx, arg.ty);
|
||||||
|
}
|
||||||
args += T_explicit_args;
|
args += T_explicit_args;
|
||||||
|
|
||||||
let ValueRef llfn = decl_cdecl_fn(cx.llmod, name, args, T_void());
|
let ValueRef llfn = decl_cdecl_fn(cx.llmod, name, args, T_void());
|
||||||
cx.fn_names.insert(cx.path, llfn);
|
cx.fn_names.insert(cx.path, llfn);
|
||||||
cx.fn_ids.insert(fid, llfn);
|
cx.fn_ids.insert(fid, llfn);
|
||||||
|
|
||||||
let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
|
let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
|
||||||
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
|
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
|
||||||
|
|
||||||
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
|
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
|
||||||
|
let hashmap[ast.def_id, ValueRef] llargs = new_def_hash[ValueRef]();
|
||||||
|
|
||||||
|
for (ast.arg arg in f.inputs) {
|
||||||
|
llargs.insert(arg.id, llvm.LLVMGetParam(llfn, arg_n));
|
||||||
|
arg_n += 1u;
|
||||||
|
}
|
||||||
|
|
||||||
ret @rec(llfn=llfn,
|
ret @rec(llfn=llfn,
|
||||||
lloutptr=lloutptr,
|
lloutptr=lloutptr,
|
||||||
lltaskptr=lltaskptr,
|
lltaskptr=lltaskptr,
|
||||||
|
llargs=llargs,
|
||||||
lllocals=lllocals,
|
lllocals=lllocals,
|
||||||
tcx=cx);
|
tcx=cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_fn(@trans_ctxt cx, &ast._fn f, ast.def_id fid) {
|
fn trans_fn(@trans_ctxt cx, &ast._fn f, ast.def_id fid) {
|
||||||
let TypeRef out = T_int();
|
|
||||||
let vec[TypeRef] args = vec();
|
|
||||||
|
|
||||||
auto fcx = new_fn_ctxt(cx, cx.path, fid, out, args);
|
auto fcx = new_fn_ctxt(cx, cx.path, f, fid);
|
||||||
|
|
||||||
trans_block(new_top_block_ctxt(fcx), f.body);
|
trans_block(new_top_block_ctxt(fcx), f.body);
|
||||||
}
|
}
|
||||||
|
@ -986,6 +1016,7 @@ fn trans_exit_task_glue(@trans_ctxt cx) {
|
||||||
auto fcx = @rec(llfn=llfn,
|
auto fcx = @rec(llfn=llfn,
|
||||||
lloutptr=lloutptr,
|
lloutptr=lloutptr,
|
||||||
lltaskptr=lltaskptr,
|
lltaskptr=lltaskptr,
|
||||||
|
llargs=new_def_hash[ValueRef](),
|
||||||
lllocals=new_def_hash[ValueRef](),
|
lllocals=new_def_hash[ValueRef](),
|
||||||
tcx=cx);
|
tcx=cx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue