Commit e2613711 authored by Ken Thompson's avatar Ken Thompson

detect recursive initialization

R=r
OCL=29544
CL=29544
parent 3aa006b8
...@@ -3,6 +3,7 @@ char *sysimport = ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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)
{ {
......
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