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