1
2
3
4
5 package escape
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "fmt"
11 )
12
13
14 func (e *escape) stmt(n ir.Node) {
15 if n == nil {
16 return
17 }
18
19 lno := ir.SetPos(n)
20 defer func() {
21 base.Pos = lno
22 }()
23
24 if base.Flag.LowerM > 2 {
25 fmt.Printf("%v:[%d] %v stmt: %v\n", base.FmtPos(base.Pos), e.loopDepth, e.curfn, n)
26 }
27
28 e.stmts(n.Init())
29
30 switch n.Op() {
31 default:
32 base.Fatalf("unexpected stmt: %v", n)
33
34 case ir.OFALL, ir.OINLMARK:
35
36
37 case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
38
39
40 case ir.OBLOCK:
41 n := n.(*ir.BlockStmt)
42 e.stmts(n.List)
43
44 case ir.ODCL:
45
46 n := n.(*ir.Decl)
47 if !ir.IsBlank(n.X) {
48 e.dcl(n.X)
49 }
50
51 case ir.OLABEL:
52 n := n.(*ir.LabelStmt)
53 if n.Label.IsBlank() {
54 break
55 }
56 switch e.labels[n.Label] {
57 case nonlooping:
58 if base.Flag.LowerM > 2 {
59 fmt.Printf("%v:%v non-looping label\n", base.FmtPos(base.Pos), n)
60 }
61 case looping:
62 if base.Flag.LowerM > 2 {
63 fmt.Printf("%v: %v looping label\n", base.FmtPos(base.Pos), n)
64 }
65 e.loopDepth++
66 default:
67 base.Fatalf("label %v missing tag", n.Label)
68 }
69 delete(e.labels, n.Label)
70
71 case ir.OIF:
72 n := n.(*ir.IfStmt)
73 e.discard(n.Cond)
74 e.block(n.Body)
75 e.block(n.Else)
76
77 case ir.OCHECKNIL:
78 n := n.(*ir.UnaryExpr)
79 e.discard(n.X)
80
81 case ir.OFOR:
82 n := n.(*ir.ForStmt)
83 base.Assert(!n.DistinctVars)
84 e.loopDepth++
85 e.discard(n.Cond)
86 e.stmt(n.Post)
87 e.block(n.Body)
88 e.loopDepth--
89
90 case ir.ORANGE:
91
92 n := n.(*ir.RangeStmt)
93 base.Assert(!n.DistinctVars)
94
95
96
97 tmp := e.newLoc(nil, true)
98 e.expr(tmp.asHole(), n.X)
99
100 e.loopDepth++
101 ks := e.addrs([]ir.Node{n.Key, n.Value})
102 if n.X.Type().IsArray() {
103 e.flow(ks[1].note(n, "range"), tmp)
104 } else {
105 e.flow(ks[1].deref(n, "range-deref"), tmp)
106 }
107 e.reassigned(ks, n)
108
109 e.block(n.Body)
110 e.loopDepth--
111
112 case ir.OSWITCH:
113 n := n.(*ir.SwitchStmt)
114
115 if guard, ok := n.Tag.(*ir.TypeSwitchGuard); ok {
116 var ks []hole
117 if guard.Tag != nil {
118 for _, cas := range n.Cases {
119 cv := cas.Var
120 k := e.dcl(cv)
121 if cv.Type().HasPointers() {
122 ks = append(ks, k.dotType(cv.Type(), cas, "switch case"))
123 }
124 }
125 }
126 e.expr(e.teeHole(ks...), n.Tag.(*ir.TypeSwitchGuard).X)
127 } else {
128 e.discard(n.Tag)
129 }
130
131 for _, cas := range n.Cases {
132 e.discards(cas.List)
133 e.block(cas.Body)
134 }
135
136 case ir.OSELECT:
137 n := n.(*ir.SelectStmt)
138 for _, cas := range n.Cases {
139 e.stmt(cas.Comm)
140 e.block(cas.Body)
141 }
142 case ir.ORECV:
143
144 n := n.(*ir.UnaryExpr)
145 e.exprSkipInit(e.discardHole(), n)
146 case ir.OSEND:
147 n := n.(*ir.SendStmt)
148 e.discard(n.Chan)
149 e.assignHeap(n.Value, "send", n)
150
151 case ir.OAS:
152 n := n.(*ir.AssignStmt)
153 e.assignList([]ir.Node{n.X}, []ir.Node{n.Y}, "assign", n)
154 case ir.OASOP:
155 n := n.(*ir.AssignOpStmt)
156
157 e.assignList([]ir.Node{n.X}, []ir.Node{n.Y}, "assign", n)
158 case ir.OAS2:
159 n := n.(*ir.AssignListStmt)
160 e.assignList(n.Lhs, n.Rhs, "assign-pair", n)
161
162 case ir.OAS2DOTTYPE:
163 n := n.(*ir.AssignListStmt)
164 e.assignList(n.Lhs, n.Rhs, "assign-pair-dot-type", n)
165 case ir.OAS2MAPR:
166 n := n.(*ir.AssignListStmt)
167 e.assignList(n.Lhs, n.Rhs, "assign-pair-mapr", n)
168 case ir.OAS2RECV, ir.OSELRECV2:
169 n := n.(*ir.AssignListStmt)
170 e.assignList(n.Lhs, n.Rhs, "assign-pair-receive", n)
171
172 case ir.OAS2FUNC:
173 n := n.(*ir.AssignListStmt)
174 e.stmts(n.Rhs[0].Init())
175 ks := e.addrs(n.Lhs)
176 e.call(ks, n.Rhs[0])
177 e.reassigned(ks, n)
178 case ir.ORETURN:
179 n := n.(*ir.ReturnStmt)
180 results := e.curfn.Type().Results()
181 dsts := make([]ir.Node, len(results))
182 for i, res := range results {
183 dsts[i] = res.Nname.(*ir.Name)
184 }
185 e.assignList(dsts, n.Results, "return", n)
186 case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OINLCALL, ir.OCLEAR, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTLN, ir.ORECOVERFP:
187 e.call(nil, n)
188 case ir.OGO, ir.ODEFER:
189 n := n.(*ir.GoDeferStmt)
190 e.goDeferStmt(n)
191
192 case ir.OTAILCALL:
193 n := n.(*ir.TailCallStmt)
194 e.call(nil, n.Call)
195 }
196 }
197
198 func (e *escape) stmts(l ir.Nodes) {
199 for _, n := range l {
200 e.stmt(n)
201 }
202 }
203
204
205 func (e *escape) block(l ir.Nodes) {
206 old := e.loopDepth
207 e.stmts(l)
208 e.loopDepth = old
209 }
210
211 func (e *escape) dcl(n *ir.Name) hole {
212 if n.Curfn != e.curfn || n.IsClosureVar() {
213 base.Fatalf("bad declaration of %v", n)
214 }
215 loc := e.oldLoc(n)
216 loc.loopDepth = e.loopDepth
217 return loc.asHole()
218 }
219
View as plain text