1
0
mirror of https://github.com/golang/go synced 2024-11-17 23:34:52 -07:00

cmd/compile: change sinit.go functions into methods

This will make it easier for subsequent CLs to track additional state
during package initialization scheduling.

Passes toolstash-check.

Updates #22326.

Change-Id: I528792ad34f41a4be52951531eb7525a94c9f350
Reviewed-on: https://go-review.googlesource.com/c/go/+/169898
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Matthew Dempsky 2019-03-25 12:32:41 -07:00
parent c196d38d5e
commit ee2836048c
2 changed files with 57 additions and 49 deletions

View File

@ -208,9 +208,9 @@ func (o *Order) addrTemp(n *Node) *Node {
dowidth(n.Type)
vstat := staticname(n.Type)
vstat.Name.SetReadonly(true)
var out []*Node
staticassign(vstat, n, &out)
if out != nil {
var s InitSchedule
s.staticassign(vstat, n)
if s.out != nil {
Fatalf("staticassign of const generated code: %+v", n)
}
vstat = typecheck(vstat, ctxExpr)

View File

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