Commit f444b8a8 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: remove all remaining nodeSeq code

Passes toolstash -cmp.

Update #14473.

Change-Id: I2ac5c595d7af7a8da1a7e3945e6a753299446250
Reviewed-on: https://go-review.googlesource.com/20497
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 53900cea
...@@ -632,7 +632,7 @@ func (p *importer) node() *Node { ...@@ -632,7 +632,7 @@ func (p *importer) node() *Node {
// if p.bool() { // if p.bool() {
// n.Left = p.node() // n.Left = p.node()
// } else { // } else {
// setNodeSeq(&n.List, p.nodeList()) // n.List.Set(p.nodeList())
// } // }
x := Nod(OCALL, p.typ().Nod, nil) x := Nod(OCALL, p.typ().Nod, nil)
if p.bool() { if p.bool() {
......
...@@ -52,13 +52,13 @@ func closurehdr(ntype *Node) { ...@@ -52,13 +52,13 @@ func closurehdr(ntype *Node) {
} }
} }
func closurebody(body *NodeList) *Node { func closurebody(body []*Node) *Node {
if body == nil { if len(body) == 0 {
body = list1(Nod(OEMPTY, nil, nil)) body = []*Node{Nod(OEMPTY, nil, nil)}
} }
func_ := Curfn func_ := Curfn
func_.Nbody.SetToNodeList(body) func_.Nbody.Set(body)
func_.Func.Endlineno = lineno func_.Func.Endlineno = lineno
funcbody(func_) funcbody(func_)
...@@ -116,7 +116,7 @@ func typecheckclosure(func_ *Node, top int) { ...@@ -116,7 +116,7 @@ func typecheckclosure(func_ *Node, top int) {
} }
// Create top-level function // Create top-level function
xtop = list(xtop, makeclosure(func_)) xtop = append(xtop, makeclosure(func_))
} }
// closurename returns name for OCLOSURE n. // closurename returns name for OCLOSURE n.
...@@ -616,7 +616,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node { ...@@ -616,7 +616,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node {
typecheck(&xfunc, Etop) typecheck(&xfunc, Etop)
sym.Def = xfunc sym.Def = xfunc
xtop = list(xtop, xfunc) xtop = append(xtop, xfunc)
Curfn = savecurfn Curfn = savecurfn
return xfunc return xfunc
......
...@@ -220,63 +220,59 @@ func addvar(n *Node, t *Type, ctxt Class) { ...@@ -220,63 +220,59 @@ func addvar(n *Node, t *Type, ctxt Class) {
// declare variables from grammar // declare variables from grammar
// new_name_list (type | [type] = expr_list) // new_name_list (type | [type] = expr_list)
func variter(vl *NodeList, t *Node, el *NodeList) *NodeList { func variter(vl []*Node, t *Node, el []*Node) []*Node {
var init *NodeList var init []*Node
doexpr := el != nil doexpr := len(el) > 0
if count(el) == 1 && count(vl) > 1 { if len(el) == 1 && len(vl) > 1 {
e := el.N e := el[0]
as2 := Nod(OAS2, nil, nil) as2 := Nod(OAS2, nil, nil)
setNodeSeq(&as2.List, vl) as2.List.Set(vl)
as2.Rlist.Set([]*Node{e}) as2.Rlist.Set([]*Node{e})
var v *Node for _, v := range vl {
for ; vl != nil; vl = vl.Next {
v = vl.N
v.Op = ONAME v.Op = ONAME
declare(v, dclcontext) declare(v, dclcontext)
v.Name.Param.Ntype = t v.Name.Param.Ntype = t
v.Name.Defn = as2 v.Name.Defn = as2
if Funcdepth > 0 { if Funcdepth > 0 {
init = list(init, Nod(ODCL, v, nil)) init = append(init, Nod(ODCL, v, nil))
} }
} }
return list(init, as2) return append(init, as2)
} }
var v *Node for _, v := range vl {
var e *Node var e *Node
for ; vl != nil; vl = vl.Next {
if doexpr { if doexpr {
if el == nil { if len(el) == 0 {
Yyerror("missing expression in var declaration") Yyerror("missing expression in var declaration")
break break
} }
e = el.N e = el[0]
el = el.Next el = el[1:]
} else { } else {
e = nil e = nil
} }
v = vl.N
v.Op = ONAME v.Op = ONAME
declare(v, dclcontext) declare(v, dclcontext)
v.Name.Param.Ntype = t v.Name.Param.Ntype = t
if e != nil || Funcdepth > 0 || isblank(v) { if e != nil || Funcdepth > 0 || isblank(v) {
if Funcdepth > 0 { if Funcdepth > 0 {
init = list(init, Nod(ODCL, v, nil)) init = append(init, Nod(ODCL, v, nil))
} }
e = Nod(OAS, v, e) e = Nod(OAS, v, e)
init = list(init, e) init = append(init, e)
if e.Right != nil { if e.Right != nil {
v.Name.Defn = e v.Name.Defn = e
} }
} }
} }
if el != nil { if len(el) != 0 {
Yyerror("extra expression in var declaration") Yyerror("extra expression in var declaration")
} }
return init return init
...@@ -284,25 +280,24 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList { ...@@ -284,25 +280,24 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList {
// declare constants from grammar // declare constants from grammar
// new_name_list [[type] = expr_list] // new_name_list [[type] = expr_list]
func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
lno := int32(0) // default is to leave line number alone in listtreecopy lno := int32(0) // default is to leave line number alone in listtreecopy
if cl == nil { if len(cl) == 0 {
if t != nil { if t != nil {
Yyerror("const declaration cannot have type without expression") Yyerror("const declaration cannot have type without expression")
} }
cl = lastconst cl = lastconst
t = lasttype t = lasttype
lno = vl.N.Lineno lno = vl[0].Lineno
} else { } else {
lastconst = cl lastconst = cl
lasttype = t lasttype = t
} }
clcopy := listtreecopy(nodeSeqSlice(cl), lno) clcopy := listtreecopy(cl, lno)
var v *Node
var c *Node var c *Node
var vv *NodeList var vv []*Node
for ; vl != nil; vl = vl.Next { for _, v := range vl {
if len(clcopy) == 0 { if len(clcopy) == 0 {
Yyerror("missing value in const declaration") Yyerror("missing value in const declaration")
break break
...@@ -311,14 +306,13 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { ...@@ -311,14 +306,13 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
c = clcopy[0] c = clcopy[0]
clcopy = clcopy[1:] clcopy = clcopy[1:]
v = vl.N
v.Op = OLITERAL v.Op = OLITERAL
declare(v, dclcontext) declare(v, dclcontext)
v.Name.Param.Ntype = t v.Name.Param.Ntype = t
v.Name.Defn = c v.Name.Defn = c
vv = list(vv, Nod(ODCLCONST, v, nil)) vv = append(vv, Nod(ODCLCONST, v, nil))
} }
if len(clcopy) != 0 { if len(clcopy) != 0 {
...@@ -483,10 +477,10 @@ func colasdefn(left Nodes, defn *Node) { ...@@ -483,10 +477,10 @@ func colasdefn(left Nodes, defn *Node) {
} }
} }
func colas(left *NodeList, right *NodeList, lno int32) *Node { func colas(left []*Node, right []*Node, lno int32) *Node {
as := Nod(OAS2, nil, nil) as := Nod(OAS2, nil, nil)
setNodeSeq(&as.List, left) as.List.Set(left)
setNodeSeq(&as.Rlist, right) as.Rlist.Set(right)
as.Colas = true as.Colas = true
as.Lineno = lno as.Lineno = lno
colasdefn(as.List, as) colasdefn(as.List, as)
...@@ -1026,56 +1020,53 @@ func embedded(s *Sym, pkg *Pkg) *Node { ...@@ -1026,56 +1020,53 @@ func embedded(s *Sym, pkg *Pkg) *Node {
} }
// check that the list of declarations is either all anonymous or all named // check that the list of declarations is either all anonymous or all named
func findtype(l *NodeList) *Node { func findtype(s []*Node) *Node {
for ; l != nil; l = l.Next { for _, n := range s {
if l.N.Op == OKEY { if n.Op == OKEY {
return l.N.Right return n.Right
} }
} }
return nil return nil
} }
func checkarglist(all *NodeList, input int) *NodeList { func checkarglist(all []*Node, input int) []*Node {
named := 0 named := false
for l := all; l != nil; l = l.Next { for _, n := range all {
if l.N.Op == OKEY { if n.Op == OKEY {
named = 1 named = true
break break
} }
} }
if named != 0 { if named {
var n *Node ok := true
var l *NodeList for _, n := range all {
for l = all; l != nil; l = l.Next {
n = l.N
if n.Op != OKEY && n.Sym == nil { if n.Op != OKEY && n.Sym == nil {
Yyerror("mixed named and unnamed function parameters") Yyerror("mixed named and unnamed function parameters")
ok = false
break break
} }
} }
if l == nil && n != nil && n.Op != OKEY { if ok && len(all) > 0 && all[len(all)-1].Op != OKEY {
Yyerror("final function parameter must have type") Yyerror("final function parameter must have type")
} }
} }
var nextt *Node var nextt *Node
var t *Node for i, n := range all {
var n *Node
for l := all; l != nil; l = l.Next {
// can cache result from findtype to avoid // can cache result from findtype to avoid
// quadratic behavior here, but unlikely to matter. // quadratic behavior here, but unlikely to matter.
n = l.N
if named != 0 { var t *Node
if named {
if n.Op == OKEY { if n.Op == OKEY {
t = n.Right t = n.Right
n = n.Left n = n.Left
nextt = nil nextt = nil
} else { } else {
if nextt == nil { if nextt == nil {
nextt = findtype(l) nextt = findtype(all[i:])
} }
t = nextt t = nextt
} }
...@@ -1107,7 +1098,7 @@ func checkarglist(all *NodeList, input int) *NodeList { ...@@ -1107,7 +1098,7 @@ func checkarglist(all *NodeList, input int) *NodeList {
if n.Right != nil && n.Right.Op == ODDD { if n.Right != nil && n.Right.Op == ODDD {
if input == 0 { if input == 0 {
Yyerror("cannot use ... in output argument list") Yyerror("cannot use ... in output argument list")
} else if l.Next != nil { } else if i+1 < len(all) {
Yyerror("can only use ... as final argument in list") Yyerror("can only use ... as final argument in list")
} }
n.Right.Op = OTARRAY n.Right.Op = OTARRAY
...@@ -1119,7 +1110,7 @@ func checkarglist(all *NodeList, input int) *NodeList { ...@@ -1119,7 +1110,7 @@ func checkarglist(all *NodeList, input int) *NodeList {
} }
} }
l.N = n all[i] = n
} }
return all return all
...@@ -1181,11 +1172,11 @@ func functype0(t *Type, this *Node, in, out []*Node) { ...@@ -1181,11 +1172,11 @@ func functype0(t *Type, this *Node, in, out []*Node) {
if this != nil { if this != nil {
t.Thistuple = 1 t.Thistuple = 1
} }
t.Outtuple = nodeSeqLen(out) t.Outtuple = len(out)
t.Intuple = nodeSeqLen(in) t.Intuple = len(in)
t.Outnamed = false t.Outnamed = false
if t.Outtuple > 0 && nodeSeqFirst(out).Left != nil && nodeSeqFirst(out).Left.Orig != nil { if t.Outtuple > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
s := nodeSeqFirst(out).Left.Orig.Sym s := out[0].Left.Orig.Sym
if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
t.Outnamed = true t.Outnamed = true
} }
......
...@@ -54,13 +54,13 @@ type bottomUpVisitor struct { ...@@ -54,13 +54,13 @@ type bottomUpVisitor struct {
// If recursive is false, the list consists of only a single function and its closures. // If recursive is false, the list consists of only a single function and its closures.
// If recursive is true, the list may still contain only a single function, // If recursive is true, the list may still contain only a single function,
// if that function is itself recursive. // if that function is itself recursive.
func visitBottomUp(list *NodeList, analyze func(list []*Node, recursive bool)) { func visitBottomUp(list []*Node, analyze func(list []*Node, recursive bool)) {
var v bottomUpVisitor var v bottomUpVisitor
v.analyze = analyze v.analyze = analyze
v.nodeID = make(map[*Node]uint32) v.nodeID = make(map[*Node]uint32)
for l := list; l != nil; l = l.Next { for _, n := range list {
if l.N.Op == ODCLFUNC && l.N.Func.FCurfn == nil { if n.Op == ODCLFUNC && n.Func.FCurfn == nil {
v.visit(l.N) v.visit(n)
} }
} }
} }
...@@ -183,7 +183,7 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 { ...@@ -183,7 +183,7 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 {
// needs to be moved to the heap, and new(T) and slice // needs to be moved to the heap, and new(T) and slice
// literals are always real allocations. // literals are always real allocations.
func escapes(all *NodeList) { func escapes(all []*Node) {
visitBottomUp(all, escAnalyze) visitBottomUp(all, escAnalyze)
} }
......
...@@ -1700,7 +1700,9 @@ func Nconv(n *Node, flag int) string { ...@@ -1700,7 +1700,9 @@ func Nconv(n *Node, flag int) string {
func (l *NodeList) String() string { func (l *NodeList) String() string {
var n Nodes var n Nodes
n.Set(nodeSeqSlice(l)) for ll := l; ll != nil; ll = ll.Next {
n.Append(ll.N)
}
return Hconv(n, 0) return Hconv(n, 0)
} }
......
...@@ -439,7 +439,7 @@ func cgen_dottype(n *Node, res, resok *Node, wb bool) { ...@@ -439,7 +439,7 @@ func cgen_dottype(n *Node, res, resok *Node, wb bool) {
call := Nod(OCALLFUNC, fn, nil) call := Nod(OCALLFUNC, fn, nil)
r1.Type = byteptr r1.Type = byteptr
r2.Type = byteptr r2.Type = byteptr
setNodeSeq(&call.List, list(list(list1(&r1), &r2), typename(n.Left.Type))) call.List.Set([]*Node{&r1, &r2, typename(n.Left.Type)})
call.List.Set(ascompatte(OCALLFUNC, call, false, fn.Type.Params(), call.List.Slice(), 0, nil)) call.List.Set(ascompatte(OCALLFUNC, call, false, fn.Type.Params(), call.List.Slice(), 0, nil))
gen(call) gen(call)
Regfree(&r1) Regfree(&r1)
...@@ -525,7 +525,7 @@ func Cgen_As2dottype(n, res, resok *Node) { ...@@ -525,7 +525,7 @@ func Cgen_As2dottype(n, res, resok *Node) {
fn := syslook("panicdottype") fn := syslook("panicdottype")
dowidth(fn.Type) dowidth(fn.Type)
call := Nod(OCALLFUNC, fn, nil) call := Nod(OCALLFUNC, fn, nil)
setNodeSeq(&call.List, list(list(list1(&r1), &r2), typename(n.Left.Type))) call.List.Set([]*Node{&r1, &r2, typename(n.Left.Type)})
call.List.Set(ascompatte(OCALLFUNC, call, false, fn.Type.Params(), call.List.Slice(), 0, nil)) call.List.Set(ascompatte(OCALLFUNC, call, false, fn.Type.Params(), call.List.Slice(), 0, nil))
gen(call) gen(call)
Regfree(&r1) Regfree(&r1)
......
...@@ -346,7 +346,7 @@ var minfltval [NTYPE]*Mpflt ...@@ -346,7 +346,7 @@ var minfltval [NTYPE]*Mpflt
var maxfltval [NTYPE]*Mpflt var maxfltval [NTYPE]*Mpflt
var xtop *NodeList var xtop []*Node
var externdcl []*Node var externdcl []*Node
...@@ -364,7 +364,7 @@ var statuniqgen int // name generator for static temps ...@@ -364,7 +364,7 @@ var statuniqgen int // name generator for static temps
var iota_ int32 var iota_ int32
var lastconst *NodeList var lastconst []*Node
var lasttype *Node var lasttype *Node
......
...@@ -88,13 +88,13 @@ func anyinit(n []*Node) bool { ...@@ -88,13 +88,13 @@ func anyinit(n []*Node) bool {
return false return false
} }
func fninit(n *NodeList) { func fninit(n []*Node) {
if Debug['A'] != 0 { if Debug['A'] != 0 {
// sys.go or unsafe.go during compiler build // sys.go or unsafe.go during compiler build
return return
} }
nf := initfix(nodeSeqSlice(n)) nf := initfix(n)
if !anyinit(nf) { if !anyinit(nf) {
return return
} }
......
...@@ -41,7 +41,7 @@ var inlfn *Node // function currently being inlined ...@@ -41,7 +41,7 @@ var inlfn *Node // function currently being inlined
var inlretlabel *Node // target of the goto substituted in place of a return var inlretlabel *Node // target of the goto substituted in place of a return
var inlretvars *NodeList // temp out variables var inlretvars []*Node // temp out variables
// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
// the ->sym can be re-used in the local package, so peel it off the receiver's type. // the ->sym can be re-used in the local package, so peel it off the receiver's type.
...@@ -246,7 +246,7 @@ func ishairy(n *Node, budget *int) bool { ...@@ -246,7 +246,7 @@ func ishairy(n *Node, budget *int) bool {
// Any name-like node of non-local class is marked for re-export by adding it to // Any name-like node of non-local class is marked for re-export by adding it to
// the exportlist. // the exportlist.
func inlcopylist(ll []*Node) []*Node { func inlcopylist(ll []*Node) []*Node {
s := make([]*Node, 0, nodeSeqLen(ll)) s := make([]*Node, 0, len(ll))
for _, n := range ll { for _, n := range ll {
s = append(s, inlcopy(n)) s = append(s, inlcopy(n))
} }
...@@ -607,11 +607,10 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -607,11 +607,10 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
} }
ninit.Append(Nod(ODCL, m, nil)) ninit.Append(Nod(ODCL, m, nil))
inlretvars = list(inlretvars, m) inlretvars = append(inlretvars, m)
} }
// assign receiver. // assign receiver.
var as *Node
if fn.Type.Thistuple != 0 && n.Left.Op == ODOTMETH { if fn.Type.Thistuple != 0 && n.Left.Op == ODOTMETH {
// method call with a receiver. // method call with a receiver.
t := fn.Type.Recv() t := fn.Type.Recv()
...@@ -625,7 +624,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -625,7 +624,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
if t == nil { if t == nil {
Fatalf("method call unknown receiver type: %v", Nconv(n, obj.FmtSign)) Fatalf("method call unknown receiver type: %v", Nconv(n, obj.FmtSign))
} }
as = Nod(OAS, tinlvar(t), n.Left.Left) as := Nod(OAS, tinlvar(t), n.Left.Left)
if as != nil { if as != nil {
typecheck(&as, Etop) typecheck(&as, Etop)
ninit.Append(as) ninit.Append(as)
...@@ -670,7 +669,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -670,7 +669,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
} }
// assign arguments to the parameters' temp names // assign arguments to the parameters' temp names
as = Nod(OAS2, nil, nil) as := Nod(OAS2, nil, nil)
as.Rlist.Set(n.List.Slice()) as.Rlist.Set(n.List.Slice())
li := 0 li := 0
...@@ -779,8 +778,8 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -779,8 +778,8 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
} }
// zero the outparams // zero the outparams
for ll := inlretvars; ll != nil; ll = ll.Next { for _, n := range inlretvars {
as = Nod(OAS, ll.N, nil) as = Nod(OAS, n, nil)
typecheck(&as, Etop) typecheck(&as, Etop)
ninit.Append(as) ninit.Append(as)
} }
...@@ -800,7 +799,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -800,7 +799,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
call.Ninit.Set(ninit.Slice()) call.Ninit.Set(ninit.Slice())
call.Nbody.Set(body) call.Nbody.Set(body)
setNodeSeq(&call.Rlist, inlretvars) call.Rlist.Set(inlretvars)
call.Type = n.Type call.Type = n.Type
call.Typecheck = 1 call.Typecheck = 1
...@@ -940,12 +939,12 @@ func inlsubst(n *Node) *Node { ...@@ -940,12 +939,12 @@ func inlsubst(n *Node) *Node {
m.Ninit.Set(inlsubstlist(n.Ninit)) m.Ninit.Set(inlsubstlist(n.Ninit))
if inlretvars != nil && n.List.Len() != 0 { if len(inlretvars) != 0 && n.List.Len() != 0 {
as := Nod(OAS2, nil, nil) as := Nod(OAS2, nil, nil)
// shallow copy or OINLCALL->rlist will be the same list, and later walk and typecheck may clobber that. // shallow copy or OINLCALL->rlist will be the same list, and later walk and typecheck may clobber that.
for ll := inlretvars; ll != nil; ll = ll.Next { for _, n := range inlretvars {
as.List.Append(ll.N) as.List.Append(n)
} }
as.Rlist.Set(inlsubstlist(n.List)) as.Rlist.Set(inlsubstlist(n.List))
typecheck(&as, Etop) typecheck(&as, Etop)
......
...@@ -381,31 +381,35 @@ func Main() { ...@@ -381,31 +381,35 @@ func Main() {
// and methods but doesn't depend on any of it. // and methods but doesn't depend on any of it.
defercheckwidth() defercheckwidth()
for l := xtop; l != nil; l = l.Next { // Don't use range--typecheck can add closures to xtop.
if l.N.Op != ODCL && l.N.Op != OAS && l.N.Op != OAS2 { for i := 0; i < len(xtop); i++ {
typecheck(&l.N, Etop) if xtop[i].Op != ODCL && xtop[i].Op != OAS && xtop[i].Op != OAS2 {
typecheck(&xtop[i], Etop)
} }
} }
// Phase 2: Variable assignments. // Phase 2: Variable assignments.
// To check interface assignments, depends on phase 1. // To check interface assignments, depends on phase 1.
for l := xtop; l != nil; l = l.Next {
if l.N.Op == ODCL || l.N.Op == OAS || l.N.Op == OAS2 { // Don't use range--typecheck can add closures to xtop.
typecheck(&l.N, Etop) for i := 0; i < len(xtop); i++ {
if xtop[i].Op == ODCL || xtop[i].Op == OAS || xtop[i].Op == OAS2 {
typecheck(&xtop[i], Etop)
} }
} }
resumecheckwidth() resumecheckwidth()
// Phase 3: Type check function bodies. // Phase 3: Type check function bodies.
for l := xtop; l != nil; l = l.Next { // Don't use range--typecheck can add closures to xtop.
if l.N.Op == ODCLFUNC || l.N.Op == OCLOSURE { for i := 0; i < len(xtop); i++ {
Curfn = l.N if xtop[i].Op == ODCLFUNC || xtop[i].Op == OCLOSURE {
Curfn = xtop[i]
decldepth = 1 decldepth = 1
saveerrors() saveerrors()
typechecklist(l.N.Nbody.Slice(), Etop) typechecklist(Curfn.Nbody.Slice(), Etop)
checkreturn(l.N) checkreturn(Curfn)
if nerrors != 0 { if nerrors != 0 {
l.N.Nbody.Set(nil) // type errors; do not compile Curfn.Nbody.Set(nil) // type errors; do not compile
} }
} }
} }
...@@ -413,10 +417,10 @@ func Main() { ...@@ -413,10 +417,10 @@ func Main() {
// Phase 4: Decide how to capture closed variables. // Phase 4: Decide how to capture closed variables.
// This needs to run before escape analysis, // This needs to run before escape analysis,
// because variables captured by value do not escape. // because variables captured by value do not escape.
for l := xtop; l != nil; l = l.Next { for _, n := range xtop {
if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil { if n.Op == ODCLFUNC && n.Func.Closure != nil {
Curfn = l.N Curfn = n
capturevars(l.N) capturevars(n)
} }
} }
...@@ -469,19 +473,20 @@ func Main() { ...@@ -469,19 +473,20 @@ func Main() {
// Phase 7: Transform closure bodies to properly reference captured variables. // Phase 7: Transform closure bodies to properly reference captured variables.
// This needs to happen before walk, because closures must be transformed // This needs to happen before walk, because closures must be transformed
// before walk reaches a call of a closure. // before walk reaches a call of a closure.
for l := xtop; l != nil; l = l.Next { for _, n := range xtop {
if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil { if n.Op == ODCLFUNC && n.Func.Closure != nil {
Curfn = l.N Curfn = n
transformclosure(l.N) transformclosure(n)
} }
} }
Curfn = nil Curfn = nil
// Phase 8: Compile top level functions. // Phase 8: Compile top level functions.
for l := xtop; l != nil; l = l.Next { // Don't use range--walk can add functions to xtop.
if l.N.Op == ODCLFUNC { for i := 0; i < len(xtop); i++ {
funccompile(l.N) if xtop[i].Op == ODCLFUNC {
funccompile(xtop[i])
} }
} }
......
...@@ -331,7 +331,7 @@ func ismulticall(l Nodes) bool { ...@@ -331,7 +331,7 @@ func ismulticall(l Nodes) bool {
// Copyret emits t1, t2, ... = n, where n is a function call, // Copyret emits t1, t2, ... = n, where n is a function call,
// and then returns the list t1, t2, .... // and then returns the list t1, t2, ....
func copyret(n *Node, order *Order) Nodes { func copyret(n *Node, order *Order) []*Node {
if n.Type.Etype != TSTRUCT || !n.Type.Funarg { if n.Type.Etype != TSTRUCT || !n.Type.Funarg {
Fatalf("copyret %v %d", n.Type, n.Left.Type.Outtuple) Fatalf("copyret %v %d", n.Type, n.Left.Type.Outtuple)
} }
...@@ -350,20 +350,16 @@ func copyret(n *Node, order *Order) Nodes { ...@@ -350,20 +350,16 @@ func copyret(n *Node, order *Order) Nodes {
typecheck(&as, Etop) typecheck(&as, Etop)
orderstmt(as, order) orderstmt(as, order)
var r Nodes return l2
r.Set(l2)
return r
} }
// Ordercallargs orders the list of call arguments l and returns the // Ordercallargs orders the list of call arguments *l.
// ordered list. func ordercallargs(l *Nodes, order *Order) {
func ordercallargs(l Nodes, order *Order) Nodes { if ismulticall(*l) {
if ismulticall(l) {
// return f() where f() is multiple values. // return f() where f() is multiple values.
return copyret(l.First(), order) l.Set(copyret(l.First(), order))
} else { } else {
orderexprlist(l, order) orderexprlist(*l, order)
return l
} }
} }
...@@ -372,7 +368,7 @@ func ordercallargs(l Nodes, order *Order) Nodes { ...@@ -372,7 +368,7 @@ func ordercallargs(l Nodes, order *Order) Nodes {
func ordercall(n *Node, order *Order) { func ordercall(n *Node, order *Order) {
orderexpr(&n.Left, order, nil) orderexpr(&n.Left, order, nil)
orderexpr(&n.Right, order, nil) // ODDDARG temp orderexpr(&n.Right, order, nil) // ODDDARG temp
setNodeSeq(&n.List, ordercallargs(n.List, order)) ordercallargs(&n.List, order)
if n.Op == OCALLFUNC { if n.Op == OCALLFUNC {
t := n.Left.Type.Params().Type t := n.Left.Type.Params().Type
...@@ -779,7 +775,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -779,7 +775,7 @@ func orderstmt(n *Node, order *Order) {
cleantemp(t, order) cleantemp(t, order)
case ORETURN: case ORETURN:
setNodeSeq(&n.List, ordercallargs(n.List, order)) ordercallargs(&n.List, order)
order.out = append(order.out, n) order.out = append(order.out, n)
// Special: clean case temporaries in each block entry. // Special: clean case temporaries in each block entry.
...@@ -887,7 +883,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -887,7 +883,7 @@ func orderstmt(n *Node, order *Order) {
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
} }
setNodeSeq(&r.List, list1(ordertemp(tmp1.Type, order, false))) r.List.Set([]*Node{ordertemp(tmp1.Type, order, false)})
tmp2 = Nod(OAS, tmp1, r.List.First()) tmp2 = Nod(OAS, tmp1, r.List.First())
typecheck(&tmp2, Etop) typecheck(&tmp2, Etop)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
...@@ -1128,7 +1124,7 @@ func orderexpr(np **Node, order *Order, lhs *Node) { ...@@ -1128,7 +1124,7 @@ func orderexpr(np **Node, order *Order, lhs *Node) {
} }
case OAPPEND: case OAPPEND:
setNodeSeq(&n.List, ordercallargs(n.List, order)) ordercallargs(&n.List, order)
if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.List.First()) { if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.List.First()) {
n = ordercopyexpr(n, n.Type, order, 0) n = ordercopyexpr(n, n.Type, order, 0)
} }
......
This diff is collapsed.
...@@ -208,7 +208,7 @@ func walkselect(sel *Node) { ...@@ -208,7 +208,7 @@ func walkselect(sel *Node) {
dflt = sel.List.First() dflt = sel.List.First()
} else { } else {
dflt = sel.List.Second() dflt = sel.List.Second()
cas = nodeSeqFirst(sel.List.Slice()) cas = sel.List.First()
} }
n := cas.Left n := cas.Left
......
...@@ -2215,8 +2215,8 @@ func listtreecopy(l []*Node, lineno int32) []*Node { ...@@ -2215,8 +2215,8 @@ func listtreecopy(l []*Node, lineno int32) []*Node {
func liststmt(l []*Node) *Node { func liststmt(l []*Node) *Node {
n := Nod(OBLOCK, nil, nil) n := Nod(OBLOCK, nil, nil)
n.List.Set(l) n.List.Set(l)
if nodeSeqLen(l) != 0 { if len(l) != 0 {
n.Lineno = nodeSeqFirst(l).Lineno n.Lineno = l[0].Lineno
} }
return n return n
} }
...@@ -2545,7 +2545,7 @@ func mkpkg(path string) *Pkg { ...@@ -2545,7 +2545,7 @@ func mkpkg(path string) *Pkg {
} }
func addinit(np **Node, init []*Node) { func addinit(np **Node, init []*Node) {
if nodeSeqLen(init) == 0 { if len(init) == 0 {
return return
} }
...@@ -2561,7 +2561,7 @@ func addinit(np **Node, init []*Node) { ...@@ -2561,7 +2561,7 @@ func addinit(np **Node, init []*Node) {
*np = n *np = n
} }
n.Ninit.Set(append(nodeSeqSlice(init), n.Ninit.Slice()...)) n.Ninit.Set(append(init, n.Ninit.Slice()...))
n.Ullman = UINF n.Ullman = UINF
} }
......
...@@ -455,21 +455,6 @@ func (n *Nodes) Second() *Node { ...@@ -455,21 +455,6 @@ func (n *Nodes) Second() *Node {
return (*n.slice)[1] return (*n.slice)[1]
} }
// NodeList returns the entries in Nodes as a NodeList.
// Changes to the NodeList entries (as in l.N = n) will *not* be
// reflected in the Nodes.
// This wastes memory and should be used as little as possible.
func (n *Nodes) NodeList() *NodeList {
if n.slice == nil {
return nil
}
var ret *NodeList
for _, n := range *n.slice {
ret = list(ret, n)
}
return ret
}
// Set sets n to a slice. // Set sets n to a slice.
// This takes ownership of the slice. // This takes ownership of the slice.
func (n *Nodes) Set(s []*Node) { func (n *Nodes) Set(s []*Node) {
...@@ -521,253 +506,3 @@ func (n *Nodes) AppendNodes(n2 *Nodes) { ...@@ -521,253 +506,3 @@ func (n *Nodes) AppendNodes(n2 *Nodes) {
} }
n2.slice = nil n2.slice = nil
} }
// SetToNodeList sets Nodes to the contents of a NodeList.
func (n *Nodes) SetToNodeList(l *NodeList) {
s := make([]*Node, 0, count(l))
for ; l != nil; l = l.Next {
s = append(s, l.N)
}
n.Set(s)
}
// AppendNodeList appends the contents of a NodeList.
func (n *Nodes) AppendNodeList(l *NodeList) {
if n.slice == nil {
n.SetToNodeList(l)
} else {
for ; l != nil; l = l.Next {
*n.slice = append(*n.slice, l.N)
}
}
}
// nodesOrNodeList must be either type Nodes or type *NodeList, or, in
// some cases, []*Node. It exists during the transition from NodeList
// to Nodes only and then should be deleted. See nodeSeqIterate to
// return an iterator from a nodesOrNodeList.
type nodesOrNodeList interface{}
// nodesOrNodeListPtr must be type *Nodes or type **NodeList, or, in
// some cases, *[]*Node. It exists during the transition from NodeList
// to Nodes only, and then should be deleted. See setNodeSeq to assign
// to a generic value.
type nodesOrNodeListPtr interface{}
// nodeSeqLen returns the length of a *NodeList, a Nodes, a []*Node, or nil.
func nodeSeqLen(ns nodesOrNodeList) int {
switch ns := ns.(type) {
case *NodeList:
return count(ns)
case Nodes:
return len(ns.Slice())
case []*Node:
return len(ns)
case nil:
return 0
default:
panic("can't happen")
}
}
// nodeSeqFirst returns the first element of a *NodeList, a Nodes,
// or a []*Node. It panics if the sequence is empty.
func nodeSeqFirst(ns nodesOrNodeList) *Node {
switch ns := ns.(type) {
case *NodeList:
return ns.N
case Nodes:
return ns.Slice()[0]
case []*Node:
return ns[0]
default:
panic("can't happen")
}
}
// nodeSeqSecond returns the second element of a *NodeList, a Nodes,
// or a []*Node. It panics if the sequence has fewer than two elements.
func nodeSeqSecond(ns nodesOrNodeList) *Node {
switch ns := ns.(type) {
case *NodeList:
return ns.Next.N
case Nodes:
return ns.Slice()[1]
case []*Node:
return ns[1]
default:
panic("can't happen")
}
}
// nodeSeqSlice returns a []*Node containing the contents of a
// *NodeList, a Nodes, or a []*Node.
// This is an interim function during the transition from NodeList to Nodes.
// TODO(iant): Remove when transition is complete.
func nodeSeqSlice(ns nodesOrNodeList) []*Node {
switch ns := ns.(type) {
case *NodeList:
var s []*Node
for l := ns; l != nil; l = l.Next {
s = append(s, l.N)
}
return s
case Nodes:
return ns.Slice()
case []*Node:
return ns
default:
panic("can't happen")
}
}
// setNodeSeq implements *a = b.
// a must have type **NodeList, *Nodes, or *[]*Node.
// b must have type *NodeList, Nodes, []*Node, or nil.
// This is an interim function during the transition from NodeList to Nodes.
// TODO(iant): Remove when transition is complete.
func setNodeSeq(a nodesOrNodeListPtr, b nodesOrNodeList) {
if b == nil {
switch a := a.(type) {
case **NodeList:
*a = nil
case *Nodes:
a.Set(nil)
case *[]*Node:
*a = nil
default:
panic("can't happen")
}
return
}
// Simplify b to either *NodeList or []*Node.
if n, ok := b.(Nodes); ok {
b = n.Slice()
}
if l, ok := a.(**NodeList); ok {
switch b := b.(type) {
case *NodeList:
*l = b
case []*Node:
var ll *NodeList
for _, n := range b {
ll = list(ll, n)
}
*l = ll
default:
panic("can't happen")
}
} else {
var s []*Node
switch b := b.(type) {
case *NodeList:
for l := b; l != nil; l = l.Next {
s = append(s, l.N)
}
case []*Node:
s = b
default:
panic("can't happen")
}
switch a := a.(type) {
case *Nodes:
a.Set(s)
case *[]*Node:
*a = s
default:
panic("can't happen")
}
}
}
// setNodeSeqNode sets the node sequence a to the node n.
// a must have type **NodeList, *Nodes, or *[]*Node.
// This is an interim function during the transition from NodeList to Nodes.
// TODO(iant): Remove when transition is complete.
func setNodeSeqNode(a nodesOrNodeListPtr, n *Node) {
switch a := a.(type) {
case **NodeList:
*a = list1(n)
case *Nodes:
a.Set([]*Node{n})
case *[]*Node:
*a = []*Node{n}
default:
panic("can't happen")
}
}
// appendNodeSeq appends the node sequence b to the node sequence a.
// a must have type **NodeList, *Nodes, or *[]*Node.
// b must have type *NodeList, Nodes, or []*Node.
// This is an interim function during the transition from NodeList to Nodes.
// TODO(iant): Remove when transition is complete.
func appendNodeSeq(a nodesOrNodeListPtr, b nodesOrNodeList) {
// Simplify b to either *NodeList or []*Node.
if n, ok := b.(Nodes); ok {
b = n.Slice()
}
if l, ok := a.(**NodeList); ok {
switch b := b.(type) {
case *NodeList:
*l = concat(*l, b)
case []*Node:
for _, n := range b {
*l = list(*l, n)
}
default:
panic("can't happen")
}
} else {
var s []*Node
switch a := a.(type) {
case *Nodes:
s = a.Slice()
case *[]*Node:
s = *a
default:
panic("can't happen")
}
switch b := b.(type) {
case *NodeList:
for l := b; l != nil; l = l.Next {
s = append(s, l.N)
}
case []*Node:
s = append(s, b...)
default:
panic("can't happen")
}
switch a := a.(type) {
case *Nodes:
a.Set(s)
case *[]*Node:
*a = s
default:
panic("can't happen")
}
}
}
// appendNodeSeqNode appends n to the node sequence a.
// a must have type **NodeList, *Nodes, or *[]*Node.
// This is an interim function during the transition from NodeList to Nodes.
// TODO(iant): Remove when transition is complete.
func appendNodeSeqNode(a nodesOrNodeListPtr, n *Node) {
switch a := a.(type) {
case **NodeList:
*a = list(*a, n)
case *Nodes:
a.Append(n)
case *[]*Node:
*a = append(*a, n)
default:
panic("can't happen")
}
}
...@@ -878,7 +878,7 @@ opswitch: ...@@ -878,7 +878,7 @@ opswitch:
if !isblank(n.List.Second()) { if !isblank(n.List.Second()) {
r.Type.Type.Down.Type = n.List.Second().Type r.Type.Type.Down.Type = n.List.Second().Type
} }
setNodeSeq(&n.Rlist, list1(r)) n.Rlist.Set([]*Node{r})
n.Op = OAS2FUNC n.Op = OAS2FUNC
// don't generate a = *var if a is _ // don't generate a = *var if a is _
...@@ -1000,12 +1000,12 @@ opswitch: ...@@ -1000,12 +1000,12 @@ opswitch:
break break
} }
var ll *NodeList var ll []*Node
if !Isinter(n.Left.Type) { if !Isinter(n.Left.Type) {
ll = list(ll, typename(n.Left.Type)) ll = append(ll, typename(n.Left.Type))
} }
if !isnilinter(n.Type) { if !isnilinter(n.Type) {
ll = list(ll, typename(n.Type)) ll = append(ll, typename(n.Type))
} }
if !Isinter(n.Left.Type) && !isnilinter(n.Type) { if !Isinter(n.Left.Type) && !isnilinter(n.Type) {
sym := Pkglookup(Tconv(n.Left.Type, obj.FmtLeft)+"."+Tconv(n.Type, obj.FmtLeft), itabpkg) sym := Pkglookup(Tconv(n.Left.Type, obj.FmtLeft)+"."+Tconv(n.Type, obj.FmtLeft), itabpkg)
...@@ -1022,7 +1022,7 @@ opswitch: ...@@ -1022,7 +1022,7 @@ opswitch:
l := Nod(OADDR, sym.Def, nil) l := Nod(OADDR, sym.Def, nil)
l.Addable = true l.Addable = true
ll = list(ll, l) ll = append(ll, l)
if isdirectiface(n.Left.Type) { if isdirectiface(n.Left.Type) {
// For pointer types, we can make a special form of optimization // For pointer types, we can make a special form of optimization
...@@ -1042,7 +1042,7 @@ opswitch: ...@@ -1042,7 +1042,7 @@ opswitch:
fn := syslook("typ2Itab") fn := syslook("typ2Itab")
n1 = Nod(OCALL, fn, nil) n1 = Nod(OCALL, fn, nil)
setNodeSeq(&n1.List, ll) n1.List.Set(ll)
typecheck(&n1, Erv) typecheck(&n1, Erv)
walkexpr(&n1, init) walkexpr(&n1, init)
...@@ -1062,7 +1062,7 @@ opswitch: ...@@ -1062,7 +1062,7 @@ opswitch:
} }
if Isinter(n.Left.Type) { if Isinter(n.Left.Type) {
ll = list(ll, n.Left) ll = append(ll, n.Left)
} else { } else {
// regular types are passed by reference to avoid C vararg calls // regular types are passed by reference to avoid C vararg calls
// orderexpr arranged for n.Left to be a temporary for all // orderexpr arranged for n.Left to be a temporary for all
...@@ -1071,9 +1071,9 @@ opswitch: ...@@ -1071,9 +1071,9 @@ opswitch:
// with non-interface cases, is not visible to orderstmt, so we // with non-interface cases, is not visible to orderstmt, so we
// have to fall back on allocating a temp here. // have to fall back on allocating a temp here.
if islvalue(n.Left) { if islvalue(n.Left) {
ll = list(ll, Nod(OADDR, n.Left, nil)) ll = append(ll, Nod(OADDR, n.Left, nil))
} else { } else {
ll = list(ll, Nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil)) ll = append(ll, Nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil))
} }
dowidth(n.Left.Type) dowidth(n.Left.Type)
r := nodnil() r := nodnil()
...@@ -1086,7 +1086,7 @@ opswitch: ...@@ -1086,7 +1086,7 @@ opswitch:
r = Nod(OADDR, r.Left, nil) r = Nod(OADDR, r.Left, nil)
typecheck(&r, Erv) typecheck(&r, Erv)
} }
ll = list(ll, r) ll = append(ll, r)
} }
fn := syslook(convFuncName(n.Left.Type, n.Type)) fn := syslook(convFuncName(n.Left.Type, n.Type))
...@@ -1097,7 +1097,7 @@ opswitch: ...@@ -1097,7 +1097,7 @@ opswitch:
} }
dowidth(fn.Type) dowidth(fn.Type)
n = Nod(OCALL, fn, nil) n = Nod(OCALL, fn, nil)
setNodeSeq(&n.List, ll) n.List.Set(ll)
typecheck(&n, Erv) typecheck(&n, Erv)
walkexpr(&n, init) walkexpr(&n, init)
...@@ -1678,7 +1678,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node { ...@@ -1678,7 +1678,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
var nln, nrn Nodes var nln, nrn Nodes
nln.Set(nl) nln.Set(nl)
nrn.Set(nr) nrn.Set(nr)
Yyerror("error in shape across %v %v %v / %d %d [%s]", Hconv(nln, obj.FmtSign), Oconv(op, 0), Hconv(nrn, obj.FmtSign), nodeSeqLen(nl), nodeSeqLen(nr), Curfn.Func.Nname.Sym.Name) Yyerror("error in shape across %v %v %v / %d %d [%s]", Hconv(nln, obj.FmtSign), Oconv(op, 0), Hconv(nrn, obj.FmtSign), len(nl), len(nr), Curfn.Func.Nname.Sym.Name)
} }
return nn return nn
} }
...@@ -1766,7 +1766,7 @@ func mkdotargslice(lr0, nn []*Node, l *Type, fp int, init *Nodes, ddd *Node) []* ...@@ -1766,7 +1766,7 @@ func mkdotargslice(lr0, nn []*Node, l *Type, fp int, init *Nodes, ddd *Node) []*
tslice.Bound = -1 tslice.Bound = -1
var n *Node var n *Node
if nodeSeqLen(lr0) == 0 { if len(lr0) == 0 {
n = nodnil() n = nodnil()
n.Type = tslice n.Type = tslice
} else { } else {
...@@ -1825,13 +1825,13 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini ...@@ -1825,13 +1825,13 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini
lr0 := lr lr0 := lr
l, savel := IterFields(nl) l, savel := IterFields(nl)
var r *Node var r *Node
if nodeSeqLen(lr) > 0 { if len(lr) > 0 {
r = nodeSeqFirst(lr) r = lr[0]
} }
var nn []*Node var nn []*Node
// f(g()) where g has multiple return values // f(g()) where g has multiple return values
if r != nil && nodeSeqLen(lr) <= 1 && r.Type.Etype == TSTRUCT && r.Type.Funarg { if r != nil && len(lr) <= 1 && r.Type.Etype == TSTRUCT && r.Type.Funarg {
// optimization - can do block copy // optimization - can do block copy
if eqtypenoname(r.Type, nl) { if eqtypenoname(r.Type, nl) {
arg := nodarg(nl, fp) arg := nodarg(nl, fp)
...@@ -1857,7 +1857,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini ...@@ -1857,7 +1857,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini
walkstmt(&a) walkstmt(&a)
init.Append(a) init.Append(a)
lr = alist lr = alist
r = nodeSeqFirst(lr) r = lr[0]
l, savel = IterFields(nl) l, savel = IterFields(nl)
} }
...@@ -2808,7 +2808,7 @@ func appendslice(n *Node, init *Nodes) *Node { ...@@ -2808,7 +2808,7 @@ func appendslice(n *Node, init *Nodes) *Node {
nif := Nod(OIF, nil, nil) nif := Nod(OIF, nil, nil)
// n := len(s) + len(l2) - cap(s) // n := len(s) + len(l2) - cap(s)
setNodeSeq(&nif.Ninit, list1(Nod(OAS, nt, Nod(OSUB, Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil)), Nod(OCAP, s, nil))))) nif.Ninit.Set([]*Node{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))
...@@ -3966,7 +3966,7 @@ func walkprintfunc(np **Node, init *Nodes) { ...@@ -3966,7 +3966,7 @@ func walkprintfunc(np **Node, init *Nodes) {
typecheck(&fn, Etop) typecheck(&fn, Etop)
typechecklist(fn.Nbody.Slice(), Etop) typechecklist(fn.Nbody.Slice(), Etop)
xtop = list(xtop, fn) xtop = append(xtop, fn)
Curfn = oldfn Curfn = oldfn
a = Nod(OCALL, nil, nil) a = Nod(OCALL, nil, nil)
......
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