diff options
author | Ken Thompson <ken@golang.org> | 2009-05-28 16:00:55 -0700 |
---|---|---|
committer | Ken Thompson <ken@golang.org> | 2009-05-28 16:00:55 -0700 |
commit | 103de3e314847a7ec67c8ff2a26f7dfe3e79ffe9 (patch) | |
tree | ef3051f1ef10e216f04df89c1aa50f6648f8b091 /src | |
parent | 627363e8a8fddda42af80877cfed1546f44d87cb (diff) | |
download | golang-103de3e314847a7ec67c8ff2a26f7dfe3e79ffe9.tar.gz |
detect recursive initialization
R=r
OCL=29544
CL=29544
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/gc/builtin.c.boot | 1 | ||||
-rw-r--r-- | src/cmd/gc/dcl.c | 68 | ||||
-rw-r--r-- | src/cmd/gc/sinit.c | 6 | ||||
-rw-r--r-- | src/cmd/gc/sys.go | 1 | ||||
-rw-r--r-- | src/runtime/runtime.c | 6 |
5 files changed, 57 insertions, 25 deletions
diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot index 6ee50e035..54aebd89f 100644 --- a/src/cmd/gc/builtin.c.boot +++ b/src/cmd/gc/builtin.c.boot @@ -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" diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 6068651b8..e5d6392e6 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -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); diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index b15061c2e..a6727e011 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -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; } } diff --git a/src/cmd/gc/sys.go b/src/cmd/gc/sys.go index 3a278d9ff..d4313d2f2 100644 --- a/src/cmd/gc/sys.go +++ b/src/cmd/gc/sys.go @@ -10,6 +10,7 @@ package PACKAGE func mal(int32) *any; func throwindex(); func throwreturn(); +func throwinit(); func panicl(int32); func printbool(bool); diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 57e257090..fb9bf5cbc 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -52,6 +52,12 @@ sys·throwreturn(void) } void +sys·throwinit(void) +{ + throw("recursive call during initialization"); +} + +void throw(int8 *s) { printf("throw: %s\n", s); |