about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-10-21 18:13:57 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-10-21 18:13:57 -0700
commit3f80e79efc6feaabea960793af1ff5baa1d2f141 (patch)
tree4e049b0079ee4b8c8566c73d54177ace963ec7e7 /src/comp
parent67477b85ae7404508e3a963d68dbfb09a3d247f9 (diff)
downloadrust-3f80e79efc6feaabea960793af1ff5baa1d2f141.tar.gz
rust-3f80e79efc6feaabea960793af1ff5baa1d2f141.zip
Add support for passing args to fns in rustc.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs67
1 files changed, 49 insertions, 18 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 76b654b72af..6263c3db8cb 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -42,9 +42,9 @@ type glue_fns = rec(ValueRef activate_glue,
 
 state type trans_ctxt = rec(session.session sess,
                             ModuleRef llmod,
-                            hashmap[str,ValueRef] upcalls,
-                            hashmap[str,ValueRef] fn_names,
-                            hashmap[ast.def_id,ValueRef] fn_ids,
+                            hashmap[str, ValueRef] upcalls,
+                            hashmap[str, ValueRef] fn_names,
+                            hashmap[ast.def_id, ValueRef] fn_ids,
                             @glue_fns glues,
                             namegen names,
                             str path);
@@ -52,6 +52,7 @@ state type trans_ctxt = rec(session.session sess,
 state type fn_ctxt = rec(ValueRef llfn,
                          ValueRef lloutptr,
                          ValueRef lltaskptr,
+                         hashmap[ast.def_id, ValueRef] llargs,
                          hashmap[ast.def_id, ValueRef] lllocals,
                          @trans_ctxt tcx);
 
@@ -659,17 +660,25 @@ fn trans_if(@block_ctxt cx, &ast.expr cond,
     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) {
         case (ast.expr_name(?n, ?dopt, _)) {
             alt (dopt) {
                 case (some[ast.def](?def)) {
                     alt (def) {
+                        case (ast.def_arg(?did)) {
+                            ret tup(res(cx, cx.fcx.llargs.get(did)), false);
+                        }
                         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)) {
-                            ret res(cx, cx.fcx.tcx.fn_ids.get(did));
+                            ret tup(res(cx, cx.fcx.tcx.fn_ids.get(did)),
+                                    false);
                         }
                         case (_) {
                             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(_,_,_)) {
             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, _)) {
             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,
-                    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, _)) {
             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,
                               cx.fcx.lltaskptr);
             llargs += args_res._1;
             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,
                str name,
-               ast.def_id fid,
-               TypeRef T_out,
-               vec[TypeRef] T_explicit_args) -> @fn_ctxt {
-    let vec[TypeRef] args = vec(T_ptr(T_out), // outptr.
+               &ast._fn f,
+               ast.def_id fid) -> @fn_ctxt {
+
+    let vec[TypeRef] args = vec(T_ptr(type_of(cx, f.output)), // outptr.
                                 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;
+
     let ValueRef llfn = decl_cdecl_fn(cx.llmod, name, args, T_void());
     cx.fn_names.insert(cx.path, llfn);
     cx.fn_ids.insert(fid, llfn);
+
     let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
     let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
+
     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,
              lloutptr=lloutptr,
              lltaskptr=lltaskptr,
+             llargs=llargs,
              lllocals=lllocals,
              tcx=cx);
 }
 
 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);
 }
@@ -986,6 +1016,7 @@ fn trans_exit_task_glue(@trans_ctxt cx) {
     auto fcx = @rec(llfn=llfn,
                     lloutptr=lloutptr,
                     lltaskptr=lltaskptr,
+                    llargs=new_def_hash[ValueRef](),
                     lllocals=new_def_hash[ValueRef](),
                     tcx=cx);