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 */