shithub: mc

Download patch

ref: cde7e0d999cf3d56f48d830cf3149f779d86fb31
parent: c74b0bc06994e9a4921131696a5714cf83642acc
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Sep 26 20:29:07 EDT 2015

Add indirect call operator.

    This should allow us to split up direct calls and environment
    calls. Currently, it doesn't actually do anything.

--- a/6/isel.c
+++ b/6/isel.c
@@ -481,15 +481,17 @@
 static void call(Isel *s, Node *n)
 {
     AsmOp op;
+    Node *fn;
     Loc *f;
 
-    if (isconstfn(n)) {
+    if (exprop(n) == Ocall) {
         op = Icall;
-        assert(tybase(exprtype(n))->type == Tycode);
-        f = locmeml(htget(s->globls, n), NULL, NULL, mode(n));
+        fn = n->expr.args[0];
+        assert(tybase(exprtype(fn))->type == Tycode);
+        f = locmeml(htget(s->globls, fn), NULL, NULL, mode(fn));
     } else {
         op = Icallind;
-        f = selexpr(s, n);
+        f = selexpr(s, n->expr.args[0]);
     }
     g(s, op, f, NULL);
 }
@@ -585,7 +587,7 @@
             argoff += size(n->expr.args[i]);
         }
     }
-    call(s, n->expr.args[0]);
+    call(s, n);
     if (argsz)
         g(s, Iadd, stkbump, rsp, NULL);
     if (retloc) {
@@ -778,6 +780,7 @@
             r = b;
             break;
         case Ocall:
+        case Ocallind:
             r = gencall(s, n);
             break;
         case Oret: 
--- a/6/simp.c
+++ b/6/simp.c
@@ -1345,12 +1345,14 @@
 
 static Node *simpcall(Simp *s, Node *n, Node *dst)
 {
+    Node *r, *call, *fn;
     size_t i, nargs;
     Node **args;
-    Node *r, *call;
     Type *ft;
+    Op op;
 
-    ft = tybase(exprtype(n->expr.args[0]));
+    fn = n->expr.args[0];
+    ft = tybase(exprtype(fn));
     if (exprtype(n)->type == Tyvoid)
         r = NULL;
     else if (isstacktype(exprtype(n)) && dst)
@@ -1360,7 +1362,11 @@
 
     args = NULL;
     nargs = 0;
-    lappend(&args, &nargs, getcode(s, n->expr.args[0]));
+    if (isconstfn(fn))
+        op = Ocall;
+    else
+        op = Ocallind;
+    lappend(&args, &nargs, getcode(s, fn));
 
     if (exprtype(n)->type != Tyvoid && isstacktype(exprtype(n)))
         lappend(&args, &nargs, addr(s, r, exprtype(n)));
@@ -1379,7 +1385,7 @@
     if (r)
         def(s, r);
 
-    call = mkexprl(n->loc, Ocall, args, nargs);
+    call = mkexprl(n->loc, op, args, nargs);
     call->expr.type = exprtype(n);
     if (r && !isstacktype(exprtype(n))) {
         append(s, set(r, call));
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1480,7 +1480,7 @@
             n->expr.type = mktype(n->loc, Tyvoid);
             break;
         case Obad: case Ocjmp: case Ovjmp: case Oset:
-        case Oslbase: case Osllen: case Outag:
+        case Oslbase: case Osllen: case Outag: case Ocallind:
         case Oblit: case  Oclear: case Oudata:
         case Otrunc: case Oswiden: case Ozwiden:
         case Oint2flt: case Oflt2int: case Oflt2flt:
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -69,6 +69,7 @@
 O(Oudata,	1,	OTpre,  "UDATA")        /* pointer to contents of union */
 O(Oblit,	1,	OTbin,  "BLIT")         /* blit memory */
 O(Oclear,       1,      OTpre,  "CLEAR")        /* zero */
+O(Ocallind,     1,      OTpre,  "CALL")         /* call with environment */
 
 /* integer conversions */
 O(Otrunc,	1,	OTmisc, NULL)   /* truncating cast */