Commit d3489711 authored by Ken Thompson's avatar Ken Thompson

add readonly flag to static initialization

R=rsc
CC=golang-dev
https://golang.org/cl/2187042
parent 19075ea6
...@@ -1023,7 +1023,7 @@ void walkselect(Node *sel); ...@@ -1023,7 +1023,7 @@ void walkselect(Node *sel);
/* /*
* sinit.c * sinit.c
*/ */
void anylit(int ctxt, Node *n, Node *var, NodeList **init); void anylit(Node *n, Node *var, NodeList **init);
int gen_as_init(Node *n); int gen_as_init(Node *n);
NodeList* initfix(NodeList *l); NodeList* initfix(NodeList *l);
int oaslit(Node *n, NodeList **init); int oaslit(Node *n, NodeList **init);
......
...@@ -179,10 +179,23 @@ initfix(NodeList *l) ...@@ -179,10 +179,23 @@ initfix(NodeList *l)
* part of the composit literal. * part of the composit literal.
*/ */
static void structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init); static void structlit(int pass, Node *n, Node *var, NodeList **init);
static void arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init); static void arraylit(int pass, Node *n, Node *var, NodeList **init);
static void slicelit(int ctxt, Node *n, Node *var, NodeList **init); static void slicelit(Node *n, Node *var, NodeList **init);
static void maplit(int ctxt, Node *n, Node *var, NodeList **init); static void maplit(Node *n, Node *var, NodeList **init);
Node*
staticname(Type *t)
{
Node *n;
snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen);
statuniqgen++;
n = newname(lookup(namebuf));
n->readonly = 1;
addvar(n, t, PEXTERN);
return n;
}
static int static int
isliteral(Node *n) isliteral(Node *n)
...@@ -257,7 +270,7 @@ getdyn(Node *n, int top) ...@@ -257,7 +270,7 @@ getdyn(Node *n, int top)
} }
static void static void
structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init) structlit(int pass, Node *n, Node *var, NodeList **init)
{ {
Node *r, *a; Node *r, *a;
NodeList *nl; NodeList *nl;
...@@ -273,25 +286,21 @@ structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init) ...@@ -273,25 +286,21 @@ structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
switch(value->op) { switch(value->op) {
case OARRAYLIT: case OARRAYLIT:
if(value->type->bound < 0) { if(value->type->bound < 0) {
if(pass == 1 && ctxt != 0) { if(pass == 2) {
a = nod(ODOT, var, newname(index->sym)); a = nod(ODOT, var, newname(index->sym));
slicelit(ctxt, value, a, init); slicelit(value, a, init);
} else
if(pass == 2 && ctxt == 0) {
a = nod(ODOT, var, newname(index->sym));
slicelit(ctxt, value, a, init);
} else } else
if(pass == 3) if(pass == 3)
break; break;
continue; continue;
} }
a = nod(ODOT, var, newname(index->sym)); a = nod(ODOT, var, newname(index->sym));
arraylit(ctxt, pass, value, a, init); arraylit(pass, value, a, init);
continue; continue;
case OSTRUCTLIT: case OSTRUCTLIT:
a = nod(ODOT, var, newname(index->sym)); a = nod(ODOT, var, newname(index->sym));
structlit(ctxt, pass, value, a, init); structlit(pass, value, a, init);
continue; continue;
} }
...@@ -317,7 +326,7 @@ structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init) ...@@ -317,7 +326,7 @@ structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
} }
static void static void
arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init) arraylit(int pass, Node *n, Node *var, NodeList **init)
{ {
Node *r, *a; Node *r, *a;
NodeList *l; NodeList *l;
...@@ -333,25 +342,21 @@ arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init) ...@@ -333,25 +342,21 @@ arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
switch(value->op) { switch(value->op) {
case OARRAYLIT: case OARRAYLIT:
if(value->type->bound < 0) { if(value->type->bound < 0) {
if(pass == 1 && ctxt != 0) { if(pass == 2) {
a = nod(OINDEX, var, index);
slicelit(ctxt, value, a, init);
} else
if(pass == 2 && ctxt == 0) {
a = nod(OINDEX, var, index); a = nod(OINDEX, var, index);
slicelit(ctxt, value, a, init); slicelit(value, a, init);
} else } else
if(pass == 3) if(pass == 3)
break; break;
continue; continue;
} }
a = nod(OINDEX, var, index); a = nod(OINDEX, var, index);
arraylit(ctxt, pass, value, a, init); arraylit(pass, value, a, init);
continue; continue;
case OSTRUCTLIT: case OSTRUCTLIT:
a = nod(OINDEX, var, index); a = nod(OINDEX, var, index);
structlit(ctxt, pass, value, a, init); structlit(pass, value, a, init);
continue; continue;
} }
...@@ -377,7 +382,7 @@ arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init) ...@@ -377,7 +382,7 @@ arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
} }
static void static void
slicelit(int ctxt, Node *n, Node *var, NodeList **init) slicelit(Node *n, Node *var, NodeList **init)
{ {
Node *r, *a; Node *r, *a;
NodeList *l; NodeList *l;
...@@ -393,22 +398,6 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -393,22 +398,6 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
t->sym = nil; t->sym = nil;
dowidth(t); dowidth(t);
if(ctxt != 0) {
// put everything into static array
vstat = staticname(t);
arraylit(ctxt, 1, n, vstat, init);
arraylit(ctxt, 2, n, vstat, init);
// copy static to slice
a = nod(OSLICE, vstat, nod(OKEY, N, N));
a = nod(OAS, var, a);
typecheck(&a, Etop);
a->dodata = 2;
*init = list(*init, a);
return;
}
// recipe for var = []t{...} // recipe for var = []t{...}
// 1. make a static array // 1. make a static array
// var vstat [...]t // var vstat [...]t
...@@ -434,7 +423,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -434,7 +423,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
mode = getdyn(n, 1); mode = getdyn(n, 1);
if(mode & MODECONST) { if(mode & MODECONST) {
vstat = staticname(t); vstat = staticname(t);
arraylit(ctxt, 1, n, vstat, init); arraylit(1, n, vstat, init);
} }
// make new auto *array (3 declare) // make new auto *array (3 declare)
...@@ -479,11 +468,11 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -479,11 +468,11 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
case OARRAYLIT: case OARRAYLIT:
if(value->type->bound < 0) if(value->type->bound < 0)
break; break;
arraylit(ctxt, 2, value, a, init); arraylit(2, value, a, init);
continue; continue;
case OSTRUCTLIT: case OSTRUCTLIT:
structlit(ctxt, 2, value, a, init); structlit(2, value, a, init);
continue; continue;
} }
...@@ -499,7 +488,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -499,7 +488,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
} }
static void static void
maplit(int ctxt, Node *n, Node *var, NodeList **init) maplit(Node *n, Node *var, NodeList **init)
{ {
Node *r, *a; Node *r, *a;
NodeList *l; NodeList *l;
...@@ -651,7 +640,7 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -651,7 +640,7 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init)
} }
void void
anylit(int ctxt, Node *n, Node *var, NodeList **init) anylit(Node *n, Node *var, NodeList **init)
{ {
Type *t; Type *t;
Node *a, *vstat; Node *a, *vstat;
...@@ -666,24 +655,18 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -666,24 +655,18 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
fatal("anylit: not struct"); fatal("anylit: not struct");
if(simplename(var)) { if(simplename(var)) {
// lay out static data
vstat = staticname(t);
structlit(1, n, vstat, init);
if(ctxt == 0) { // copy static to var
// lay out static data a = nod(OAS, var, vstat);
vstat = staticname(t); typecheck(&a, Etop);
structlit(1, 1, n, vstat, init); walkexpr(&a, init);
*init = list(*init, a);
// copy static to var
a = nod(OAS, var, vstat);
typecheck(&a, Etop);
walkexpr(&a, init);
*init = list(*init, a);
// add expressions to automatic // add expressions to automatic
structlit(ctxt, 2, n, var, init); structlit(2, n, var, init);
break;
}
structlit(ctxt, 1, n, var, init);
structlit(ctxt, 2, n, var, init);
break; break;
} }
...@@ -694,36 +677,30 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -694,36 +677,30 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
walkexpr(&a, init); walkexpr(&a, init);
*init = list(*init, a); *init = list(*init, a);
} }
structlit(ctxt, 3, n, var, init); structlit(3, n, var, init);
break; break;
case OARRAYLIT: case OARRAYLIT:
if(t->etype != TARRAY) if(t->etype != TARRAY)
fatal("anylit: not array"); fatal("anylit: not array");
if(t->bound < 0) { if(t->bound < 0) {
slicelit(ctxt, n, var, init); slicelit(n, var, init);
break; break;
} }
if(simplename(var)) { if(simplename(var)) {
// lay out static data
vstat = staticname(t);
arraylit(1, n, vstat, init);
if(ctxt == 0) { // copy static to automatic
// lay out static data a = nod(OAS, var, vstat);
vstat = staticname(t); typecheck(&a, Etop);
arraylit(1, 1, n, vstat, init); walkexpr(&a, init);
*init = list(*init, a);
// copy static to automatic
a = nod(OAS, var, vstat);
typecheck(&a, Etop);
walkexpr(&a, init);
*init = list(*init, a);
// add expressions to automatic // add expressions to automatic
arraylit(ctxt, 2, n, var, init); arraylit(2, n, var, init);
break;
}
arraylit(ctxt, 1, n, var, init);
arraylit(ctxt, 2, n, var, init);
break; break;
} }
...@@ -734,13 +711,13 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -734,13 +711,13 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
walkexpr(&a, init); walkexpr(&a, init);
*init = list(*init, a); *init = list(*init, a);
} }
arraylit(ctxt, 3, n, var, init); arraylit(3, n, var, init);
break; break;
case OMAPLIT: case OMAPLIT:
if(t->etype != TMAP) if(t->etype != TMAP)
fatal("anylit: not map"); fatal("anylit: not map");
maplit(ctxt, n, var, init); maplit(n, var, init);
break; break;
} }
} }
...@@ -748,8 +725,6 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) ...@@ -748,8 +725,6 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
int int
oaslit(Node *n, NodeList **init) oaslit(Node *n, NodeList **init)
{ {
int ctxt;
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
goto no; goto no;
if(n->left->type == T || n->right->type == T) if(n->left->type == T || n->right->type == T)
...@@ -762,9 +737,6 @@ oaslit(Node *n, NodeList **init) ...@@ -762,9 +737,6 @@ oaslit(Node *n, NodeList **init)
// context is init() function. // context is init() function.
// implies generated data executed // implies generated data executed
// exactly once and not subject to races. // exactly once and not subject to races.
ctxt = 0;
if(n->dodata == 1)
ctxt = 1;
switch(n->right->op) { switch(n->right->op) {
default: default:
...@@ -775,7 +747,7 @@ oaslit(Node *n, NodeList **init) ...@@ -775,7 +747,7 @@ oaslit(Node *n, NodeList **init)
case OMAPLIT: case OMAPLIT:
if(vmatch1(n->left, n->right)) if(vmatch1(n->left, n->right))
goto no; goto no;
anylit(ctxt, n->right, n->left, init); anylit(n->right, n->left, init);
break; break;
} }
n->op = OEMPTY; n->op = OEMPTY;
......
...@@ -2593,19 +2593,6 @@ brrev(int a) ...@@ -2593,19 +2593,6 @@ brrev(int a)
return a; return a;
} }
Node*
staticname(Type *t)
{
Node *n;
snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen);
statuniqgen++;
n = newname(lookup(namebuf));
// n->readonly = 1;
addvar(n, t, PEXTERN);
return n;
}
/* /*
* return side effect-free appending side effects to init. * return side effect-free appending side effects to init.
* result is assignable if n is. * result is assignable if n is.
......
...@@ -1159,7 +1159,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -1159,7 +1159,7 @@ walkexpr(Node **np, NodeList **init)
case OMAPLIT: case OMAPLIT:
case OSTRUCTLIT: case OSTRUCTLIT:
nvar = makenewvar(n->type, init, &nstar); nvar = makenewvar(n->type, init, &nstar);
anylit(0, n->left, nstar, init); anylit(n->left, nstar, init);
n = nvar; n = nvar;
goto ret; goto ret;
} }
...@@ -1341,7 +1341,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -1341,7 +1341,7 @@ walkexpr(Node **np, NodeList **init)
case OSTRUCTLIT: case OSTRUCTLIT:
nvar = nod(OXXX, N, N); nvar = nod(OXXX, N, N);
tempname(nvar, n->type); tempname(nvar, n->type);
anylit(0, n, nvar, init); anylit(n, nvar, init);
n = nvar; n = nvar;
goto ret; goto ret;
......
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