initialization
SVN=128115
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index ac724a0..601acf5 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -877,3 +877,105 @@
s->forwtype = t;
return t;
}
+
+// hand-craft the following initialization code
+// var init_%%%_done bool; (1)
+// func init_%%%_function() (2)
+// if init_%%%_done { return } (3)
+// init_%%%_done = true; (4)
+// for Y {
+// init_%%%_function() (5)
+// }
+// if true { <init stmts> } (6)
+// init() // if any (7)
+// return (8)
+// }
+// export init_%%%_function (9)
+
+void
+fninit(Node *n)
+{
+ Node *done, *any, *init;
+ Node *a, *b, *r;
+ Iter iter;
+ ulong h;
+ Sym *s;
+
+ r = N;
+
+ // (1)
+ vargen++;
+ snprint(namebuf, sizeof(namebuf), "init_%.3ld_done", vargen);
+ done = newname(lookup(namebuf));
+ addvar(done, types[TBOOL], PEXTERN);
+
+ // (2)
+
+ maxarg = 0;
+ stksize = 0;
+
+ vargen++;
+ h = vargen;
+ if(strcmp(package, "main") == 0)
+ h = 999;
+ snprint(namebuf, sizeof(namebuf), "init_%.3ld_function", h);
+ b = nod(ODCLFUNC, N, N);
+ b->nname = newname(lookup(namebuf));
+ b->type = functype(N, N, N);
+ funchdr(b);
+
+ // (3)
+ a = nod(OIF, N, N);
+ a->ntest = done;
+ a->nbody = nod(ORETURN, N, N);
+ r = list(r, a);
+
+ // (4)
+ a = nod(OAS, done, booltrue);
+ r = list(r, a);
+
+ // (5)
+ init = N;
+ for(h=0; h<NHASH; h++)
+ for(s = hash[h]; s != S; s = s->link) {
+ if(s->name[0] != 'i')
+ continue;
+ if(strstr(s->name, "init") == nil)
+ continue;
+ if(strstr(s->name, "_function") == nil) {
+ if(strcmp(s->name, "init") == 0)
+ init = s->oname;
+ continue;
+ }
+ if(s->oname == N)
+ continue;
+
+ a = nod(OCALL, s->oname, N);
+ r = list(r, a);
+ }
+
+ // (6)
+ r = list(r, n);
+
+ // (7)
+ if(init != N) {
+ a = nod(OCALL, init, N);
+ r = list(r, a);
+ }
+
+ // (8)
+ a = nod(ORETURN, N, N);
+ r = list(r, a);
+
+ // (9)
+ a = nod(OEXPORT, N, N);
+ a->sym = b->nname->sym;
+ markexport(a);
+
+ b->nbody = rev(r);
+//dump("b", b);
+//dump("r", b->nbody);
+
+ popdcl();
+ compile(b);
+}
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index ffc75ad..547be9d 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -542,6 +542,7 @@
Type* newtype(Sym*);
Type* oldtype(Sym*);
Type* forwdcl(Sym*);
+void fninit(Node*);
/*
* export.c
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 0b0e425c..672e53a 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -66,6 +66,7 @@
{
if(debug['f'])
frame(1);
+ fninit($4);
testdclstack();
}
@@ -138,12 +139,17 @@
| LEXPORT export_list_r
{
markexport(rev($2));
+ $$ = N;
}
| LEXPORT '(' export_list_r ')'
{
markexport(rev($3));
+ $$ = N;
}
| xfndcl
+ {
+ $$ = N;
+ }
| ';'
{
$$ = N;
@@ -168,9 +174,9 @@
}
| LCONST '(' constdcl_list_r osemi ')'
{
- $$ = N;
iota = 0;
lastconst = N;
+ $$ = N;
}
| LTYPE Atypedcl
{
@@ -1089,7 +1095,7 @@
xdcl
| xdcl_list_r xdcl
{
- $$ = nod(OLIST, $1, $2);
+ $$ = list($1, $2);
}
vardcl_list_r:
diff --git a/src/runtime/rt0_amd64.s b/src/runtime/rt0_amd64.s
index aad67cb..5544833 100644
--- a/src/runtime/rt0_amd64.s
+++ b/src/runtime/rt0_amd64.s
@@ -33,6 +33,7 @@
MOVQ 24(SP), AX // copy argv
MOVQ AX, 8(SP)
CALL args(SB)
+ CALL mainĀ·init_999_function(SB) // initialization
// create a new goroutine to start program