Commit 1d31a25d authored by Ken Thompson's avatar Ken Thompson

more coroutine

fixed a,b,c := x,x,x

SVN=126250
parent f86c6f67
......@@ -172,17 +172,17 @@ cgen(Node *n, Node *res)
break;
case OCALLMETH:
cgen_callmeth(n);
cgen_callmeth(n, 0);
cgen_callret(n, res);
break;
case OCALLINTER:
cgen_callinter(n, res);
cgen_callinter(n, res, 0);
cgen_callret(n, res);
break;
case OCALL:
cgen_call(n);
cgen_call(n, 0);
cgen_callret(n, res);
break;
......@@ -281,17 +281,17 @@ agen(Node *n, Node *res)
// break;
case OCALLMETH:
cgen_callmeth(n);
cgen_callmeth(n, 0);
cgen_aret(n, res);
break;
case OCALLINTER:
cgen_callinter(n, res);
cgen_callinter(n, res, 0);
cgen_aret(n, res);
break;
case OCALL:
cgen_call(n);
cgen_call(n, 0);
cgen_aret(n, res);
break;
......
......@@ -14,6 +14,7 @@ enum
};
static Node* curfn;
static Node* newproc;
void
compile(Node *fn)
......@@ -23,6 +24,16 @@ compile(Node *fn)
Prog *ptxt;
long lno;
if(newproc == N) {
newproc = nod(ONAME, N, N);
memset(newproc, 0, sizeof(*newproc));
newproc->op = ONAME;
newproc->sym = pkglookup("_newproc", "sys");
newproc->class = PEXTERN;
newproc->addable = 1;
newproc->ullman = 0;
}
if(fn->nbody == N)
return;
lno = setlineno(fn);
......@@ -298,15 +309,19 @@ loop:
break;
case OCALLMETH:
cgen_callmeth(n);
cgen_callmeth(n, 0);
break;
case OCALLINTER:
cgen_callinter(n, N);
cgen_callinter(n, N, 0);
break;
case OCALL:
cgen_call(n);
cgen_call(n, 0);
break;
case OPROC:
cgen_proc(n);
break;
case ORETURN:
......@@ -552,7 +567,21 @@ genpanic(void)
}
void
cgen_callinter(Node *n, Node *res)
ginscall(Node *f, int proc)
{
Node regax;
if(proc) {
nodreg(&regax, types[TINT64], D_AX);
gins(ALEAQ, f, &regax);
gins(ACALL, N, newproc);
return;
}
gins(ACALL, N, f);
}
void
cgen_callinter(Node *n, Node *res, int proc)
{
Node *i, *f;
Node tmpi, nodo, nodr, nodsp;
......@@ -588,21 +617,19 @@ cgen_callinter(Node *n, Node *res)
nodo.xoffset -= widthptr;
cgen(&nodo, &nodr); // REG = 0(REG) -- i.m
//print("field = %N\n", f);
//print("offset = %ld\n", n->left->xoffset);
nodo.xoffset = n->left->xoffset + 4*widthptr;
cgen(&nodo, &nodr); // REG = 32+offset(REG) -- i.m->fun[f]
gins(ACALL, N, &nodr);
regfree(&nodr);
ginscall(&nodr, proc);
regfree(&nodr);
regfree(&nodo);
setmaxarg(n->left->type);
}
void
cgen_callmeth(Node *n)
cgen_callmeth(Node *n, int proc)
{
Node *l;
......@@ -619,14 +646,14 @@ cgen_callmeth(Node *n)
if(n->left->op == ONAME)
n->left->class = PEXTERN;
cgen_call(n);
cgen_call(n, proc);
}
void
cgen_call(Node *n)
cgen_call(Node *n, int proc)
{
Type *t;
Node nod, afun;
Node nod, afun, regax;
if(n == N)
return;
......@@ -652,7 +679,7 @@ cgen_call(Node *n)
if(n->left->ullman >= UINF) {
regalloc(&nod, types[tptr], N);
cgen_as(&nod, &afun, 0);
gins(ACALL, N, &nod);
ginscall(&nod, proc);
regfree(&nod);
goto ret;
}
......@@ -661,19 +688,41 @@ cgen_call(Node *n)
if(isptr[n->left->type->etype]) {
regalloc(&nod, types[tptr], N);
cgen_as(&nod, n->left, 0);
gins(ACALL, N, &nod);
ginscall(&nod, proc);
regfree(&nod);
goto ret;
}
// call direct
n->left->method = 1;
gins(ACALL, N, n->left);
ginscall(n->left, proc);
ret:
;
}
void
cgen_proc(Node *n)
{
switch(n->left->op) {
default:
fatal("cgen_proc: unknown call %O", n->left->op);
case OCALLMETH:
cgen_callmeth(n->left, 1);
break;
case OCALLINTER:
cgen_callinter(n->left, N, 1);
break;
case OCALL:
cgen_call(n->left, 1);
break;
}
}
void
cgen_callret(Node *n, Node *res)
{
......
......@@ -113,9 +113,10 @@ void agen_inter(Node*, Node*);
void cgen_as(Node*, Node*, int);
void cgen_asop(Node*);
void cgen_ret(Node*);
void cgen_call(Node*);
void cgen_callmeth(Node*);
void cgen_callinter(Node*, Node*);
void cgen_call(Node*, int);
void cgen_callmeth(Node*, int);
void cgen_callinter(Node*, Node*, int);
void cgen_proc(Node*);
void cgen_callret(Node*, Node*);
void cgen_div(int, Node*, Node*, Node*);
void cgen_shift(int, Node*, Node*, Node*);
......
......@@ -1673,7 +1673,6 @@ tempname(Node *n, Type *t)
n->op = ONAME;
n->sym = s;
n->type = t;
n->sym = s;
n->etype = t->etype;
n->class = PAUTO;
n->addable = 1;
......
......@@ -581,7 +581,6 @@ Node* nodpanic(long);
Node* newcompat(Node*);
Node* stringop(Node*, int);
Node* mapop(Node*, int);
Node* procop(Node*);
Node* convas(Node*);
void arrayconv(Type*, Node*);
Node* colas(Node*, Node*);
......
......@@ -44,8 +44,6 @@ func mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
func mapassign1(hmap *map[any]any, key any, val any);
func mapassign2(hmap *map[any]any, key any, val any, pres bool);
func newproc() bool; // create a new coroutine; true is child
func readfile(string) (string, bool); // read file into string; boolean status
func exit(int32);
......@@ -93,9 +91,6 @@ export
mapassign1
mapassign2
// threads/coroutines
newproc
// files
readfile
......
This diff is collapsed.
......@@ -159,7 +159,7 @@ loop:
case OPROC:
if(top != Etop)
goto nottop;
*n = *procop(n);
walktype(n->left, Etop);
goto ret;
case OCALLMETH:
......@@ -1594,27 +1594,6 @@ nottop:
return N;
}
Node*
procop(Node *n)
{
Node *r, *on;
switch(n->op) {
default:
fatal("mapop: unknown op %E", n->op);
case OPROC: // rewrite if(sys.newproc()) (n->left)
on = syslook("newproc", 0);
r = nod(OIF, N, N);
r->ntest = nod(OCALL, on, N);
r->nbody = n->left;
dump("newproc", r);
walktype(r, Etop);
break;
}
return r;
}
void
diagnamed(Type *t)
{
......@@ -1772,6 +1751,7 @@ colas(Node *nl, Node *nr)
l = listnext(&savel);
r = listnext(&saver);
}
n = rev(n);
return n;
multi:
......@@ -1827,6 +1807,7 @@ multi:
n = nod(OLIST, n, a);
break;
}
n = rev(n);
return n;
badt:
......
......@@ -179,6 +179,12 @@ easy:
TEXT _endmorestack(SB), 7, $-8
RET
// call a subroutine in a new coroutine
// argument list is on the stack addr of fn is in AX
TEXT sys·_newproc(SB), 7, $0
JMP AX
RET
TEXT FLUSH(SB),7,$-8
RET
......@@ -186,5 +192,4 @@ TEXT getu(SB),7,$-8
MOVQ R15, AX
RET
GLOBL peruser<>(SB),$64
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment