E []InitEntry
 }
 
+type InitSchedule struct {
+       out []*Node
+}
+
+func (s *InitSchedule) append(n *Node) {
+       s.out = append(s.out, n)
+}
+
 var (
        initlist  []*Node
        initplans map[*Node]*InitPlan
 
 // init1 walks the AST starting at n, and accumulates in out
 // the list of definitions needing init code in dependency order.
-func init1(n *Node, out *[]*Node) {
+func (s *InitSchedule) init1(n *Node) {
        if n == nil {
                return
        }
-       init1(n.Left, out)
-       init1(n.Right, out)
+       s.init1(n.Left)
+       s.init1(n.Right)
        for _, n1 := range n.List.Slice() {
-               init1(n1, out)
+               s.init1(n1)
        }
 
        if n.isMethodExpression() {
                // Methods called as Type.Method(receiver, ...).
                // Definitions for method expressions are stored in type->nname.
-               init1(asNode(n.Type.FuncType().Nname), out)
+               s.init1(asNode(n.Type.FuncType().Nname))
        }
 
        if n.Op != ONAME {
                        Fatalf("init1: bad defn")
 
                case ODCLFUNC:
-                       init2list(defn.Nbody, out)
+                       s.init2list(defn.Nbody)
 
                case OAS:
                        if defn.Left != n {
                                break
                        }
 
-                       init2(defn.Right, out)
+                       s.init2(defn.Right)
                        if Debug['j'] != 0 {
                                fmt.Printf("%v\n", n.Sym)
                        }
-                       if n.isBlank() || !staticinit(n, out) {
+                       if n.isBlank() || !s.staticinit(n) {
                                if Debug['%'] != 0 {
                                        Dump("nonstatic", defn)
                                }
-                               *out = append(*out, defn)
+                               s.append(defn)
                        }
 
                case OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV:
                        }
                        defn.SetInitorder(InitPending)
                        for _, n2 := range defn.Rlist.Slice() {
-                               init1(n2, out)
+                               s.init1(n2)
                        }
                        if Debug['%'] != 0 {
                                Dump("nonstatic", defn)
                        }
-                       *out = append(*out, defn)
+                       s.append(defn)
                        defn.SetInitorder(InitDone)
                }
        }
 }
 
 // recurse over n, doing init1 everywhere.
-func init2(n *Node, out *[]*Node) {
+func (s *InitSchedule) init2(n *Node) {
        if n == nil || n.Initorder() == InitDone {
                return
        }
                Fatalf("name %v with ninit: %+v\n", n.Sym, n)
        }
 
-       init1(n, out)
-       init2(n.Left, out)
-       init2(n.Right, out)
-       init2list(n.Ninit, out)
-       init2list(n.List, out)
-       init2list(n.Rlist, out)
-       init2list(n.Nbody, out)
+       s.init1(n)
+       s.init2(n.Left)
+       s.init2(n.Right)
+       s.init2list(n.Ninit)
+       s.init2list(n.List)
+       s.init2list(n.Rlist)
+       s.init2list(n.Nbody)
 
        switch n.Op {
        case OCLOSURE:
-               init2list(n.Func.Closure.Nbody, out)
+               s.init2list(n.Func.Closure.Nbody)
        case ODOTMETH, OCALLPART:
-               init2(asNode(n.Type.FuncType().Nname), out)
+               s.init2(asNode(n.Type.FuncType().Nname))
        }
 }
 
-func init2list(l Nodes, out *[]*Node) {
+func (s *InitSchedule) init2list(l Nodes) {
        for _, n := range l.Slice() {
-               init2(n, out)
+               s.init2(n)
        }
 }
 
-func initreorder(l []*Node, out *[]*Node) {
+func (s *InitSchedule) initreorder(l []*Node) {
        for _, n := range l {
                switch n.Op {
                case ODCLFUNC, ODCLCONST, ODCLTYPE:
                        continue
                }
 
-               initreorder(n.Ninit.Slice(), out)
+               s.initreorder(n.Ninit.Slice())
                n.Ninit.Set(nil)
-               init1(n, out)
+               s.init1(n)
        }
 }
 
 // declarations and outputs the corresponding list of statements
 // to include in the init() function body.
 func initfix(l []*Node) []*Node {
-       var lout []*Node
+       var s InitSchedule
        initplans = make(map[*Node]*InitPlan)
        lno := lineno
-       initreorder(l, &lout)
+       s.initreorder(l)
        lineno = lno
        initplans = nil
-       return lout
+       return s.out
 }
 
 // compilation of top-level (static) assignments
 // into DATA statements if at all possible.
-func staticinit(n *Node, out *[]*Node) bool {
+func (s *InitSchedule) staticinit(n *Node) bool {
        if n.Op != ONAME || n.Class() != PEXTERN || n.Name.Defn == nil || n.Name.Defn.Op != OAS {
                Fatalf("staticinit")
        }
        lineno = n.Pos
        l := n.Name.Defn.Left
        r := n.Name.Defn.Right
-       return staticassign(l, r, out)
+       return s.staticassign(l, r)
 }
 
 // like staticassign but we are copying an already
 // initialized value r.
-func staticcopy(l *Node, r *Node, out *[]*Node) bool {
+func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
        if r.Op != ONAME {
                return false
        }
 
        switch r.Op {
        case ONAME:
-               if staticcopy(l, r, out) {
+               if s.staticcopy(l, r) {
                        return true
                }
                // We may have skipped past one or more OCONVNOPs, so
                // use conv to ensure r is assignable to l (#13263).
-               *out = append(*out, nod(OAS, l, conv(r, l.Type)))
+               s.append(nod(OAS, l, conv(r, l.Type)))
                return true
 
        case OLITERAL:
                                continue
                        }
                        ll := n.sepcopy()
-                       if staticcopy(ll, e.Expr, out) {
+                       if s.staticcopy(ll, e.Expr) {
                                continue
                        }
                        // Requires computation, but we're
                        rr.Type = ll.Type
                        rr.Xoffset += e.Xoffset
                        setlineno(rr)
-                       *out = append(*out, nod(OAS, ll, rr))
+                       s.append(nod(OAS, ll, rr))
                }
 
                return true
        return false
 }
 
-func staticassign(l *Node, r *Node, out *[]*Node) bool {
+func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
        for r.Op == OCONVNOP {
                r = r.Left
        }
 
        switch r.Op {
        case ONAME:
-               return staticcopy(l, r, out)
+               return s.staticcopy(l, r)
 
        case OLITERAL:
                if isZero(r) {
                        gdata(l, nod(OADDR, a, nil), int(l.Type.Width))
 
                        // Init underlying literal.
-                       if !staticassign(a, r.Left, out) {
-                               *out = append(*out, nod(OAS, a, r.Left))
+                       if !s.staticassign(a, r.Left) {
+                               s.append(nod(OAS, a, r.Left))
                        }
                        return true
                }
                        }
                        setlineno(e.Expr)
                        a := n.sepcopy()
-                       if !staticassign(a, e.Expr, out) {
-                               *out = append(*out, nod(OAS, a, e.Expr))
+                       if !s.staticassign(a, e.Expr) {
+                               s.append(nod(OAS, a, e.Expr))
                        }
                }
 
                        n.Type = val.Type
                        setlineno(val)
                        a := n.sepcopy()
-                       if !staticassign(a, val, out) {
-                               *out = append(*out, nod(OAS, a, val))
+                       if !s.staticassign(a, val) {
+                               s.append(nod(OAS, a, val))
                        }
                } else {
                        // Construct temp to hold val, write pointer to temp into n.
                        a := staticname(val.Type)
                        inittemps[val] = a
-                       if !staticassign(a, val, out) {
-                               *out = append(*out, nod(OAS, a, val))
+                       if !s.staticassign(a, val) {
+                               s.append(nod(OAS, a, val))
                        }
                        ptr := nod(OADDR, a, nil)
                        n.Type = types.NewPtr(val.Type)