mirror of
https://github.com/golang/go.git
synced 2025-05-14 03:44:40 +00:00
another step toward eliminating forward declarations.
introduce NodeList* type in compiler to replace OLIST. this clarifies where lists can and cannot occur. list append and concatenation are now cheap. the _r rules are gone from yacc. rev and unrev are gone. no more lists of lists. the representation of assignments is a bit clunkier. split into OAS (1=1) and OAS2 (2 or more on one side). delete dead chanrecv3 code. delay construction of func types. R=ken OCL=31745 CL=31762
This commit is contained in:
parent
9b475bd2a4
commit
e52e9ca82e
@ -26,7 +26,7 @@ compile(Node *fn)
|
||||
throwreturn = sysfunc("throwreturn");
|
||||
}
|
||||
|
||||
if(fn->nbody == N)
|
||||
if(fn->nbody == nil)
|
||||
return;
|
||||
|
||||
// set up domain for labels
|
||||
@ -42,7 +42,7 @@ compile(Node *fn)
|
||||
t = structfirst(&save, getoutarg(curfn->type));
|
||||
while(t != T) {
|
||||
if(t->nname != N)
|
||||
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody);
|
||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
||||
t = structnext(&save);
|
||||
}
|
||||
}
|
||||
@ -65,8 +65,8 @@ compile(Node *fn)
|
||||
ptxt = gins(ATEXT, curfn->nname, &nod1);
|
||||
afunclit(&ptxt->from);
|
||||
|
||||
gen(curfn->enter);
|
||||
gen(curfn->nbody);
|
||||
genlist(curfn->enter);
|
||||
genlist(curfn->nbody);
|
||||
checklabels();
|
||||
|
||||
if(curfn->type->outtuple != 0)
|
||||
@ -326,7 +326,7 @@ cgen_aret(Node *n, Node *res)
|
||||
void
|
||||
cgen_ret(Node *n)
|
||||
{
|
||||
gen(n->left); // copy out args
|
||||
genlist(n->list); // copy out args
|
||||
if(hasdefer)
|
||||
ginscall(deferreturn, 0);
|
||||
gins(ARET, N, N);
|
||||
|
@ -26,7 +26,7 @@ compile(Node *fn)
|
||||
throwreturn = sysfunc("throwreturn");
|
||||
}
|
||||
|
||||
if(fn->nbody == N)
|
||||
if(fn->nbody == nil)
|
||||
return;
|
||||
|
||||
// set up domain for labels
|
||||
@ -42,7 +42,7 @@ compile(Node *fn)
|
||||
t = structfirst(&save, getoutarg(curfn->type));
|
||||
while(t != T) {
|
||||
if(t->nname != N)
|
||||
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody);
|
||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
||||
t = structnext(&save);
|
||||
}
|
||||
}
|
||||
@ -66,8 +66,8 @@ compile(Node *fn)
|
||||
afunclit(&ptxt->from);
|
||||
|
||||
ginit();
|
||||
gen(curfn->enter);
|
||||
gen(curfn->nbody);
|
||||
genlist(curfn->enter);
|
||||
genlist(curfn->nbody);
|
||||
gclean();
|
||||
checklabels();
|
||||
|
||||
@ -164,7 +164,7 @@ cgen_callinter(Node *n, Node *res, int proc)
|
||||
i = &tmpi;
|
||||
}
|
||||
|
||||
gen(n->right); // args
|
||||
genlist(n->list); // assign the args
|
||||
|
||||
regalloc(&nodr, types[tptr], res);
|
||||
regalloc(&nodo, types[tptr], &nodr);
|
||||
@ -214,7 +214,7 @@ cgen_call(Node *n, int proc)
|
||||
cgen(n->left, &afun);
|
||||
}
|
||||
|
||||
gen(n->right); // assign the args
|
||||
genlist(n->list); // assign the args
|
||||
t = n->left->type;
|
||||
|
||||
setmaxarg(t);
|
||||
@ -322,7 +322,7 @@ cgen_aret(Node *n, Node *res)
|
||||
void
|
||||
cgen_ret(Node *n)
|
||||
{
|
||||
gen(n->left); // copy out args
|
||||
genlist(n->list); // copy out args
|
||||
if(hasdefer)
|
||||
ginscall(deferreturn, 0);
|
||||
gins(ARET, N, N);
|
||||
|
@ -24,7 +24,7 @@ compile(Node *fn)
|
||||
throwreturn = sysfunc("throwreturn");
|
||||
}
|
||||
|
||||
if(fn->nbody == N)
|
||||
if(fn->nbody == nil)
|
||||
return;
|
||||
|
||||
// set up domain for labels
|
||||
@ -40,7 +40,7 @@ compile(Node *fn)
|
||||
t = structfirst(&save, getoutarg(curfn->type));
|
||||
while(t != T) {
|
||||
if(t->nname != N)
|
||||
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody);
|
||||
curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
|
||||
t = structnext(&save);
|
||||
}
|
||||
}
|
||||
@ -64,8 +64,8 @@ compile(Node *fn)
|
||||
afunclit(&ptxt->from);
|
||||
|
||||
ginit();
|
||||
gen(curfn->enter);
|
||||
gen(curfn->nbody);
|
||||
genlist(curfn->enter);
|
||||
genlist(curfn->nbody);
|
||||
gclean();
|
||||
checklabels();
|
||||
|
||||
@ -200,7 +200,7 @@ cgen_callinter(Node *n, Node *res, int proc)
|
||||
i = &tmpi;
|
||||
}
|
||||
|
||||
gen(n->right); // args
|
||||
genlist(n->list); // assign the args
|
||||
|
||||
// Can regalloc now; i is known to be addable,
|
||||
// so the agen will be easy.
|
||||
@ -255,7 +255,7 @@ cgen_call(Node *n, int proc)
|
||||
cgen(n->left, &afun);
|
||||
}
|
||||
|
||||
gen(n->right); // assign the args
|
||||
genlist(n->list); // assign the args
|
||||
t = n->left->type;
|
||||
|
||||
setmaxarg(t);
|
||||
@ -360,7 +360,7 @@ cgen_aret(Node *n, Node *res)
|
||||
void
|
||||
cgen_ret(Node *n)
|
||||
{
|
||||
gen(n->left); // copy out args
|
||||
genlist(n->list); // copy out args
|
||||
if(hasdefer)
|
||||
ginscall(deferreturn, 0);
|
||||
gins(ARET, N, N);
|
||||
|
@ -307,7 +307,7 @@ typeinit(void)
|
||||
mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308");
|
||||
|
||||
/* for walk to use in error messages */
|
||||
types[TFUNC] = functype(N, N, N);
|
||||
types[TFUNC] = functype(N, nil, nil);
|
||||
|
||||
/* types used in front end */
|
||||
// types[TNIL] got set early in lexinit
|
||||
|
@ -53,7 +53,6 @@ char *sysimport =
|
||||
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
|
||||
"func sys.chanrecv1 (hchan <-chan any) (elem any)\n"
|
||||
"func sys.chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
|
||||
"func sys.chanrecv3 (hchan <-chan any, elem *any) (pres bool)\n"
|
||||
"func sys.chansend1 (hchan chan<- any, elem any)\n"
|
||||
"func sys.chansend2 (hchan chan<- any, elem any) (pres bool)\n"
|
||||
"func sys.closechan (hchan any)\n"
|
||||
|
350
src/cmd/gc/dcl.c
350
src/cmd/gc/dcl.c
@ -22,16 +22,13 @@ dflag(void)
|
||||
* append ODCL nodes to *init
|
||||
*/
|
||||
void
|
||||
dodclvar(Node *n, Type *t, Node **init)
|
||||
dodclvar(Node *n, Type *t, NodeList **init)
|
||||
{
|
||||
if(n == N)
|
||||
return;
|
||||
|
||||
if(t != T && (t->etype == TIDEAL || t->etype == TNIL))
|
||||
fatal("dodclvar %T", t);
|
||||
for(; n->op == OLIST; n = n->right)
|
||||
dodclvar(n->left, t, init);
|
||||
|
||||
dowidth(t);
|
||||
|
||||
// in case of type checking error,
|
||||
@ -51,10 +48,6 @@ dodclconst(Node *n, Node *e)
|
||||
{
|
||||
if(n == N)
|
||||
return;
|
||||
|
||||
for(; n->op == OLIST; n=n->right)
|
||||
dodclconst(n, e);
|
||||
|
||||
addconst(n, e, dclcontext);
|
||||
autoexport(n->sym);
|
||||
}
|
||||
@ -179,18 +172,6 @@ updatetype(Type *n, Type *t)
|
||||
/*
|
||||
* return nelem of list
|
||||
*/
|
||||
int
|
||||
listcount(Node *n)
|
||||
{
|
||||
int v;
|
||||
Iter s;
|
||||
|
||||
v = 0;
|
||||
for(n = listfirst(&s, &n); n != N; n = listnext(&s))
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
int
|
||||
structcount(Type *t)
|
||||
{
|
||||
@ -208,19 +189,24 @@ structcount(Type *t)
|
||||
* into a type
|
||||
*/
|
||||
Type*
|
||||
functype(Node *this, Node *in, Node *out)
|
||||
functype(Node *this, NodeList *in, NodeList *out)
|
||||
{
|
||||
Type *t;
|
||||
NodeList *rcvr;
|
||||
|
||||
t = typ(TFUNC);
|
||||
|
||||
t->type = dostruct(this, TFUNC);
|
||||
rcvr = nil;
|
||||
if(this)
|
||||
rcvr = list1(this);
|
||||
t->type = dostruct(rcvr, TFUNC);
|
||||
t->type->down = dostruct(out, TFUNC);
|
||||
t->type->down->down = dostruct(in, TFUNC);
|
||||
|
||||
t->thistuple = listcount(this);
|
||||
t->outtuple = listcount(out);
|
||||
t->intuple = listcount(in);
|
||||
if(this)
|
||||
t->thistuple = 1;
|
||||
t->outtuple = count(out);
|
||||
t->intuple = count(in);
|
||||
|
||||
checkwidth(t);
|
||||
return t;
|
||||
@ -367,9 +353,9 @@ addmethod(Node *n, Type *t, int local)
|
||||
}
|
||||
|
||||
if(d == T)
|
||||
stotype(n, 0, &pa->method);
|
||||
stotype(list1(n), 0, &pa->method);
|
||||
else
|
||||
stotype(n, 0, &d->down);
|
||||
stotype(list1(n), 0, &d->down);
|
||||
|
||||
if(dflag())
|
||||
print("method %S of type %T\n", sf, pa);
|
||||
@ -545,13 +531,14 @@ funclit0(Type *t)
|
||||
}
|
||||
|
||||
Node*
|
||||
funclit1(Type *type, Node *body)
|
||||
funclit1(Type *type, NodeList *body)
|
||||
{
|
||||
Node *func;
|
||||
Node *a, *d, *f, *n, *args, *clos, *in, *out;
|
||||
Node *a, *d, *f, *n, *clos;
|
||||
Type *ft, *t;
|
||||
Iter save;
|
||||
int narg, shift;
|
||||
NodeList *args, *l, *in, *out;
|
||||
|
||||
popdcl();
|
||||
func = funclit;
|
||||
@ -559,15 +546,15 @@ funclit1(Type *type, Node *body)
|
||||
|
||||
// build up type of func f that we're going to compile.
|
||||
// as we referred to variables from the outer function,
|
||||
// we accumulated a list of PHEAP names in func.
|
||||
//
|
||||
// we accumulated a list of PHEAP names in func->cvars.
|
||||
narg = 0;
|
||||
if(func->cvars == N)
|
||||
if(func->cvars == nil)
|
||||
ft = type;
|
||||
else {
|
||||
// add PHEAP versions as function arguments.
|
||||
in = N;
|
||||
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) {
|
||||
in = nil;
|
||||
for(l=func->cvars; l; l=l->next) {
|
||||
a = l->n;
|
||||
d = nod(ODCLFIELD, a, N);
|
||||
d->type = ptrto(a->type);
|
||||
in = list(in, d);
|
||||
@ -612,10 +599,9 @@ funclit1(Type *type, Node *body)
|
||||
a->xoffset += shift;
|
||||
}
|
||||
}
|
||||
in = rev(in);
|
||||
|
||||
// out arguments
|
||||
out = N;
|
||||
out = nil;
|
||||
for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) {
|
||||
d = nod(ODCLFIELD, t->nname, N);
|
||||
d->type = t->type;
|
||||
@ -628,7 +614,6 @@ funclit1(Type *type, Node *body)
|
||||
a->xoffset += shift;
|
||||
}
|
||||
}
|
||||
out = rev(out);
|
||||
|
||||
ft = functype(N, in, out);
|
||||
ft->outnamed = type->outnamed;
|
||||
@ -645,35 +630,35 @@ funclit1(Type *type, Node *body)
|
||||
n = nod(ODCLFUNC, N, N);
|
||||
n->nname = f;
|
||||
n->type = ft;
|
||||
if(body == N)
|
||||
body = nod(ORETURN, N, N);
|
||||
if(body == nil)
|
||||
body = list1(nod(ORETURN, N, N));
|
||||
n->nbody = body;
|
||||
compile(n);
|
||||
funcdepth--;
|
||||
autodcl = func->dcl;
|
||||
|
||||
// if there's no closure, we can use f directly
|
||||
if(func->cvars == N)
|
||||
if(func->cvars == nil)
|
||||
return f;
|
||||
|
||||
// build up type for this instance of the closure func.
|
||||
in = N;
|
||||
in = nil;
|
||||
d = nod(ODCLFIELD, N, N); // siz
|
||||
d->type = types[TINT];
|
||||
in = list(in, d);
|
||||
d = nod(ODCLFIELD, N, N); // f
|
||||
d->type = ft;
|
||||
in = list(in, d);
|
||||
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) {
|
||||
for(l=func->cvars; l; l=l->next) {
|
||||
a = l->n;
|
||||
d = nod(ODCLFIELD, N, N); // arg
|
||||
d->type = ptrto(a->type);
|
||||
in = list(in, d);
|
||||
}
|
||||
in = rev(in);
|
||||
|
||||
d = nod(ODCLFIELD, N, N);
|
||||
d->type = type;
|
||||
out = d;
|
||||
out = list1(d);
|
||||
|
||||
clos = syslook("closure", 1);
|
||||
clos->type = functype(N, in, out);
|
||||
@ -681,47 +666,42 @@ funclit1(Type *type, Node *body)
|
||||
// literal expression is sys.closure(siz, f, arg0, arg1, ...)
|
||||
// which builds a function that calls f after filling in arg0,
|
||||
// arg1, ... for the PHEAP arguments above.
|
||||
args = N;
|
||||
args = nil;
|
||||
if(narg*widthptr > 100)
|
||||
yyerror("closure needs too many variables; runtime will reject it");
|
||||
a = nodintconst(narg*widthptr);
|
||||
args = list(args, a); // siz
|
||||
args = list(args, f); // f
|
||||
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) {
|
||||
for(l=func->cvars; l; l=l->next) {
|
||||
a = l->n;
|
||||
d = oldname(a->sym);
|
||||
addrescapes(d);
|
||||
args = list(args, nod(OADDR, d, N));
|
||||
}
|
||||
args = rev(args);
|
||||
|
||||
return nod(OCALL, clos, args);
|
||||
n = nod(OCALL, clos, N);
|
||||
n->list = args;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* turn a parsed struct into a type
|
||||
*/
|
||||
Type**
|
||||
stotype(Node *n, int et, Type **t)
|
||||
stotype(NodeList *l, int et, Type **t)
|
||||
{
|
||||
Type *f, *t1;
|
||||
Iter save;
|
||||
Strlit *note;
|
||||
int lno;
|
||||
Node *init;
|
||||
NodeList *init;
|
||||
Node *n;
|
||||
|
||||
init = N;
|
||||
init = nil;
|
||||
lno = lineno;
|
||||
for(n = listfirst(&save, &n); n != N; n = listnext(&save)) {
|
||||
note = nil;
|
||||
|
||||
for(; l; l=l->next) {
|
||||
n = l->n;
|
||||
lineno = n->lineno;
|
||||
if(n->op == OLIST) {
|
||||
// recursive because it can be lists of lists
|
||||
t = stotype(n, et, t);
|
||||
continue;
|
||||
}
|
||||
note = nil;
|
||||
|
||||
if(n->op != ODCLFIELD)
|
||||
fatal("stotype: oops %N\n", n);
|
||||
@ -803,7 +783,7 @@ stotype(Node *n, int et, Type **t)
|
||||
}
|
||||
|
||||
Type*
|
||||
dostruct(Node *n, int et)
|
||||
dostruct(NodeList *l, int et)
|
||||
{
|
||||
Type *t;
|
||||
int funarg;
|
||||
@ -820,7 +800,7 @@ dostruct(Node *n, int et)
|
||||
}
|
||||
t = typ(et);
|
||||
t->funarg = funarg;
|
||||
stotype(n, et, &t->type);
|
||||
stotype(l, et, &t->type);
|
||||
if(!funarg)
|
||||
checkwidth(t);
|
||||
return t;
|
||||
@ -1218,7 +1198,7 @@ oldname(Sym *s)
|
||||
n->closure = c;
|
||||
c->closure = n;
|
||||
if(funclit != N)
|
||||
funclit->cvars = list(c, funclit->cvars);
|
||||
funclit->cvars = list(funclit->cvars, c);
|
||||
}
|
||||
// return ref to closure var, not original
|
||||
return n->closure;
|
||||
@ -1265,45 +1245,15 @@ oldtype(Sym *s)
|
||||
}
|
||||
|
||||
/*
|
||||
* n is a node with a name (or a reversed list of them).
|
||||
* make it an anonymous declaration of that name's type.
|
||||
*/
|
||||
Node*
|
||||
nametoanondcl(Node *na)
|
||||
{
|
||||
Node **l, *n;
|
||||
Type *t;
|
||||
|
||||
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
|
||||
n->right = nametoanondcl(n->right);
|
||||
|
||||
n = n->sym->def;
|
||||
if(n == N || n->op != OTYPE || (t = n->type) == T) {
|
||||
yyerror("%S is not a type", n->sym);
|
||||
t = typ(TINT32);
|
||||
}
|
||||
n = nod(ODCLFIELD, N, N);
|
||||
n->type = t;
|
||||
*l = n;
|
||||
return na;
|
||||
}
|
||||
|
||||
/*
|
||||
* n is a node with a name (or a reversed list of them).
|
||||
* n is a node with a name.
|
||||
* make it a declaration of the given type.
|
||||
*/
|
||||
Node*
|
||||
nametodcl(Node *na, Type *t)
|
||||
nametodcl(Node *n, Type *t)
|
||||
{
|
||||
Node **l, *n;
|
||||
|
||||
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
|
||||
n->right = nametodcl(n->right, t);
|
||||
|
||||
n = nod(ODCLFIELD, n, N);
|
||||
n->type = t;
|
||||
*l = n;
|
||||
return na;
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1320,22 +1270,16 @@ anondcl(Type *t)
|
||||
}
|
||||
|
||||
static Node*
|
||||
findtype(Node *n)
|
||||
findtype(NodeList *l)
|
||||
{
|
||||
Node *r;
|
||||
|
||||
for(r=n; r->op==OLIST; r=r->right)
|
||||
if(r->left->op == OKEY)
|
||||
return r->left->right;
|
||||
if(r->op == OKEY)
|
||||
return r->right;
|
||||
if(n->op == OLIST)
|
||||
n = n->left;
|
||||
for(; l; l=l->next)
|
||||
if(l->n->op == OKEY)
|
||||
return l->n->right;
|
||||
return N;
|
||||
}
|
||||
|
||||
static Node*
|
||||
xanondcl(Node *nt, int dddok)
|
||||
xanondcl(Node *nt)
|
||||
{
|
||||
Node *n;
|
||||
Type *t;
|
||||
@ -1347,13 +1291,11 @@ xanondcl(Node *nt, int dddok)
|
||||
}
|
||||
n = nod(ODCLFIELD, N, N);
|
||||
n->type = t;
|
||||
if(!dddok && t->etype == TDDD)
|
||||
yyerror("only last argument can have type ...");
|
||||
return n;
|
||||
}
|
||||
|
||||
static Node*
|
||||
namedcl(Node *nn, Node *nt, int dddok)
|
||||
namedcl(Node *nn, Node *nt)
|
||||
{
|
||||
Node *n;
|
||||
Type *t;
|
||||
@ -1362,7 +1304,7 @@ namedcl(Node *nn, Node *nt, int dddok)
|
||||
nn = nn->left;
|
||||
if(nn->op == OTYPE && nn->sym == S) {
|
||||
yyerror("cannot mix anonymous %T with named arguments", nn->type);
|
||||
return xanondcl(nn, dddok);
|
||||
return xanondcl(nn);
|
||||
}
|
||||
t = types[TINT32];
|
||||
if(nt == N)
|
||||
@ -1373,41 +1315,39 @@ namedcl(Node *nn, Node *nt, int dddok)
|
||||
t = nt->type;
|
||||
n = nod(ODCLFIELD, newname(nn->sym), N);
|
||||
n->type = t;
|
||||
if(!dddok && t->etype == TDDD)
|
||||
yyerror("only last argument can have type ...");
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* check that the list of declarations is either all anonymous or all named
|
||||
*/
|
||||
Node*
|
||||
checkarglist(Node *n)
|
||||
NodeList*
|
||||
checkarglist(NodeList *all)
|
||||
{
|
||||
int named;
|
||||
Node *r;
|
||||
Node **l;
|
||||
NodeList *l;
|
||||
|
||||
// check for all anonymous
|
||||
for(r=n; r->op==OLIST; r=r->right)
|
||||
if(r->left->op == OKEY)
|
||||
goto named;
|
||||
if(r->op == OKEY)
|
||||
goto named;
|
||||
named = 0;
|
||||
for(l=all; l; l=l->next) {
|
||||
if(l->n->op == OKEY) {
|
||||
named = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// all anonymous - add names
|
||||
for(l=&n; (r=*l)->op==OLIST; l=&r->right)
|
||||
r->left = xanondcl(r->left, 0);
|
||||
*l = xanondcl(r, 1);
|
||||
return n;
|
||||
|
||||
|
||||
named:
|
||||
// otherwise, each run of names ends in a type.
|
||||
// add a type to each one that needs one.
|
||||
for(l=&n; (r=*l)->op==OLIST; l=&r->right)
|
||||
r->left = namedcl(r->left, findtype(r), 0);
|
||||
*l = namedcl(r, findtype(r), 1);
|
||||
return n;
|
||||
for(l=all; l; l=l->next) {
|
||||
if(named)
|
||||
l->n = namedcl(l->n, findtype(l));
|
||||
else
|
||||
l->n = xanondcl(l->n);
|
||||
if(l->next != nil) {
|
||||
r = l->n;
|
||||
if(r != N && r->type != T && r->type->etype == TDDD)
|
||||
yyerror("only last argument can have type ...");
|
||||
}
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1429,13 +1369,13 @@ named:
|
||||
* }
|
||||
*/
|
||||
int
|
||||
anyinit(Node *n)
|
||||
anyinit(NodeList *n)
|
||||
{
|
||||
uint32 h;
|
||||
Sym *s;
|
||||
|
||||
// are there any init statements
|
||||
if(n != N)
|
||||
if(n != nil)
|
||||
return 1;
|
||||
|
||||
// is this main
|
||||
@ -1463,10 +1403,11 @@ anyinit(Node *n)
|
||||
}
|
||||
|
||||
void
|
||||
fninit(Node *n)
|
||||
fninit(NodeList *n)
|
||||
{
|
||||
Node *gatevar;
|
||||
Node *a, *b, *fn, *r;
|
||||
Node *a, *b, *fn;
|
||||
NodeList *r;
|
||||
uint32 h;
|
||||
Sym *s, *initsym;
|
||||
|
||||
@ -1478,7 +1419,7 @@ fninit(Node *n)
|
||||
if(!anyinit(n))
|
||||
return;
|
||||
|
||||
r = N;
|
||||
r = nil;
|
||||
|
||||
// (1)
|
||||
snprint(namebuf, sizeof(namebuf), "initdone·%s", filename);
|
||||
@ -1500,7 +1441,7 @@ fninit(Node *n)
|
||||
fn = nod(ODCLFUNC, N, N);
|
||||
initsym = lookup(namebuf);
|
||||
fn->nname = newname(initsym);
|
||||
fn->type = functype(N, N, N);
|
||||
fn->type = functype(N, nil, nil);
|
||||
funchdr(fn);
|
||||
|
||||
// (3)
|
||||
@ -1511,8 +1452,8 @@ fninit(Node *n)
|
||||
// (4)
|
||||
b = nod(OIF, N, N);
|
||||
b->ntest = nod(OEQ, gatevar, nodintconst(2));
|
||||
b->nbody = nod(ORETURN, N, N);
|
||||
a->nbody = b;
|
||||
b->nbody = list1(nod(ORETURN, N, N));
|
||||
a->nbody = list1(b);
|
||||
|
||||
// (5)
|
||||
b = syslook("throwinit", 0);
|
||||
@ -1540,7 +1481,7 @@ fninit(Node *n)
|
||||
}
|
||||
|
||||
// (8)
|
||||
r = list(r, initfix(n));
|
||||
r = concat(r, initfix(n));
|
||||
|
||||
// (9)
|
||||
// could check that it is fn of no args/returns
|
||||
@ -1562,7 +1503,7 @@ fninit(Node *n)
|
||||
|
||||
exportsym(fn->nname->sym);
|
||||
|
||||
fn->nbody = rev(r);
|
||||
fn->nbody = r;
|
||||
//dump("b", fn);
|
||||
//dump("r", fn->nbody);
|
||||
|
||||
@ -1679,26 +1620,28 @@ embedded(Sym *s)
|
||||
* declare variables from grammar
|
||||
* new_name_list (type | [type] = expr_list)
|
||||
*/
|
||||
Node*
|
||||
variter(Node *vv, Type *t, Node *ee)
|
||||
NodeList*
|
||||
variter(NodeList *vl, Type *t, NodeList *el)
|
||||
{
|
||||
Iter viter, eiter;
|
||||
Node *v, *e, *r, *a;
|
||||
int doexpr;
|
||||
Node *v, *e, *a;
|
||||
Type *tv;
|
||||
NodeList *r;
|
||||
|
||||
vv = rev(vv);
|
||||
ee = rev(ee);
|
||||
|
||||
v = listfirst(&viter, &vv);
|
||||
e = listfirst(&eiter, &ee);
|
||||
r = N;
|
||||
|
||||
while(v != N) {
|
||||
if(ee != N && e == N) {
|
||||
r = nil;
|
||||
doexpr = el != nil;
|
||||
for(; vl; vl=vl->next) {
|
||||
if(doexpr) {
|
||||
if(el == nil) {
|
||||
yyerror("missing expr in var dcl");
|
||||
break;
|
||||
}
|
||||
e = el->n;
|
||||
el = el->next;
|
||||
} else
|
||||
e = N;
|
||||
|
||||
v = vl->n;
|
||||
a = N;
|
||||
if(e != N || funcdepth > 0)
|
||||
a = nod(OAS, v, e);
|
||||
@ -1709,15 +1652,12 @@ variter(Node *vv, Type *t, Node *ee)
|
||||
tv = e->type;
|
||||
}
|
||||
dodclvar(v, tv, &r);
|
||||
if(a != N)
|
||||
r = list(r, a);
|
||||
|
||||
v = listnext(&viter);
|
||||
if(ee != N)
|
||||
e = listnext(&eiter);
|
||||
}
|
||||
if(e != N)
|
||||
if(el != nil)
|
||||
yyerror("extra expr in var dcl");
|
||||
return rev(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1725,40 +1665,33 @@ variter(Node *vv, Type *t, Node *ee)
|
||||
* new_name_list [[type] = expr_list]
|
||||
*/
|
||||
void
|
||||
constiter(Node *vv, Type *t, Node *cc)
|
||||
constiter(NodeList *vl, Type *t, NodeList *cl)
|
||||
{
|
||||
Iter viter, citer;
|
||||
Node *v, *c, *init;
|
||||
Node *v, *c;
|
||||
NodeList *init;
|
||||
|
||||
if(cc == N) {
|
||||
if(cl == nil) {
|
||||
if(t != T)
|
||||
yyerror("constdcl cannot have type without expr");
|
||||
cc = lastconst;
|
||||
cl = lastconst;
|
||||
t = lasttype;
|
||||
}
|
||||
lastconst = cc;
|
||||
} else {
|
||||
lastconst = cl;
|
||||
lasttype = t;
|
||||
vv = rev(vv);
|
||||
cc = rev(treecopy(cc));
|
||||
|
||||
v = listfirst(&viter, &vv);
|
||||
c = listfirst(&citer, &cc);
|
||||
|
||||
loop:
|
||||
if(v == N && c == N) {
|
||||
iota += 1;
|
||||
return;
|
||||
}
|
||||
cl = listtreecopy(cl);
|
||||
|
||||
if(v == N || c == N) {
|
||||
yyerror("shape error in const dcl");
|
||||
iota += 1;
|
||||
return;
|
||||
for(; vl; vl=vl->next) {
|
||||
if(cl == nil) {
|
||||
yyerror("missing expr in const dcl");
|
||||
break;
|
||||
}
|
||||
c = cl->n;
|
||||
cl = cl->next;
|
||||
|
||||
init = N;
|
||||
init = nil;
|
||||
gettype(c, &init);
|
||||
if(init != N) {
|
||||
if(init != nil) {
|
||||
// the expression had extra code to run.
|
||||
// dodclconst is going to print an error
|
||||
// because the expression isn't constant,
|
||||
@ -1770,11 +1703,13 @@ loop:
|
||||
convlit(c, t);
|
||||
if(t == T)
|
||||
lasttype = c->type;
|
||||
dodclconst(v, c);
|
||||
|
||||
v = listnext(&viter);
|
||||
c = listnext(&citer);
|
||||
goto loop;
|
||||
v = vl->n;
|
||||
dodclconst(v, c);
|
||||
}
|
||||
if(cl != nil)
|
||||
yyerror("extra expr in const dcl");
|
||||
iota += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1784,27 +1719,28 @@ loop:
|
||||
* rewrite with a constant
|
||||
*/
|
||||
Node*
|
||||
unsafenmagic(Node *l, Node *r)
|
||||
unsafenmagic(Node *fn, NodeList *args)
|
||||
{
|
||||
Node *n, *init;
|
||||
Node *r, *n;
|
||||
Sym *s;
|
||||
Type *t, *tr;
|
||||
long v;
|
||||
Val val;
|
||||
|
||||
if(l == N || r == N)
|
||||
goto no;
|
||||
if(l->op != ONAME)
|
||||
goto no;
|
||||
s = l->sym;
|
||||
if(s == S)
|
||||
if(fn == N || fn->op != ONAME || (s = fn->sym) == S)
|
||||
goto no;
|
||||
if(strcmp(s->package, "unsafe") != 0)
|
||||
goto no;
|
||||
|
||||
init = N;
|
||||
if(args == nil) {
|
||||
yyerror("missing argument for %S", s);
|
||||
goto no;
|
||||
}
|
||||
r = args->n;
|
||||
|
||||
n = nod(OLITERAL, N, N);
|
||||
if(strcmp(s->name, "Sizeof") == 0) {
|
||||
walkexpr(r, Erv, &init);
|
||||
walkexpr(r, Erv, &n->ninit);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
@ -1816,12 +1752,12 @@ unsafenmagic(Node *l, Node *r)
|
||||
if(strcmp(s->name, "Offsetof") == 0) {
|
||||
if(r->op != ODOT && r->op != ODOTPTR)
|
||||
goto no;
|
||||
walkexpr(r, Erv, &init);
|
||||
walkexpr(r, Erv, &n->ninit);
|
||||
v = r->xoffset;
|
||||
goto yes;
|
||||
}
|
||||
if(strcmp(s->name, "Alignof") == 0) {
|
||||
walkexpr(r, Erv, &init);
|
||||
walkexpr(r, Erv, &n->ninit);
|
||||
tr = r->type;
|
||||
if(r->op == OLITERAL && r->val.ctype == CTSTR)
|
||||
tr = types[TSTRING];
|
||||
@ -1846,6 +1782,8 @@ no:
|
||||
return N;
|
||||
|
||||
yes:
|
||||
if(args->next != nil)
|
||||
yyerror("extra arguments for %S", s);
|
||||
// any side effects disappear; ignore init
|
||||
val.ctype = CTINT;
|
||||
val.u.xval = mal(sizeof(*n->val.u.xval));
|
||||
|
@ -127,6 +127,13 @@ findlab(Sym *s)
|
||||
/*
|
||||
* compile statements
|
||||
*/
|
||||
void
|
||||
genlist(NodeList *l)
|
||||
{
|
||||
for(; l; l=l->next)
|
||||
gen(l->n);
|
||||
}
|
||||
|
||||
void
|
||||
gen(Node *n)
|
||||
{
|
||||
@ -137,13 +144,12 @@ gen(Node *n)
|
||||
|
||||
lno = setlineno(n);
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
goto ret;
|
||||
|
||||
p3 = pc; // save pc for loop labels
|
||||
if(n->ninit)
|
||||
gen(n->ninit);
|
||||
genlist(n->ninit);
|
||||
|
||||
setlineno(n);
|
||||
|
||||
@ -152,11 +158,6 @@ loop:
|
||||
fatal("gen: unknown op %N", n);
|
||||
break;
|
||||
|
||||
case OLIST:
|
||||
gen(n->left);
|
||||
n = n->right;
|
||||
goto loop;
|
||||
|
||||
case OCASE:
|
||||
case OFALL:
|
||||
case OXCASE:
|
||||
@ -164,6 +165,10 @@ loop:
|
||||
case OEMPTY:
|
||||
break;
|
||||
|
||||
case OBLOCK:
|
||||
genlist(n->list);
|
||||
break;
|
||||
|
||||
case OLABEL:
|
||||
newlab(OLABEL, n->left->sym);
|
||||
break;
|
||||
@ -232,10 +237,10 @@ loop:
|
||||
gen(n->nincr); // contin: incr
|
||||
patch(p1, pc); // test:
|
||||
if(n->ntest != N)
|
||||
if(n->ntest->ninit != N)
|
||||
gen(n->ntest->ninit);
|
||||
if(n->ntest->ninit != nil)
|
||||
genlist(n->ntest->ninit);
|
||||
bgen(n->ntest, 0, breakpc); // if(!test) goto break
|
||||
gen(n->nbody); // body
|
||||
genlist(n->nbody); // body
|
||||
gjmp(continpc);
|
||||
patch(breakpc, pc); // done:
|
||||
continpc = scontin;
|
||||
@ -247,13 +252,13 @@ loop:
|
||||
p2 = gjmp(P); // p2: goto else
|
||||
patch(p1, pc); // test:
|
||||
if(n->ntest != N)
|
||||
if(n->ntest->ninit != N)
|
||||
gen(n->ntest->ninit);
|
||||
if(n->ntest->ninit != nil)
|
||||
genlist(n->ntest->ninit);
|
||||
bgen(n->ntest, 0, p2); // if(!test) goto p2
|
||||
gen(n->nbody); // then
|
||||
genlist(n->nbody); // then
|
||||
p3 = gjmp(P); // goto done
|
||||
patch(p2, pc); // else:
|
||||
gen(n->nelse); // else
|
||||
genlist(n->nelse); // else
|
||||
patch(p3, pc); // done:
|
||||
break;
|
||||
|
||||
@ -272,7 +277,7 @@ loop:
|
||||
}
|
||||
|
||||
patch(p1, pc); // test:
|
||||
gen(n->nbody); // switch(test) body
|
||||
genlist(n->nbody); // switch(test) body
|
||||
patch(breakpc, pc); // done:
|
||||
breakpc = sbreak;
|
||||
break;
|
||||
@ -292,7 +297,7 @@ loop:
|
||||
}
|
||||
|
||||
patch(p1, pc); // test:
|
||||
gen(n->nbody); // select() body
|
||||
genlist(n->nbody); // select() body
|
||||
patch(breakpc, pc); // done:
|
||||
breakpc = sbreak;
|
||||
break;
|
||||
@ -432,12 +437,6 @@ cgen_as(Node *nl, Node *nr)
|
||||
|
||||
iszer = 0;
|
||||
if(nr == N || isnil(nr)) {
|
||||
if(nl->op == OLIST) {
|
||||
cgen_as(nl->left, nr);
|
||||
cgen_as(nl->right, nr);
|
||||
return;
|
||||
}
|
||||
|
||||
// externals and heaps should already be clear
|
||||
if(nr == N) {
|
||||
if(nl->class == PEXTERN)
|
||||
|
120
src/cmd/gc/go.h
120
src/cmd/gc/go.h
@ -129,6 +129,7 @@ struct Val
|
||||
|
||||
typedef struct Sym Sym;
|
||||
typedef struct Node Node;
|
||||
typedef struct NodeList NodeList;
|
||||
typedef struct Type Type;
|
||||
typedef struct Dcl Dcl;
|
||||
|
||||
@ -198,24 +199,26 @@ struct Node
|
||||
Node* left;
|
||||
Node* right;
|
||||
Type* type;
|
||||
NodeList* list;
|
||||
NodeList* rlist;
|
||||
|
||||
// for-body
|
||||
Node* ninit;
|
||||
NodeList* ninit;
|
||||
Node* ntest;
|
||||
Node* nincr;
|
||||
Node* nbody;
|
||||
NodeList* nbody;
|
||||
|
||||
// if-body
|
||||
Node* nelse;
|
||||
NodeList* nelse;
|
||||
|
||||
// cases
|
||||
Node* ncase;
|
||||
|
||||
// func
|
||||
Node* nname;
|
||||
Node* enter;
|
||||
Node* exit;
|
||||
Node* cvars; // closure params
|
||||
NodeList* enter;
|
||||
NodeList* exit;
|
||||
NodeList* cvars; // closure params
|
||||
Dcl* dcl; // outer autodcl
|
||||
|
||||
// OLITERAL/OREGISTER
|
||||
@ -242,6 +245,13 @@ struct Node
|
||||
};
|
||||
#define N ((Node*)0)
|
||||
|
||||
struct NodeList
|
||||
{
|
||||
Node* n;
|
||||
NodeList* next;
|
||||
NodeList* end;
|
||||
};
|
||||
|
||||
struct Sym
|
||||
{
|
||||
ushort block; // blocknumber to catch redeclaration
|
||||
@ -308,12 +318,12 @@ enum
|
||||
ODCL,
|
||||
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
|
||||
ODCLFUNC, ODCLFIELD, ODCLARG,
|
||||
OLIST, OCMP, OPTR, OARRAY, ORANGE,
|
||||
OCMP, OPTR, OARRAY, ORANGE,
|
||||
ORETURN, OFOR, OIF, OSWITCH, ODEFER,
|
||||
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
|
||||
OAS, OAS2, OASOP, OCASE, OXCASE, OFALL, OXFALL,
|
||||
OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT,
|
||||
OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF,
|
||||
OCLOSE, OCLOSED,
|
||||
OCLOSE, OCLOSED, OBLOCK,
|
||||
|
||||
OOROR,
|
||||
OANDAND,
|
||||
@ -590,7 +600,7 @@ EXTERN int statuniqgen; // name generator for static temps
|
||||
EXTERN int loophack;
|
||||
|
||||
EXTERN uint32 iota;
|
||||
EXTERN Node* lastconst;
|
||||
EXTERN NodeList* lastconst;
|
||||
EXTERN Type* lasttype;
|
||||
EXTERN int32 vargen;
|
||||
EXTERN int32 exportgen;
|
||||
@ -605,7 +615,6 @@ EXTERN int maxround;
|
||||
EXTERN int widthptr;
|
||||
|
||||
EXTERN Node* retnil;
|
||||
EXTERN Node* fskel;
|
||||
|
||||
EXTERN Node* typeswvar;
|
||||
|
||||
@ -726,15 +735,12 @@ void linehist(char*, int32, int);
|
||||
int32 setlineno(Node*);
|
||||
Node* nod(int, Node*, Node*);
|
||||
Node* nodlit(Val);
|
||||
Node* list(Node*, Node*);
|
||||
Type* typ(int);
|
||||
Dcl* dcl(void);
|
||||
int algtype(Type*);
|
||||
Node* rev(Node*);
|
||||
Node* unrev(Node*);
|
||||
Node* appendr(Node*, Node*);
|
||||
void dodump(Node*, int);
|
||||
void dump(char*, Node*);
|
||||
void dumplist(char*, NodeList*);
|
||||
Type* aindex(Node*, Type*);
|
||||
int isnil(Node*);
|
||||
int isptrto(Type*, int);
|
||||
@ -762,17 +768,23 @@ Node* nodbool(int);
|
||||
void ullmancalc(Node*);
|
||||
void badtype(int, Type*, Type*);
|
||||
Type* ptrto(Type*);
|
||||
Node* cleanidlist(Node*);
|
||||
NodeList* cleanidlist(NodeList*);
|
||||
Node* syslook(char*, int);
|
||||
Node* treecopy(Node*);
|
||||
NodeList* listtreecopy(NodeList*);
|
||||
int isselect(Node*);
|
||||
void tempname(Node*, Type*);
|
||||
Node* staticname(Type*);
|
||||
int iscomposite(Type*);
|
||||
Node* callnew(Type*);
|
||||
Node* saferef(Node*, Node**);
|
||||
Node* saferef(Node*, NodeList**);
|
||||
int is64(Type*);
|
||||
int noconv(Type*, Type*);
|
||||
NodeList* list1(Node*);
|
||||
NodeList* list(NodeList*, Node*);
|
||||
NodeList* concat(NodeList*, NodeList*);
|
||||
int count(NodeList*);
|
||||
Node* liststmt(NodeList*);
|
||||
|
||||
Type** getthis(Type*);
|
||||
Type** getoutarg(Type*);
|
||||
@ -782,8 +794,6 @@ Type* getthisx(Type*);
|
||||
Type* getoutargx(Type*);
|
||||
Type* getinargx(Type*);
|
||||
|
||||
Node* listfirst(Iter*, Node**);
|
||||
Node* listnext(Iter*);
|
||||
Type* structfirst(Iter*, Type**);
|
||||
Type* structnext(Iter*);
|
||||
Type* funcfirst(Iter*, Type*);
|
||||
@ -817,18 +827,17 @@ int simsimtype(Type*);
|
||||
/*
|
||||
* dcl.c
|
||||
*/
|
||||
void dodclvar(Node*, Type*, Node**);
|
||||
void dodclvar(Node*, Type*, NodeList**);
|
||||
Type* dodcltype(Type*);
|
||||
void updatetype(Type*, Type*);
|
||||
void dodclconst(Node*, Node*);
|
||||
void defaultlit(Node*, Type*);
|
||||
void defaultlit2(Node*, Node*);
|
||||
int listcount(Node*);
|
||||
int structcount(Type*);
|
||||
void addmethod(Node*, Type*, int);
|
||||
Node* methodname(Node*, Type*);
|
||||
Sym* methodsym(Sym*, Type*);
|
||||
Type* functype(Node*, Node*, Node*);
|
||||
Type* functype(Node*, NodeList*, NodeList*);
|
||||
char* thistypenam(Node*);
|
||||
void funcnam(Type*, char*);
|
||||
Node* renameinit(Node*);
|
||||
@ -836,8 +845,8 @@ void funchdr(Node*);
|
||||
void funcargs(Type*);
|
||||
void funcbody(Node*);
|
||||
Node* typenod(Type*);
|
||||
Type* dostruct(Node*, int);
|
||||
Type** stotype(Node*, int, Type**);
|
||||
Type* dostruct(NodeList*, int);
|
||||
Type** stotype(NodeList*, int, Type**);
|
||||
Type* sortinter(Type*);
|
||||
void markdcl(void);
|
||||
void popdcl(void);
|
||||
@ -855,27 +864,26 @@ Node* newname(Sym*);
|
||||
Node* oldname(Sym*);
|
||||
Type* newtype(Sym*);
|
||||
Type* oldtype(Sym*);
|
||||
void fninit(Node*);
|
||||
Node* nametoanondcl(Node*);
|
||||
void fninit(NodeList*);
|
||||
Node* nametodcl(Node*, Type*);
|
||||
Node* anondcl(Type*);
|
||||
Node* checkarglist(Node*);
|
||||
NodeList* checkarglist(NodeList*);
|
||||
void checkwidth(Type*);
|
||||
void defercheckwidth(void);
|
||||
void resumecheckwidth(void);
|
||||
Node* embedded(Sym*);
|
||||
Node* variter(Node*, Type*, Node*);
|
||||
void constiter(Node*, Type*, Node*);
|
||||
NodeList* variter(NodeList*, Type*, NodeList*);
|
||||
void constiter(NodeList*, Type*, NodeList*);
|
||||
|
||||
void funclit0(Type*);
|
||||
Node* funclit1(Type*, Node*);
|
||||
Node* unsafenmagic(Node*, Node*);
|
||||
Node* funclit1(Type*, NodeList*);
|
||||
Node* unsafenmagic(Node*, NodeList*);
|
||||
|
||||
/*
|
||||
* sinit.c
|
||||
*/
|
||||
|
||||
Node* initfix(Node*);
|
||||
NodeList* initfix(NodeList*);
|
||||
|
||||
/*
|
||||
* export.c
|
||||
@ -912,30 +920,33 @@ Type* pkgtype(Sym*);
|
||||
/*
|
||||
* walk.c
|
||||
*/
|
||||
void gettype(Node*, Node**);
|
||||
void gettype(Node*, NodeList**);
|
||||
void walk(Node*);
|
||||
void walkstmt(Node*);
|
||||
void walkexpr(Node*, int, Node**);
|
||||
void walkconv(Node*, Node**);
|
||||
void walkdottype(Node*, Node**);
|
||||
void walkstmtlist(NodeList*);
|
||||
void walkexpr(Node*, int, NodeList**);
|
||||
void walkexprlist(NodeList*, int, NodeList**);
|
||||
void walkconv(Node*, NodeList**);
|
||||
void walkdottype(Node*, NodeList**);
|
||||
void walkas(Node*);
|
||||
void walkbool(Node*);
|
||||
void walkswitch(Node*);
|
||||
void walkselect(Node*);
|
||||
void walkdot(Node*, Node**);
|
||||
Node* ascompatee(int, Node**, Node**, Node**);
|
||||
Node* ascompatet(int, Node**, Type**, int, Node**);
|
||||
Node* ascompatte(int, Type**, Node**, int, Node**);
|
||||
void walkdot(Node*, NodeList**);
|
||||
Node* ascompatee1(int, Node*, Node*, NodeList**);
|
||||
NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
|
||||
NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
|
||||
NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**);
|
||||
int ascompat(Type*, Type*);
|
||||
Node* prcompat(Node*, int);
|
||||
Node* prcompat(NodeList*, int, int);
|
||||
Node* nodpanic(int32);
|
||||
Node* newcompat(Node*);
|
||||
Node* makecompat(Node*);
|
||||
Node* stringop(Node*, int, Node**);
|
||||
Node* stringop(Node*, int, NodeList**);
|
||||
Type* fixmap(Type*);
|
||||
Node* mapop(Node*, int, Node**);
|
||||
Node* mapop(Node*, int, NodeList**);
|
||||
Type* fixchan(Type*);
|
||||
Node* chanop(Node*, int, Node**);
|
||||
Node* chanop(Node*, int, NodeList**);
|
||||
Node* arrayop(Node*, int);
|
||||
Node* ifacecvt(Type*, Node*, int);
|
||||
Node* ifaceop(Node*);
|
||||
@ -943,18 +954,18 @@ int ifaceas(Type*, Type*, int);
|
||||
int ifaceas1(Type*, Type*, int);
|
||||
void ifacecheck(Type*, Type*, int, int);
|
||||
void runifacechecks(void);
|
||||
Node* convas(Node*, Node**);
|
||||
Node* convas(Node*, NodeList**);
|
||||
void arrayconv(Type*, Node*);
|
||||
Node* colas(Node*, Node*, Node**);
|
||||
Node* colas(NodeList*, NodeList*);
|
||||
Node* dorange(Node*);
|
||||
Node* reorder1(Node*);
|
||||
Node* reorder3(Node*);
|
||||
Node* reorder4(Node*);
|
||||
Node* structlit(Node*, Node*, Node**);
|
||||
Node* arraylit(Node*, Node*, Node**);
|
||||
Node* maplit(Node*, Node*, Node**);
|
||||
Node* selectas(Node*, Node*, Node**);
|
||||
Node* old2new(Node*, Type*, Node**);
|
||||
NodeList* reorder1(NodeList*);
|
||||
NodeList* reorder3(NodeList*);
|
||||
NodeList* reorder4(NodeList*);
|
||||
Node* structlit(Node*, Node*, NodeList**);
|
||||
Node* arraylit(Node*, Node*, NodeList**);
|
||||
Node* maplit(Node*, Node*, NodeList**);
|
||||
Node* selectas(Node*, Node*, NodeList**);
|
||||
Node* old2new(Node*, Type*, NodeList**);
|
||||
void addrescapes(Node*);
|
||||
void heapmoves(void);
|
||||
|
||||
@ -1044,6 +1055,7 @@ void cgen_proc(Node *n, int proc);
|
||||
void checklabels(void);
|
||||
Label* findlab(Sym *s);
|
||||
void gen(Node *n);
|
||||
void genlist(NodeList *l);
|
||||
void newlab(int op, Sym *s);
|
||||
Node* sysfunc(char *name);
|
||||
Plist* newplist(void);
|
||||
|
697
src/cmd/gc/go.y
697
src/cmd/gc/go.y
File diff suppressed because it is too large
Load Diff
@ -94,12 +94,6 @@ main(int argc, char *argv[])
|
||||
typelist = mal(sizeof(*typelist));
|
||||
typelist->back = typelist;
|
||||
|
||||
// function field skeleton
|
||||
fskel = nod(OLIST, N, nod(OLIST, N, N));
|
||||
fskel->left = nod(ODCLFIELD, N, N);
|
||||
fskel->right->left = nod(ODCLFIELD, N, N);
|
||||
fskel->right->right = nod(ODCLFIELD, N, N);
|
||||
|
||||
nerrors = 0;
|
||||
yyparse();
|
||||
runifacechecks();
|
||||
|
@ -90,10 +90,11 @@ lsort(Sig *l, int(*f)(Sig*, Sig*))
|
||||
static Type*
|
||||
methodfunc(Type *f)
|
||||
{
|
||||
Node *in, *out, *d;
|
||||
NodeList *in, *out;
|
||||
Node *d;
|
||||
Type *t;
|
||||
|
||||
in = N;
|
||||
in = nil;
|
||||
if(!isifacemethod(f)) {
|
||||
d = nod(ODCLFIELD, N, N);
|
||||
d->type = getthisx(f->type)->type->type;
|
||||
@ -105,14 +106,14 @@ methodfunc(Type *f)
|
||||
in = list(in, d);
|
||||
}
|
||||
|
||||
out = N;
|
||||
out = nil;
|
||||
for(t=getoutargx(f->type)->type; t; t=t->down) {
|
||||
d = nod(ODCLFIELD, N, N);
|
||||
d->type = t->type;
|
||||
out = list(out, d);
|
||||
}
|
||||
|
||||
return functype(N, rev(in), rev(out));
|
||||
return functype(N, in, out);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
Node* list;
|
||||
NodeList* list;
|
||||
Node* mapname;
|
||||
Type* type;
|
||||
} xxx;
|
||||
@ -59,35 +59,25 @@ typeclass(Type *t)
|
||||
}
|
||||
|
||||
void
|
||||
initlin(Node* n)
|
||||
initlin(NodeList *l)
|
||||
{
|
||||
Node *n;
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
return;
|
||||
for(; l; l=l->next) {
|
||||
n = l->n;
|
||||
initlin(n->ninit);
|
||||
n->ninit = nil;
|
||||
xxx.list = list(xxx.list, n);
|
||||
switch(n->op) {
|
||||
default:
|
||||
print("o = %O\n", n->op);
|
||||
n->ninit = N;
|
||||
xxx.list = list(xxx.list, n);
|
||||
break;
|
||||
|
||||
case OCALL:
|
||||
// call to mapassign1
|
||||
n->ninit = N;
|
||||
xxx.list = list(xxx.list, n);
|
||||
break;
|
||||
|
||||
case OAS:
|
||||
n->ninit = N;
|
||||
xxx.list = list(xxx.list, n);
|
||||
break;
|
||||
|
||||
case OLIST:
|
||||
initlin(n->left);
|
||||
n = n->right;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,23 +105,22 @@ sametmp(Node *n1, Node *n2)
|
||||
Node*
|
||||
findarg(Node *n, char *arg, char *fn)
|
||||
{
|
||||
Iter param;
|
||||
Node *a;
|
||||
NodeList *l;
|
||||
|
||||
if(n == N || n->op != OCALL ||
|
||||
n->left == N || n->left->sym == S ||
|
||||
strcmp(n->left->sym->name, fn) != 0)
|
||||
return N;
|
||||
|
||||
a = listfirst(¶m, &n->right);
|
||||
while(a != N) {
|
||||
for(l=n->list; l; l=l->next) {
|
||||
a = l->n;
|
||||
if(a->op == OAS &&
|
||||
a->left != N && a->right != N &&
|
||||
a->left->op == OINDREG &&
|
||||
a->left->sym != S)
|
||||
if(strcmp(a->left->sym->name, arg) == 0)
|
||||
return a->right;
|
||||
a = listnext(¶m);
|
||||
}
|
||||
return N;
|
||||
}
|
||||
@ -226,7 +215,7 @@ no:
|
||||
Node*
|
||||
mapindex(Node *n)
|
||||
{
|
||||
Node *index, *val, *key, *a, *b;
|
||||
Node *index, *val, *key, *a, *b, *r;
|
||||
|
||||
// pull all the primatives
|
||||
key = findarg(n, "key", "mapassign1");
|
||||
@ -248,10 +237,9 @@ mapindex(Node *n)
|
||||
b = nod(ODOT, b, newname(lookup("val")));
|
||||
b = nod(OAS, b, val);
|
||||
|
||||
a = nod(OLIST, a, b);
|
||||
walkexpr(a, Etop, nil);
|
||||
|
||||
return a;
|
||||
r = liststmt(list(list1(a), b));
|
||||
walkstmt(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// for a copy out reference, A = B,
|
||||
@ -261,8 +249,8 @@ mapindex(Node *n)
|
||||
void
|
||||
initsub(Node *n, Node *nam)
|
||||
{
|
||||
Iter iter;
|
||||
Node *r, *w, *c;
|
||||
NodeList *l;
|
||||
int class, state;
|
||||
|
||||
// we could probably get a little more
|
||||
@ -287,7 +275,8 @@ initsub(Node *n, Node *nam)
|
||||
return;
|
||||
|
||||
str:
|
||||
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) {
|
||||
for(l=xxx.list; l; l=l->next) {
|
||||
r = l->n;
|
||||
if(r->op != OAS && r->op != OEMPTY)
|
||||
continue;
|
||||
|
||||
@ -326,7 +315,8 @@ str:
|
||||
return;
|
||||
|
||||
ary:
|
||||
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) {
|
||||
for(l=xxx.list; l; l=l->next) {
|
||||
r = l->n;
|
||||
if(r->op != OAS && r->op != OEMPTY)
|
||||
continue;
|
||||
|
||||
@ -366,7 +356,8 @@ ary:
|
||||
|
||||
sli:
|
||||
w = N;
|
||||
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) {
|
||||
for(l=xxx.list; l; l=l->next) {
|
||||
r = l->n;
|
||||
if(r->op != OAS && r->op != OEMPTY)
|
||||
continue;
|
||||
|
||||
@ -411,7 +402,8 @@ sli:
|
||||
map:
|
||||
return;
|
||||
w = N;
|
||||
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) {
|
||||
for(l=xxx.list; l; l=l->next) {
|
||||
r = l->n;
|
||||
if(r->op == OCALL) {
|
||||
// middle usage "(CALL mapassign1 key, val, map)"
|
||||
c = mapindex(r);
|
||||
@ -454,27 +446,23 @@ return;
|
||||
|
||||
}
|
||||
|
||||
Node*
|
||||
initfix(Node* n)
|
||||
NodeList*
|
||||
initfix(NodeList *l)
|
||||
{
|
||||
Iter iter;
|
||||
Node *r;
|
||||
|
||||
xxx.list = N;
|
||||
initlin(n);
|
||||
xxx.list = rev(xxx.list);
|
||||
xxx.list = nil;
|
||||
initlin(l);
|
||||
|
||||
if(0)
|
||||
return xxx.list;
|
||||
|
||||
// look for the copy-out reference
|
||||
r = listfirst(&iter, &xxx.list);
|
||||
while(r != N) {
|
||||
for(l=xxx.list; l; l=l->next) {
|
||||
r = l->n;
|
||||
if(r->op == OAS)
|
||||
if(inittmp(r->right)) {
|
||||
if(inittmp(r->right))
|
||||
initsub(r->left, r->right);
|
||||
}
|
||||
r = listnext(&iter);
|
||||
}
|
||||
return xxx.list;
|
||||
}
|
||||
|
@ -381,16 +381,6 @@ iskeytype(Type *t)
|
||||
return algtype(t) != ANOEQ;
|
||||
}
|
||||
|
||||
Node*
|
||||
list(Node *a, Node *b)
|
||||
{
|
||||
if(a == N)
|
||||
return b;
|
||||
if(b == N)
|
||||
return a;
|
||||
return nod(OLIST, a, b);
|
||||
}
|
||||
|
||||
Type*
|
||||
typ(int et)
|
||||
{
|
||||
@ -461,80 +451,16 @@ nodbool(int b)
|
||||
return c;
|
||||
}
|
||||
|
||||
Node*
|
||||
rev(Node *na)
|
||||
{
|
||||
Node *i, *n;
|
||||
|
||||
/*
|
||||
* since yacc wants to build lists
|
||||
* stacked down on the left -
|
||||
* this routine converts them to
|
||||
* stack down on the right -
|
||||
* in memory without recursion
|
||||
*/
|
||||
|
||||
if(na == N || na->op != OLIST)
|
||||
return na;
|
||||
i = na;
|
||||
for(n = na->left; n != N; n = n->left) {
|
||||
if(n->op != OLIST)
|
||||
break;
|
||||
i->left = n->right;
|
||||
n->right = i;
|
||||
i = n;
|
||||
}
|
||||
i->left = n;
|
||||
return i;
|
||||
}
|
||||
|
||||
Node*
|
||||
unrev(Node *na)
|
||||
{
|
||||
Node *i, *n;
|
||||
|
||||
/*
|
||||
* this restores a reverse list
|
||||
*/
|
||||
if(na == N || na->op != OLIST)
|
||||
return na;
|
||||
i = na;
|
||||
for(n = na->right; n != N; n = n->right) {
|
||||
if(n->op != OLIST)
|
||||
break;
|
||||
i->right = n->left;
|
||||
n->left = i;
|
||||
i = n;
|
||||
}
|
||||
i->right = n;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* na and nb are reversed lists.
|
||||
* append them into one big reversed list.
|
||||
*/
|
||||
Node*
|
||||
appendr(Node *na, Node *nb)
|
||||
{
|
||||
Node **l, *n;
|
||||
|
||||
for(l=&nb; (n=*l)->op == OLIST; l=&n->left)
|
||||
;
|
||||
*l = nod(OLIST, na, *l);
|
||||
return nb;
|
||||
}
|
||||
|
||||
Type*
|
||||
aindex(Node *b, Type *t)
|
||||
{
|
||||
Node *top;
|
||||
NodeList *init;
|
||||
Type *r;
|
||||
int bound;
|
||||
|
||||
bound = -1; // open bound
|
||||
top = N;
|
||||
walkexpr(b, Erv, &top);
|
||||
init = nil;
|
||||
walkexpr(b, Erv, &init);
|
||||
if(b != nil) {
|
||||
switch(consttype(b)) {
|
||||
default:
|
||||
@ -565,39 +491,36 @@ indent(int dep)
|
||||
print(". ");
|
||||
}
|
||||
|
||||
void
|
||||
dodumplist(NodeList *l, int dep)
|
||||
{
|
||||
for(; l; l=l->next)
|
||||
dodump(l->n, dep);
|
||||
}
|
||||
|
||||
void
|
||||
dodump(Node *n, int dep)
|
||||
{
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
return;
|
||||
|
||||
switch(n->op) {
|
||||
case OLIST:
|
||||
if(n->left != N && n->left->op == OLIST)
|
||||
dodump(n->left, dep+1);
|
||||
else
|
||||
dodump(n->left, dep);
|
||||
n = n->right;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
indent(dep);
|
||||
if(dep > 10) {
|
||||
print("...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(n->ninit != N) {
|
||||
if(n->ninit != nil) {
|
||||
print("%O-init\n", n->op);
|
||||
dodump(n->ninit, dep+1);
|
||||
dodumplist(n->ninit, dep+1);
|
||||
indent(dep);
|
||||
}
|
||||
|
||||
switch(n->op) {
|
||||
default:
|
||||
print("%N\n", n);
|
||||
dodump(n->left, dep+1);
|
||||
dodump(n->right, dep+1);
|
||||
break;
|
||||
|
||||
case OTYPE:
|
||||
@ -607,32 +530,32 @@ loop:
|
||||
case OIF:
|
||||
print("%O%J\n", n->op, n);
|
||||
dodump(n->ntest, dep+1);
|
||||
if(n->nbody != N) {
|
||||
if(n->nbody != nil) {
|
||||
indent(dep);
|
||||
print("%O-then\n", n->op);
|
||||
dodump(n->nbody, dep+1);
|
||||
dodumplist(n->nbody, dep+1);
|
||||
}
|
||||
if(n->nelse != N) {
|
||||
if(n->nelse != nil) {
|
||||
indent(dep);
|
||||
print("%O-else\n", n->op);
|
||||
dodump(n->nelse, dep+1);
|
||||
dodumplist(n->nelse, dep+1);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
case OSELECT:
|
||||
print("%O%J\n", n->op, n);
|
||||
dodump(n->nbody, dep+1);
|
||||
return;
|
||||
dodumplist(n->nbody, dep+1);
|
||||
break;
|
||||
|
||||
case OSWITCH:
|
||||
case OFOR:
|
||||
print("%O%J\n", n->op, n);
|
||||
dodump(n->ntest, dep+1);
|
||||
|
||||
if(n->nbody != N) {
|
||||
if(n->nbody != nil) {
|
||||
indent(dep);
|
||||
print("%O-body\n", n->op);
|
||||
dodump(n->nbody, dep+1);
|
||||
dodumplist(n->nbody, dep+1);
|
||||
}
|
||||
|
||||
if(n->nincr != N) {
|
||||
@ -640,7 +563,7 @@ loop:
|
||||
print("%O-incr\n", n->op);
|
||||
dodump(n->nincr, dep+1);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
case OCASE:
|
||||
// the right side points to label of the body
|
||||
@ -649,13 +572,26 @@ loop:
|
||||
else
|
||||
print("%O%J\n", n->op, n);
|
||||
dodump(n->left, dep+1);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
dodump(n->left, dep+1);
|
||||
n = n->right;
|
||||
dep++;
|
||||
goto loop;
|
||||
if(n->list != nil) {
|
||||
indent(dep);
|
||||
print("%O-list\n", n->op);
|
||||
dodumplist(n->list, dep+1);
|
||||
}
|
||||
if(n->rlist != nil) {
|
||||
indent(dep);
|
||||
print("%O-rlist\n", n->op);
|
||||
dodumplist(n->rlist, dep+1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dumplist(char *s, NodeList *l)
|
||||
{
|
||||
print("%s\n", s);
|
||||
dodumplist(l, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -687,7 +623,9 @@ opnames[] =
|
||||
[OARRAY] = "ARRAY",
|
||||
[OASOP] = "ASOP",
|
||||
[OAS] = "AS",
|
||||
[OAS2] = "AS2",
|
||||
[OBAD] = "BAD",
|
||||
[OBLOCK] = "BLOCK",
|
||||
[OBREAK] = "BREAK",
|
||||
[OCALLINTER] = "CALLINTER",
|
||||
[OCALLMETH] = "CALLMETH",
|
||||
@ -735,7 +673,6 @@ opnames[] =
|
||||
[OLABEL] = "LABEL",
|
||||
[OLEN] = "LEN",
|
||||
[OLE] = "LE",
|
||||
[OLIST] = "LIST",
|
||||
[OLITERAL] = "LITERAL",
|
||||
[OLSH] = "LSH",
|
||||
[OLT] = "LT",
|
||||
@ -1422,6 +1359,7 @@ treecopy(Node *n)
|
||||
*m = *n;
|
||||
m->left = treecopy(n->left);
|
||||
m->right = treecopy(n->right);
|
||||
m->list = listtreecopy(n->list);
|
||||
break;
|
||||
|
||||
case OLITERAL:
|
||||
@ -2154,34 +2092,6 @@ badtype(int o, Type *tl, Type *tr)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine gets called to propagate the type
|
||||
* of the last decl up to the arguments before it.
|
||||
* (a,b,c int) comes out (a int, b int, c int).
|
||||
*/
|
||||
Node*
|
||||
cleanidlist(Node *na)
|
||||
{
|
||||
Node *last, *n;
|
||||
|
||||
if(na->op != OLIST) {
|
||||
if(na->op != ODCLFIELD)
|
||||
fatal("cleanidlist: %O", na->op);
|
||||
if(na->right == N)
|
||||
fatal("cleanidlist: no type");
|
||||
return na;
|
||||
}
|
||||
|
||||
for(last=na; last->op == OLIST; last=last->right)
|
||||
;
|
||||
|
||||
for(n=na; n->op == OLIST; n=n->right) {
|
||||
n->left->right = last->right;
|
||||
n->left->val = last->val;
|
||||
}
|
||||
return na;
|
||||
}
|
||||
|
||||
/*
|
||||
* iterator to walk a structure declaration
|
||||
*/
|
||||
@ -2285,63 +2195,6 @@ funcnext(Iter *s)
|
||||
return fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* iterator to walk a list
|
||||
*/
|
||||
Node*
|
||||
listfirst(Iter *s, Node **nn)
|
||||
{
|
||||
Node *n;
|
||||
|
||||
n = *nn;
|
||||
if(n == N) {
|
||||
s->done = 1;
|
||||
s->an = &s->n;
|
||||
s->n = N;
|
||||
return N;
|
||||
}
|
||||
|
||||
if(n->op == OLIST) {
|
||||
s->done = 0;
|
||||
s->n = n;
|
||||
s->an = &n->left;
|
||||
return n->left;
|
||||
}
|
||||
|
||||
s->done = 1;
|
||||
s->an = nn;
|
||||
return n;
|
||||
}
|
||||
|
||||
Node*
|
||||
listnext(Iter *s)
|
||||
{
|
||||
Node *n, *r;
|
||||
|
||||
if(s->done) {
|
||||
s->an = &s->n;
|
||||
s->n = N;
|
||||
return N;
|
||||
}
|
||||
|
||||
n = s->n;
|
||||
r = n->right;
|
||||
if(r == N) {
|
||||
s->an = &s->n;
|
||||
s->n = N;
|
||||
return N;
|
||||
}
|
||||
if(r->op == OLIST) {
|
||||
s->n = r;
|
||||
s->an = &r->left;
|
||||
return r->left;
|
||||
}
|
||||
|
||||
s->done = 1;
|
||||
s->an = &n->right;
|
||||
return n->right;
|
||||
}
|
||||
|
||||
Type**
|
||||
getthis(Type *t)
|
||||
{
|
||||
@ -2475,7 +2328,7 @@ staticname(Type *t)
|
||||
* return side effect-free n, appending side effects to init.
|
||||
*/
|
||||
Node*
|
||||
saferef(Node *n, Node **init)
|
||||
saferef(Node *n, NodeList **init)
|
||||
{
|
||||
Node *l;
|
||||
Node *r;
|
||||
@ -2657,13 +2510,13 @@ out:
|
||||
Node*
|
||||
adddot(Node *n)
|
||||
{
|
||||
Node *top;
|
||||
NodeList *init;
|
||||
Type *t;
|
||||
Sym *s;
|
||||
int c, d;
|
||||
|
||||
top = N;
|
||||
walkexpr(n->left, Erv, &top);
|
||||
init = nil;
|
||||
walkexpr(n->left, Erv, &init);
|
||||
t = n->left->type;
|
||||
if(t == T)
|
||||
goto ret;
|
||||
@ -2691,8 +2544,7 @@ out:
|
||||
n->left->right = newname(dotlist[c].field->sym);
|
||||
}
|
||||
ret:
|
||||
if(top != N)
|
||||
n->ninit = list(top, n->ninit);
|
||||
n->ninit = concat(init, n->ninit);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -2847,16 +2699,17 @@ expandmeth(Sym *s, Type *t)
|
||||
/*
|
||||
* Given funarg struct list, return list of ODCLFIELD Node fn args.
|
||||
*/
|
||||
Node*
|
||||
NodeList*
|
||||
structargs(Type **tl, int mustname)
|
||||
{
|
||||
Iter savet;
|
||||
Node *args, *a;
|
||||
Node *a;
|
||||
NodeList *args;
|
||||
Type *t;
|
||||
char nam[100];
|
||||
int n;
|
||||
|
||||
args = N;
|
||||
args = nil;
|
||||
n = 0;
|
||||
for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
|
||||
if(t->sym)
|
||||
@ -2869,7 +2722,6 @@ structargs(Type **tl, int mustname)
|
||||
a = anondcl(t->type);
|
||||
args = list(args, a);
|
||||
}
|
||||
args = rev(args);
|
||||
return args;
|
||||
}
|
||||
|
||||
@ -2899,9 +2751,8 @@ structargs(Type **tl, int mustname)
|
||||
void
|
||||
genwrapper(Type *rcvr, Type *method, Sym *newnam)
|
||||
{
|
||||
Node *this, *in, *out, *fn, *args, *call;
|
||||
Node *l;
|
||||
Iter savel;
|
||||
Node *this, *fn, *call, *n;
|
||||
NodeList *l, *args, *in, *out;
|
||||
|
||||
if(debug['r'])
|
||||
print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
|
||||
@ -2920,19 +2771,22 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
|
||||
funchdr(fn);
|
||||
|
||||
// arg list
|
||||
args = N;
|
||||
for(l = listfirst(&savel, &in); l; l = listnext(&savel))
|
||||
args = list(args, l->left);
|
||||
args = rev(args);
|
||||
args = nil;
|
||||
for(l=in; l; l=l->next)
|
||||
args = list(args, l->n->left);
|
||||
|
||||
// generate call
|
||||
call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), args);
|
||||
fn->nbody = call;
|
||||
if(method->type->outtuple > 0)
|
||||
fn->nbody = nod(ORETURN, call, N);
|
||||
call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), N);
|
||||
call->list = args;
|
||||
fn->nbody = list1(call);
|
||||
if(method->type->outtuple > 0) {
|
||||
n = nod(ORETURN, N, N);
|
||||
n->list = fn->nbody;
|
||||
fn->nbody = list1(n);
|
||||
}
|
||||
|
||||
if(debug['r'])
|
||||
dump("genwrapper body", fn->nbody);
|
||||
dumplist("genwrapper body", fn->nbody);
|
||||
|
||||
funcbody(fn);
|
||||
}
|
||||
@ -3137,3 +2991,71 @@ simsimtype(Type *t)
|
||||
return et;
|
||||
}
|
||||
|
||||
NodeList*
|
||||
concat(NodeList *a, NodeList *b)
|
||||
{
|
||||
if(a == nil)
|
||||
return b;
|
||||
if(b == nil)
|
||||
return a;
|
||||
|
||||
a->end->next = b;
|
||||
a->end = b->end;
|
||||
b->end = nil;
|
||||
return a;
|
||||
}
|
||||
|
||||
NodeList*
|
||||
list1(Node *n)
|
||||
{
|
||||
NodeList *l;
|
||||
|
||||
if(n == nil)
|
||||
return nil;
|
||||
if(n->op == OBLOCK && n->ninit == nil)
|
||||
return n->list;
|
||||
l = mal(sizeof *l);
|
||||
l->n = n;
|
||||
l->end = l;
|
||||
return l;
|
||||
}
|
||||
|
||||
NodeList*
|
||||
list(NodeList *l, Node *n)
|
||||
{
|
||||
return concat(l, list1(n));
|
||||
}
|
||||
|
||||
NodeList*
|
||||
listtreecopy(NodeList *l)
|
||||
{
|
||||
NodeList *out;
|
||||
|
||||
out = nil;
|
||||
for(; l; l=l->next)
|
||||
out = list(out, treecopy(l->n));
|
||||
return out;
|
||||
}
|
||||
|
||||
Node*
|
||||
liststmt(NodeList *l)
|
||||
{
|
||||
Node *n;
|
||||
|
||||
n = nod(OBLOCK, N, N);
|
||||
n->list = l;
|
||||
if(l)
|
||||
n->lineno = l->n->lineno;
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
count(NodeList *l)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
for(; l; l=l->next)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
174
src/cmd/gc/swt.c
174
src/cmd/gc/swt.c
@ -305,23 +305,16 @@ sw3(Node *c, Type *place, int arg)
|
||||
Type*
|
||||
walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg)
|
||||
{
|
||||
Iter save;
|
||||
Node *n;
|
||||
NodeList *l;
|
||||
Type *place;
|
||||
int32 lno;
|
||||
|
||||
lno = setlineno(sw);
|
||||
place = call(sw->ntest, T, arg);
|
||||
|
||||
n = listfirst(&save, &sw->nbody->left);
|
||||
if(n == N || n->op == OEMPTY)
|
||||
return T;
|
||||
|
||||
loop:
|
||||
if(n == N) {
|
||||
lineno = lno;
|
||||
return place;
|
||||
}
|
||||
for(l=sw->list; l; l=l->next) {
|
||||
n = l->n;
|
||||
|
||||
if(n->op != OCASE)
|
||||
fatal("walkcases: not case %O\n", n->op);
|
||||
@ -330,8 +323,9 @@ loop:
|
||||
setlineno(n);
|
||||
place = call(n->left, place, arg);
|
||||
}
|
||||
n = listnext(&save);
|
||||
goto loop;
|
||||
}
|
||||
lineno = lno;
|
||||
return place;
|
||||
}
|
||||
|
||||
Node*
|
||||
@ -352,35 +346,32 @@ newlabel(void)
|
||||
void
|
||||
casebody(Node *sw)
|
||||
{
|
||||
Iter save, save1;
|
||||
Node *os, *oc, *n, *n1, *c;
|
||||
Node *cas, *stat, *def;
|
||||
Node *os, *oc, *n, *c, *last;
|
||||
Node *def;
|
||||
NodeList *cas, *stat, *l, *lc;
|
||||
Node *go, *br;
|
||||
int32 lno;
|
||||
|
||||
lno = setlineno(sw);
|
||||
n = listfirst(&save, &sw->nbody);
|
||||
if(n == N || n->op == OEMPTY) {
|
||||
sw->nbody = nod(OLIST, N, N);
|
||||
if(sw->list == nil)
|
||||
return;
|
||||
}
|
||||
|
||||
cas = N; // cases
|
||||
stat = N; // statements
|
||||
cas = nil; // cases
|
||||
stat = nil; // statements
|
||||
def = N; // defaults
|
||||
os = N; // last statement
|
||||
oc = N; // last case
|
||||
br = nod(OBREAK, N, N);
|
||||
|
||||
for(; n != N; n = listnext(&save)) {
|
||||
for(l=sw->list; l; l=l->next) {
|
||||
n = l->n;
|
||||
lno = setlineno(n);
|
||||
if(n->op != OXCASE)
|
||||
fatal("casebody %O", n->op);
|
||||
n->op = OCASE;
|
||||
|
||||
go = nod(OGOTO, newlabel(), N);
|
||||
c = n->left;
|
||||
if(c == N) {
|
||||
if(n->list == nil) {
|
||||
if(def != N)
|
||||
yyerror("more than one default case");
|
||||
// reuse original default case
|
||||
@ -388,59 +379,54 @@ casebody(Node *sw)
|
||||
def = n;
|
||||
}
|
||||
|
||||
// expand multi-valued cases
|
||||
for(; c!=N; c=c->right) {
|
||||
if(c->op != OLIST) {
|
||||
// reuse original case
|
||||
if(n->list != nil && n->list->next == nil) {
|
||||
// one case - reuse OCASE node.
|
||||
c = n->list->n;
|
||||
n->left = c;
|
||||
n->right = go;
|
||||
n->list = nil;
|
||||
cas = list(cas, n);
|
||||
break;
|
||||
} else {
|
||||
// expand multi-valued cases
|
||||
for(lc=n->list; lc; lc=lc->next) {
|
||||
c = lc->n;
|
||||
cas = list(cas, nod(OCASE, c, go));
|
||||
}
|
||||
cas = list(cas, nod(OCASE, c->left, go));
|
||||
}
|
||||
|
||||
stat = list(stat, nod(OLABEL, go->left, N));
|
||||
|
||||
os = N;
|
||||
for(n1 = listfirst(&save1, &n->nbody); n1 != N; n1 = listnext(&save1)) {
|
||||
os = n1;
|
||||
stat = list(stat, n1);
|
||||
}
|
||||
stat = concat(stat, n->nbody);
|
||||
|
||||
// botch - shouldnt fall thru declaration
|
||||
if(os != N && os->op == OXFALL)
|
||||
os->op = OFALL;
|
||||
last = stat->end->n;
|
||||
if(last->op == OXFALL)
|
||||
last->op = OFALL;
|
||||
else
|
||||
stat = list(stat, br);
|
||||
}
|
||||
|
||||
stat = list(stat, br);
|
||||
if(def)
|
||||
cas = list(cas, def);
|
||||
|
||||
sw->nbody = nod(OLIST, rev(cas), rev(stat));
|
||||
//dump("case", sw->nbody->left);
|
||||
//dump("stat", sw->nbody->right);
|
||||
sw->list = cas;
|
||||
sw->nbody = stat;
|
||||
lineno = lno;
|
||||
}
|
||||
|
||||
Case*
|
||||
mkcaselist(Node *sw, int arg)
|
||||
{
|
||||
Iter save;
|
||||
Node *n;
|
||||
Case *c, *c1;
|
||||
NodeList *l;
|
||||
int ord;
|
||||
|
||||
c = C;
|
||||
ord = 0;
|
||||
|
||||
n = listfirst(&save, &sw->nbody->left);
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
goto done;
|
||||
|
||||
for(l=sw->list; l; l=l->next) {
|
||||
n = l->n;
|
||||
c1 = mal(sizeof(*c1));
|
||||
c1->link = c;
|
||||
c = c1;
|
||||
@ -451,7 +437,7 @@ loop:
|
||||
|
||||
if(n->left == N) {
|
||||
c->type = Tdefault;
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(arg) {
|
||||
@ -459,16 +445,16 @@ loop:
|
||||
c->hash = 0;
|
||||
if(n->left->left == N) {
|
||||
c->type = Ttypenil;
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
if(istype(n->left->left->type, TINTER)) {
|
||||
c->type = Ttypevar;
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
|
||||
c->hash = typehash(n->left->left->type, 1, 0);
|
||||
c->type = Ttypeconst;
|
||||
goto next;
|
||||
continue;
|
||||
|
||||
case Snorm:
|
||||
case Strue:
|
||||
@ -480,13 +466,10 @@ loop:
|
||||
case CTSTR:
|
||||
c->type = Texprconst;
|
||||
}
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
next:
|
||||
n = listnext(&save);
|
||||
goto loop;
|
||||
|
||||
done:
|
||||
if(c == C)
|
||||
return C;
|
||||
|
||||
@ -528,12 +511,12 @@ static Node* exprname;
|
||||
Node*
|
||||
exprbsw(Case *c0, int ncase, int arg)
|
||||
{
|
||||
Node *cas;
|
||||
NodeList *cas;
|
||||
Node *a, *n;
|
||||
Case *c;
|
||||
int i, half, lno;
|
||||
|
||||
cas = N;
|
||||
cas = nil;
|
||||
if(ncase < Ncase) {
|
||||
for(i=0; i<ncase; i++) {
|
||||
n = c0->node;
|
||||
@ -543,19 +526,19 @@ exprbsw(Case *c0, int ncase, int arg)
|
||||
case Strue:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = n->left; // if val
|
||||
a->nbody = n->right; // then goto l
|
||||
a->nbody = list1(n->right); // then goto l
|
||||
break;
|
||||
|
||||
case Sfalse:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(ONOT, n->left, N); // if !val
|
||||
a->nbody = n->right; // then goto l
|
||||
a->nbody = list1(n->right); // then goto l
|
||||
break;
|
||||
|
||||
default:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, exprname, n->left); // if name == val
|
||||
a->nbody = n->right; // then goto l
|
||||
a->nbody = list1(n->right); // then goto l
|
||||
break;
|
||||
}
|
||||
|
||||
@ -563,7 +546,7 @@ exprbsw(Case *c0, int ncase, int arg)
|
||||
c0 = c0->link;
|
||||
lineno = lno;
|
||||
}
|
||||
return cas;
|
||||
return liststmt(cas);
|
||||
}
|
||||
|
||||
// find the middle and recur
|
||||
@ -573,8 +556,8 @@ exprbsw(Case *c0, int ncase, int arg)
|
||||
c = c->link;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OLE, exprname, c->node->left);
|
||||
a->nbody = exprbsw(c0, half, arg);
|
||||
a->nelse = exprbsw(c->link, ncase-half, arg);
|
||||
a->nbody = list1(exprbsw(c0, half, arg));
|
||||
a->nelse = list1(exprbsw(c->link, ncase-half, arg));
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -585,7 +568,8 @@ exprbsw(Case *c0, int ncase, int arg)
|
||||
void
|
||||
exprswitch(Node *sw)
|
||||
{
|
||||
Node *def, *cas;
|
||||
Node *def;
|
||||
NodeList *cas;
|
||||
Node *a;
|
||||
Case *c0, *c, *c1;
|
||||
Type *t;
|
||||
@ -620,11 +604,11 @@ exprswitch(Node *sw)
|
||||
* convert the switch into OIF statements
|
||||
*/
|
||||
exprname = N;
|
||||
cas = N;
|
||||
cas = nil;
|
||||
if(arg != Strue && arg != Sfalse) {
|
||||
exprname = nod(OXXX, N, N);
|
||||
tempname(exprname, sw->ntest->type);
|
||||
cas = nod(OAS, exprname, sw->ntest);
|
||||
cas = list1(nod(OAS, exprname, sw->ntest));
|
||||
}
|
||||
|
||||
c0 = mkcaselist(sw, arg);
|
||||
@ -638,8 +622,9 @@ exprswitch(Node *sw)
|
||||
loop:
|
||||
if(c0 == C) {
|
||||
cas = list(cas, def);
|
||||
sw->nbody->left = rev(cas);
|
||||
walkstmt(sw->nbody);
|
||||
sw->nbody = concat(cas, sw->nbody);
|
||||
sw->list = nil;
|
||||
walkstmtlist(sw->nbody);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -680,34 +665,36 @@ static Node* boolname;
|
||||
Node*
|
||||
typeone(Node *t)
|
||||
{
|
||||
Node *a, *b, *dcl;
|
||||
NodeList *init;
|
||||
Node *a, *b, *var;
|
||||
|
||||
a = t->left->left; // var
|
||||
dcl = nod(ODCL, a, N);
|
||||
|
||||
a = nod(OLIST, a, boolname); // var,bool
|
||||
var = t->left->left;
|
||||
init = list1(nod(ODCL, var, N));
|
||||
|
||||
a = nod(OAS2, N, N);
|
||||
a->list = list(list1(var), boolname); // var,bool =
|
||||
b = nod(ODOTTYPE, facename, N);
|
||||
b->type = t->left->left->type; // interface.(type)
|
||||
|
||||
a = nod(OAS, a, b); // var,bool = interface.(type)
|
||||
a->rlist = list1(b);
|
||||
init = list(init, a);
|
||||
|
||||
b = nod(OIF, N, N);
|
||||
b->ntest = boolname;
|
||||
b->nbody = t->right; // if bool { goto l }
|
||||
return list(list(dcl, a), b);
|
||||
b->nbody = list1(t->right); // if bool { goto l }
|
||||
a = liststmt(list(init, b));
|
||||
return a;
|
||||
}
|
||||
|
||||
Node*
|
||||
typebsw(Case *c0, int ncase)
|
||||
{
|
||||
Node *cas;
|
||||
NodeList *cas;
|
||||
Node *a, *n;
|
||||
Case *c;
|
||||
int i, half;
|
||||
Val v;
|
||||
|
||||
cas = N;
|
||||
cas = nil;
|
||||
|
||||
if(ncase < Ncase) {
|
||||
for(i=0; i<ncase; i++) {
|
||||
@ -719,7 +706,7 @@ typebsw(Case *c0, int ncase)
|
||||
v.ctype = CTNIL;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, facename, nodlit(v));
|
||||
a->nbody = n->right; // if i==nil { goto l }
|
||||
a->nbody = list1(n->right); // if i==nil { goto l }
|
||||
cas = list(cas, a);
|
||||
break;
|
||||
|
||||
@ -731,13 +718,13 @@ typebsw(Case *c0, int ncase)
|
||||
case Ttypeconst:
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
|
||||
a->nbody = rev(typeone(n));
|
||||
a->nbody = list1(typeone(n));
|
||||
cas = list(cas, a);
|
||||
break;
|
||||
}
|
||||
c0 = c0->link;
|
||||
}
|
||||
return cas;
|
||||
return liststmt(cas);
|
||||
}
|
||||
|
||||
// find the middle and recur
|
||||
@ -747,8 +734,8 @@ typebsw(Case *c0, int ncase)
|
||||
c = c->link;
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = nod(OLE, hashname, nodintconst(c->hash));
|
||||
a->nbody = typebsw(c0, half);
|
||||
a->nelse = typebsw(c->link, ncase-half);
|
||||
a->nbody = list1(typebsw(c0, half));
|
||||
a->nelse = list1(typebsw(c->link, ncase-half));
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -760,7 +747,8 @@ typebsw(Case *c0, int ncase)
|
||||
void
|
||||
typeswitch(Node *sw)
|
||||
{
|
||||
Node *cas, *def;
|
||||
Node *def;
|
||||
NodeList *cas;
|
||||
Node *a;
|
||||
Case *c, *c0, *c1;
|
||||
int ncase;
|
||||
@ -779,7 +767,7 @@ typeswitch(Node *sw)
|
||||
return;
|
||||
}
|
||||
walkcases(sw, sw0, Stype);
|
||||
cas = N;
|
||||
cas = nil;
|
||||
|
||||
/*
|
||||
* predeclare temporary variables
|
||||
@ -802,7 +790,8 @@ typeswitch(Node *sw)
|
||||
else
|
||||
a = syslook("ifacethash", 1);
|
||||
argtype(a, t);
|
||||
a = nod(OCALL, a, facename);
|
||||
a = nod(OCALL, a, N);
|
||||
a->list = list1(facename);
|
||||
a = nod(OAS, hashname, a);
|
||||
cas = list(cas, a);
|
||||
|
||||
@ -817,8 +806,9 @@ typeswitch(Node *sw)
|
||||
loop:
|
||||
if(c0 == C) {
|
||||
cas = list(cas, def);
|
||||
sw->nbody->left = rev(cas);
|
||||
walkstmt(sw->nbody);
|
||||
sw->nbody = concat(cas, sw->nbody);
|
||||
sw->list = nil;
|
||||
walkstmtlist(sw->nbody);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -860,7 +850,7 @@ walkswitch(Node *sw)
|
||||
* cases have OGOTO into statements.
|
||||
* both have inserted OBREAK statements
|
||||
*/
|
||||
walkstmt(sw->ninit);
|
||||
walkstmtlist(sw->ninit);
|
||||
if(sw->ntest == N)
|
||||
sw->ntest = nodbool(1);
|
||||
casebody(sw);
|
||||
|
@ -67,7 +67,6 @@ func mapiter2(hiter *any) (key any, val any);
|
||||
func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
|
||||
func chanrecv1(hchan <-chan any) (elem any);
|
||||
func chanrecv2(hchan <-chan any) (elem any, pres bool);
|
||||
func chanrecv3(hchan <-chan any, elem *any) (pres bool);
|
||||
func chansend1(hchan chan<- any, elem any);
|
||||
func chansend2(hchan chan<- any, elem any) (pres bool);
|
||||
func closechan(hchan any);
|
||||
|
1594
src/cmd/gc/walk.c
1594
src/cmd/gc/walk.c
File diff suppressed because it is too large
Load Diff
@ -431,13 +431,6 @@ sys·chanrecv2(Hchan* c, ...)
|
||||
chanrecv(c, ae, ap);
|
||||
}
|
||||
|
||||
// chanrecv3(hchan *chan any, elem *any) (pres bool);
|
||||
void
|
||||
sys·chanrecv3(Hchan* c, byte* ep, byte pres)
|
||||
{
|
||||
chanrecv(c, ep, &pres);
|
||||
}
|
||||
|
||||
// newselect(size uint32) (sel *byte);
|
||||
void
|
||||
sys·newselect(int32 size, ...)
|
||||
|
@ -99,8 +99,7 @@ throw: interface conversion
|
||||
panic PC=xxx
|
||||
|
||||
=========== bugs/bug159.go
|
||||
xyz: expected 1 2 3 got 3 2 1
|
||||
abc: expected 4 5 6 got -4 4 4
|
||||
abc: expected 4 5 6 got 4 4 -4
|
||||
BUG: bug159
|
||||
|
||||
=========== bugs/bug162.go
|
||||
|
Loading…
x
Reference in New Issue
Block a user