@@ -26,6 +26,14 @@ type InitPlan struct {
26
26
E []InitEntry
27
27
}
28
28
29
+ type InitSchedule struct {
30
+ out []* Node
31
+ }
32
+
33
+ func (s * InitSchedule ) append (n * Node ) {
34
+ s .out = append (s .out , n )
35
+ }
36
+
29
37
var (
30
38
initlist []* Node
31
39
initplans map [* Node ]* InitPlan
@@ -34,20 +42,20 @@ var (
34
42
35
43
// init1 walks the AST starting at n, and accumulates in out
36
44
// the list of definitions needing init code in dependency order.
37
- func init1 ( n * Node , out * [] * Node ) {
45
+ func ( s * InitSchedule ) init1 ( n * Node ) {
38
46
if n == nil {
39
47
return
40
48
}
41
- init1 (n .Left , out )
42
- init1 (n .Right , out )
49
+ s . init1 (n .Left )
50
+ s . init1 (n .Right )
43
51
for _ , n1 := range n .List .Slice () {
44
- init1 (n1 , out )
52
+ s . init1 (n1 )
45
53
}
46
54
47
55
if n .isMethodExpression () {
48
56
// Methods called as Type.Method(receiver, ...).
49
57
// Definitions for method expressions are stored in type->nname.
50
- init1 (asNode (n .Type .FuncType ().Nname ), out )
58
+ s . init1 (asNode (n .Type .FuncType ().Nname ))
51
59
}
52
60
53
61
if n .Op != ONAME {
@@ -108,7 +116,7 @@ func init1(n *Node, out *[]*Node) {
108
116
Fatalf ("init1: bad defn" )
109
117
110
118
case ODCLFUNC :
111
- init2list (defn .Nbody , out )
119
+ s . init2list (defn .Nbody )
112
120
113
121
case OAS :
114
122
if defn .Left != n {
@@ -122,15 +130,15 @@ func init1(n *Node, out *[]*Node) {
122
130
break
123
131
}
124
132
125
- init2 (defn .Right , out )
133
+ s . init2 (defn .Right )
126
134
if Debug ['j' ] != 0 {
127
135
fmt .Printf ("%v\n " , n .Sym )
128
136
}
129
- if n .isBlank () || ! staticinit (n , out ) {
137
+ if n .isBlank () || ! s . staticinit (n ) {
130
138
if Debug ['%' ] != 0 {
131
139
Dump ("nonstatic" , defn )
132
140
}
133
- * out = append (* out , defn )
141
+ s . append (defn )
134
142
}
135
143
136
144
case OAS2FUNC , OAS2MAPR , OAS2DOTTYPE , OAS2RECV :
@@ -139,12 +147,12 @@ func init1(n *Node, out *[]*Node) {
139
147
}
140
148
defn .SetInitorder (InitPending )
141
149
for _ , n2 := range defn .Rlist .Slice () {
142
- init1 (n2 , out )
150
+ s . init1 (n2 )
143
151
}
144
152
if Debug ['%' ] != 0 {
145
153
Dump ("nonstatic" , defn )
146
154
}
147
- * out = append (* out , defn )
155
+ s . append (defn )
148
156
defn .SetInitorder (InitDone )
149
157
}
150
158
}
@@ -196,7 +204,7 @@ func foundinitloop(node, visited *Node) {
196
204
}
197
205
198
206
// recurse over n, doing init1 everywhere.
199
- func init2 ( n * Node , out * [] * Node ) {
207
+ func ( s * InitSchedule ) init2 ( n * Node ) {
200
208
if n == nil || n .Initorder () == InitDone {
201
209
return
202
210
}
@@ -205,70 +213,70 @@ func init2(n *Node, out *[]*Node) {
205
213
Fatalf ("name %v with ninit: %+v\n " , n .Sym , n )
206
214
}
207
215
208
- init1 (n , out )
209
- init2 (n .Left , out )
210
- init2 (n .Right , out )
211
- init2list (n .Ninit , out )
212
- init2list (n .List , out )
213
- init2list (n .Rlist , out )
214
- init2list (n .Nbody , out )
216
+ s . init1 (n )
217
+ s . init2 (n .Left )
218
+ s . init2 (n .Right )
219
+ s . init2list (n .Ninit )
220
+ s . init2list (n .List )
221
+ s . init2list (n .Rlist )
222
+ s . init2list (n .Nbody )
215
223
216
224
switch n .Op {
217
225
case OCLOSURE :
218
- init2list (n .Func .Closure .Nbody , out )
226
+ s . init2list (n .Func .Closure .Nbody )
219
227
case ODOTMETH , OCALLPART :
220
- init2 (asNode (n .Type .FuncType ().Nname ), out )
228
+ s . init2 (asNode (n .Type .FuncType ().Nname ))
221
229
}
222
230
}
223
231
224
- func init2list (l Nodes , out * [] * Node ) {
232
+ func ( s * InitSchedule ) init2list (l Nodes ) {
225
233
for _ , n := range l .Slice () {
226
- init2 (n , out )
234
+ s . init2 (n )
227
235
}
228
236
}
229
237
230
- func initreorder ( l [] * Node , out * []* Node ) {
238
+ func ( s * InitSchedule ) initreorder ( l []* Node ) {
231
239
for _ , n := range l {
232
240
switch n .Op {
233
241
case ODCLFUNC , ODCLCONST , ODCLTYPE :
234
242
continue
235
243
}
236
244
237
- initreorder (n .Ninit .Slice (), out )
245
+ s . initreorder (n .Ninit .Slice ())
238
246
n .Ninit .Set (nil )
239
- init1 (n , out )
247
+ s . init1 (n )
240
248
}
241
249
}
242
250
243
251
// initfix computes initialization order for a list l of top-level
244
252
// declarations and outputs the corresponding list of statements
245
253
// to include in the init() function body.
246
254
func initfix (l []* Node ) []* Node {
247
- var lout [] * Node
255
+ var s InitSchedule
248
256
initplans = make (map [* Node ]* InitPlan )
249
257
lno := lineno
250
- initreorder (l , & lout )
258
+ s . initreorder (l )
251
259
lineno = lno
252
260
initplans = nil
253
- return lout
261
+ return s . out
254
262
}
255
263
256
264
// compilation of top-level (static) assignments
257
265
// into DATA statements if at all possible.
258
- func staticinit ( n * Node , out * [] * Node ) bool {
266
+ func ( s * InitSchedule ) staticinit ( n * Node ) bool {
259
267
if n .Op != ONAME || n .Class () != PEXTERN || n .Name .Defn == nil || n .Name .Defn .Op != OAS {
260
268
Fatalf ("staticinit" )
261
269
}
262
270
263
271
lineno = n .Pos
264
272
l := n .Name .Defn .Left
265
273
r := n .Name .Defn .Right
266
- return staticassign (l , r , out )
274
+ return s . staticassign (l , r )
267
275
}
268
276
269
277
// like staticassign but we are copying an already
270
278
// initialized value r.
271
- func staticcopy (l * Node , r * Node , out * [] * Node ) bool {
279
+ func ( s * InitSchedule ) staticcopy (l * Node , r * Node ) bool {
272
280
if r .Op != ONAME {
273
281
return false
274
282
}
@@ -294,12 +302,12 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
294
302
295
303
switch r .Op {
296
304
case ONAME :
297
- if staticcopy (l , r , out ) {
305
+ if s . staticcopy (l , r ) {
298
306
return true
299
307
}
300
308
// We may have skipped past one or more OCONVNOPs, so
301
309
// use conv to ensure r is assignable to l (#13263).
302
- * out = append (* out , nod (OAS , l , conv (r , l .Type )))
310
+ s . append (nod (OAS , l , conv (r , l .Type )))
303
311
return true
304
312
305
313
case OLITERAL :
@@ -350,7 +358,7 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
350
358
continue
351
359
}
352
360
ll := n .sepcopy ()
353
- if staticcopy (ll , e .Expr , out ) {
361
+ if s . staticcopy (ll , e .Expr ) {
354
362
continue
355
363
}
356
364
// Requires computation, but we're
@@ -359,7 +367,7 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
359
367
rr .Type = ll .Type
360
368
rr .Xoffset += e .Xoffset
361
369
setlineno (rr )
362
- * out = append (* out , nod (OAS , ll , rr ))
370
+ s . append (nod (OAS , ll , rr ))
363
371
}
364
372
365
373
return true
@@ -368,14 +376,14 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
368
376
return false
369
377
}
370
378
371
- func staticassign (l * Node , r * Node , out * [] * Node ) bool {
379
+ func ( s * InitSchedule ) staticassign (l * Node , r * Node ) bool {
372
380
for r .Op == OCONVNOP {
373
381
r = r .Left
374
382
}
375
383
376
384
switch r .Op {
377
385
case ONAME :
378
- return staticcopy (l , r , out )
386
+ return s . staticcopy (l , r )
379
387
380
388
case OLITERAL :
381
389
if isZero (r ) {
@@ -404,8 +412,8 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
404
412
gdata (l , nod (OADDR , a , nil ), int (l .Type .Width ))
405
413
406
414
// Init underlying literal.
407
- if ! staticassign (a , r .Left , out ) {
408
- * out = append (* out , nod (OAS , a , r .Left ))
415
+ if ! s . staticassign (a , r .Left ) {
416
+ s . append (nod (OAS , a , r .Left ))
409
417
}
410
418
return true
411
419
}
@@ -452,8 +460,8 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
452
460
}
453
461
setlineno (e .Expr )
454
462
a := n .sepcopy ()
455
- if ! staticassign (a , e .Expr , out ) {
456
- * out = append (* out , nod (OAS , a , e .Expr ))
463
+ if ! s . staticassign (a , e .Expr ) {
464
+ s . append (nod (OAS , a , e .Expr ))
457
465
}
458
466
}
459
467
@@ -516,15 +524,15 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
516
524
n .Type = val .Type
517
525
setlineno (val )
518
526
a := n .sepcopy ()
519
- if ! staticassign (a , val , out ) {
520
- * out = append (* out , nod (OAS , a , val ))
527
+ if ! s . staticassign (a , val ) {
528
+ s . append (nod (OAS , a , val ))
521
529
}
522
530
} else {
523
531
// Construct temp to hold val, write pointer to temp into n.
524
532
a := staticname (val .Type )
525
533
inittemps [val ] = a
526
- if ! staticassign (a , val , out ) {
527
- * out = append (* out , nod (OAS , a , val ))
534
+ if ! s . staticassign (a , val ) {
535
+ s . append (nod (OAS , a , val ))
528
536
}
529
537
ptr := nod (OADDR , a , nil )
530
538
n .Type = types .NewPtr (val .Type )
0 commit comments