]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove remaining nodeSeqIterate calls
authorIan Lance Taylor <iant@golang.org>
Wed, 9 Mar 2016 20:39:36 +0000 (12:39 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 9 Mar 2016 22:52:11 +0000 (22:52 +0000)
Mix in several other minor cleanups, including adding some new methods
to Nodes: Index, Addr, SetIndex, SetNodes.

Passes toolstash -cmp.

Update #14473.

Change-Id: I8bd4ae3fde7c5e20ba66e7dd1654fbc70c3ddeb8
Reviewed-on: https://go-review.googlesource.com/20491
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
15 files changed:
src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/cgen.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/order.go
src/cmd/compile/internal/gc/racewalk.go
src/cmd/compile/internal/gc/range.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/swt.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go

index 97ce543f8b291aa9b55be48bb8f4d868b2b45e93..c349c39a4482998990814183dd1f9a2c3d605f03 100644 (file)
@@ -806,24 +806,23 @@ func (p *exporter) inlinedBody(n *Node) {
 }
 
 func (p *exporter) nodeList(list Nodes) {
-       it := nodeSeqIterate(list)
        if p.trace {
                p.tracef("[ ")
        }
-       p.int(it.Len())
+       p.int(list.Len())
        if p.trace {
-               if it.Len() <= 1 {
+               if list.Len() == 0 {
                        p.tracef("] {}")
                } else {
                        p.tracef("] {>")
                        defer p.tracef("<\n}")
                }
        }
-       for ; !it.Done(); it.Next() {
+       for _, n := range list.Slice() {
                if p.trace {
                        p.tracef("\n")
                }
-               p.node(it.N())
+               p.node(n)
        }
 }
 
index 439c52d72ee280bc3887149163fda9078a083bf8..4915796b9d5d3677e1284abad98cfd19ce053a35 100644 (file)
@@ -1762,7 +1762,7 @@ func bvgenjump(n, res *Node, wantTrue, geninit bool) {
        Bgen(n, wantTrue, 0, p2)
        Thearch.Gmove(Nodbool(false), res)
        Patch(p3, Pc)
-       n.Ninit.Set(init.Slice())
+       n.Ninit.MoveNodes(&init)
 }
 
 // bgenx is the backend for Bgen and Bvgen.
@@ -2943,9 +2943,7 @@ func cgen_append(n, res *Node) {
        // is not going to use a write barrier.
        i := 0
        var r2 Node
-       it := nodeSeqIterate(n.List)
-       it.Next()
-       for ; !it.Done(); it.Next() {
+       for _, n2 := range n.List.Slice()[1:] {
                Regalloc(&r1, Types[Tptr], nil)
                Thearch.Gmove(base, &r1)
                Regalloc(&r2, Types[TUINT], nil)
@@ -2966,7 +2964,7 @@ func cgen_append(n, res *Node) {
 
                r1.Op = OINDREG
                r1.Type = res.Type.Type
-               cgen_wb(it.N(), &r1, needwritebarrier(&r1, it.N()))
+               cgen_wb(n2, &r1, needwritebarrier(&r1, n2))
                Regfree(&r1)
                i++
        }
index 6cda036cbbdeb5efd13a62e02e2e1475e28280d1..6d1559613a6fe01efeef66f3117d4dbd48644705 100644 (file)
@@ -475,7 +475,7 @@ func colasdefn(left Nodes, defn *Node) {
                declare(n, dclcontext)
                n.Name.Defn = defn
                defn.Ninit.Append(Nod(ODCL, n, nil))
-               left.Slice()[i2] = n
+               left.SetIndex(i2, n)
        }
 
        if nnew == 0 && nerr == 0 {
@@ -833,9 +833,9 @@ func tostruct0(t *Type, l []*Node) {
                Fatalf("struct expected")
        }
 
-       for tp, it := &t.Type, nodeSeqIterate(l); !it.Done(); it.Next() {
-               f := structfield(it.N())
-
+       tp := &t.Type
+       for _, n := range l {
+               f := structfield(n)
                *tp = f
                tp = &f.Down
        }
@@ -860,13 +860,14 @@ func tofunargs(l []*Node) *Type {
        t := typ(TSTRUCT)
        t.Funarg = true
 
-       for tp, it := &t.Type, nodeSeqIterate(l); !it.Done(); it.Next() {
-               f = structfield(it.N())
+       tp := &t.Type
+       for _, n := range l {
+               f = structfield(n)
                f.Funarg = true
 
                // esc.go needs to find f given a PPARAM to add the tag.
-               if it.N().Left != nil && it.N().Left.Class == PPARAM {
-                       it.N().Left.Name.Param.Field = f
+               if n.Left != nil && n.Left.Class == PPARAM {
+                       n.Left.Name.Param.Field = f
                }
 
                *tp = f
index a814ce13a652f7636279e949a34abffa38a57e7f..f9108fcdfeee323f5b86569c18a1de19c07e7032 100644 (file)
@@ -722,10 +722,9 @@ func esc(e *EscState, n *Node, up *Node) {
 
        case OAS2: // x,y = a,b
                if n.List.Len() == n.Rlist.Len() {
-                       lrit := nodeSeqIterate(n.Rlist)
-                       for _, n3 := range n.List.Slice() {
-                               escassign(e, n3, lrit.N())
-                               lrit.Next()
+                       rs := n.Rlist.Slice()
+                       for i, n := range n.List.Slice() {
+                               escassign(e, n, rs[i])
                        }
                }
 
@@ -759,14 +758,14 @@ func esc(e *EscState, n *Node, up *Node) {
 
                // esccall already done on n->rlist->n. tie it's escretval to n->list
        case OAS2FUNC: // x,y = f()
-               lrit := nodeSeqIterate(e.nodeEscState(n.Rlist.First()).Escretval)
-
-               var llit nodeSeqIterator
-               for llit = nodeSeqIterate(n.List); !lrit.Done() && !llit.Done(); llit.Next() {
-                       escassign(e, llit.N(), lrit.N())
-                       lrit.Next()
+               rs := e.nodeEscState(n.Rlist.First()).Escretval.Slice()
+               for i, n := range n.List.Slice() {
+                       if i >= len(rs) {
+                               break
+                       }
+                       escassign(e, n, rs[i])
                }
-               if !llit.Done() || !lrit.Done() {
+               if n.List.Len() != len(rs) {
                        Fatalf("esc oas2func")
                }
 
@@ -779,19 +778,19 @@ func esc(e *EscState, n *Node, up *Node) {
                        ll = e.nodeEscState(n.List.First()).Escretval
                }
 
-               llit := nodeSeqIterate(ll)
+               i := 0
                for _, lrn := range Curfn.Func.Dcl {
-                       if llit.Done() {
+                       if i >= ll.Len() {
                                break
                        }
                        if lrn.Op != ONAME || lrn.Class != PPARAMOUT {
                                continue
                        }
-                       escassign(e, lrn, llit.N())
-                       llit.Next()
+                       escassign(e, lrn, ll.Index(i))
+                       i++
                }
 
-               if !llit.Done() {
+               if i < ll.Len() {
                        Fatalf("esc return list")
                }
 
@@ -801,10 +800,8 @@ func esc(e *EscState, n *Node, up *Node) {
 
        case OAPPEND:
                if !n.Isddd {
-                       llit := nodeSeqIterate(n.List)
-                       llit.Next()
-                       for ; !llit.Done(); llit.Next() {
-                               escassign(e, &e.theSink, llit.N()) // lose track of assign to dereference
+                       for _, n := range n.List.Slice()[1:] {
+                               escassign(e, &e.theSink, n) // lose track of assign to dereference
                        }
                } else {
                        // append(slice1, slice2...) -- slice2 itself does not escape, but contents do.
@@ -1229,8 +1226,8 @@ func escassignfromtag(e *EscState, note *string, dsts Nodes, src *Node) uint16 {
        }
 
        em0 := em
-       it := nodeSeqIterate(dsts)
-       for em >>= EscReturnBits; em != 0 && !it.Done(); em = em >> bitsPerOutputInTag {
+       dstsi := 0
+       for em >>= EscReturnBits; em != 0 && dstsi < dsts.Len(); em = em >> bitsPerOutputInTag {
                // Prefer the lowest-level path to the reference (for escape purposes).
                // Two-bit encoding (for example. 1, 3, and 4 bits are other options)
                //  01 = 0-level
@@ -1242,15 +1239,15 @@ func escassignfromtag(e *EscState, note *string, dsts Nodes, src *Node) uint16 {
                        for i := uint16(0); i < embits-1; i++ {
                                n = e.addDereference(n) // encode level>0 as indirections
                        }
-                       escassign(e, it.N(), n)
+                       escassign(e, dsts.Index(dstsi), n)
                }
-               it.Next()
+               dstsi++
        }
        // If there are too many outputs to fit in the tag,
        // that is handled at the encoding end as EscHeap,
        // so there is no need to check here.
 
-       if em != 0 && it.Done() {
+       if em != 0 && dstsi >= dsts.Len() {
                Fatalf("corrupt esc tag %q or messed up escretval list\n", note)
        }
        return em0
@@ -1419,36 +1416,37 @@ func esccall(e *EscState, n *Node, up *Node) {
                }
 
                var src *Node
-               llit := nodeSeqIterate(ll)
-               for lrit := nodeSeqIterate(fn.Name.Param.Ntype.List); !llit.Done() && !lrit.Done(); llit.Next() {
-                       src = llit.N()
-                       if lrit.N().Isddd && !n.Isddd {
+               lls := ll.Slice()
+               lrs := fn.Name.Param.Ntype.List.Slice()
+               i := 0
+               for ; i < len(lls) && i < len(lrs); i++ {
+                       src = lls[i]
+                       if lrs[i].Isddd && !n.Isddd {
                                // Introduce ODDDARG node to represent ... allocation.
                                src = Nod(ODDDARG, nil, nil)
                                src.Type = typ(TARRAY)
-                               src.Type.Type = lrit.N().Type.Type
-                               src.Type.Bound = int64(llit.Len())
+                               src.Type.Type = lrs[i].Type.Type
+                               src.Type.Bound = int64(len(lls) - i)
                                src.Type = Ptrto(src.Type) // make pointer so it will be tracked
                                src.Lineno = n.Lineno
                                e.track(src)
                                n.Right = src
                        }
 
-                       if lrit.N().Left != nil {
-                               escassign(e, lrit.N().Left, src)
+                       if lrs[i].Left != nil {
+                               escassign(e, lrs[i].Left, src)
                        }
-                       if src != llit.N() {
+                       if src != lls[i] {
                                break
                        }
-                       lrit.Next()
                }
 
                // "..." arguments are untracked
-               for ; !llit.Done(); llit.Next() {
+               for ; i < len(lls); i++ {
                        if Debug['m'] > 2 {
-                               fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(llit.N(), obj.FmtShort))
+                               fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(lls[i], obj.FmtShort))
                        }
-                       escassign(e, &e.theSink, llit.N())
+                       escassign(e, &e.theSink, lls[i])
                }
 
                return
@@ -1478,16 +1476,17 @@ func esccall(e *EscState, n *Node, up *Node) {
        }
 
        var src *Node
-       it := nodeSeqIterate(ll)
-       for t := fntype.Params().Type; !it.Done(); it.Next() {
-               src = it.N()
+       i := 0
+       lls := ll.Slice()
+       for t := fntype.Params().Type; i < len(lls); i++ {
+               src = lls[i]
                if t.Isddd && !n.Isddd {
                        // Introduce ODDDARG node to represent ... allocation.
                        src = Nod(ODDDARG, nil, nil)
                        src.Lineno = n.Lineno
                        src.Type = typ(TARRAY)
                        src.Type.Type = t.Type.Type
-                       src.Type.Bound = int64(it.Len())
+                       src.Type.Bound = int64(len(lls) - i)
                        src.Type = Ptrto(src.Type) // make pointer so it will be tracked
                        e.track(src)
                        n.Right = src
@@ -1520,18 +1519,18 @@ func esccall(e *EscState, n *Node, up *Node) {
                        }
                }
 
-               if src != it.N() {
+               if src != lls[i] {
                        // This occurs when function parameter type Isddd and n not Isddd
                        break
                }
                t = t.Down
        }
 
-       for ; !it.Done(); it.Next() {
+       for ; i < len(lls); i++ {
                if Debug['m'] > 2 {
-                       fmt.Printf("%v::esccall:: ... <- %v\n", linestr(lineno), Nconv(it.N(), obj.FmtShort))
+                       fmt.Printf("%v::esccall:: ... <- %v\n", linestr(lineno), Nconv(lls[i], obj.FmtShort))
                }
-               escassign(e, src, it.N()) // args to slice
+               escassign(e, src, lls[i]) // args to slice
        }
 }
 
index a900376519222ca7b3d65f487cb34858839c9ef9..7883e02909412cb2b2e67dc179e22f19fc1c112b 100644 (file)
@@ -1257,10 +1257,10 @@ func exprfmt(n *Node, prec int) string {
                        } else {
                                f += fmt.Sprintf("(%v{", n.Type)
                        }
-                       for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
-                               f += fmt.Sprintf(" %v:%v", Sconv(it.N().Left.Sym, obj.FmtShort|obj.FmtByte), it.N().Right)
+                       for i1, n1 := range n.List.Slice() {
+                               f += fmt.Sprintf(" %v:%v", Sconv(n1.Left.Sym, obj.FmtShort|obj.FmtByte), n1.Right)
 
-                               if it.Len() > 1 {
+                               if i1+1 < n.List.Len() {
                                        f += ","
                                } else {
                                        f += " "
@@ -1725,9 +1725,9 @@ func Hconv(l Nodes, flag int) string {
        }
 
        var buf bytes.Buffer
-       for it := nodeSeqIterate(l); !it.Done(); it.Next() {
-               buf.WriteString(Nconv(it.N(), 0))
-               if it.Len() > 1 {
+       for i, n := range l.Slice() {
+               buf.WriteString(Nconv(n, 0))
+               if i+1 < l.Len() {
                        buf.WriteString(sep)
                }
        }
index 69615ba0f5cdad5c6bd6a71b405b18e6e1571ce5..88ac1c9a91d902486dac1ed25873d95e346b1f18 100644 (file)
@@ -325,8 +325,9 @@ func inlconv2list(n *Node) []*Node {
 }
 
 func inlnodelist(l Nodes) {
-       for i := range l.Slice() {
-               inlnode(&l.Slice()[i])
+       s := l.Slice()
+       for i := range s {
+               inlnode(&s[i])
        }
 }
 
@@ -411,9 +412,10 @@ func inlnode(np **Node) {
                fallthrough
 
        default:
-               for i3, n3 := range n.List.Slice() {
-                       if n3.Op == OINLCALL {
-                               inlconv2expr(&n.List.Slice()[i3])
+               s := n.List.Slice()
+               for i1, n1 := range s {
+                       if n1.Op == OINLCALL {
+                               inlconv2expr(&s[i1])
                        }
                }
        }
@@ -431,12 +433,13 @@ func inlnode(np **Node) {
                fallthrough
 
        default:
-               for i4, n4 := range n.Rlist.Slice() {
-                       if n4.Op == OINLCALL {
+               s := n.Rlist.Slice()
+               for i1, n1 := range s {
+                       if n1.Op == OINLCALL {
                                if n.Op == OIF {
-                                       inlconv2stmt(n4)
+                                       inlconv2stmt(n1)
                                } else {
-                                       inlconv2expr(&n.Rlist.Slice()[i4])
+                                       inlconv2expr(&s[i1])
                                }
                        }
                }
@@ -670,7 +673,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
        as = Nod(OAS2, nil, nil)
 
        as.Rlist.Set(n.List.Slice())
-       it := nodeSeqIterate(n.List)
+       li := 0
 
        // TODO: if len(nlist) == 1 but multiple args, check that n->list->n is a call?
        if fn.Type.Thistuple != 0 && n.Left.Op != ODOTMETH {
@@ -689,7 +692,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                        Fatalf("method call unknown receiver type: %v", Nconv(n, obj.FmtSign))
                }
                as.List.Append(tinlvar(t))
-               it.Next() // track argument count.
+               li++
        }
 
        // append ordinary arguments to LHS.
@@ -703,7 +706,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                for t, it2 := IterFields(fn.Type.Params()); t != nil; t = it2.Next() {
                        if variadic && t.Isddd {
                                vararg = tinlvar(t)
-                               for i = 0; i < varargcount && it.Len() != 0; i++ {
+                               for i = 0; i < varargcount && li < n.List.Len(); i++ {
                                        m = argvar(varargtype, i)
                                        varargs = append(varargs, m)
                                        as.List.Append(m)
@@ -718,7 +721,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                // match arguments except final variadic (unless the call is dotted itself)
                var t *Type
                for t = fn.Type.Params().Type; t != nil; {
-                       if it.Done() {
+                       if li >= n.List.Len() {
                                break
                        }
                        if variadic && t.Isddd {
@@ -726,18 +729,18 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                        }
                        as.List.Append(tinlvar(t))
                        t = t.Down
-                       it.Next()
+                       li++
                }
 
                // match varargcount arguments with variadic parameters.
                if variadic && t != nil && t.Isddd {
                        vararg = tinlvar(t)
                        var i int
-                       for i = 0; i < varargcount && !it.Done(); i++ {
+                       for i = 0; i < varargcount && li < n.List.Len(); i++ {
                                m = argvar(varargtype, i)
                                varargs = append(varargs, m)
                                as.List.Append(m)
-                               it.Next()
+                               li++
                        }
 
                        if i == varargcount {
@@ -745,7 +748,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                        }
                }
 
-               if !it.Done() || t != nil {
+               if li < n.List.Len() || t != nil {
                        Fatalf("arg count mismatch: %v  vs %v\n", Tconv(fn.Type.Params(), obj.FmtSharp), Hconv(n.List, obj.FmtComma))
                }
        }
index d287ae6fc3d5415084d9f275f83e47357e140ca6..f2c73415535bde2541dd707c0db3d44065969d80 100644 (file)
@@ -376,14 +376,17 @@ func ordercall(n *Node, order *Order) {
 
        if n.Op == OCALLFUNC {
                t := n.Left.Type.Params().Type
-               for it := nodeSeqIterate(n.List); !it.Done() && t != nil; it.Next() {
+               for i := range n.List.Slice() {
                        // Check for "unsafe-uintptr" tag provided by escape analysis.
                        // If present and the argument is really a pointer being converted
                        // to uintptr, arrange for the pointer to be kept alive until the call
                        // returns, by copying it into a temp and marking that temp
                        // still alive when we pop the temp stack.
+                       if t == nil {
+                               break
+                       }
                        if t.Note != nil && *t.Note == unsafeUintptrTag {
-                               xp := it.P()
+                               xp := n.List.Addr(i)
                                for (*xp).Op == OCONVNOP && !Isptr[(*xp).Type.Etype] {
                                        xp = &(*xp).Left
                                }
@@ -452,14 +455,15 @@ func ordermapassign(n *Node, order *Order) {
                                if !istemp(m.Right) {
                                        m.Right = ordercopyexpr(m.Right, m.Right.Type, order, 0)
                                }
-                               n.List.Slice()[i1] = ordertemp(m.Type, order, false)
-                               a = Nod(OAS, m, n.List.Slice()[i1])
+                               n.List.SetIndex(i1, ordertemp(m.Type, order, false))
+                               a = Nod(OAS, m, n.List.Index(i1))
                                typecheck(&a, Etop)
                                post = append(post, a)
-                       } else if instrumenting && n.Op == OAS2FUNC && !isblank(n.List.Slice()[i1]) {
-                               m = n.List.Slice()[i1]
-                               n.List.Slice()[i1] = ordertemp(m.Type, order, false)
-                               a = Nod(OAS, m, n.List.Slice()[i1])
+                       } else if instrumenting && n.Op == OAS2FUNC && !isblank(n.List.Index(i1)) {
+                               m = n.List.Index(i1)
+                               t := ordertemp(m.Type, order, false)
+                               n.List.SetIndex(i1, t)
+                               a = Nod(OAS, m, t)
                                typecheck(&a, Etop)
                                post = append(post, a)
                        }
@@ -651,9 +655,7 @@ func orderstmt(n *Node, order *Order) {
                        orderexprlist(n.Left.List, order)
 
                        t1 := marktemp(order)
-                       it := nodeSeqIterate(n.Left.List)
-                       it.Next()
-                       np := it.P() // map key
+                       np := n.Left.List.Addr(1) // map key
                        *np = ordercopyexpr(*np, (*np).Type, order, 0)
                        poptemp(t1, order)
 
@@ -666,11 +668,9 @@ func orderstmt(n *Node, order *Order) {
 
        case ODELETE:
                t := marktemp(order)
-               it := nodeSeqIterate(n.List)
-               orderexpr(it.P(), order, nil)
-               it.Next()
-               orderexpr(it.P(), order, nil)
-               orderaddrtemp(it.P(), order) // map key
+               orderexpr(n.List.Addr(0), order, nil)
+               orderexpr(n.List.Addr(1), order, nil)
+               orderaddrtemp(n.List.Addr(1), order) // map key
                order.out = append(order.out, n)
                cleantemp(t, order)
 
@@ -771,8 +771,8 @@ func orderstmt(n *Node, order *Order) {
                        // n->alloc is the temp for the iterator.
                        prealloc[n] = ordertemp(Types[TUINT8], order, true)
                }
-               for i1 := range n.List.Slice() {
-                       orderexprinplace(&n.List.Slice()[i1], order)
+               for i := range n.List.Slice() {
+                       orderexprinplace(n.List.Addr(i), order)
                }
                orderblockNodes(&n.Nbody)
                order.out = append(order.out, n)
@@ -815,20 +815,20 @@ func orderstmt(n *Node, order *Order) {
                                        Yyerror("unknown op in select %v", Oconv(r.Op, 0))
                                        Dump("select case", r)
 
-                                       // If this is case x := <-ch or case x, y := <-ch, the case has
+                               // If this is case x := <-ch or case x, y := <-ch, the case has
                                // the ODCL nodes to declare x and y. We want to delay that
                                // declaration (and possible allocation) until inside the case body.
                                // Delete the ODCL nodes here and recreate them inside the body below.
                                case OSELRECV, OSELRECV2:
                                        if r.Colas {
-                                               itinit := nodeSeqIterate(r.Ninit)
-                                               if itinit.Len() != 0 && itinit.N().Op == ODCL && itinit.N().Left == r.Left {
-                                                       itinit.Next()
+                                               i := 0
+                                               if r.Ninit.Len() != 0 && r.Ninit.First().Op == ODCL && r.Ninit.First().Left == r.Left {
+                                                       i++
                                                }
-                                               if itinit.Len() != 0 && itinit.N().Op == ODCL && r.List.Len() != 0 && itinit.N().Left == r.List.First() {
-                                                       itinit.Next()
+                                               if i < r.Ninit.Len() && r.Ninit.Index(i).Op == ODCL && r.List.Len() != 0 && r.Ninit.Index(i).Left == r.List.First() {
+                                                       i++
                                                }
-                                               if itinit.Done() {
+                                               if i >= r.Ninit.Len() {
                                                        r.Ninit.Set(nil)
                                                }
                                        }
@@ -967,16 +967,18 @@ func orderstmt(n *Node, order *Order) {
 
 // Orderexprlist orders the expression list l into order.
 func orderexprlist(l Nodes, order *Order) {
-       for i := range l.Slice() {
-               orderexpr(&l.Slice()[i], order, nil)
+       s := l.Slice()
+       for i := range s {
+               orderexpr(&s[i], order, nil)
        }
 }
 
 // Orderexprlist orders the expression list l but saves
 // the side effects on the individual expression ninit lists.
 func orderexprlistinplace(l Nodes, order *Order) {
-       for i := range l.Slice() {
-               orderexprinplace(&l.Slice()[i], order)
+       s := l.Slice()
+       for i := range s {
+               orderexprinplace(&s[i], order)
        }
 }
 
index 04afc587502eb4e624f76577e0173f2fd9817533..ccddfc487001ae9c729a9638562cc58391aea8da 100644 (file)
@@ -87,11 +87,12 @@ func instrument(fn *Node) {
 }
 
 func instrumentlist(l Nodes, init *Nodes) {
-       for i := range l.Slice() {
+       s := l.Slice()
+       for i := range s {
                var instr Nodes
-               instrumentnode(&l.Slice()[i], &instr, 0, 0)
+               instrumentnode(&s[i], &instr, 0, 0)
                if init == nil {
-                       l.Slice()[i].Ninit.AppendNodes(&instr)
+                       s[i].Ninit.AppendNodes(&instr)
                } else {
                        init.AppendNodes(&instr)
                }
@@ -146,25 +147,26 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
 
        case OBLOCK:
                var out []*Node
-               for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
-                       switch it.N().Op {
+               ls := n.List.Slice()
+               for i := 0; i < len(ls); i++ {
+                       switch ls[i].Op {
                        case OCALLFUNC, OCALLMETH, OCALLINTER:
-                               instrumentnode(it.P(), &it.N().Ninit, 0, 0)
-                               out = append(out, it.N())
+                               instrumentnode(&ls[i], &ls[i].Ninit, 0, 0)
+                               out = append(out, ls[i])
                                // Scan past OAS nodes copying results off stack.
                                // Those must not be instrumented, because the
                                // instrumentation calls will smash the results.
                                // The assignments are to temporaries, so they cannot
                                // be involved in races and need not be instrumented.
-                               for it.Len() > 1 && nodeSeqSecond(it.Seq()).Op == OAS && iscallret(nodeSeqSecond(it.Seq()).Right) {
-                                       it.Next()
-                                       out = append(out, it.N())
+                               for i+1 < len(ls) && ls[i+1].Op == OAS && iscallret(ls[i+1].Right) {
+                                       i++
+                                       out = append(out, ls[i])
                                }
                        default:
                                var outn Nodes
                                outn.Set(out)
-                               instrumentnode(it.P(), &outn, 0, 0)
-                               out = append(outn.Slice(), it.N())
+                               instrumentnode(&ls[i], &outn, 0, 0)
+                               out = append(outn.Slice(), ls[i])
                        }
                }
                n.List.Set(out)
index 841c95b6e72150950c67f9735a3f7d9b5056c5ad..8264d2a18cd2aa6a7545aa52018c5a0915425592 100644 (file)
@@ -14,6 +14,7 @@ func typecheckrange(n *Node) {
        var t2 *Type
        var v1 *Node
        var v2 *Node
+       var ls []*Node
 
        // Typechecking order is important here:
        // 0. first typecheck range expression (slice/map/chan),
@@ -32,9 +33,10 @@ func typecheckrange(n *Node) {
                goto out
        }
        // delicate little dance.  see typecheckas2
-       for i1, n1 := range n.List.Slice() {
+       ls = n.List.Slice()
+       for i1, n1 := range ls {
                if n1.Name == nil || n1.Name.Defn != n {
-                       typecheck(&n.List.Slice()[i1], Erv|Easgn)
+                       typecheck(&ls[i1], Erv|Easgn)
                }
        }
 
@@ -119,9 +121,10 @@ func typecheckrange(n *Node) {
        // second half of dance
 out:
        n.Typecheck = 1
-       for i2, n2 := range n.List.Slice() {
-               if n2.Typecheck == 0 {
-                       typecheck(&n.List.Slice()[i2], Erv|Easgn)
+       ls = n.List.Slice()
+       for i1, n1 := range ls {
+               if n1.Typecheck == 0 {
+                       typecheck(&ls[i1], Erv|Easgn)
                }
        }
 
@@ -342,10 +345,10 @@ func memclrrange(n, v1, v2, a *Node) bool {
        if v1 == nil || v2 != nil {
                return false
        }
-       if len(n.Nbody.Slice()) == 0 || n.Nbody.Slice()[0] == nil || len(n.Nbody.Slice()) > 1 {
+       if n.Nbody.Len() == 0 || n.Nbody.First() == nil || n.Nbody.Len() > 1 {
                return false
        }
-       stmt := n.Nbody.Slice()[0] // only stmt in body
+       stmt := n.Nbody.First() // only stmt in body
        if stmt.Op != OAS || stmt.Left.Op != OINDEX {
                return false
        }
index 91cb086e5e386d97c3346673edf948129f37f2b7..6d8c327772ab0da00599f8edfacd1e0f8184e07c 100644 (file)
@@ -31,8 +31,7 @@ func typecheckselect(sel *Node) {
                } else if ncase.List.Len() > 1 {
                        Yyerror("select cases cannot be lists")
                } else {
-                       it2 := nodeSeqIterate(ncase.List)
-                       n = typecheck(it2.P(), Etop)
+                       n = typecheck(ncase.List.Addr(0), Etop)
                        ncase.Left = n
                        ncase.List.Set(nil)
                        setlineno(n)
@@ -101,7 +100,6 @@ func walkselect(sel *Node) {
        var n *Node
        var var_ *Node
        var selv *Node
-       var cas *Node
        if i == 0 {
                sel.Nbody.Set([]*Node{mkcall("block", nil, nil)})
                goto out
@@ -172,8 +170,7 @@ func walkselect(sel *Node) {
 
        // convert case value arguments to addresses.
        // this rewrite is used by both the general code and the next optimization.
-       for it := nodeSeqIterate(sel.List); !it.Done(); it.Next() {
-               cas = it.N()
+       for _, cas := range sel.List.Slice() {
                setlineno(cas)
                n = cas.Left
                if n == nil {
@@ -189,9 +186,8 @@ func walkselect(sel *Node) {
                                n.Op = OSELRECV
                        }
                        if n.Op == OSELRECV2 {
-                               it := nodeSeqIterate(n.List)
-                               *it.P() = Nod(OADDR, it.N(), nil)
-                               typecheck(it.P(), Erv)
+                               n.List.SetIndex(0, Nod(OADDR, n.List.First(), nil))
+                               typecheck(n.List.Addr(0), Erv)
                        }
 
                        if n.Left == nil {
@@ -268,7 +264,7 @@ func walkselect(sel *Node) {
        typecheck(&r, Etop)
        init = append(init, r)
        // register cases
-       for _, cas = range sel.List.Slice() {
+       for _, cas := range sel.List.Slice() {
                setlineno(cas)
                n = cas.Left
                r = Nod(OIF, nil, nil)
index e124d02b61a4d383441292e652ee78d67c8df953..40e12d5b9bfb17ad217375b3a40a5ced983f6780 100644 (file)
@@ -2066,14 +2066,12 @@ func (s *state) expr(n *Node) *ssa.Value {
                // Evaluate args
                args := make([]*ssa.Value, 0, nargs)
                store := make([]bool, 0, nargs)
-               it := nodeSeqIterate(n.List)
-               it.Next()
-               for ; !it.Done(); it.Next() {
-                       if canSSAType(it.N().Type) {
-                               args = append(args, s.expr(it.N()))
+               for _, n := range n.List.Slice()[1:] {
+                       if canSSAType(n.Type) {
+                               args = append(args, s.expr(n))
                                store = append(store, true)
                        } else {
-                               args = append(args, s.addr(it.N(), false))
+                               args = append(args, s.addr(n, false))
                                store = append(store, false)
                        }
                }
index d54e4d61aa37139d57954c838720e2251862b886..054fee32b03053336cbf63282a599740549b85e7 100644 (file)
@@ -115,30 +115,33 @@ func typecheckswitch(n *Node) {
                                def = ncase
                        }
                } else {
-                       for i1, n1 := range ncase.List.Slice() {
+                       ls := ncase.List.Slice()
+                       for i1, n1 := range ls {
                                setlineno(n1)
-                               typecheck(&ncase.List.Slice()[i1], Erv|Etype)
-                               if ncase.List.Slice()[i1].Type == nil || t == nil {
+                               typecheck(&ls[i1], Erv|Etype)
+                               n1 = ls[i1]
+                               if n1.Type == nil || t == nil {
                                        continue
                                }
                                setlineno(ncase)
                                switch top {
                                // expression switch
                                case Erv:
-                                       defaultlit(&ncase.List.Slice()[i1], t)
+                                       defaultlit(&ls[i1], t)
+                                       n1 = ls[i1]
                                        switch {
-                                       case ncase.List.Slice()[i1].Op == OTYPE:
-                                               Yyerror("type %v is not an expression", ncase.List.Slice()[i1].Type)
-                                       case ncase.List.Slice()[i1].Type != nil && assignop(ncase.List.Slice()[i1].Type, t, nil) == 0 && assignop(t, ncase.List.Slice()[i1].Type, nil) == 0:
+                                       case n1.Op == OTYPE:
+                                               Yyerror("type %v is not an expression", n1.Type)
+                                       case n1.Type != nil && assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0:
                                                if n.Left != nil {
-                                                       Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", ncase.List.Slice()[i1], n.Left, ncase.List.Slice()[i1].Type, t)
+                                                       Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
                                                } else {
-                                                       Yyerror("invalid case %v in switch (mismatched types %v and bool)", ncase.List.Slice()[i1], ncase.List.Slice()[i1].Type)
+                                                       Yyerror("invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
                                                }
-                                       case nilonly != "" && !isnil(ncase.List.Slice()[i1]):
-                                               Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ncase.List.Slice()[i1], nilonly, n.Left)
-                                       case Isinter(t) && !Isinter(ncase.List.Slice()[i1].Type) && algtype1(ncase.List.Slice()[i1].Type, nil) == ANOEQ:
-                                               Yyerror("invalid case %v in switch (incomparable type)", Nconv(ncase.List.Slice()[i1], obj.FmtLong))
+                                       case nilonly != "" && !isnil(n1):
+                                               Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
+                                       case Isinter(t) && !Isinter(n1.Type) && algtype1(n1.Type, nil) == ANOEQ:
+                                               Yyerror("invalid case %v in switch (incomparable type)", Nconv(n1, obj.FmtLong))
                                        }
 
                                // type switch
@@ -146,16 +149,17 @@ func typecheckswitch(n *Node) {
                                        var missing, have *Type
                                        var ptr int
                                        switch {
-                                       case ncase.List.Slice()[i1].Op == OLITERAL && Istype(ncase.List.Slice()[i1].Type, TNIL):
-                                       case ncase.List.Slice()[i1].Op != OTYPE && ncase.List.Slice()[i1].Type != nil: // should this be ||?
-                                               Yyerror("%v is not a type", Nconv(ncase.List.Slice()[i1], obj.FmtLong))
+                                       case n1.Op == OLITERAL && Istype(n1.Type, TNIL):
+                                       case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
+                                               Yyerror("%v is not a type", Nconv(n1, obj.FmtLong))
                                                // reset to original type
-                                               ncase.List.Slice()[i1] = n.Left.Right
-                                       case ncase.List.Slice()[i1].Type.Etype != TINTER && t.Etype == TINTER && !implements(ncase.List.Slice()[i1].Type, t, &missing, &have, &ptr):
+                                               n1 = n.Left.Right
+                                               ls[i1] = n1
+                                       case n1.Type.Etype != TINTER && t.Etype == TINTER && !implements(n1.Type, t, &missing, &have, &ptr):
                                                if have != nil && !missing.Broke && !have.Broke {
-                                                       Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Left.Right, obj.FmtLong), ncase.List.Slice()[i1].Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
+                                                       Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Left.Right, obj.FmtLong), n1.Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
                                                } else if !missing.Broke {
-                                                       Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), ncase.List.Slice()[i1].Type, missing.Sym)
+                                                       Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), n1.Type, missing.Sym)
                                                }
                                        }
                                }
@@ -175,8 +179,7 @@ func typecheckswitch(n *Node) {
                                }
 
                                typecheck(&nvar, Erv|Easgn)
-                               rit := nodeSeqIterate(ncase.Rlist)
-                               *rit.P() = nvar
+                               ncase.Rlist.SetIndex(0, nvar)
                        }
                }
 
@@ -344,8 +347,7 @@ func casebody(sw *Node, typeswvar *Node) {
        var def *Node    // defaults
        br := Nod(OBREAK, nil, nil)
 
-       for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() {
-               n := it.N()
+       for i, n := range sw.List.Slice() {
                setlineno(n)
                if n.Op != OXCASE {
                        Fatalf("casebody %v", Oconv(n.Op, 0))
@@ -395,7 +397,7 @@ func casebody(sw *Node, typeswvar *Node) {
                                Yyerror("cannot fallthrough in type switch")
                        }
 
-                       if it.Len() <= 1 {
+                       if i+1 >= sw.List.Len() {
                                setlineno(last)
                                Yyerror("cannot fallthrough final case in switch")
                        }
index 59748ea1fd1921f11c73f8334adad36f3f522d5f..505f55e526ba1382cedd7465f017da015e57197f 100644 (file)
@@ -437,14 +437,20 @@ func (n *Nodes) Len() int {
        return len(*n.slice)
 }
 
-// First returns the first element of Nodes.
-// It panics if Nodes has no elements.
+// Index returns the i'th element of Nodes.
+// It panics if n does not have at least i+1 elements.
+func (n *Nodes) Index(i int) *Node {
+       return (*n.slice)[i]
+}
+
+// First returns the first element of Nodes (same as n.Index(0)).
+// It panics if n has no elements.
 func (n *Nodes) First() *Node {
        return (*n.slice)[0]
 }
 
-// Second returns the second element of Nodes.
-// It panics if Nodes has fewer than two elements.
+// Second returns the second element of Nodes (same as n.Index(1)).
+// It panics if n has fewer than two elements.
 func (n *Nodes) Second() *Node {
        return (*n.slice)[1]
 }
@@ -464,7 +470,7 @@ func (n *Nodes) NodeList() *NodeList {
        return ret
 }
 
-// Set sets Nodes to a slice.
+// Set sets n to a slice.
 // This takes ownership of the slice.
 func (n *Nodes) Set(s []*Node) {
        if len(s) == 0 {
@@ -474,6 +480,24 @@ func (n *Nodes) Set(s []*Node) {
        }
 }
 
+// MoveNodes sets n to the contents of n2, then clears n2.
+func (n *Nodes) MoveNodes(n2 *Nodes) {
+       n.slice = n2.slice
+       n2.slice = nil
+}
+
+// SetIndex sets the i'th element of Nodes to node.
+// It panics if n does not have at least i+1 elements.
+func (n *Nodes) SetIndex(i int, node *Node) {
+       (*n.slice)[i] = node
+}
+
+// Addr returns the address of the i'th element of Nodes.
+// It panics if n does not have at least i+1 elements.
+func (n *Nodes) Addr(i int) **Node {
+       return &(*n.slice)[i]
+}
+
 // Append appends entries to Nodes.
 // If a slice is passed in, this will take ownership of it.
 func (n *Nodes) Append(a ...*Node) {
@@ -530,106 +554,6 @@ type nodesOrNodeList interface{}
 // to a generic value.
 type nodesOrNodeListPtr interface{}
 
-// nodeSeqIterator is an interface used to iterate over a sequence of nodes.
-// TODO(iant): Remove after conversion from NodeList to Nodes is complete.
-type nodeSeqIterator interface {
-       // Return whether iteration is complete.
-       Done() bool
-       // Advance to the next node.
-       Next()
-       // Return the current node.
-       N() *Node
-       // Return the address of the current node.
-       P() **Node
-       // Return the number of items remaining in the iteration.
-       Len() int
-       // Return the remaining items as a sequence.
-       // This will have the same type as that passed to nodeSeqIterate.
-       Seq() nodesOrNodeList
-}
-
-// nodeListIterator is a type that implements nodeSeqIterator using a
-// *NodeList.
-type nodeListIterator struct {
-       l *NodeList
-}
-
-func (nli *nodeListIterator) Done() bool {
-       return nli.l == nil
-}
-
-func (nli *nodeListIterator) Next() {
-       nli.l = nli.l.Next
-}
-
-func (nli *nodeListIterator) N() *Node {
-       return nli.l.N
-}
-
-func (nli *nodeListIterator) P() **Node {
-       return &nli.l.N
-}
-
-func (nli *nodeListIterator) Len() int {
-       return count(nli.l)
-}
-
-func (nli *nodeListIterator) Seq() nodesOrNodeList {
-       return nli.l
-}
-
-// nodesIterator implements nodeSeqIterator using a Nodes.
-type nodesIterator struct {
-       n Nodes
-       i int
-}
-
-func (ni *nodesIterator) Done() bool {
-       return ni.i >= len(ni.n.Slice())
-}
-
-func (ni *nodesIterator) Next() {
-       ni.i++
-}
-
-func (ni *nodesIterator) N() *Node {
-       return ni.n.Slice()[ni.i]
-}
-
-func (ni *nodesIterator) P() **Node {
-       return &ni.n.Slice()[ni.i]
-}
-
-func (ni *nodesIterator) Len() int {
-       return len(ni.n.Slice()[ni.i:])
-}
-
-func (ni *nodesIterator) Seq() nodesOrNodeList {
-       var r Nodes
-       r.Set(ni.n.Slice()[ni.i:])
-       return r
-}
-
-// nodeSeqIterate returns an iterator over a *NodeList, a Nodes,
-// a []*Node, or nil.
-func nodeSeqIterate(ns nodesOrNodeList) nodeSeqIterator {
-       switch ns := ns.(type) {
-       case *NodeList:
-               return &nodeListIterator{ns}
-       case Nodes:
-               return &nodesIterator{ns, 0}
-       case []*Node:
-               var r Nodes
-               r.Set(ns)
-               return &nodesIterator{r, 0}
-       case nil:
-               var r Nodes
-               return &nodesIterator{r, 0}
-       default:
-               panic("can't happen")
-       }
-}
-
 // nodeSeqLen returns the length of a *NodeList, a Nodes, a []*Node, or nil.
 func nodeSeqLen(ns nodesOrNodeList) int {
        switch ns := ns.(type) {
index e1840ee89e4c432eb867750376875a5997e82df3..0878214f3e4a3ac5337e72797297b92b29acd2c4 100644 (file)
@@ -1289,8 +1289,7 @@ OpSwitch:
                }
 
                if n.List.Len() == 1 && !n.Isddd {
-                       it := nodeSeqIterate(n.List)
-                       typecheck(it.P(), Erv|Efnstruct)
+                       typecheck(n.List.Addr(0), Erv|Efnstruct)
                } else {
                        typechecklist(n.List.Slice(), Erv)
                }
@@ -1576,9 +1575,7 @@ OpSwitch:
                        return
                }
 
-               it := nodeSeqIterate(args)
-               it.Next()
-               *it.P() = assignconv(r, l.Type.Down, "delete")
+               args.SetIndex(1, assignconv(r, l.Type.Down, "delete"))
                break OpSwitch
 
        case OAPPEND:
@@ -1591,8 +1588,7 @@ OpSwitch:
                }
 
                if args.Len() == 1 && !n.Isddd {
-                       it := nodeSeqIterate(args)
-                       typecheck(it.P(), Erv|Efnstruct)
+                       typecheck(args.Addr(0), Erv|Efnstruct)
                } else {
                        typechecklist(args.Slice(), Erv)
                }
@@ -1637,15 +1633,11 @@ OpSwitch:
                        }
 
                        if Istype(t.Type, TUINT8) && Istype(args.Second().Type, TSTRING) {
-                               it := nodeSeqIterate(args)
-                               it.Next()
-                               defaultlit(it.P(), Types[TSTRING])
+                               defaultlit(args.Addr(1), Types[TSTRING])
                                break OpSwitch
                        }
 
-                       it := nodeSeqIterate(args)
-                       it.Next()
-                       *it.P() = assignconv(args.Second(), t.Orig, "append")
+                       args.SetIndex(1, assignconv(args.Index(1), t.Orig, "append"))
                        break OpSwitch
                }
 
@@ -1656,13 +1648,12 @@ OpSwitch:
                                }
                        }
                } else {
-                       it := nodeSeqIterate(args)
-                       it.Next()
-                       for ; !it.Done(); it.Next() {
-                               if it.N().Type == nil {
+                       as := args.Slice()[1:]
+                       for i, n := range as {
+                               if n.Type == nil {
                                        continue
                                }
-                               *it.P() = assignconv(it.N(), t.Type, "append")
+                               as[i] = assignconv(n, t.Type, "append")
                        }
                }
 
@@ -1777,16 +1768,15 @@ OpSwitch:
 
        case OMAKE:
                ok |= Erv
-               args := nodeSeqIterate(n.List)
-               if args.Len() == 0 {
+               args := n.List.Slice()
+               if len(args) == 0 {
                        Yyerror("missing argument to make")
                        n.Type = nil
                        return
                }
 
                n.List.Set(nil)
-               l := args.N()
-               args.Next()
+               l := args[0]
                typecheck(&l, Etype)
                t := l.Type
                if t == nil {
@@ -1794,6 +1784,7 @@ OpSwitch:
                        return
                }
 
+               i := 1
                switch t.Etype {
                default:
                        Yyerror("cannot make type %v", t)
@@ -1807,19 +1798,19 @@ OpSwitch:
                                return
                        }
 
-                       if args.Done() {
+                       if i >= len(args) {
                                Yyerror("missing len argument to make(%v)", t)
                                n.Type = nil
                                return
                        }
 
-                       l = args.N()
-                       args.Next()
+                       l = args[i]
+                       i++
                        typecheck(&l, Erv)
                        var r *Node
-                       if !args.Done() {
-                               r = args.N()
-                               args.Next()
+                       if i < len(args) {
+                               r = args[i]
+                               i++
                                typecheck(&r, Erv)
                        }
 
@@ -1842,9 +1833,9 @@ OpSwitch:
                        n.Op = OMAKESLICE
 
                case TMAP:
-                       if !args.Done() {
-                               l = args.N()
-                               args.Next()
+                       if i < len(args) {
+                               l = args[i]
+                               i++
                                typecheck(&l, Erv)
                                defaultlit(&l, Types[TINT])
                                if l.Type == nil {
@@ -1863,9 +1854,9 @@ OpSwitch:
 
                case TCHAN:
                        l = nil
-                       if !args.Done() {
-                               l = args.N()
-                               args.Next()
+                       if i < len(args) {
+                               l = args[i]
+                               i++
                                typecheck(&l, Erv)
                                defaultlit(&l, Types[TINT])
                                if l.Type == nil {
@@ -1883,7 +1874,7 @@ OpSwitch:
                        n.Op = OMAKECHAN
                }
 
-               if !args.Done() {
+               if i < len(args) {
                        Yyerror("too many arguments to make(%v)", t)
                        n.Op = OMAKE
                        n.Type = nil
@@ -1922,12 +1913,13 @@ OpSwitch:
        case OPRINT, OPRINTN:
                ok |= Etop
                typechecklist(n.List.Slice(), Erv|Eindir) // Eindir: address does not escape
-               for i1, n1 := range n.List.Slice() {
+               ls := n.List.Slice()
+               for i1, n1 := range ls {
                        // Special case for print: int constant is int64, not int.
                        if Isconst(n1, CTINT) {
-                               defaultlit(&n.List.Slice()[i1], Types[TINT64])
+                               defaultlit(&ls[i1], Types[TINT64])
                        } else {
-                               defaultlit(&n.List.Slice()[i1], nil)
+                               defaultlit(&ls[i1], nil)
                        }
                }
 
@@ -2611,7 +2603,7 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc
        var n *Node
        var n1 int
        var n2 int
-       var it nodeSeqIterator
+       var i int
 
        lno := lineno
 
@@ -2698,48 +2690,48 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc
                }
        }
 
-       it = nodeSeqIterate(nl)
+       i = 0
        for tl := tstruct.Type; tl != nil; tl = tl.Down {
                t = tl.Type
                if tl.Isddd {
                        if isddd {
-                               if it.Done() {
+                               if i >= nl.Len() {
                                        goto notenough
                                }
-                               if it.Len() > 1 {
+                               if nl.Len()-i > 1 {
                                        goto toomany
                                }
-                               n = it.N()
+                               n = nl.Index(i)
                                setlineno(n)
                                if n.Type != nil {
-                                       *it.P() = assignconvfn(n, t, desc)
+                                       nl.SetIndex(i, assignconvfn(n, t, desc))
                                }
                                goto out
                        }
 
-                       for ; !it.Done(); it.Next() {
-                               n = it.N()
-                               setlineno(it.N())
+                       for ; i < nl.Len(); i++ {
+                               n = nl.Index(i)
+                               setlineno(n)
                                if n.Type != nil {
-                                       *it.P() = assignconvfn(n, t.Type, desc)
+                                       nl.SetIndex(i, assignconvfn(n, t.Type, desc))
                                }
                        }
 
                        goto out
                }
 
-               if it.Done() {
+               if i >= nl.Len() {
                        goto notenough
                }
-               n = it.N()
+               n = nl.Index(i)
                setlineno(n)
                if n.Type != nil {
-                       *it.P() = assignconvfn(n, t, desc)
+                       nl.SetIndex(i, assignconvfn(n, t, desc))
                }
-               it.Next()
+               i++
        }
 
-       if !it.Done() {
+       if i < nl.Len() {
                goto toomany
        }
        if isddd {
@@ -2983,7 +2975,7 @@ func typecheckcomplit(np **Node) {
                                l = Nod(OKEY, Nodintconst(int64(i)), l)
                                l.Left.Type = Types[TINT]
                                l.Left.Typecheck = 1
-                               n.List.Slice()[i2] = l
+                               n.List.SetIndex(i2, l)
                        }
 
                        typecheck(&l.Left, Erv)
@@ -3030,7 +3022,7 @@ func typecheckcomplit(np **Node) {
                        l = n3
                        setlineno(l)
                        if l.Op != OKEY {
-                               typecheck(&n.List.Slice()[i3], Erv)
+                               typecheck(n.List.Addr(i3), Erv)
                                Yyerror("missing key in map literal")
                                continue
                        }
@@ -3060,9 +3052,11 @@ func typecheckcomplit(np **Node) {
                        f := t.Type
 
                        var s *Sym
-                       for i4, n4 := range n.List.Slice() {
-                               setlineno(n4)
-                               typecheck(&n.List.Slice()[i4], Erv)
+                       ls := n.List.Slice()
+                       for i1, n1 := range ls {
+                               setlineno(n1)
+                               typecheck(&ls[i1], Erv)
+                               n1 = ls[i1]
                                if f == nil {
                                        if bad == 0 {
                                                Yyerror("too many values in struct initializer")
@@ -3076,10 +3070,11 @@ func typecheckcomplit(np **Node) {
                                        Yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
                                }
                                // No pushtype allowed here. Must name fields for that.
-                               n.List.Slice()[i4] = assignconv(n.List.Slice()[i4], f.Type, "field value")
-                               n.List.Slice()[i4] = Nod(OKEY, newname(f.Sym), n.List.Slice()[i4])
-                               n.List.Slice()[i4].Left.Type = f
-                               n.List.Slice()[i4].Left.Typecheck = 1
+                               n1 = assignconv(n1, f.Type, "field value")
+                               n1 = Nod(OKEY, newname(f.Sym), n1)
+                               n1.Left.Type = f
+                               n1.Left.Typecheck = 1
+                               ls[i1] = n1
                                f = f.Down
                        }
 
@@ -3090,23 +3085,19 @@ func typecheckcomplit(np **Node) {
                        hash := make(map[string]bool)
 
                        // keyed list
-                       var s *Sym
-                       var f *Type
-                       var l *Node
-                       var s1 *Sym
-                       for i5, n5 := range n.List.Slice() {
-                               l = n5
+                       ls := n.List.Slice()
+                       for i, l := range ls {
                                setlineno(l)
                                if l.Op != OKEY {
                                        if bad == 0 {
                                                Yyerror("mixture of field:value and value initializers")
                                        }
                                        bad++
-                                       typecheck(&n.List.Slice()[i5], Erv)
+                                       typecheck(&ls[i], Erv)
                                        continue
                                }
 
-                               s = l.Left.Sym
+                               s := l.Left.Sym
                                if s == nil {
                                        Yyerror("invalid field name %v in struct initializer", l.Left)
                                        typecheck(&l.Right, Erv)
@@ -3117,13 +3108,13 @@ func typecheckcomplit(np **Node) {
                                // package, because of import dot. Redirect to correct sym
                                // before we do the lookup.
                                if s.Pkg != localpkg && exportname(s.Name) {
-                                       s1 = Lookup(s.Name)
+                                       s1 := Lookup(s.Name)
                                        if s1.Origpkg == s.Pkg {
                                                s = s1
                                        }
                                }
 
-                               f = lookdot1(nil, s, t, t.Type, 0)
+                               f := lookdot1(nil, s, t, t.Type, 0)
                                if f == nil {
                                        Yyerror("unknown %v field '%v' in struct literal", t, s)
                                        continue
@@ -3313,20 +3304,21 @@ func checkassignto(src *Type, dst *Node) {
 }
 
 func typecheckas2(n *Node) {
-       for i1 := range n.List.Slice() {
+       ls := n.List.Slice()
+       for i1, n1 := range ls {
                // delicate little dance.
-               n.List.Slice()[i1] = resolve(n.List.Slice()[i1])
+               n1 = resolve(n1)
+               ls[i1] = n1
 
-               if n.List.Slice()[i1].Name == nil || n.List.Slice()[i1].Name.Defn != n || n.List.Slice()[i1].Name.Param.Ntype != nil {
-                       typecheck(&n.List.Slice()[i1], Erv|Easgn)
+               if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil {
+                       typecheck(&ls[i1], Erv|Easgn)
                }
        }
 
        cl := n.List.Len()
        cr := n.Rlist.Len()
        if cl > 1 && cr == 1 {
-               it := nodeSeqIterate(n.Rlist)
-               typecheck(it.P(), Erv|Efnstruct)
+               typecheck(n.Rlist.Addr(0), Erv|Efnstruct)
        } else {
                typechecklist(n.Rlist.Slice(), Erv)
        }
@@ -3336,16 +3328,17 @@ func typecheckas2(n *Node) {
        var r *Node
        if cl == cr {
                // easy
-               lrit := nodeSeqIterate(n.Rlist)
-               for _, n2 := range n.List.Slice() {
-                       if n2.Type != nil && lrit.N().Type != nil {
-                               *lrit.P() = assignconv(lrit.N(), n2.Type, "assignment")
+               ls := n.List.Slice()
+               rs := n.Rlist.Slice()
+               for il, nl := range ls {
+                       nr := rs[il]
+                       if nl.Type != nil && nr.Type != nil {
+                               rs[il] = assignconv(nr, nl.Type, "assignment")
                        }
-                       if n2.Name != nil && n2.Name.Defn == n && n2.Name.Param.Ntype == nil {
-                               defaultlit(lrit.P(), nil)
-                               n2.Type = lrit.N().Type
+                       if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil {
+                               defaultlit(&rs[il], nil)
+                               nl.Type = rs[il].Type
                        }
-                       lrit.Next()
                }
 
                goto out
@@ -3426,9 +3419,10 @@ mismatch:
        // second half of dance
 out:
        n.Typecheck = 1
-       for i4, n4 := range n.List.Slice() {
-               if n4.Typecheck == 0 {
-                       typecheck(&n.List.Slice()[i4], Erv|Easgn)
+       ls = n.List.Slice()
+       for i1, n1 := range ls {
+               if n1.Typecheck == 0 {
+                       typecheck(&ls[i1], Erv|Easgn)
                }
        }
 }
@@ -3886,9 +3880,10 @@ func markbreak(n *Node, implicit *Node) {
 }
 
 func markbreaklist(l Nodes, implicit *Node) {
-       for it := nodeSeqIterate(l); !it.Done(); it.Next() {
-               n := it.N()
-               if n.Op == OLABEL && it.Len() > 1 && n.Name.Defn == nodeSeqSlice(it.Seq())[1] {
+       s := l.Slice()
+       for i := 0; i < len(s); i++ {
+               n := s[i]
+               if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
                        switch n.Name.Defn.Op {
                        case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE:
                                lab := new(Label)
@@ -3896,7 +3891,7 @@ func markbreaklist(l Nodes, implicit *Node) {
                                n.Left.Sym.Label = lab
                                markbreak(n.Name.Defn, n.Name.Defn)
                                n.Left.Sym.Label = nil
-                               it.Next()
+                               i++
                                continue
                        }
                }
@@ -3920,11 +3915,12 @@ func (l *NodeList) isterminating() bool {
 // Isterminating whether the Nodes list ends with a terminating
 // statement.
 func (l Nodes) isterminating() bool {
-       c := len(l.Slice())
+       s := l.Slice()
+       c := len(s)
        if c == 0 {
                return false
        }
-       return l.Slice()[c-1].isterminating()
+       return s[c-1].isterminating()
 }
 
 // Isterminating returns whether the node n, the last one in a
index a53d1bddc30e1fe308f6c4a70e7496175b445248..c1f1931b677778f144620c88a4a580604f3cb4b4 100644 (file)
@@ -321,8 +321,9 @@ func walkstmt(np **Node) {
 
                        ll := ascompatee(n.Op, rl, n.List.Slice(), &n.Ninit)
                        n.List.Set(reorder3(ll))
-                       for i1 := range n.List.Slice() {
-                               n.List.Slice()[i1] = applywritebarrier(n.List.Slice()[i1])
+                       ls := n.List.Slice()
+                       for i, n := range ls {
+                               ls[i] = applywritebarrier(n)
                        }
                        break
                }
@@ -884,8 +885,7 @@ opswitch:
                if !isblank(a) {
                        var_ := temp(Ptrto(t.Type))
                        var_.Typecheck = 1
-                       it := nodeSeqIterate(n.List)
-                       *it.P() = var_
+                       n.List.SetIndex(0, var_)
                        walkexpr(&n, init)
                        init.Append(n)
                        n = Nod(OAS, a, Nod(OIND, var_, nil))
@@ -1661,20 +1661,20 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
        }
 
        var nn []*Node
-       nlit := nodeSeqIterate(nl)
-       nrit := nodeSeqIterate(nr)
-       for ; !nlit.Done() && !nrit.Done(); nlit.Next() {
+       i := 0
+       for ; i < len(nl); i++ {
+               if i >= len(nr) {
+                       break
+               }
                // Do not generate 'x = x' during return. See issue 4014.
-               if op == ORETURN && nlit.N() == nrit.N() {
-                       nrit.Next()
+               if op == ORETURN && nl[i] == nr[i] {
                        continue
                }
-               nn = append(nn, ascompatee1(op, nlit.N(), nrit.N(), init))
-               nrit.Next()
+               nn = append(nn, ascompatee1(op, nl[i], nr[i], init))
        }
 
        // cannot happen: caller checked that lists had same length
-       if !nlit.Done() || !nrit.Done() {
+       if i < len(nl) || i < len(nr) {
                var nln, nrn Nodes
                nln.Set(nl)
                nrn.Set(nr)
@@ -1714,12 +1714,12 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
        var nn []*Node
        var mm []*Node
        ucount := 0
-       it := nodeSeqIterate(nl)
-       for ; !it.Done(); it.Next() {
+       var i int
+       for i = 0; i < nl.Len(); i++ {
                if r == nil {
                        break
                }
-               l = it.N()
+               l = nl.Index(i)
                if isblank(l) {
                        r = saver.Next()
                        continue
@@ -1749,7 +1749,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
                r = saver.Next()
        }
 
-       if !it.Done() || r != nil {
+       if i < nl.Len() || r != nil {
                Yyerror("ascompatet: assignment count mismatch: %d = %d", nl.Len(), structcount(*nr))
        }
 
@@ -1985,7 +1985,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
                        defaultlit(&n, Types[TINT64])
                }
                defaultlit(&n, nil)
-               all.Slice()[i1] = n
+               all.SetIndex(i1, n)
                if n.Type == nil || n.Type.Etype == TFORW {
                        continue
                }
@@ -2811,14 +2811,13 @@ func addstr(n *Node, init *Nodes) *Node {
 // l2 is allowed to be a string.
 func appendslice(n *Node, init *Nodes) *Node {
        walkexprlistsafe(n.List.Slice(), init)
-       for i1 := range
 
        // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
        // and n are name or literal, but those may index the slice we're
        // modifying here. Fix explicitly.
-       n.List.Slice() {
-               n.List.Slice()[i1] = cheapexpr(n.List.Slice()[i1],
-                       init)
+       ls := n.List.Slice()
+       for i1, n1 := range ls {
+               ls[i1] = cheapexpr(n1, init)
        }
 
        l1 := n.List.First()
@@ -2933,9 +2932,8 @@ func appendslice(n *Node, init *Nodes) *Node {
 //   s
 func walkappend(n *Node, init *Nodes, dst *Node) *Node {
        if !samesafeexpr(dst, n.List.First()) {
-               it := nodeSeqIterate(n.List)
-               *it.P() = safeexpr(it.N(), init)
-               walkexpr(it.P(), init)
+               n.List.SetIndex(0, safeexpr(n.List.Index(0), init))
+               walkexpr(n.List.Addr(0), init)
        }
        walkexprlistsafe(n.List.Slice()[1:], init)
 
@@ -2945,10 +2943,9 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
        // Using cheapexpr also makes sure that the evaluation
        // of all arguments (and especially any panics) happen
        // before we begin to modify the slice in a visible way.
-       it := nodeSeqIterate(n.List)
-       it.Next()
-       for ; !it.Done(); it.Next() {
-               *it.P() = cheapexpr(it.N(), init)
+       ls := n.List.Slice()[1:]
+       for i, n := range ls {
+               ls[i] = cheapexpr(n, init)
        }
 
        nsrc := n.List.First()
@@ -2991,13 +2988,12 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
        nx.Etype = 1
        l = append(l, Nod(OAS, ns, nx)) // s = s[:n+argc]
 
-       it = nodeSeqIterate(n.List)
-       it.Next()
-       for ; !it.Done(); it.Next() {
+       ls = n.List.Slice()[1:]
+       for i, n := range ls {
                nx = Nod(OINDEX, ns, nn) // s[n] ...
                nx.Bounded = true
-               l = append(l, Nod(OAS, nx, it.N())) // s[n] = arg
-               if it.Len() > 1 {
+               l = append(l, Nod(OAS, nx, n)) // s[n] = arg
+               if i+1 < len(ls) {
                        l = append(l, Nod(OAS, nn, Nod(OADD, nn, Nodintconst(1)))) // n = n + 1
                }
        }