mirror of
https://github.com/golang/go
synced 2024-11-05 14:36:11 -07:00
detect recursive initialization
R=r OCL=29544 CL=29544
This commit is contained in:
parent
3aa006b8cd
commit
e2613711aa
@ -3,6 +3,7 @@ char *sysimport =
|
||||
"func sys.mal (? int32) (? *any)\n"
|
||||
"func sys.throwindex ()\n"
|
||||
"func sys.throwreturn ()\n"
|
||||
"func sys.throwinit ()\n"
|
||||
"func sys.panicl (? int32)\n"
|
||||
"func sys.printbool (? bool)\n"
|
||||
"func sys.printfloat (? float64)\n"
|
||||
|
@ -1284,18 +1284,24 @@ mixed:
|
||||
yyerror("cannot mix anonymous and named function arguments");
|
||||
}
|
||||
|
||||
// hand-craft the following initialization code
|
||||
// var initdone·<file> bool (1)
|
||||
// func Init·<file>() (2)
|
||||
// if initdone·<file> { return } (3)
|
||||
// initdone.<file> = true; (4)
|
||||
// // over all matching imported symbols
|
||||
// <pkg>.init·<file>() (5)
|
||||
// { <init stmts> } (6)
|
||||
// init·<file>() // if any (7)
|
||||
// return (8)
|
||||
// }
|
||||
|
||||
/*
|
||||
* hand-craft the following initialization code
|
||||
* var initdone·<file> uint8 (1)
|
||||
* func Init·<file>() (2)
|
||||
* if initdone·<file> { (3)
|
||||
* if initdone·<file> == 2 (4)
|
||||
* return
|
||||
* throw(); (5)
|
||||
* }
|
||||
* initdone.<file>++; (6)
|
||||
* // over all matching imported symbols
|
||||
* <pkg>.init·<file>() (7)
|
||||
* { <init stmts> } (8)
|
||||
* init·<file>() // if any (9)
|
||||
* initdone.<file>++; (10)
|
||||
* return (11)
|
||||
* }
|
||||
*/
|
||||
int
|
||||
anyinit(Node *n)
|
||||
{
|
||||
@ -1333,8 +1339,8 @@ anyinit(Node *n)
|
||||
void
|
||||
fninit(Node *n)
|
||||
{
|
||||
Node *done;
|
||||
Node *a, *fn, *r;
|
||||
Node *gatevar;
|
||||
Node *a, *b, *fn, *r;
|
||||
uint32 h;
|
||||
Sym *s, *initsym;
|
||||
|
||||
@ -1350,8 +1356,8 @@ fninit(Node *n)
|
||||
|
||||
// (1)
|
||||
snprint(namebuf, sizeof(namebuf), "initdone·%s", filename);
|
||||
done = newname(lookup(namebuf));
|
||||
addvar(done, types[TBOOL], PEXTERN);
|
||||
gatevar = newname(lookup(namebuf));
|
||||
addvar(gatevar, types[TUINT8], PEXTERN);
|
||||
|
||||
// (2)
|
||||
|
||||
@ -1373,15 +1379,26 @@ fninit(Node *n)
|
||||
|
||||
// (3)
|
||||
a = nod(OIF, N, N);
|
||||
a->ntest = done;
|
||||
a->nbody = nod(ORETURN, N, N);
|
||||
a->ntest = nod(ONE, gatevar, nodintconst(0));
|
||||
r = list(r, a);
|
||||
|
||||
// (4)
|
||||
a = nod(OAS, done, nodbool(1));
|
||||
r = list(r, a);
|
||||
b = nod(OIF, N, N);
|
||||
b->ntest = nod(OEQ, gatevar, nodintconst(2));
|
||||
b->nbody = nod(ORETURN, N, N);
|
||||
a->nbody = b;
|
||||
|
||||
// (5)
|
||||
b = syslook("throwinit", 0);
|
||||
b = nod(OCALL, b, N);
|
||||
a->nbody = list(a->nbody, b);
|
||||
|
||||
// (6)
|
||||
a = nod(OASOP, gatevar, nodintconst(1));
|
||||
a->etype = OADD;
|
||||
r = list(r, a);
|
||||
|
||||
// (7)
|
||||
for(h=0; h<NHASH; h++)
|
||||
for(s = hash[h]; s != S; s = s->link) {
|
||||
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
|
||||
@ -1396,10 +1413,10 @@ fninit(Node *n)
|
||||
r = list(r, a);
|
||||
}
|
||||
|
||||
// (6)
|
||||
// (8)
|
||||
r = list(r, initfix(n));
|
||||
|
||||
// (7)
|
||||
// (9)
|
||||
// could check that it is fn of no args/returns
|
||||
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
|
||||
s = lookup(namebuf);
|
||||
@ -1408,7 +1425,12 @@ fninit(Node *n)
|
||||
r = list(r, a);
|
||||
}
|
||||
|
||||
// (8)
|
||||
// (10)
|
||||
a = nod(OASOP, gatevar, nodintconst(1));
|
||||
a->etype = OADD;
|
||||
r = list(r, a);
|
||||
|
||||
// (11)
|
||||
a = nod(ORETURN, N, N);
|
||||
r = list(r, a);
|
||||
|
||||
|
@ -61,6 +61,8 @@ typeclass(Type *t)
|
||||
void
|
||||
initlin(Node* n)
|
||||
{
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
return;
|
||||
initlin(n->ninit);
|
||||
@ -84,8 +86,8 @@ initlin(Node* n)
|
||||
|
||||
case OLIST:
|
||||
initlin(n->left);
|
||||
initlin(n->right);
|
||||
break;
|
||||
n = n->right;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ package PACKAGE
|
||||
func mal(int32) *any;
|
||||
func throwindex();
|
||||
func throwreturn();
|
||||
func throwinit();
|
||||
func panicl(int32);
|
||||
|
||||
func printbool(bool);
|
||||
|
@ -51,6 +51,12 @@ sys·throwreturn(void)
|
||||
throw("no return at end of a typed function");
|
||||
}
|
||||
|
||||
void
|
||||
sys·throwinit(void)
|
||||
{
|
||||
throw("recursive call during initialization");
|
||||
}
|
||||
|
||||
void
|
||||
throw(int8 *s)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user