Commit 132ebeac authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: convert walk.go and friends to use nodeSeq

Pases toolstash -cmp.

Update #14473.

Change-Id: I450d9f51fd280da91952008cd917b749d88960a3
Reviewed-on: https://go-review.googlesource.com/20210
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 1765863e
...@@ -404,7 +404,7 @@ func transformclosure(xfunc *Node) { ...@@ -404,7 +404,7 @@ func transformclosure(xfunc *Node) {
lineno = lno lineno = lno
} }
func walkclosure(func_ *Node, init **NodeList) *Node { func walkclosure(func_ *Node, init nodesOrNodeListPtr) *Node {
// If no closure vars, don't bother wrapping. // If no closure vars, don't bother wrapping.
if len(func_.Func.Cvars.Slice()) == 0 { if len(func_.Func.Cvars.Slice()) == 0 {
return func_.Func.Closure.Func.Nname return func_.Func.Closure.Func.Nname
...@@ -623,7 +623,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node { ...@@ -623,7 +623,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node {
return xfunc return xfunc
} }
func walkpartialcall(n *Node, init **NodeList) *Node { func walkpartialcall(n *Node, init nodesOrNodeListPtr) *Node {
// Create closure in the form of a composite literal. // Create closure in the form of a composite literal.
// For x.M with receiver (x) type T, the generated code looks like: // For x.M with receiver (x) type T, the generated code looks like:
// //
......
...@@ -321,7 +321,7 @@ func walkselect(sel *Node) { ...@@ -321,7 +321,7 @@ func walkselect(sel *Node) {
out: out:
sel.List = nil sel.List = nil
walkstmtslice(sel.Nbody.Slice()) walkstmtlist(sel.Nbody)
lineno = lno lineno = lno
} }
......
...@@ -534,11 +534,11 @@ func simplename(n *Node) bool { ...@@ -534,11 +534,11 @@ func simplename(n *Node) bool {
return true return true
} }
func litas(l *Node, r *Node, init **NodeList) { func litas(l *Node, r *Node, init nodesOrNodeListPtr) {
a := Nod(OAS, l, r) a := Nod(OAS, l, r)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
const ( const (
...@@ -576,7 +576,7 @@ func getdyn(n *Node, top int) int { ...@@ -576,7 +576,7 @@ func getdyn(n *Node, top int) int {
return mode return mode
} }
func structlit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) { func structlit(ctxt int, pass int, n *Node, var_ *Node, init nodesOrNodeListPtr) {
for nl := n.List; nl != nil; nl = nl.Next { for nl := n.List; nl != nil; nl = nl.Next {
r := nl.N r := nl.N
if r.Op != OKEY { if r.Op != OKEY {
...@@ -637,11 +637,11 @@ func structlit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) { ...@@ -637,11 +637,11 @@ func structlit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) {
walkstmt(&a) walkstmt(&a)
} }
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
} }
func arraylit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) { func arraylit(ctxt int, pass int, n *Node, var_ *Node, init nodesOrNodeListPtr) {
for l := n.List; l != nil; l = l.Next { for l := n.List; l != nil; l = l.Next {
r := l.N r := l.N
if r.Op != OKEY { if r.Op != OKEY {
...@@ -702,11 +702,11 @@ func arraylit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) { ...@@ -702,11 +702,11 @@ func arraylit(ctxt int, pass int, n *Node, var_ *Node, init **NodeList) {
walkstmt(&a) walkstmt(&a)
} }
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
} }
func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { func slicelit(ctxt int, n *Node, var_ *Node, init nodesOrNodeListPtr) {
// make an array type // make an array type
t := shallow(n.Type) t := shallow(n.Type)
...@@ -729,7 +729,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -729,7 +729,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a = Nod(OAS, var_, a) a = Nod(OAS, var_, a)
typecheck(&a, Etop) typecheck(&a, Etop)
a.Dodata = 2 a.Dodata = 2
*init = list(*init, a) appendNodeSeqNode(init, a)
return return
} }
...@@ -774,7 +774,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -774,7 +774,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
if vstat == nil { if vstat == nil {
a = Nod(OAS, x, nil) a = Nod(OAS, x, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) // zero new temp appendNodeSeqNode(init, a) // zero new temp
} }
a = Nod(OADDR, x, nil) a = Nod(OADDR, x, nil)
...@@ -783,7 +783,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -783,7 +783,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
if vstat == nil { if vstat == nil {
a = Nod(OAS, temp(t), nil) a = Nod(OAS, temp(t), nil)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) // zero new temp appendNodeSeqNode(init, a) // zero new temp
a = a.Left a = a.Left
} }
...@@ -796,7 +796,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -796,7 +796,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a = Nod(OAS, vauto, a) a = Nod(OAS, vauto, a)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
if vstat != nil { if vstat != nil {
// copy static to heap (4) // copy static to heap (4)
...@@ -805,7 +805,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -805,7 +805,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a = Nod(OAS, a, vstat) a = Nod(OAS, a, vstat)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
// make slice out of heap (5) // make slice out of heap (5)
...@@ -814,7 +814,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -814,7 +814,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
orderstmtinplace(&a) orderstmtinplace(&a)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
// put dynamics into slice (6) // put dynamics into slice (6)
for l := n.List; l != nil; l = l.Next { for l := n.List; l != nil; l = l.Next {
...@@ -853,11 +853,11 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -853,11 +853,11 @@ func slicelit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
orderstmtinplace(&a) orderstmtinplace(&a)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
} }
func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { func maplit(ctxt int, n *Node, var_ *Node, init nodesOrNodeListPtr) {
ctxt = 0 ctxt = 0
// make the map var // make the map var
...@@ -933,7 +933,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -933,7 +933,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
a.Dodata = 2 a.Dodata = 2
*init = list(*init, a) appendNodeSeqNode(init, a)
// build vstat[b].b = value; // build vstat[b].b = value;
setlineno(value) setlineno(value)
...@@ -945,7 +945,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -945,7 +945,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
a.Dodata = 2 a.Dodata = 2
*init = list(*init, a) appendNodeSeqNode(init, a)
b++ b++
} }
...@@ -977,7 +977,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -977,7 +977,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
// put in dynamic entries one-at-a-time // put in dynamic entries one-at-a-time
...@@ -1006,18 +1006,18 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1006,18 +1006,18 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a = Nod(OAS, key, r.Left) a = Nod(OAS, key, r.Left)
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
setlineno(r.Right) setlineno(r.Right)
a = Nod(OAS, val, r.Right) a = Nod(OAS, val, r.Right)
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
setlineno(val) setlineno(val)
a = Nod(OAS, Nod(OINDEX, var_, key), val) a = Nod(OAS, Nod(OINDEX, var_, key), val)
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
if nerr != nerrors { if nerr != nerrors {
break break
...@@ -1027,14 +1027,14 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1027,14 +1027,14 @@ func maplit(ctxt int, n *Node, var_ *Node, init **NodeList) {
if key != nil { if key != nil {
a = Nod(OVARKILL, key, nil) a = Nod(OVARKILL, key, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
a = Nod(OVARKILL, val, nil) a = Nod(OVARKILL, val, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
} }
func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { func anylit(ctxt int, n *Node, var_ *Node, init nodesOrNodeListPtr) {
t := n.Type t := n.Type
switch n.Op { switch n.Op {
default: default:
...@@ -1060,7 +1060,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1060,7 +1060,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a := Nod(OAS, var_, r) a := Nod(OAS, var_, r)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
var_ = Nod(OIND, var_, nil) var_ = Nod(OIND, var_, nil)
typecheck(&var_, Erv|Easgn) typecheck(&var_, Erv|Easgn)
...@@ -1083,7 +1083,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1083,7 +1083,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
// add expressions to automatic // add expressions to automatic
structlit(ctxt, 2, n, var_, init) structlit(ctxt, 2, n, var_, init)
...@@ -1101,7 +1101,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1101,7 +1101,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a := Nod(OAS, var_, nil) a := Nod(OAS, var_, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
structlit(ctxt, 3, n, var_, init) structlit(ctxt, 3, n, var_, init)
...@@ -1127,7 +1127,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1127,7 +1127,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
// add expressions to automatic // add expressions to automatic
arraylit(ctxt, 2, n, var_, init) arraylit(ctxt, 2, n, var_, init)
...@@ -1145,7 +1145,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1145,7 +1145,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
a := Nod(OAS, var_, nil) a := Nod(OAS, var_, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
arraylit(ctxt, 3, n, var_, init) arraylit(ctxt, 3, n, var_, init)
...@@ -1158,7 +1158,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) { ...@@ -1158,7 +1158,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
} }
} }
func oaslit(n *Node, init **NodeList) bool { func oaslit(n *Node, init nodesOrNodeListPtr) bool {
if n.Left == nil || n.Right == nil { if n.Left == nil || n.Right == nil {
// not a special composit literal assignment // not a special composit literal assignment
return false return false
......
...@@ -1651,15 +1651,15 @@ func Brrev(op Op) Op { ...@@ -1651,15 +1651,15 @@ func Brrev(op Op) Op {
// return side effect-free n, appending side effects to init. // return side effect-free n, appending side effects to init.
// result is assignable if n is. // result is assignable if n is.
func safeexpr(n *Node, init **NodeList) *Node { func safeexpr(n *Node, init nodesOrNodeListPtr) *Node {
if n == nil { if n == nil {
return nil return nil
} }
if n.Ninit != nil { if nodeSeqLen(n.Ninit) != 0 {
walkstmtlist(n.Ninit) walkstmtlist(n.Ninit)
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
} }
switch n.Op { switch n.Op {
...@@ -1710,18 +1710,18 @@ func safeexpr(n *Node, init **NodeList) *Node { ...@@ -1710,18 +1710,18 @@ func safeexpr(n *Node, init **NodeList) *Node {
return cheapexpr(n, init) return cheapexpr(n, init)
} }
func copyexpr(n *Node, t *Type, init **NodeList) *Node { func copyexpr(n *Node, t *Type, init nodesOrNodeListPtr) *Node {
l := temp(t) l := temp(t)
a := Nod(OAS, l, n) a := Nod(OAS, l, n)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*init = list(*init, a) appendNodeSeqNode(init, a)
return l return l
} }
// return side-effect free and cheap n, appending side effects to init. // return side-effect free and cheap n, appending side effects to init.
// result may not be assignable. // result may not be assignable.
func cheapexpr(n *Node, init **NodeList) *Node { func cheapexpr(n *Node, init nodesOrNodeListPtr) *Node {
switch n.Op { switch n.Op {
case ONAME, OLITERAL: case ONAME, OLITERAL:
return n return n
...@@ -2804,7 +2804,7 @@ func isbadimport(path string) bool { ...@@ -2804,7 +2804,7 @@ func isbadimport(path string) bool {
return false return false
} }
func checknil(x *Node, init **NodeList) { func checknil(x *Node, init nodesOrNodeListPtr) {
if Isinter(x.Type) { if Isinter(x.Type) {
x = Nod(OITAB, x, nil) x = Nod(OITAB, x, nil)
typecheck(&x, Erv) typecheck(&x, Erv)
...@@ -2812,7 +2812,7 @@ func checknil(x *Node, init **NodeList) { ...@@ -2812,7 +2812,7 @@ func checknil(x *Node, init **NodeList) {
n := Nod(OCHECKNIL, x, nil) n := Nod(OCHECKNIL, x, nil)
n.Typecheck = 1 n.Typecheck = 1
*init = list(*init, n) appendNodeSeqNode(init, n)
} }
// Can this type be stored directly in an interface word? // Can this type be stored directly in an interface word?
......
...@@ -279,7 +279,7 @@ func (s *exprSwitch) walk(sw *Node) { ...@@ -279,7 +279,7 @@ func (s *exprSwitch) walk(sw *Node) {
if nerrors == 0 { if nerrors == 0 {
cas = append(cas, def) cas = append(cas, def)
sw.Nbody.Set(append(cas, sw.Nbody.Slice()...)) sw.Nbody.Set(append(cas, sw.Nbody.Slice()...))
walkstmtslice(sw.Nbody.Slice()) walkstmtlist(sw.Nbody)
} }
} }
...@@ -670,7 +670,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -670,7 +670,7 @@ func (s *typeSwitch) walk(sw *Node) {
cas = append(cas, def) cas = append(cas, def)
sw.Nbody.Set(append(cas, sw.Nbody.Slice()...)) sw.Nbody.Set(append(cas, sw.Nbody.Slice()...))
sw.List = nil sw.List = nil
walkstmtslice(sw.Nbody.Slice()) walkstmtlist(sw.Nbody)
} }
} }
......
...@@ -587,13 +587,17 @@ func (ni *nodesIterator) Seq() nodesOrNodeList { ...@@ -587,13 +587,17 @@ func (ni *nodesIterator) Seq() nodesOrNodeList {
return r return r
} }
// nodeSeqIterate returns an iterator over either a *NodeList or a Nodes. // nodeSeqIterate returns an iterator over a *NodeList, a Nodes, or a []*Node.
func nodeSeqIterate(ns nodesOrNodeList) nodeSeqIterator { func nodeSeqIterate(ns nodesOrNodeList) nodeSeqIterator {
switch ns := ns.(type) { switch ns := ns.(type) {
case *NodeList: case *NodeList:
return &nodeListIterator{ns} return &nodeListIterator{ns}
case Nodes: case Nodes:
return &nodesIterator{ns, 0} return &nodesIterator{ns, 0}
case []*Node:
var r Nodes
r.Set(ns)
return &nodesIterator{r, 0}
default: default:
panic("can't happen") panic("can't happen")
} }
......
...@@ -64,7 +64,7 @@ func walk(fn *Node) { ...@@ -64,7 +64,7 @@ func walk(fn *Node) {
if nerrors != 0 { if nerrors != 0 {
return return
} }
walkstmtslice(Curfn.Nbody.Slice()) walkstmtlist(Curfn.Nbody)
if Debug['W'] != 0 { if Debug['W'] != 0 {
s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym) s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
dumpslice(s, Curfn.Nbody.Slice()) dumpslice(s, Curfn.Nbody.Slice())
...@@ -77,9 +77,9 @@ func walk(fn *Node) { ...@@ -77,9 +77,9 @@ func walk(fn *Node) {
} }
} }
func walkstmtlist(l *NodeList) { func walkstmtlist(l nodesOrNodeList) {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
walkstmt(&l.N) walkstmt(it.P())
} }
} }
...@@ -122,8 +122,8 @@ func adjustargs(n *Node, adjust int) { ...@@ -122,8 +122,8 @@ func adjustargs(n *Node, adjust int) {
var lhs *Node var lhs *Node
callfunc := n.Left callfunc := n.Left
for args := callfunc.List; args != nil; args = args.Next { for argsit := nodeSeqIterate(callfunc.List); !argsit.Done(); argsit.Next() {
arg = args.N arg = argsit.N()
if arg.Op != OAS { if arg.Op != OAS {
Yyerror("call arg not assignment") Yyerror("call arg not assignment")
} }
...@@ -192,7 +192,7 @@ func walkstmt(np **Node) { ...@@ -192,7 +192,7 @@ func walkstmt(np **Node) {
Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign)) Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign))
} }
init := n.Ninit init := n.Ninit
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
walkexpr(&n, &init) walkexpr(&n, &init)
addinit(&n, init) addinit(&n, init)
if (*np).Op == OCOPY && n.Op == OCONVNOP { if (*np).Op == OCOPY && n.Op == OCONVNOP {
...@@ -206,7 +206,7 @@ func walkstmt(np **Node) { ...@@ -206,7 +206,7 @@ func walkstmt(np **Node) {
Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign)) Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign))
} }
init := n.Ninit init := n.Ninit
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
walkexpr(&n.Left, &init) walkexpr(&n.Left, &init)
n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, typename(n.Left.Type), n.Left, nodnil()) n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, typename(n.Left.Type), n.Left, nodnil())
...@@ -258,17 +258,17 @@ func walkstmt(np **Node) { ...@@ -258,17 +258,17 @@ func walkstmt(np **Node) {
if n.Left != nil { if n.Left != nil {
walkstmtlist(n.Left.Ninit) walkstmtlist(n.Left.Ninit)
init := n.Left.Ninit init := n.Left.Ninit
n.Left.Ninit = nil setNodeSeq(&n.Left.Ninit, nil)
walkexpr(&n.Left, &init) walkexpr(&n.Left, &init)
addinit(&n.Left, init) addinit(&n.Left, init)
} }
walkstmt(&n.Right) walkstmt(&n.Right)
walkstmtslice(n.Nbody.Slice()) walkstmtlist(n.Nbody)
case OIF: case OIF:
walkexpr(&n.Left, &n.Ninit) walkexpr(&n.Left, &n.Ninit)
walkstmtslice(n.Nbody.Slice()) walkstmtlist(n.Nbody)
walkstmtlist(n.Rlist) walkstmtlist(n.Rlist)
case OPROC: case OPROC:
...@@ -288,10 +288,10 @@ func walkstmt(np **Node) { ...@@ -288,10 +288,10 @@ func walkstmt(np **Node) {
case ORETURN: case ORETURN:
walkexprlist(n.List, &n.Ninit) walkexprlist(n.List, &n.Ninit)
if n.List == nil { if nodeSeqLen(n.List) == 0 {
break break
} }
if (Curfn.Type.Outnamed && count(n.List) > 1) || paramoutheap(Curfn) { if (Curfn.Type.Outnamed && nodeSeqLen(n.List) > 1) || paramoutheap(Curfn) {
// assign to the function out parameters, // assign to the function out parameters,
// so that reorder3 can fix up conflicts // so that reorder3 can fix up conflicts
var rl *NodeList var rl *NodeList
...@@ -307,7 +307,7 @@ func walkstmt(np **Node) { ...@@ -307,7 +307,7 @@ func walkstmt(np **Node) {
} }
} }
if got, want := count(n.List), count(rl); got != want { if got, want := nodeSeqLen(n.List), nodeSeqLen(rl); got != want {
// order should have rewritten multi-value function calls // order should have rewritten multi-value function calls
// with explicit OAS2FUNC nodes. // with explicit OAS2FUNC nodes.
Fatalf("expected %v return arguments, have %v", want, got) Fatalf("expected %v return arguments, have %v", want, got)
...@@ -315,7 +315,7 @@ func walkstmt(np **Node) { ...@@ -315,7 +315,7 @@ func walkstmt(np **Node) {
if samelist(rl, n.List) { if samelist(rl, n.List) {
// special return in disguise // special return in disguise
n.List = nil setNodeSeq(&n.List, nil)
break break
} }
...@@ -324,15 +324,15 @@ func walkstmt(np **Node) { ...@@ -324,15 +324,15 @@ func walkstmt(np **Node) {
walkexprlistsafe(n.List, &n.Ninit) walkexprlistsafe(n.List, &n.Ninit)
ll := ascompatee(n.Op, rl, n.List, &n.Ninit) ll := ascompatee(n.Op, rl, n.List, &n.Ninit)
n.List = reorder3(ll) setNodeSeq(&n.List, reorder3(ll))
for lr := n.List; lr != nil; lr = lr.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
lr.N = applywritebarrier(lr.N) *it.P() = applywritebarrier(it.N())
} }
break break
} }
ll := ascompatte(n.Op, nil, false, Getoutarg(Curfn.Type), n.List, 1, &n.Ninit) ll := ascompatte(n.Op, nil, false, Getoutarg(Curfn.Type), n.List, 1, &n.Ninit)
n.List = ll setNodeSeq(&n.List, ll)
case ORETJMP: case ORETJMP:
break break
...@@ -377,27 +377,27 @@ func isSmallMakeSlice(n *Node) bool { ...@@ -377,27 +377,27 @@ func isSmallMakeSlice(n *Node) bool {
// the types expressions are calculated. // the types expressions are calculated.
// compile-time constants are evaluated. // compile-time constants are evaluated.
// complex side effects like statements are appended to init // complex side effects like statements are appended to init
func walkexprlist(l *NodeList, init **NodeList) { func walkexprlist(l nodesOrNodeList, init nodesOrNodeListPtr) {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
walkexpr(&l.N, init) walkexpr(it.P(), init)
} }
} }
func walkexprlistsafe(l *NodeList, init **NodeList) { func walkexprlistsafe(l nodesOrNodeList, init nodesOrNodeListPtr) {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
l.N = safeexpr(l.N, init) *it.P() = safeexpr(it.N(), init)
walkexpr(&l.N, init) walkexpr(it.P(), init)
} }
} }
func walkexprlistcheap(l *NodeList, init **NodeList) { func walkexprlistcheap(l nodesOrNodeList, init nodesOrNodeListPtr) {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
l.N = cheapexpr(l.N, init) *it.P() = cheapexpr(it.N(), init)
walkexpr(&l.N, init) walkexpr(it.P(), init)
} }
} }
func walkexpr(np **Node, init **NodeList) { func walkexpr(np **Node, init nodesOrNodeListPtr) {
n := *np n := *np
if n == nil { if n == nil {
...@@ -411,10 +411,10 @@ func walkexpr(np **Node, init **NodeList) { ...@@ -411,10 +411,10 @@ func walkexpr(np **Node, init **NodeList) {
Fatalf("walkexpr init == &n->ninit") Fatalf("walkexpr init == &n->ninit")
} }
if n.Ninit != nil { if nodeSeqLen(n.Ninit) != 0 {
walkstmtlist(n.Ninit) walkstmtlist(n.Ninit)
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
} }
// annoying case - not typechecked // annoying case - not typechecked
...@@ -519,8 +519,8 @@ opswitch: ...@@ -519,8 +519,8 @@ opswitch:
OCOMPLEX, OCOMPLEX,
OLROT: OLROT:
if n.Op == OCOMPLEX && n.Left == nil && n.Right == nil { if n.Op == OCOMPLEX && n.Left == nil && n.Right == nil {
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
n.Right = n.List.Next.N n.Right = nodeSeqSecond(n.List)
} }
walkexpr(&n.Left, init) walkexpr(&n.Left, init)
...@@ -580,13 +580,13 @@ opswitch: ...@@ -580,13 +580,13 @@ opswitch:
case OCALLINTER: case OCALLINTER:
t := n.Left.Type t := n.Left.Type
if n.List != nil && n.List.N.Op == OAS { if nodeSeqLen(n.List) != 0 && nodeSeqFirst(n.List).Op == OAS {
break break
} }
walkexpr(&n.Left, init) walkexpr(&n.Left, init)
walkexprlist(n.List, init) walkexprlist(n.List, init)
ll := ascompatte(n.Op, n, n.Isddd, getinarg(t), n.List, 0, init) ll := ascompatte(n.Op, n, n.Isddd, getinarg(t), n.List, 0, init)
n.List = reorder1(ll) setNodeSeq(&n.List, reorder1(ll))
case OCALLFUNC: case OCALLFUNC:
if n.Left.Op == OCLOSURE { if n.Left.Op == OCLOSURE {
...@@ -594,7 +594,7 @@ opswitch: ...@@ -594,7 +594,7 @@ opswitch:
// transformclosure already did all preparation work. // transformclosure already did all preparation work.
// Prepend captured variables to argument list. // Prepend captured variables to argument list.
n.List = concat(n.Left.Func.Enter.NodeList(), n.List) setNodeSeq(&n.List, concat(n.Left.Func.Enter.NodeList(), n.List))
n.Left.Func.Enter.Set(nil) n.Left.Func.Enter.Set(nil)
...@@ -615,7 +615,7 @@ opswitch: ...@@ -615,7 +615,7 @@ opswitch:
} }
t := n.Left.Type t := n.Left.Type
if n.List != nil && n.List.N.Op == OAS { if nodeSeqLen(n.List) != 0 && nodeSeqFirst(n.List).Op == OAS {
break break
} }
...@@ -626,18 +626,18 @@ opswitch: ...@@ -626,18 +626,18 @@ opswitch:
switch Thearch.Thechar { switch Thearch.Thechar {
case '5', '6', '7': case '5', '6', '7':
n.Op = OSQRT n.Op = OSQRT
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
n.List = nil setNodeSeq(&n.List, nil)
break opswitch break opswitch
} }
} }
ll := ascompatte(n.Op, n, n.Isddd, getinarg(t), n.List, 0, init) ll := ascompatte(n.Op, n, n.Isddd, getinarg(t), n.List, 0, init)
n.List = reorder1(ll) setNodeSeq(&n.List, reorder1(ll))
case OCALLMETH: case OCALLMETH:
t := n.Left.Type t := n.Left.Type
if n.List != nil && n.List.N.Op == OAS { if nodeSeqLen(n.List) != 0 && nodeSeqFirst(n.List).Op == OAS {
break break
} }
walkexpr(&n.Left, init) walkexpr(&n.Left, init)
...@@ -647,11 +647,11 @@ opswitch: ...@@ -647,11 +647,11 @@ opswitch:
ll = concat(ll, lr) ll = concat(ll, lr)
n.Left.Left = nil n.Left.Left = nil
ullmancalc(n.Left) ullmancalc(n.Left)
n.List = reorder1(ll) setNodeSeq(&n.List, reorder1(ll))
case OAS: case OAS:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
walkexpr(&n.Left, init) walkexpr(&n.Left, init)
n.Left = safeexpr(n.Left, init) n.Left = safeexpr(n.Left, init)
...@@ -734,8 +734,8 @@ opswitch: ...@@ -734,8 +734,8 @@ opswitch:
} }
case OAS2: case OAS2:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
walkexprlistsafe(n.Rlist, init) walkexprlistsafe(n.Rlist, init)
ll := ascompatee(OAS, n.List, n.Rlist, init) ll := ascompatee(OAS, n.List, n.Rlist, init)
...@@ -747,10 +747,10 @@ opswitch: ...@@ -747,10 +747,10 @@ opswitch:
// a,b,... = fn() // a,b,... = fn()
case OAS2FUNC: case OAS2FUNC:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
r := n.Rlist.N r := nodeSeqFirst(n.Rlist)
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
walkexpr(&r, init) walkexpr(&r, init)
...@@ -763,30 +763,30 @@ opswitch: ...@@ -763,30 +763,30 @@ opswitch:
// x, y = <-c // x, y = <-c
// orderstmt made sure x is addressable. // orderstmt made sure x is addressable.
case OAS2RECV: case OAS2RECV:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
r := n.Rlist.N r := nodeSeqFirst(n.Rlist)
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
walkexpr(&r.Left, init) walkexpr(&r.Left, init)
var n1 *Node var n1 *Node
if isblank(n.List.N) { if isblank(nodeSeqFirst(n.List)) {
n1 = nodnil() n1 = nodnil()
} else { } else {
n1 = Nod(OADDR, n.List.N, nil) n1 = Nod(OADDR, nodeSeqFirst(n.List), nil)
} }
n1.Etype = 1 // addr does not escape n1.Etype = 1 // addr does not escape
fn := chanfn("chanrecv2", 2, r.Left.Type) fn := chanfn("chanrecv2", 2, r.Left.Type)
r = mkcall1(fn, n.List.Next.N.Type, init, typename(r.Left.Type), r.Left, n1) r = mkcall1(fn, nodeSeqSecond(n.List).Type, init, typename(r.Left.Type), r.Left, n1)
n = Nod(OAS, n.List.Next.N, r) n = Nod(OAS, nodeSeqSecond(n.List), r)
typecheck(&n, Etop) typecheck(&n, Etop)
// a,b = m[i]; // a,b = m[i];
case OAS2MAPR: case OAS2MAPR:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
r := n.Rlist.N r := nodeSeqFirst(n.Rlist)
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
walkexpr(&r.Left, init) walkexpr(&r.Left, init)
walkexpr(&r.Right, init) walkexpr(&r.Right, init)
...@@ -820,7 +820,7 @@ opswitch: ...@@ -820,7 +820,7 @@ opswitch:
// to: // to:
// var,b = mapaccess2*(t, m, i) // var,b = mapaccess2*(t, m, i)
// a = *var // a = *var
a := n.List.N a := nodeSeqFirst(n.List)
fn := mapfn(p, t) fn := mapfn(p, t)
r = mkcall1(fn, getoutargx(fn.Type), init, typename(t), r.Left, key) r = mkcall1(fn, getoutargx(fn.Type), init, typename(t), r.Left, key)
...@@ -828,19 +828,20 @@ opswitch: ...@@ -828,19 +828,20 @@ opswitch:
// mapaccess2* returns a typed bool, but due to spec changes, // mapaccess2* returns a typed bool, but due to spec changes,
// the boolean result of i.(T) is now untyped so we make it the // the boolean result of i.(T) is now untyped so we make it the
// same type as the variable on the lhs. // same type as the variable on the lhs.
if !isblank(n.List.Next.N) { if !isblank(nodeSeqSecond(n.List)) {
r.Type.Type.Down.Type = n.List.Next.N.Type r.Type.Type.Down.Type = nodeSeqSecond(n.List).Type
} }
n.Rlist = list1(r) setNodeSeq(&n.Rlist, list1(r))
n.Op = OAS2FUNC n.Op = OAS2FUNC
// don't generate a = *var if a is _ // don't generate a = *var if a is _
if !isblank(a) { if !isblank(a) {
var_ := temp(Ptrto(t.Type)) var_ := temp(Ptrto(t.Type))
var_.Typecheck = 1 var_.Typecheck = 1
n.List.N = var_ it := nodeSeqIterate(n.List)
*it.P() = var_
walkexpr(&n, init) walkexpr(&n, init)
*init = list(*init, n) appendNodeSeqNode(init, n)
n = Nod(OAS, a, Nod(OIND, var_, nil)) n = Nod(OAS, a, Nod(OIND, var_, nil))
} }
...@@ -850,10 +851,10 @@ opswitch: ...@@ -850,10 +851,10 @@ opswitch:
// TODO: ptr is always non-nil, so disable nil check for this OIND op. // TODO: ptr is always non-nil, so disable nil check for this OIND op.
case ODELETE: case ODELETE:
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
map_ := n.List.N map_ := nodeSeqFirst(n.List)
key := n.List.Next.N key := nodeSeqSecond(n.List)
walkexpr(&map_, init) walkexpr(&map_, init)
walkexpr(&key, init) walkexpr(&key, init)
...@@ -864,7 +865,7 @@ opswitch: ...@@ -864,7 +865,7 @@ opswitch:
n = mkcall1(mapfndel("mapdelete", t), nil, init, typename(t), map_, key) n = mkcall1(mapfndel("mapdelete", t), nil, init, typename(t), map_, key)
case OAS2DOTTYPE: case OAS2DOTTYPE:
e := n.Rlist.N // i.(T) e := nodeSeqFirst(n.Rlist) // i.(T)
// TODO(rsc): The Isfat is for consistency with componentgen and orderexpr. // TODO(rsc): The Isfat is for consistency with componentgen and orderexpr.
// It needs to be removed in all three places. // It needs to be removed in all three places.
// That would allow inlining x.(struct{*int}) the same as x.(*int). // That would allow inlining x.(struct{*int}) the same as x.(*int).
...@@ -877,8 +878,8 @@ opswitch: ...@@ -877,8 +878,8 @@ opswitch:
// res, ok = i.(T) // res, ok = i.(T)
// orderstmt made sure a is addressable. // orderstmt made sure a is addressable.
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
walkexpr(&e.Left, init) walkexpr(&e.Left, init)
...@@ -886,7 +887,7 @@ opswitch: ...@@ -886,7 +887,7 @@ opswitch:
from := e.Left // i from := e.Left // i
oktype := Types[TBOOL] oktype := Types[TBOOL]
ok := n.List.Next.N ok := nodeSeqSecond(n.List)
if !isblank(ok) { if !isblank(ok) {
oktype = ok.Type oktype = ok.Type
} }
...@@ -897,7 +898,7 @@ opswitch: ...@@ -897,7 +898,7 @@ opswitch:
// Avoid runtime calls in a few cases of the form _, ok := i.(T). // Avoid runtime calls in a few cases of the form _, ok := i.(T).
// This is faster and shorter and allows the corresponding assertX2X2 // This is faster and shorter and allows the corresponding assertX2X2
// routines to skip nil checks on their last argument. // routines to skip nil checks on their last argument.
if isblank(n.List.N) { if isblank(nodeSeqFirst(n.List)) {
var fast *Node var fast *Node
switch { switch {
case fromKind == "E" && toKind == "T": case fromKind == "E" && toKind == "T":
...@@ -921,10 +922,10 @@ opswitch: ...@@ -921,10 +922,10 @@ opswitch:
} }
var resptr *Node // &res var resptr *Node // &res
if isblank(n.List.N) { if isblank(nodeSeqFirst(n.List)) {
resptr = nodnil() resptr = nodnil()
} else { } else {
resptr = Nod(OADDR, n.List.N, nil) resptr = Nod(OADDR, nodeSeqFirst(n.List), nil)
} }
resptr.Etype = 1 // addr does not escape resptr.Etype = 1 // addr does not escape
...@@ -999,11 +1000,11 @@ opswitch: ...@@ -999,11 +1000,11 @@ opswitch:
n1 := Nod(OAS, l, sym.Def) n1 := Nod(OAS, l, sym.Def)
typecheck(&n1, Etop) typecheck(&n1, Etop)
*init = list(*init, n1) appendNodeSeqNode(init, n1)
fn := syslook("typ2Itab", 1) fn := syslook("typ2Itab", 1)
n1 = Nod(OCALL, fn, nil) n1 = Nod(OCALL, fn, nil)
n1.List = ll setNodeSeq(&n1.List, ll)
typecheck(&n1, Erv) typecheck(&n1, Erv)
walkexpr(&n1, init) walkexpr(&n1, init)
...@@ -1012,7 +1013,7 @@ opswitch: ...@@ -1012,7 +1013,7 @@ opswitch:
n2.Nbody.Set([]*Node{Nod(OAS, l, n1)}) n2.Nbody.Set([]*Node{Nod(OAS, l, n1)})
n2.Likely = -1 n2.Likely = -1
typecheck(&n2, Etop) typecheck(&n2, Etop)
*init = list(*init, n2) appendNodeSeqNode(init, n2)
l = Nod(OEFACE, l, n.Left) l = Nod(OEFACE, l, n.Left)
l.Typecheck = n.Typecheck l.Typecheck = n.Typecheck
...@@ -1043,7 +1044,7 @@ opswitch: ...@@ -1043,7 +1044,7 @@ opswitch:
r = temp(n.Left.Type) r = temp(n.Left.Type)
r = Nod(OAS, r, nil) // zero temp r = Nod(OAS, r, nil) // zero temp
typecheck(&r, Etop) typecheck(&r, Etop)
*init = list(*init, r) appendNodeSeqNode(init, r)
r = Nod(OADDR, r.Left, nil) r = Nod(OADDR, r.Left, nil)
typecheck(&r, Erv) typecheck(&r, Erv)
} }
...@@ -1057,7 +1058,7 @@ opswitch: ...@@ -1057,7 +1058,7 @@ opswitch:
} }
dowidth(fn.Type) dowidth(fn.Type)
n = Nod(OCALL, fn, nil) n = Nod(OCALL, fn, nil)
n.List = ll setNodeSeq(&n.List, ll)
typecheck(&n, Erv) typecheck(&n, Erv)
walkexpr(&n, init) walkexpr(&n, init)
...@@ -1280,7 +1281,7 @@ opswitch: ...@@ -1280,7 +1281,7 @@ opswitch:
r := temp(n.Type.Type) r := temp(n.Type.Type)
r = Nod(OAS, r, nil) // zero temp r = Nod(OAS, r, nil) // zero temp
typecheck(&r, Etop) typecheck(&r, Etop)
*init = list(*init, r) appendNodeSeqNode(init, r)
r = Nod(OADDR, r.Left, nil) r = Nod(OADDR, r.Left, nil)
typecheck(&r, Erv) typecheck(&r, Erv)
n = r n = r
...@@ -1303,9 +1304,9 @@ opswitch: ...@@ -1303,9 +1304,9 @@ opswitch:
} }
// s + "badgerbadgerbadger" == "badgerbadgerbadger" // s + "badgerbadgerbadger" == "badgerbadgerbadger"
if (Op(n.Etype) == OEQ || Op(n.Etype) == ONE) && Isconst(n.Right, CTSTR) && n.Left.Op == OADDSTR && count(n.Left.List) == 2 && Isconst(n.Left.List.Next.N, CTSTR) && strlit(n.Right) == strlit(n.Left.List.Next.N) { if (Op(n.Etype) == OEQ || Op(n.Etype) == ONE) && Isconst(n.Right, CTSTR) && n.Left.Op == OADDSTR && nodeSeqLen(n.Left.List) == 2 && Isconst(nodeSeqSecond(n.Left.List), CTSTR) && strlit(n.Right) == strlit(nodeSeqSecond(n.Left.List)) {
// TODO(marvin): Fix Node.EType type union. // TODO(marvin): Fix Node.EType type union.
r := Nod(Op(n.Etype), Nod(OLEN, n.Left.List.N, nil), Nodintconst(0)) r := Nod(Op(n.Etype), Nod(OLEN, nodeSeqFirst(n.Left.List), nil), Nodintconst(0))
typecheck(&r, Erv) typecheck(&r, Erv)
walkexpr(&r, init) walkexpr(&r, init)
r.Type = n.Type r.Type = n.Type
...@@ -1386,7 +1387,7 @@ opswitch: ...@@ -1386,7 +1387,7 @@ opswitch:
a = Nod(OAS, var_, nil) // zero temp a = Nod(OAS, var_, nil) // zero temp
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
a = Nod(OADDR, var_, nil) a = Nod(OADDR, var_, nil)
// Allocate one bucket on stack. // Allocate one bucket on stack.
...@@ -1396,7 +1397,7 @@ opswitch: ...@@ -1396,7 +1397,7 @@ opswitch:
r = Nod(OAS, var_, nil) // zero temp r = Nod(OAS, var_, nil) // zero temp
typecheck(&r, Etop) typecheck(&r, Etop)
*init = list(*init, r) appendNodeSeqNode(init, r)
r = Nod(OADDR, var_, nil) r = Nod(OADDR, var_, nil)
} }
...@@ -1421,7 +1422,7 @@ opswitch: ...@@ -1421,7 +1422,7 @@ opswitch:
var_ := temp(t) var_ := temp(t)
a := Nod(OAS, var_, nil) // zero temp a := Nod(OAS, var_, nil) // zero temp
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
r := Nod(OSLICE, var_, Nod(OKEY, nil, l)) // arr[:l] r := Nod(OSLICE, var_, Nod(OKEY, nil, l)) // arr[:l]
r = conv(r, n.Type) // in case n.Type is named. r = conv(r, n.Type) // in case n.Type is named.
typecheck(&r, Erv) typecheck(&r, Erv)
...@@ -1596,7 +1597,7 @@ func reduceSlice(n *Node) *Node { ...@@ -1596,7 +1597,7 @@ func reduceSlice(n *Node) *Node {
return n return n
} }
func ascompatee1(op Op, l *Node, r *Node, init **NodeList) *Node { func ascompatee1(op Op, l *Node, r *Node, init nodesOrNodeListPtr) *Node {
// convas will turn map assigns into function calls, // convas will turn map assigns into function calls,
// making it impossible for reorder3 to work. // making it impossible for reorder3 to work.
n := Nod(OAS, l, r) n := Nod(OAS, l, r)
...@@ -1608,7 +1609,7 @@ func ascompatee1(op Op, l *Node, r *Node, init **NodeList) *Node { ...@@ -1608,7 +1609,7 @@ func ascompatee1(op Op, l *Node, r *Node, init **NodeList) *Node {
return convas(n, init) return convas(n, init)
} }
func ascompatee(op Op, nl *NodeList, nr *NodeList, init **NodeList) *NodeList { func ascompatee(op Op, nl *NodeList, nr *NodeList, init nodesOrNodeListPtr) *NodeList {
// check assign expression list to // check assign expression list to
// a expression list. called in // a expression list. called in
// expr-list = expr-list // expr-list = expr-list
...@@ -1657,7 +1658,7 @@ func fncall(l *Node, rt *Type) bool { ...@@ -1657,7 +1658,7 @@ func fncall(l *Node, rt *Type) bool {
return true return true
} }
func ascompatet(op Op, nl *NodeList, nr **Type, fp int, init **NodeList) *NodeList { func ascompatet(op Op, nl *NodeList, nr **Type, fp int, init nodesOrNodeListPtr) *NodeList {
var l *Node var l *Node
var tmp *Node var tmp *Node
var a *Node var a *Node
...@@ -1717,7 +1718,7 @@ func ascompatet(op Op, nl *NodeList, nr **Type, fp int, init **NodeList) *NodeLi ...@@ -1717,7 +1718,7 @@ func ascompatet(op Op, nl *NodeList, nr **Type, fp int, init **NodeList) *NodeLi
} }
// package all the arguments that match a ... T parameter into a []T. // package all the arguments that match a ... T parameter into a []T.
func mkdotargslice(lr0 nodesOrNodeList, nn *NodeList, l *Type, fp int, init **NodeList, ddd *Node) *NodeList { func mkdotargslice(lr0 nodesOrNodeList, nn *NodeList, l *Type, fp int, init nodesOrNodeListPtr, ddd *Node) *NodeList {
esc := uint16(EscUnknown) esc := uint16(EscUnknown)
if ddd != nil { if ddd != nil {
esc = ddd.Esc esc = ddd.Esc
...@@ -1798,7 +1799,7 @@ func dumpnodetypes(l nodesOrNodeList, what string) string { ...@@ -1798,7 +1799,7 @@ func dumpnodetypes(l nodesOrNodeList, what string) string {
// a type list. called in // a type list. called in
// return expr-list // return expr-list
// func(expr-list) // func(expr-list)
func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr nodesOrNodeList, fp int, init **NodeList) *NodeList { func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr nodesOrNodeList, fp int, init nodesOrNodeListPtr) *NodeList {
var savel Iter var savel Iter
lr0 := lr lr0 := lr
...@@ -1835,11 +1836,11 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr nodesOrNodeList, fp ...@@ -1835,11 +1836,11 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr nodesOrNodeList, fp
} }
a = Nod(OAS2, nil, nil) a = Nod(OAS2, nil, nil)
a.List = alist setNodeSeq(&a.List, alist)
setNodeSeq(&a.Rlist, lr) setNodeSeq(&a.Rlist, lr)
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
*init = list(*init, a) appendNodeSeqNode(init, a)
lr = alist lr = alist
r = nodeSeqFirst(lr) r = nodeSeqFirst(lr)
l = Structfirst(&savel, nl) l = Structfirst(&savel, nl)
...@@ -1908,7 +1909,7 @@ ret: ...@@ -1908,7 +1909,7 @@ ret:
} }
// generate code for print // generate code for print
func walkprint(nn *Node, init **NodeList) *Node { func walkprint(nn *Node, init nodesOrNodeListPtr) *Node {
var r *Node var r *Node
var n *Node var n *Node
var on *Node var on *Node
...@@ -1925,14 +1926,14 @@ func walkprint(nn *Node, init **NodeList) *Node { ...@@ -1925,14 +1926,14 @@ func walkprint(nn *Node, init **NodeList) *Node {
calls = list(calls, mkcall("printlock", nil, init)) calls = list(calls, mkcall("printlock", nil, init))
for l := all; l != nil; l = l.Next { for it := nodeSeqIterate(all); !it.Done(); it.Next() {
if notfirst { if notfirst {
calls = list(calls, mkcall("printsp", nil, init)) calls = list(calls, mkcall("printsp", nil, init))
} }
notfirst = op == OPRINTN notfirst = op == OPRINTN
n = l.N n = it.N()
if n.Op == OLITERAL { if n.Op == OLITERAL {
switch n.Val().Ctype() { switch n.Val().Ctype() {
case CTRUNE: case CTRUNE:
...@@ -1950,7 +1951,7 @@ func walkprint(nn *Node, init **NodeList) *Node { ...@@ -1950,7 +1951,7 @@ func walkprint(nn *Node, init **NodeList) *Node {
defaultlit(&n, Types[TINT64]) defaultlit(&n, Types[TINT64])
} }
defaultlit(&n, nil) defaultlit(&n, nil)
l.N = n *it.P() = n
if n.Type == nil || n.Type.Etype == TFORW { if n.Type == nil || n.Type.Etype == TFORW {
continue continue
} }
...@@ -2007,7 +2008,7 @@ func walkprint(nn *Node, init **NodeList) *Node { ...@@ -2007,7 +2008,7 @@ func walkprint(nn *Node, init **NodeList) *Node {
} }
r = Nod(OCALL, on, nil) r = Nod(OCALL, on, nil)
r.List = list1(n) appendNodeSeqNode(&r.List, n)
calls = list(calls, r) calls = list(calls, r)
} }
...@@ -2023,7 +2024,7 @@ func walkprint(nn *Node, init **NodeList) *Node { ...@@ -2023,7 +2024,7 @@ func walkprint(nn *Node, init **NodeList) *Node {
r = Nod(OEMPTY, nil, nil) r = Nod(OEMPTY, nil, nil)
typecheck(&r, Etop) typecheck(&r, Etop)
walkexpr(&r, init) walkexpr(&r, init)
r.Ninit = calls setNodeSeq(&r.Ninit, calls)
return r return r
} }
...@@ -2152,7 +2153,7 @@ func applywritebarrier(n *Node) *Node { ...@@ -2152,7 +2153,7 @@ func applywritebarrier(n *Node) *Node {
return n return n
} }
func convas(n *Node, init **NodeList) *Node { func convas(n *Node, init nodesOrNodeListPtr) *Node {
if n.Op != OAS { if n.Op != OAS {
Fatalf("convas: not OAS %v", Oconv(int(n.Op), 0)) Fatalf("convas: not OAS %v", Oconv(int(n.Op), 0))
} }
...@@ -2498,8 +2499,8 @@ func vmatch2(l *Node, r *Node) bool { ...@@ -2498,8 +2499,8 @@ func vmatch2(l *Node, r *Node) bool {
if vmatch2(l, r.Right) { if vmatch2(l, r.Right) {
return true return true
} }
for ll := r.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(r.List); !it.Done(); it.Next() {
if vmatch2(l, ll.N) { if vmatch2(l, it.N()) {
return true return true
} }
} }
...@@ -2539,8 +2540,8 @@ func vmatch1(l *Node, r *Node) bool { ...@@ -2539,8 +2540,8 @@ func vmatch1(l *Node, r *Node) bool {
if vmatch1(l.Right, r) { if vmatch1(l.Right, r) {
return true return true
} }
for ll := l.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
if vmatch1(ll.N, r) { if vmatch1(it.N(), r) {
return true return true
} }
} }
...@@ -2627,19 +2628,15 @@ func heapmoves() { ...@@ -2627,19 +2628,15 @@ func heapmoves() {
lineno = lno lineno = lno
} }
func vmkcall(fn *Node, t *Type, init **NodeList, va []*Node) *Node { func vmkcall(fn *Node, t *Type, init nodesOrNodeListPtr, va []*Node) *Node {
if fn.Type == nil || fn.Type.Etype != TFUNC { if fn.Type == nil || fn.Type.Etype != TFUNC {
Fatalf("mkcall %v %v", fn, fn.Type) Fatalf("mkcall %v %v", fn, fn.Type)
} }
var args *NodeList
n := fn.Type.Intuple n := fn.Type.Intuple
for i := 0; i < n; i++ {
args = list(args, va[i])
}
r := Nod(OCALL, fn, nil) r := Nod(OCALL, fn, nil)
r.List = args setNodeSeq(&r.List, va[:n])
if fn.Type.Outtuple > 0 { if fn.Type.Outtuple > 0 {
typecheck(&r, Erv|Efnstruct) typecheck(&r, Erv|Efnstruct)
} else { } else {
...@@ -2650,11 +2647,11 @@ func vmkcall(fn *Node, t *Type, init **NodeList, va []*Node) *Node { ...@@ -2650,11 +2647,11 @@ func vmkcall(fn *Node, t *Type, init **NodeList, va []*Node) *Node {
return r return r
} }
func mkcall(name string, t *Type, init **NodeList, args ...*Node) *Node { func mkcall(name string, t *Type, init nodesOrNodeListPtr, args ...*Node) *Node {
return vmkcall(syslook(name, 0), t, init, args) return vmkcall(syslook(name, 0), t, init, args)
} }
func mkcall1(fn *Node, t *Type, init **NodeList, args ...*Node) *Node { func mkcall1(fn *Node, t *Type, init nodesOrNodeListPtr, args ...*Node) *Node {
return vmkcall(fn, t, init, args) return vmkcall(fn, t, init, args)
} }
...@@ -2708,9 +2705,9 @@ func writebarrierfn(name string, l *Type, r *Type) *Node { ...@@ -2708,9 +2705,9 @@ func writebarrierfn(name string, l *Type, r *Type) *Node {
return fn return fn
} }
func addstr(n *Node, init **NodeList) *Node { func addstr(n *Node, init nodesOrNodeListPtr) *Node {
// orderexpr rewrote OADDSTR to have a list of strings. // orderexpr rewrote OADDSTR to have a list of strings.
c := count(n.List) c := nodeSeqLen(n.List)
if c < 2 { if c < 2 {
Yyerror("addstr count %d too small", c) Yyerror("addstr count %d too small", c)
...@@ -2719,9 +2716,9 @@ func addstr(n *Node, init **NodeList) *Node { ...@@ -2719,9 +2716,9 @@ func addstr(n *Node, init **NodeList) *Node {
buf := nodnil() buf := nodnil()
if n.Esc == EscNone { if n.Esc == EscNone {
sz := int64(0) sz := int64(0)
for l := n.List; l != nil; l = l.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if l.N.Op == OLITERAL { if it.N().Op == OLITERAL {
sz += int64(len(l.N.Val().U.(string))) sz += int64(len(it.N().Val().U.(string)))
} }
} }
...@@ -2735,10 +2732,10 @@ func addstr(n *Node, init **NodeList) *Node { ...@@ -2735,10 +2732,10 @@ func addstr(n *Node, init **NodeList) *Node {
} }
// build list of string arguments // build list of string arguments
args := list1(buf) args := []*Node{buf}
for l := n.List; l != nil; l = l.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
args = list(args, conv(l.N, Types[TSTRING])) args = append(args, conv(it.N(), Types[TSTRING]))
} }
var fn string var fn string
...@@ -2757,15 +2754,15 @@ func addstr(n *Node, init **NodeList) *Node { ...@@ -2757,15 +2754,15 @@ func addstr(n *Node, init **NodeList) *Node {
if prealloc[n] != nil { if prealloc[n] != nil {
prealloc[slice] = prealloc[n] prealloc[slice] = prealloc[n]
} }
slice.List = args.Next // skip buf arg setNodeSeq(&slice.List, args[1:]) // skip buf arg
args = list1(buf) args = []*Node{buf}
args = list(args, slice) args = append(args, slice)
slice.Esc = EscNone slice.Esc = EscNone
} }
cat := syslook(fn, 1) cat := syslook(fn, 1)
r := Nod(OCALL, cat, nil) r := Nod(OCALL, cat, nil)
r.List = args setNodeSeq(&r.List, args)
typecheck(&r, Erv) typecheck(&r, Erv)
walkexpr(&r, init) walkexpr(&r, init)
r.Type = n.Type r.Type = n.Type
...@@ -2785,29 +2782,29 @@ func addstr(n *Node, init **NodeList) *Node { ...@@ -2785,29 +2782,29 @@ func addstr(n *Node, init **NodeList) *Node {
// s // s
// //
// l2 is allowed to be a string. // l2 is allowed to be a string.
func appendslice(n *Node, init **NodeList) *Node { func appendslice(n *Node, init nodesOrNodeListPtr) *Node {
walkexprlistsafe(n.List, init) walkexprlistsafe(n.List, init)
// walkexprlistsafe will leave OINDEX (s[n]) alone if both s // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
// and n are name or literal, but those may index the slice we're // and n are name or literal, but those may index the slice we're
// modifying here. Fix explicitly. // modifying here. Fix explicitly.
for l := n.List; l != nil; l = l.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
l.N = cheapexpr(l.N, init) *it.P() = cheapexpr(it.N(), init)
} }
l1 := n.List.N l1 := nodeSeqFirst(n.List)
l2 := n.List.Next.N l2 := nodeSeqSecond(n.List)
s := temp(l1.Type) // var s []T s := temp(l1.Type) // var s []T
var l *NodeList var l []*Node
l = list(l, Nod(OAS, s, l1)) // s = l1 l = append(l, Nod(OAS, s, l1)) // s = l1
nt := temp(Types[TINT]) nt := temp(Types[TINT])
nif := Nod(OIF, nil, nil) nif := Nod(OIF, nil, nil)
// n := len(s) + len(l2) - cap(s) // n := len(s) + len(l2) - cap(s)
nif.Ninit = list1(Nod(OAS, nt, Nod(OSUB, Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil)), Nod(OCAP, s, nil)))) setNodeSeq(&nif.Ninit, list1(Nod(OAS, nt, Nod(OSUB, Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil)), Nod(OCAP, s, nil)))))
nif.Left = Nod(OGT, nt, Nodintconst(0)) nif.Left = Nod(OGT, nt, Nodintconst(0))
...@@ -2818,7 +2815,7 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2818,7 +2815,7 @@ func appendslice(n *Node, init **NodeList) *Node {
// s = growslice_n(T, s, n) // s = growslice_n(T, s, n)
nif.Nbody.Set([]*Node{Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt))}) nif.Nbody.Set([]*Node{Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt))})
l = list(l, nif) l = append(l, nif)
if haspointers(l1.Type.Type) { if haspointers(l1.Type.Type) {
// copy(s[len(l1):len(l1)+len(l2)], l2) // copy(s[len(l1):len(l1)+len(l2)], l2)
...@@ -2829,7 +2826,7 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2829,7 +2826,7 @@ func appendslice(n *Node, init **NodeList) *Node {
fn := syslook("typedslicecopy", 1) fn := syslook("typedslicecopy", 1)
substArgTypes(fn, l1.Type, l2.Type) substArgTypes(fn, l1.Type, l2.Type)
nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2) nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2)
l = list(l, nt) l = append(l, nt)
} else if instrumenting { } else if instrumenting {
// rely on runtime to instrument copy. // rely on runtime to instrument copy.
// copy(s[len(l1):len(l1)+len(l2)], l2) // copy(s[len(l1):len(l1)+len(l2)], l2)
...@@ -2845,7 +2842,7 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2845,7 +2842,7 @@ func appendslice(n *Node, init **NodeList) *Node {
} }
substArgTypes(fn, l1.Type, l2.Type) substArgTypes(fn, l1.Type, l2.Type)
nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width)) nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width))
l = list(l, nt) l = append(l, nt)
} else { } else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := Nod(OINDEX, s, Nod(OLEN, l1, nil)) nptr1 := Nod(OINDEX, s, Nod(OLEN, l1, nil))
...@@ -2862,7 +2859,7 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2862,7 +2859,7 @@ func appendslice(n *Node, init **NodeList) *Node {
nwid = Nod(OMUL, nwid, Nodintconst(s.Type.Type.Width)) nwid = Nod(OMUL, nwid, Nodintconst(s.Type.Type.Width))
nt := mkcall1(fn, nil, &l, nptr1, nptr2, nwid) nt := mkcall1(fn, nil, &l, nptr1, nptr2, nwid)
l = list(l, nt) l = append(l, nt)
} }
// s = s[:len(l1)+len(l2)] // s = s[:len(l1)+len(l2)]
...@@ -2870,11 +2867,11 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2870,11 +2867,11 @@ func appendslice(n *Node, init **NodeList) *Node {
nt = Nod(OSLICE, s, Nod(OKEY, nil, nt)) nt = Nod(OSLICE, s, Nod(OKEY, nil, nt))
nt.Etype = 1 nt.Etype = 1
l = list(l, Nod(OAS, s, nt)) l = append(l, Nod(OAS, s, nt))
typechecklist(l, Etop) typechecklist(l, Etop)
walkstmtlist(l) walkstmtlist(l)
*init = concat(*init, l) appendNodeSeq(init, l)
return s return s
} }
...@@ -2899,13 +2896,15 @@ func appendslice(n *Node, init **NodeList) *Node { ...@@ -2899,13 +2896,15 @@ func appendslice(n *Node, init **NodeList) *Node {
// ... // ...
// } // }
// s // s
func walkappend(n *Node, init **NodeList, dst *Node) *Node { func walkappend(n *Node, init nodesOrNodeListPtr, dst *Node) *Node {
if !samesafeexpr(dst, n.List.N) { if !samesafeexpr(dst, n.List.N) {
l := n.List it := nodeSeqIterate(n.List)
l.N = safeexpr(l.N, init) *it.P() = safeexpr(it.N(), init)
walkexpr(&l.N, init) walkexpr(it.P(), init)
} }
walkexprlistsafe(n.List.Next, init) it := nodeSeqIterate(n.List)
it.Next()
walkexprlistsafe(it.Seq(), init)
// walkexprlistsafe will leave OINDEX (s[n]) alone if both s // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
// and n are name or literal, but those may index the slice we're // and n are name or literal, but those may index the slice we're
...@@ -2913,17 +2912,19 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node { ...@@ -2913,17 +2912,19 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node {
// Using cheapexpr also makes sure that the evaluation // Using cheapexpr also makes sure that the evaluation
// of all arguments (and especially any panics) happen // of all arguments (and especially any panics) happen
// before we begin to modify the slice in a visible way. // before we begin to modify the slice in a visible way.
for l := n.List.Next; l != nil; l = l.Next { it = nodeSeqIterate(n.List)
l.N = cheapexpr(l.N, init) it.Next()
for ; !it.Done(); it.Next() {
*it.P() = cheapexpr(it.N(), init)
} }
nsrc := n.List.N nsrc := nodeSeqFirst(n.List)
// Resolve slice type of multi-valued return. // Resolve slice type of multi-valued return.
if Istype(nsrc.Type, TSTRUCT) { if Istype(nsrc.Type, TSTRUCT) {
nsrc.Type = nsrc.Type.Type.Type nsrc.Type = nsrc.Type.Type.Type
} }
argc := count(n.List) - 1 argc := nodeSeqLen(n.List) - 1
if argc < 1 { if argc < 1 {
return nsrc return nsrc
} }
...@@ -2934,10 +2935,10 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node { ...@@ -2934,10 +2935,10 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node {
return n return n
} }
var l *NodeList var l []*Node
ns := temp(nsrc.Type) ns := temp(nsrc.Type)
l = list(l, Nod(OAS, ns, nsrc)) // s = src l = append(l, Nod(OAS, ns, nsrc)) // s = src
na := Nodintconst(int64(argc)) // const argc na := Nodintconst(int64(argc)) // const argc
nx := Nod(OIF, nil, nil) // if cap(s) - len(s) < argc nx := Nod(OIF, nil, nil) // if cap(s) - len(s) < argc
...@@ -2948,27 +2949,29 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node { ...@@ -2948,27 +2949,29 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node {
nx.Nbody.Set([]*Node{Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, Nod(OADD, Nod(OLEN, ns, nil), na)))}) nx.Nbody.Set([]*Node{Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, Nod(OADD, Nod(OLEN, ns, nil), na)))})
l = list(l, nx) l = append(l, nx)
nn := temp(Types[TINT]) nn := temp(Types[TINT])
l = list(l, Nod(OAS, nn, Nod(OLEN, ns, nil))) // n = len(s) l = append(l, Nod(OAS, nn, Nod(OLEN, ns, nil))) // n = len(s)
nx = Nod(OSLICE, ns, Nod(OKEY, nil, Nod(OADD, nn, na))) // ...s[:n+argc] nx = Nod(OSLICE, ns, Nod(OKEY, nil, Nod(OADD, nn, na))) // ...s[:n+argc]
nx.Etype = 1 nx.Etype = 1
l = list(l, Nod(OAS, ns, nx)) // s = s[:n+argc] l = append(l, Nod(OAS, ns, nx)) // s = s[:n+argc]
for a := n.List.Next; a != nil; a = a.Next { it = nodeSeqIterate(n.List)
it.Next()
for ; !it.Done(); it.Next() {
nx = Nod(OINDEX, ns, nn) // s[n] ... nx = Nod(OINDEX, ns, nn) // s[n] ...
nx.Bounded = true nx.Bounded = true
l = list(l, Nod(OAS, nx, a.N)) // s[n] = arg l = append(l, Nod(OAS, nx, it.N())) // s[n] = arg
if a.Next != nil { if it.Len() != 0 {
l = list(l, Nod(OAS, nn, Nod(OADD, nn, Nodintconst(1)))) // n = n + 1 l = append(l, Nod(OAS, nn, Nod(OADD, nn, Nodintconst(1)))) // n = n + 1
} }
} }
typechecklist(l, Etop) typechecklist(l, Etop)
walkstmtlist(l) walkstmtlist(l)
*init = concat(*init, l) appendNodeSeq(init, l)
return ns return ns
} }
...@@ -2983,7 +2986,7 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node { ...@@ -2983,7 +2986,7 @@ func walkappend(n *Node, init **NodeList, dst *Node) *Node {
// //
// Also works if b is a string. // Also works if b is a string.
// //
func copyany(n *Node, init **NodeList, runtimecall bool) *Node { func copyany(n *Node, init nodesOrNodeListPtr, runtimecall bool) *Node {
if haspointers(n.Left.Type.Type) { if haspointers(n.Left.Type.Type) {
fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type) fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
return mkcall1(fn, n.Type, init, typename(n.Left.Type.Type), n.Left, n.Right) return mkcall1(fn, n.Type, init, typename(n.Left.Type.Type), n.Left, n.Right)
...@@ -3034,7 +3037,7 @@ func copyany(n *Node, init **NodeList, runtimecall bool) *Node { ...@@ -3034,7 +3037,7 @@ func copyany(n *Node, init **NodeList, runtimecall bool) *Node {
typechecklist(l, Etop) typechecklist(l, Etop)
walkstmtlist(l) walkstmtlist(l)
*init = concat(*init, l) appendNodeSeq(init, l)
return nlen return nlen
} }
...@@ -3060,9 +3063,9 @@ func eqfor(t *Type, needsize *int) *Node { ...@@ -3060,9 +3063,9 @@ func eqfor(t *Type, needsize *int) *Node {
n := newname(sym) n := newname(sym)
n.Class = PFUNC n.Class = PFUNC
ntype := Nod(OTFUNC, nil, nil) ntype := Nod(OTFUNC, nil, nil)
ntype.List = list(ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) appendNodeSeqNode(&ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
ntype.List = list(ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) appendNodeSeqNode(&ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
ntype.Rlist = list(ntype.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TBOOL]))) appendNodeSeqNode(&ntype.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
typecheck(&ntype, Etype) typecheck(&ntype, Etype)
n.Type = ntype.Type n.Type = ntype.Type
*needsize = 0 *needsize = 0
...@@ -3077,7 +3080,7 @@ func countfield(t *Type) int { ...@@ -3077,7 +3080,7 @@ func countfield(t *Type) int {
return n return n
} }
func walkcompare(np **Node, init **NodeList) { func walkcompare(np **Node, init nodesOrNodeListPtr) {
n := *np n := *np
// Given interface value l and concrete value r, rewrite // Given interface value l and concrete value r, rewrite
...@@ -3103,7 +3106,7 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3103,7 +3106,7 @@ func walkcompare(np **Node, init **NodeList) {
if haspointers(r.Type) { if haspointers(r.Type) {
a := Nod(OAS, x, nil) a := Nod(OAS, x, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
} }
ok := temp(Types[TBOOL]) ok := temp(Types[TBOOL])
...@@ -3115,9 +3118,9 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3115,9 +3118,9 @@ func walkcompare(np **Node, init **NodeList) {
// x, ok := l.(type(r)) // x, ok := l.(type(r))
expr := Nod(OAS2, nil, nil) expr := Nod(OAS2, nil, nil)
expr.List = list1(x) appendNodeSeqNode(&expr.List, x)
expr.List = list(expr.List, ok) appendNodeSeqNode(&expr.List, ok)
expr.Rlist = list1(a) appendNodeSeqNode(&expr.Rlist, a)
typecheck(&expr, Etop) typecheck(&expr, Etop)
walkexpr(&expr, init) walkexpr(&expr, init)
...@@ -3126,7 +3129,7 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3126,7 +3129,7 @@ func walkcompare(np **Node, init **NodeList) {
} else { } else {
r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r)) r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r))
} }
*init = list(*init, expr) appendNodeSeqNode(init, expr)
finishcompare(np, n, r, init) finishcompare(np, n, r, init)
return return
} }
...@@ -3165,13 +3168,13 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3165,13 +3168,13 @@ func walkcompare(np **Node, init **NodeList) {
a := Nod(OAS, l, Nod(OADDR, cmpl, nil)) a := Nod(OAS, l, Nod(OADDR, cmpl, nil))
a.Right.Etype = 1 // addr does not escape a.Right.Etype = 1 // addr does not escape
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
r = temp(Ptrto(t)) r = temp(Ptrto(t))
a = Nod(OAS, r, Nod(OADDR, cmpr, nil)) a = Nod(OAS, r, Nod(OADDR, cmpr, nil))
a.Right.Etype = 1 // addr does not escape a.Right.Etype = 1 // addr does not escape
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) appendNodeSeqNode(init, a)
var andor Op = OANDAND var andor Op = OANDAND
if n.Op == ONE { if n.Op == ONE {
...@@ -3247,10 +3250,10 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3247,10 +3250,10 @@ func walkcompare(np **Node, init **NodeList) {
var needsize int var needsize int
call := Nod(OCALL, eqfor(t, &needsize), nil) call := Nod(OCALL, eqfor(t, &needsize), nil)
call.List = list(call.List, l) appendNodeSeqNode(&call.List, l)
call.List = list(call.List, r) appendNodeSeqNode(&call.List, r)
if needsize != 0 { if needsize != 0 {
call.List = list(call.List, Nodintconst(t.Width)) appendNodeSeqNode(&call.List, Nodintconst(t.Width))
} }
r = call r = call
if n.Op != OEQ { if n.Op != OEQ {
...@@ -3261,7 +3264,7 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3261,7 +3264,7 @@ func walkcompare(np **Node, init **NodeList) {
return return
} }
func finishcompare(np **Node, n, r *Node, init **NodeList) { func finishcompare(np **Node, n, r *Node, init nodesOrNodeListPtr) {
// Using np here to avoid passing &r to typecheck. // Using np here to avoid passing &r to typecheck.
*np = r *np = r
typecheck(np, Erv) typecheck(np, Erv)
...@@ -3363,7 +3366,7 @@ func walkrotate(np **Node) { ...@@ -3363,7 +3366,7 @@ func walkrotate(np **Node) {
} }
// walkmul rewrites integer multiplication by powers of two as shifts. // walkmul rewrites integer multiplication by powers of two as shifts.
func walkmul(np **Node, init **NodeList) { func walkmul(np **Node, init nodesOrNodeListPtr) {
n := *np n := *np
if !Isint[n.Type.Etype] { if !Isint[n.Type.Etype] {
return return
...@@ -3433,7 +3436,7 @@ ret: ...@@ -3433,7 +3436,7 @@ ret:
// walkdiv rewrites division by a constant as less expensive // walkdiv rewrites division by a constant as less expensive
// operations. // operations.
func walkdiv(np **Node, init **NodeList) { func walkdiv(np **Node, init nodesOrNodeListPtr) {
// if >= 0, nr is 1<<pow // 1 if nr is negative. // if >= 0, nr is 1<<pow // 1 if nr is negative.
// TODO(minux) // TODO(minux)
...@@ -3802,18 +3805,9 @@ func usefield(n *Node) { ...@@ -3802,18 +3805,9 @@ func usefield(n *Node) {
Curfn.Func.Fieldtrack = append(Curfn.Func.Fieldtrack, field) Curfn.Func.Fieldtrack = append(Curfn.Func.Fieldtrack, field)
} }
func candiscardlist(l *NodeList) bool { func candiscardlist(l nodesOrNodeList) bool {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
if !candiscard(l.N) { if !candiscard(it.N()) {
return false
}
}
return true
}
func candiscardslice(l []*Node) bool {
for _, n := range l {
if !candiscard(n) {
return false return false
} }
} }
...@@ -3906,7 +3900,7 @@ func candiscard(n *Node) bool { ...@@ -3906,7 +3900,7 @@ func candiscard(n *Node) bool {
return false return false
} }
if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardslice(n.Nbody.Slice()) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) { if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
return false return false
} }
...@@ -3923,26 +3917,26 @@ func candiscard(n *Node) bool { ...@@ -3923,26 +3917,26 @@ func candiscard(n *Node) bool {
var walkprintfunc_prgen int var walkprintfunc_prgen int
func walkprintfunc(np **Node, init **NodeList) { func walkprintfunc(np **Node, init nodesOrNodeListPtr) {
n := *np n := *np
if n.Ninit != nil { if nodeSeqLen(n.Ninit) != 0 {
walkstmtlist(n.Ninit) walkstmtlist(n.Ninit)
*init = concat(*init, n.Ninit) appendNodeSeq(init, n.Ninit)
n.Ninit = nil setNodeSeq(&n.Ninit, nil)
} }
t := Nod(OTFUNC, nil, nil) t := Nod(OTFUNC, nil, nil)
num := 0 num := 0
var printargs *NodeList var printargs []*Node
var a *Node var a *Node
var buf string var buf string
for l := n.List; l != nil; l = l.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
buf = fmt.Sprintf("a%d", num) buf = fmt.Sprintf("a%d", num)
num++ num++
a = Nod(ODCLFIELD, newname(Lookup(buf)), typenod(l.N.Type)) a = Nod(ODCLFIELD, newname(Lookup(buf)), typenod(it.N().Type))
t.List = list(t.List, a) appendNodeSeqNode(&t.List, a)
printargs = list(printargs, a.Left) printargs = append(printargs, a.Left)
} }
fn := Nod(ODCLFUNC, nil, nil) fn := Nod(ODCLFUNC, nil, nil)
...@@ -3958,7 +3952,7 @@ func walkprintfunc(np **Node, init **NodeList) { ...@@ -3958,7 +3952,7 @@ func walkprintfunc(np **Node, init **NodeList) {
funchdr(fn) funchdr(fn)
a = Nod(n.Op, nil, nil) a = Nod(n.Op, nil, nil)
a.List = printargs setNodeSeq(&a.List, printargs)
typecheck(&a, Etop) typecheck(&a, Etop)
walkstmt(&a) walkstmt(&a)
...@@ -3973,7 +3967,7 @@ func walkprintfunc(np **Node, init **NodeList) { ...@@ -3973,7 +3967,7 @@ func walkprintfunc(np **Node, init **NodeList) {
a = Nod(OCALL, nil, nil) a = Nod(OCALL, nil, nil)
a.Left = fn.Func.Nname a.Left = fn.Func.Nname
a.List = n.List setNodeSeq(&a.List, n.List)
typecheck(&a, Etop) typecheck(&a, Etop)
walkexpr(&a, init) walkexpr(&a, init)
*np = a *np = a
......
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