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) ...@@ -172,17 +172,17 @@ cgen(Node *n, Node *res)
break; break;
case OCALLMETH: case OCALLMETH:
cgen_callmeth(n); cgen_callmeth(n, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
case OCALLINTER: case OCALLINTER:
cgen_callinter(n, res); cgen_callinter(n, res, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
case OCALL: case OCALL:
cgen_call(n); cgen_call(n, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
...@@ -281,17 +281,17 @@ agen(Node *n, Node *res) ...@@ -281,17 +281,17 @@ agen(Node *n, Node *res)
// break; // break;
case OCALLMETH: case OCALLMETH:
cgen_callmeth(n); cgen_callmeth(n, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
case OCALLINTER: case OCALLINTER:
cgen_callinter(n, res); cgen_callinter(n, res, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
case OCALL: case OCALL:
cgen_call(n); cgen_call(n, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
......
...@@ -14,6 +14,7 @@ enum ...@@ -14,6 +14,7 @@ enum
}; };
static Node* curfn; static Node* curfn;
static Node* newproc;
void void
compile(Node *fn) compile(Node *fn)
...@@ -23,6 +24,16 @@ compile(Node *fn) ...@@ -23,6 +24,16 @@ compile(Node *fn)
Prog *ptxt; Prog *ptxt;
long lno; 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) if(fn->nbody == N)
return; return;
lno = setlineno(fn); lno = setlineno(fn);
...@@ -298,15 +309,19 @@ loop: ...@@ -298,15 +309,19 @@ loop:
break; break;
case OCALLMETH: case OCALLMETH:
cgen_callmeth(n); cgen_callmeth(n, 0);
break; break;
case OCALLINTER: case OCALLINTER:
cgen_callinter(n, N); cgen_callinter(n, N, 0);
break; break;
case OCALL: case OCALL:
cgen_call(n); cgen_call(n, 0);
break;
case OPROC:
cgen_proc(n);
break; break;
case ORETURN: case ORETURN:
...@@ -552,7 +567,21 @@ genpanic(void) ...@@ -552,7 +567,21 @@ genpanic(void)
} }
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 *i, *f;
Node tmpi, nodo, nodr, nodsp; Node tmpi, nodo, nodr, nodsp;
...@@ -588,21 +617,19 @@ cgen_callinter(Node *n, Node *res) ...@@ -588,21 +617,19 @@ cgen_callinter(Node *n, Node *res)
nodo.xoffset -= widthptr; nodo.xoffset -= widthptr;
cgen(&nodo, &nodr); // REG = 0(REG) -- i.m 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; nodo.xoffset = n->left->xoffset + 4*widthptr;
cgen(&nodo, &nodr); // REG = 32+offset(REG) -- i.m->fun[f] cgen(&nodo, &nodr); // REG = 32+offset(REG) -- i.m->fun[f]
gins(ACALL, N, &nodr); ginscall(&nodr, proc);
regfree(&nodr);
regfree(&nodr); regfree(&nodr);
regfree(&nodo);
setmaxarg(n->left->type); setmaxarg(n->left->type);
} }
void void
cgen_callmeth(Node *n) cgen_callmeth(Node *n, int proc)
{ {
Node *l; Node *l;
...@@ -619,14 +646,14 @@ cgen_callmeth(Node *n) ...@@ -619,14 +646,14 @@ cgen_callmeth(Node *n)
if(n->left->op == ONAME) if(n->left->op == ONAME)
n->left->class = PEXTERN; n->left->class = PEXTERN;
cgen_call(n); cgen_call(n, proc);
} }
void void
cgen_call(Node *n) cgen_call(Node *n, int proc)
{ {
Type *t; Type *t;
Node nod, afun; Node nod, afun, regax;
if(n == N) if(n == N)
return; return;
...@@ -652,7 +679,7 @@ cgen_call(Node *n) ...@@ -652,7 +679,7 @@ cgen_call(Node *n)
if(n->left->ullman >= UINF) { if(n->left->ullman >= UINF) {
regalloc(&nod, types[tptr], N); regalloc(&nod, types[tptr], N);
cgen_as(&nod, &afun, 0); cgen_as(&nod, &afun, 0);
gins(ACALL, N, &nod); ginscall(&nod, proc);
regfree(&nod); regfree(&nod);
goto ret; goto ret;
} }
...@@ -661,19 +688,41 @@ cgen_call(Node *n) ...@@ -661,19 +688,41 @@ cgen_call(Node *n)
if(isptr[n->left->type->etype]) { if(isptr[n->left->type->etype]) {
regalloc(&nod, types[tptr], N); regalloc(&nod, types[tptr], N);
cgen_as(&nod, n->left, 0); cgen_as(&nod, n->left, 0);
gins(ACALL, N, &nod); ginscall(&nod, proc);
regfree(&nod); regfree(&nod);
goto ret; goto ret;
} }
// call direct // call direct
n->left->method = 1; n->left->method = 1;
gins(ACALL, N, n->left); ginscall(n->left, proc);
ret: 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 void
cgen_callret(Node *n, Node *res) cgen_callret(Node *n, Node *res)
{ {
......
...@@ -113,9 +113,10 @@ void agen_inter(Node*, Node*); ...@@ -113,9 +113,10 @@ void agen_inter(Node*, Node*);
void cgen_as(Node*, Node*, int); void cgen_as(Node*, Node*, int);
void cgen_asop(Node*); void cgen_asop(Node*);
void cgen_ret(Node*); void cgen_ret(Node*);
void cgen_call(Node*); void cgen_call(Node*, int);
void cgen_callmeth(Node*); void cgen_callmeth(Node*, int);
void cgen_callinter(Node*, Node*); void cgen_callinter(Node*, Node*, int);
void cgen_proc(Node*);
void cgen_callret(Node*, Node*); void cgen_callret(Node*, Node*);
void cgen_div(int, Node*, Node*, Node*); void cgen_div(int, Node*, Node*, Node*);
void cgen_shift(int, Node*, Node*, Node*); void cgen_shift(int, Node*, Node*, Node*);
......
...@@ -1673,7 +1673,6 @@ tempname(Node *n, Type *t) ...@@ -1673,7 +1673,6 @@ tempname(Node *n, Type *t)
n->op = ONAME; n->op = ONAME;
n->sym = s; n->sym = s;
n->type = t; n->type = t;
n->sym = s;
n->etype = t->etype; n->etype = t->etype;
n->class = PAUTO; n->class = PAUTO;
n->addable = 1; n->addable = 1;
......
...@@ -581,7 +581,6 @@ Node* nodpanic(long); ...@@ -581,7 +581,6 @@ Node* nodpanic(long);
Node* newcompat(Node*); Node* newcompat(Node*);
Node* stringop(Node*, int); Node* stringop(Node*, int);
Node* mapop(Node*, int); Node* mapop(Node*, int);
Node* procop(Node*);
Node* convas(Node*); Node* convas(Node*);
void arrayconv(Type*, Node*); void arrayconv(Type*, Node*);
Node* colas(Node*, Node*); Node* colas(Node*, Node*);
......
...@@ -44,8 +44,6 @@ func mapaccess2(hmap *map[any]any, key any) (val any, pres bool); ...@@ -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 mapassign1(hmap *map[any]any, key any, val any);
func mapassign2(hmap *map[any]any, key any, val any, pres bool); 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 readfile(string) (string, bool); // read file into string; boolean status
func exit(int32); func exit(int32);
...@@ -93,9 +91,6 @@ export ...@@ -93,9 +91,6 @@ export
mapassign1 mapassign1
mapassign2 mapassign2
// threads/coroutines
newproc
// files // files
readfile readfile
......
This diff is collapsed.
...@@ -159,7 +159,7 @@ loop: ...@@ -159,7 +159,7 @@ loop:
case OPROC: case OPROC:
if(top != Etop) if(top != Etop)
goto nottop; goto nottop;
*n = *procop(n); walktype(n->left, Etop);
goto ret; goto ret;
case OCALLMETH: case OCALLMETH:
...@@ -1594,27 +1594,6 @@ nottop: ...@@ -1594,27 +1594,6 @@ nottop:
return N; 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 void
diagnamed(Type *t) diagnamed(Type *t)
{ {
...@@ -1772,6 +1751,7 @@ colas(Node *nl, Node *nr) ...@@ -1772,6 +1751,7 @@ colas(Node *nl, Node *nr)
l = listnext(&savel); l = listnext(&savel);
r = listnext(&saver); r = listnext(&saver);
} }
n = rev(n);
return n; return n;
multi: multi:
...@@ -1827,6 +1807,7 @@ multi: ...@@ -1827,6 +1807,7 @@ multi:
n = nod(OLIST, n, a); n = nod(OLIST, n, a);
break; break;
} }
n = rev(n);
return n; return n;
badt: badt:
......
...@@ -179,6 +179,12 @@ easy: ...@@ -179,6 +179,12 @@ easy:
TEXT _endmorestack(SB), 7, $-8 TEXT _endmorestack(SB), 7, $-8
RET 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 TEXT FLUSH(SB),7,$-8
RET RET
...@@ -186,5 +192,4 @@ TEXT getu(SB),7,$-8 ...@@ -186,5 +192,4 @@ TEXT getu(SB),7,$-8
MOVQ R15, AX MOVQ R15, AX
RET RET
GLOBL peruser<>(SB),$64 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