summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-26 19:47:54 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-26 19:47:54 -0700
commitbb4ff654b3f0ce2e067e707f83310af5ebc50679 (patch)
treef3e0d5927b875b7802cde945afe7aba8b18c624e /6
parent0dd5d1f71505ce3d8a51e8244cf3128c54eb8293 (diff)
downloadmc-bb4ff654b3f0ce2e067e707f83310af5ebc50679.tar.gz
Create a new call node instead of mutating.
This should make indirect calls easier.
Diffstat (limited to '6')
-rw-r--r--6/simp.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/6/simp.c b/6/simp.c
index ae80bb7..5021494 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -1256,15 +1256,7 @@ static Node *compare(Simp *s, Node *n, int fields)
return r;
}
-static int isvariadic(Node *fn)
-{
- Type *ty;
-
- ty = exprtype(fn);
- return tybase(ty->sub[ty->nsub - 1])->type == Tyvalist;
-}
-
-static void addvatype(Simp *s, Node *n)
+static Node *vatypeinfo(Simp *s, Node *n)
{
Node *ti, *tp, *td, *tn;
Type *ft, *vt, **st;
@@ -1304,8 +1296,8 @@ static void addvatype(Simp *s, Node *n)
tp = mkexpr(Zloc, Oaddr, ti, NULL);
tp->expr.type = mktyptr(n->loc, td->decl.type);
- linsert(&n->expr.args, &n->expr.nargs, ft->nsub - 1, tp);
htput(s->globls, td, asmname(td));
+ return tp;
}
static Node *capture(Simp *s, Node *n, Node *dst)
@@ -1351,9 +1343,12 @@ static Node *capture(Simp *s, Node *n, Node *dst)
static Node *simpcall(Simp *s, Node *n, Node *dst)
{
- Node *r;
- size_t i;
+ size_t i, nargs;
+ Node **args;
+ Node *r, *call;
+ Type *ft;
+ ft = tybase(exprtype(n->expr.args[0]));
if (exprtype(n)->type == Tyvoid)
r = NULL;
else if (stacktype(exprtype(n)) && dst)
@@ -1361,25 +1356,33 @@ static Node *simpcall(Simp *s, Node *n, Node *dst)
else
r = temp(s, n);
- if (isvariadic(n->expr.args[0]))
- addvatype(s, n);
+ args = NULL;
+ nargs = 0;
+ lappend(&args, &nargs, rval(s, n->expr.args[0], NULL));
+
if (exprtype(n)->type != Tyvoid && stacktype(exprtype(n)))
- linsert(&n->expr.args, &n->expr.nargs, 1, addr(s, r, exprtype(n)));
+ lappend(&args, &nargs, addr(s, r, exprtype(n)));
- for (i = 0; i < n->expr.nargs; i++) {
- n->expr.args[i] = rval(s, n->expr.args[i], NULL);
+ for (i = 1; i < n->expr.nargs; i++) {
+ if (i < ft->nsub && tybase(ft->sub[i])->type == Tyvalist)
+ lappend(&args, &nargs, vatypeinfo(s, n));
+ lappend(&args, &nargs, rval(s, n->expr.args[i], NULL));
if (exprop(n->expr.args[i]) == Oaddr)
if (exprop(n->expr.args[i]->expr.args[0]) == Ovar)
def(s, n->expr.args[i]->expr.args[0]);
}
+ if (i < ft->nsub && tybase(ft->sub[i])->type == Tyvalist)
+ lappend(&args, &nargs, vatypeinfo(s, n));
if (r)
def(s, r);
+ call = mkexprl(n->loc, Ocall, args, nargs);
+ call->expr.type = exprtype(n);
if (r && !stacktype(exprtype(n))) {
- append(s, set(r, n));
+ append(s, set(r, call));
} else {
- append(s, n);
+ append(s, call);
}
return r;
}