This source file includes following definitions.
- renameinit
- anyinit
- fninit
#include <u.h>
#include <libc.h>
#include "go.h"
Sym*
renameinit(void)
{
static int initgen;
snprint(namebuf, sizeof(namebuf), "init·%d", ++initgen);
return lookup(namebuf);
}
static int
anyinit(NodeList *n)
{
uint32 h;
Sym *s;
NodeList *l;
for(l=n; l; l=l->next) {
switch(l->n->op) {
case ODCLFUNC:
case ODCLCONST:
case ODCLTYPE:
case OEMPTY:
break;
case OAS:
if(isblank(l->n->left) && candiscard(l->n->right))
break;
default:
return 1;
}
}
if(strcmp(localpkg->name, "main") == 0)
return 1;
snprint(namebuf, sizeof(namebuf), "init·1");
s = lookup(namebuf);
if(s->def != N)
return 1;
for(h=0; h<NHASH; h++)
for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'i' || strcmp(s->name, "init") != 0)
continue;
if(s->def == N)
continue;
return 1;
}
return 0;
}
void
fninit(NodeList *n)
{
int i;
Node *gatevar;
Node *a, *b, *fn;
NodeList *r;
uint32 h;
Sym *s, *initsym;
if(debug['A']) {
return;
}
n = initfix(n);
if(!anyinit(n))
return;
r = nil;
snprint(namebuf, sizeof(namebuf), "initdone·");
gatevar = newname(lookup(namebuf));
addvar(gatevar, types[TUINT8], PEXTERN);
maxarg = 0;
snprint(namebuf, sizeof(namebuf), "init");
fn = nod(ODCLFUNC, N, N);
initsym = lookup(namebuf);
fn->nname = newname(initsym);
fn->nname->defn = fn;
fn->nname->ntype = nod(OTFUNC, N, N);
declare(fn->nname, PFUNC);
funchdr(fn);
a = nod(OIF, N, N);
a->ntest = nod(ONE, gatevar, nodintconst(0));
r = list(r, a);
b = nod(OIF, N, N);
b->ntest = nod(OEQ, gatevar, nodintconst(2));
b->nbody = list1(nod(ORETURN, N, N));
a->nbody = list1(b);
b = syslook("throwinit", 0);
b = nod(OCALL, b, N);
a->nbody = list(a->nbody, b);
a = nod(OAS, gatevar, nodintconst(1));
r = list(r, a);
for(h=0; h<NHASH; h++)
for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'i' || strcmp(s->name, "init") != 0)
continue;
if(s->def == N)
continue;
if(s == initsym)
continue;
a = nod(OCALL, s->def, N);
r = list(r, a);
}
r = concat(r, n);
for(i=1;; i++) {
snprint(namebuf, sizeof(namebuf), "init·%d", i);
s = lookup(namebuf);
if(s->def == N)
break;
a = nod(OCALL, s->def, N);
r = list(r, a);
}
a = nod(OAS, gatevar, nodintconst(2));
r = list(r, a);
a = nod(ORETURN, N, N);
r = list(r, a);
exportsym(fn->nname);
fn->nbody = r;
funcbody(fn);
curfn = fn;
typecheck(&fn, Etop);
typechecklist(r, Etop);
curfn = nil;
funccompile(fn, 0);
}