diff options
Diffstat (limited to 'src/cmd/gc/sinit.c')
-rw-r--r-- | src/cmd/gc/sinit.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 5ac14a537..19ee3327b 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -92,15 +92,9 @@ init1(Node *n, NodeList **out) break; case OAS2FUNC: - if(n->defn->initorder) - break; - n->defn->initorder = 1; - for(l=n->defn->rlist; l; l=l->next) - init1(l->n, out); - *out = list(*out, n->defn); - break; - case OAS2MAPR: + case OAS2DOTTYPE: + case OAS2RECV: if(n->defn->initorder) break; n->defn->initorder = 1; @@ -190,6 +184,20 @@ static void arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init); static void slicelit(int ctxt, Node *n, Node *var, NodeList **init); static void maplit(int ctxt, Node *n, Node *var, NodeList **init); +static Node* +staticname(Type *t, int ctxt) +{ + Node *n; + + snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen); + statuniqgen++; + n = newname(lookup(namebuf)); + if(!ctxt) + n->readonly = 1; + addvar(n, t, PEXTERN); + return n; +} + static int isliteral(Node *n) { @@ -402,12 +410,12 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) if(ctxt != 0) { // put everything into static array - vstat = staticname(t); + vstat = staticname(t, ctxt); arraylit(ctxt, 1, n, vstat, init); arraylit(ctxt, 2, n, vstat, init); // copy static to slice - a = nod(OADDR, vstat, N); + a = nod(OSLICE, vstat, nod(OKEY, N, N)); a = nod(OAS, var, a); typecheck(&a, Etop); a->dodata = 2; @@ -439,7 +447,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) vstat = N; mode = getdyn(n, 1); if(mode & MODECONST) { - vstat = staticname(t); + vstat = staticname(t, ctxt); arraylit(ctxt, 1, n, vstat, init); } @@ -465,7 +473,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) } // make slice out of heap (5) - a = nod(OAS, var, vauto); + a = nod(OAS, var, nod(OSLICE, vauto, nod(OKEY, N, N))); typecheck(&a, Etop); walkexpr(&a, init); *init = list(*init, a); @@ -514,6 +522,8 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init) Node *vstat, *index, *value; Sym *syma, *symb; +ctxt = 0; + // make the map var nerr = nerrors; @@ -566,7 +576,7 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init) dowidth(t); // make and initialize static array - vstat = staticname(t); + vstat = staticname(t, ctxt); b = 0; for(l=n->list; l; l=l->next) { r = l->n; @@ -675,7 +685,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) if(ctxt == 0) { // lay out static data - vstat = staticname(t); + vstat = staticname(t, ctxt); structlit(1, 1, n, vstat, init); // copy static to var @@ -715,7 +725,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) if(ctxt == 0) { // lay out static data - vstat = staticname(t); + vstat = staticname(t, ctxt); arraylit(1, 1, n, vstat, init); // copy static to automatic @@ -769,8 +779,8 @@ oaslit(Node *n, NodeList **init) // implies generated data executed // exactly once and not subject to races. ctxt = 0; - if(n->dodata == 1) - ctxt = 1; +// if(n->dodata == 1) +// ctxt = 1; switch(n->right->op) { default: @@ -870,8 +880,18 @@ gen_as_init(Node *n) default: goto no; - case OCONVSLICE: - goto slice; + case OCONVNOP: + nr = nr->left; + if(nr == N || nr->op != OSLICEARR) + goto no; + // fall through + + case OSLICEARR: + if(nr->right->op == OKEY && nr->right->left == N && nr->right->right == N) { + nr = nr->left; + goto slice; + } + goto no; case OLITERAL: break; @@ -920,7 +940,7 @@ yes: slice: gused(N); // in case the data is the dest of a goto - nr = n->right->left; + nl = nr; if(nr == N || nr->op != OADDR) goto no; nr = nr->left; @@ -932,7 +952,7 @@ slice: goto no; nam.xoffset += Array_array; - gdata(&nam, n->right->left, types[tptr]->width); + gdata(&nam, nl, types[tptr]->width); nam.xoffset += Array_nel-Array_array; nodconst(&nod1, types[TINT32], nr->type->bound); |