LEFT | RIGHT |
1 package ssa | 1 package ssa |
2 | 2 |
3 // This package defines a high-level intermediate representation for | 3 // This package defines a high-level intermediate representation for |
4 // Go programs using static single-assignment (SSA) form. | 4 // Go programs using static single-assignment (SSA) form. |
5 | 5 |
6 import ( | 6 import ( |
7 "fmt" | 7 "fmt" |
8 "go/ast" | 8 "go/ast" |
9 "go/token" | 9 "go/token" |
10 "go/types" | 10 "go/types" |
11 ) | 11 ) |
12 | 12 |
13 // A Package a single analyzed Go package, containing Members for all | 13 // A Program is a partial or complete Go program converted to SSA form. |
14 // package-level functions, variables, constants and types it | 14 // Each Builder creates and populates a single Program during its |
| 15 // lifetime. |
| 16 // |
| 17 // TODO(adonovan): synthetic methods for promoted methods and for |
| 18 // standalone interface methods do not belong to any package. Make |
| 19 // them enumerable here. |
| 20 // |
| 21 // TODO(adonovan): MethodSets of types other than named types |
| 22 // (i.e. anon structs) are not currently accessible, nor are they |
| 23 // memoized. Add a method: MethodSetForType() which looks in the |
| 24 // appropriate Package (for methods of named types) or in |
| 25 // Program.AnonStructMethods (for methods of anon structs). |
| 26 // |
| 27 type Program struct { |
| 28 » Files *token.FileSet // position information for the files
of this Program |
| 29 » Packages map[string]*Package // all loaded Packages, keyed by impo
rt path |
| 30 » Builtins map[types.Object]*Builtin // all built-in functions, keyed by t
ypechecker objects. |
| 31 } |
| 32 |
| 33 // A Package is a single analyzed Go package, containing Members for |
| 34 // all package-level functions, variables, constants and types it |
15 // declares. These may be accessed directly via Members, or via the | 35 // declares. These may be accessed directly via Members, or via the |
16 // type-specific accessor methods Func, Type, Var and Const. | 36 // type-specific accessor methods Func, Type, Var and Const. |
17 // | 37 // |
18 type Package struct { | 38 type Package struct { |
| 39 Prog *Program // the owning program |
19 Types *types.Package // the type checker's package object for th
is package. | 40 Types *types.Package // the type checker's package object for th
is package. |
20 ImportPath string // e.g. "sync/atomic" | 41 ImportPath string // e.g. "sync/atomic" |
21 » Position token.Position // position of an arbitrary file in the pac
kage [this will change] | 42 » Pos token.Pos // position of an arbitrary file in the pac
kage |
22 Members map[string]Member // all exported and unexported members of t
he package | 43 Members map[string]Member // all exported and unexported members of t
he package |
23 AnonFuncs []*Function // all anonymous functions in this package | 44 AnonFuncs []*Function // all anonymous functions in this package |
24 Init *Function // the package's (concatenated) init functi
on | 45 Init *Function // the package's (concatenated) init functi
on |
25 | 46 |
26 // The following fields are set transiently during building, | 47 // The following fields are set transiently during building, |
27 // then cleared. | 48 // then cleared. |
28 files []*ast.File // the abstract syntax tree for the files of the packa
ge | 49 files []*ast.File // the abstract syntax tree for the files of the packa
ge |
29 } | 50 } |
30 | 51 |
31 // A Member is a member of a Go package, implemented by *Literal, | 52 // A Member is a member of a Go package, implemented by *Literal, |
(...skipping 14 matching lines...) Expand all Loading... |
46 // letter, a simple string is unambiguous. | 67 // letter, a simple string is unambiguous. |
47 // | 68 // |
48 // However, a method set or struct may contain multiple unexported | 69 // However, a method set or struct may contain multiple unexported |
49 // names with identical spelling that are logically distinct because | 70 // names with identical spelling that are logically distinct because |
50 // they originate in different packages. Unexported names must | 71 // they originate in different packages. Unexported names must |
51 // therefore be disambiguated by their package too. | 72 // therefore be disambiguated by their package too. |
52 // | 73 // |
53 // The Pkg field of an Id is therefore nil iff the name is exported. | 74 // The Pkg field of an Id is therefore nil iff the name is exported. |
54 // | 75 // |
55 // This type is suitable for use as a map key because the equivalence | 76 // This type is suitable for use as a map key because the equivalence |
56 // relation == is consistent with identifier equality. (QualifiedName | 77 // relation == is consistent with identifier equality. |
57 // instances returned by the type-checker do not have this property.) | 78 type Id struct { |
58 // | 79 » Pkg *types.Package |
59 type Id types.QualifiedName | 80 » Name string |
| 81 } |
60 | 82 |
61 // A MethodSet contains all the methods whose receiver is either T or | 83 // A MethodSet contains all the methods whose receiver is either T or |
62 // *T, for some named or struct type T. | 84 // *T, for some named or struct type T. |
63 // | 85 // |
64 // TODO(adonovan): the client is required to adapt T<=>*T, e.g. when | 86 // TODO(adonovan): the client is required to adapt T<=>*T, e.g. when |
65 // invoking an interface method. (This could be simplified for the | 87 // invoking an interface method. (This could be simplified for the |
66 // client by having distinct method sets for T and *T, with the SSA | 88 // client by having distinct method sets for T and *T, with the SSA |
67 // Builder generating wrappers as needed, but probably the client is | 89 // Builder generating wrappers as needed, but probably the client is |
68 // able to do a better job.) Document the precise rules the client | 90 // able to do a better job.) Document the precise rules the client |
69 // must follow. | 91 // must follow. |
70 // | 92 // |
71 type MethodSet map[Id]*Function | 93 type MethodSet map[Id]*Function |
72 | 94 |
73 // A Type is a Member of a Package representing the name, underlying | 95 // A Type is a Member of a Package representing the name, underlying |
74 // type and method set of a named type declared at package scope. | 96 // type and method set of a named type declared at package scope. |
75 // | 97 // |
76 // The method set contains only concrete methods; it is empty for | 98 // The method set contains only concrete methods; it is empty for |
77 // interface types. | 99 // interface types. |
78 // | 100 // |
79 type Type struct { | 101 type Type struct { |
80 NamedType *types.NamedType | 102 NamedType *types.NamedType |
81 Methods MethodSet | 103 Methods MethodSet |
82 } | 104 } |
83 | 105 |
84 // An SSA value that can be referenced by an instruction. | 106 // An SSA value that can be referenced by an instruction. |
85 // | |
86 // The following types are assignable to Value: Capture, Parameter, | |
87 // Literal, Global, Function, Builtin, plus all of the following | |
88 // instructions: Alloc, Phi, Call, BinOp, UnOp, MakeClosure, MakeChan, | |
89 // MakeMap, MakeSlice, Slice, Field, FieldAddr, IndexAddr, Index, | |
90 // Select, Range, TypeAssert, Extract, Next, Lookup, Conv, | |
91 // ChangeInterface, MakeInterface. | |
92 // | 107 // |
93 // TODO(adonovan): add methods: | 108 // TODO(adonovan): add methods: |
94 // - Referrers() []*Instruction // all instructions that refer to this value. | 109 // - Referrers() []*Instruction // all instructions that refer to this value. |
95 // | 110 // |
96 type Value interface { | 111 type Value interface { |
97 // Name returns the name of this value, and determines how | 112 // Name returns the name of this value, and determines how |
98 // this Value appears when used as an operand of an | 113 // this Value appears when used as an operand of an |
99 // Instruction. | 114 // Instruction. |
100 // | 115 // |
101 // This is the same as the source name for Parameters, | 116 // This is the same as the source name for Parameters, |
102 // Builtins, Functions, Captures, Globals and some Allocs. | 117 // Builtins, Functions, Captures, Globals and some Allocs. |
103 // For literals, it is a representation of the literal's value | 118 // For literals, it is a representation of the literal's value |
104 // and type. For all other Values this is the name of the | 119 // and type. For all other Values this is the name of the |
105 // virtual register defined by the instruction. | 120 // virtual register defined by the instruction. |
106 // | 121 // |
107 » // With the exception of Builtin, the name of an SSA Value is | 122 » // The name of an SSA Value is not semantically significant, |
108 » // not semantically significant, and may not even be unique | 123 » // and may not even be unique within a function. |
109 » // within a function. | |
110 Name() string | 124 Name() string |
111 | 125 |
112 // If this value is an Instruction, String returns its | 126 // If this value is an Instruction, String returns its |
113 // disassembled form; otherwise it returns unspecified | 127 // disassembled form; otherwise it returns unspecified |
114 // human-readable information about the Value, such as its | 128 // human-readable information about the Value, such as its |
115 // kind, name and type. | 129 // kind, name and type. |
116 String() string | 130 String() string |
117 | 131 |
118 // Type returns the type of this value. Many instructions | 132 // Type returns the type of this value. Many instructions |
119 // (e.g. IndexAddr) change the behaviour depending on the | 133 // (e.g. IndexAddr) change the behaviour depending on the |
120 // types of their operands. | 134 // types of their operands. |
121 // | 135 // |
122 // Documented type invariants below (e.g. "Alloc.Type() | 136 // Documented type invariants below (e.g. "Alloc.Type() |
123 // returns a *types.Pointer") refer to the underlying type in | 137 // returns a *types.Pointer") refer to the underlying type in |
124 // the case of NamedTypes. | 138 // the case of NamedTypes. |
125 Type() types.Type | 139 Type() types.Type |
126 | 140 |
127 // Dummy method to indicate the "implements" relation. | 141 // Dummy method to indicate the "implements" relation. |
128 ImplementsValue() | 142 ImplementsValue() |
129 } | 143 } |
130 | 144 |
131 // An Instruction is an SSA instruction that computes a new Value or | 145 // An Instruction is an SSA instruction that computes a new Value or |
132 // has some effect. | 146 // has some effect. |
133 // | 147 // |
134 // An Instruction that defines a value (e.g. BinOp) also implements | 148 // An Instruction that defines a value (e.g. BinOp) also implements |
135 // the Value interface; an Instruction that only has an effect (e.g. Store) | 149 // the Value interface; an Instruction that only has an effect (e.g. Store) |
136 // does not. | 150 // does not. |
137 // | |
138 // The following types are assignable to Instruction: If, Jump, Ret, | |
139 // Alloc Phi, Call, BinOp, UnOp, MakeClosure, MakeChan, MakeMap, | |
140 // MakeSlice, Slice, Field, FieldAddr, IndexAddr, Index, Select, | |
141 // Range, TypeAssert, Extract, Go, Defer, Send, Store, MapUpdate, | |
142 // Next, Lookup, Conv, ChangeInterface, MakeInterface. | |
143 // | 151 // |
144 // TODO(adonovan): add method: | 152 // TODO(adonovan): add method: |
145 // - Operands() []Value // all Values referenced by this instruction. | 153 // - Operands() []Value // all Values referenced by this instruction. |
146 // | 154 // |
147 type Instruction interface { | 155 type Instruction interface { |
148 // String returns the disassembled form of this value. e.g. | 156 // String returns the disassembled form of this value. e.g. |
149 // | 157 // |
150 // Examples of Instructions that define a Value: | 158 // Examples of Instructions that define a Value: |
151 // e.g. "x + y" (BinOp) | 159 // e.g. "x + y" (BinOp) |
152 // "len([])" (Call) | 160 // "len([])" (Call) |
(...skipping 19 matching lines...) Expand all Loading... |
172 | 180 |
173 // Dummy method to indicate the "implements" relation. | 181 // Dummy method to indicate the "implements" relation. |
174 ImplementsInstruction() | 182 ImplementsInstruction() |
175 } | 183 } |
176 | 184 |
177 // Function represents the parameters, results and code of a function | 185 // Function represents the parameters, results and code of a function |
178 // or method. | 186 // or method. |
179 // | 187 // |
180 // If Blocks is nil, this indicates an external function for which no | 188 // If Blocks is nil, this indicates an external function for which no |
181 // Go source code is available. In this case, Captures and Locals | 189 // Go source code is available. In this case, Captures and Locals |
182 // will be nil too. | 190 // will be nil too. Clients performing whole-program analysis must |
183 // TODO(adonovan): add Params to this list; I think only | 191 // handle external functions specially. |
184 // print.go needs it. | |
185 // Clients performing whole-program analysis must handle external | |
186 // functions specially. | |
187 // | 192 // |
188 // Functions are immutable values; they do not have addresses. | 193 // Functions are immutable values; they do not have addresses. |
189 // | 194 // |
190 // Blocks[0] is the function entry point; block order is not otherwise | 195 // Blocks[0] is the function entry point; block order is not otherwise |
191 // semantically significant, though it may affect the readability of | 196 // semantically significant, though it may affect the readability of |
192 // the disassembly. | 197 // the disassembly. |
193 // | 198 // |
194 // A nested function that refers to one or more lexically enclosing | 199 // A nested function that refers to one or more lexically enclosing |
195 // local variables ("free variables") has Capture parameters. Such | 200 // local variables ("free variables") has Capture parameters. Such |
196 // functions cannot be called directly but require a value created by | 201 // functions cannot be called directly but require a value created by |
197 // MakeClosure which, via its Bindings, supplies values for these | 202 // MakeClosure which, via its Bindings, supplies values for these |
198 // parameters. Captures are always addresses. | 203 // parameters. Captures are always addresses. |
199 // | 204 // |
200 // If the function is a method (Signature.Recv != nil) then the first | 205 // If the function is a method (Signature.Recv != nil) then the first |
201 // element of Params is the receiver parameter. | 206 // element of Params is the receiver parameter. |
202 // | 207 // |
203 // Type() returns the function's Signature. | 208 // Type() returns the function's Signature. |
204 // | 209 // |
205 // Function implements the Value and Member interface. | |
206 // | |
207 // Clients may need to construct additional Function values directly, | |
208 // e.g. for handling externals and intrinsics with special semantics. | |
209 // NewFunction is provided for this purpose. | |
210 // TODO(adonovan): export the name field and abolish NewFunction. | |
211 // But: "Name" is already taken by a method. | |
212 // | |
213 type Function struct { | 210 type Function struct { |
214 Name_ string | 211 Name_ string |
215 Signature *types.Signature | 212 Signature *types.Signature |
216 | 213 |
217 » Position token.Position // location of the definition [this will change
] | 214 » Pos token.Pos // location of the definition |
218 » Enclosing *Function // enclosing function if anon; nil if global | 215 » Enclosing *Function // enclosing function if anon; nil if global |
219 » Pkg *Package // enclosing package; nil for some synthetic me
thods | 216 » Pkg *Package // enclosing package; nil for some synthetic methods |
| 217 » Prog *Program // enclosing program |
220 Params []*Parameter | 218 Params []*Parameter |
221 FreeVars []*Capture // free variables whose values must be supplied by
closure | 219 FreeVars []*Capture // free variables whose values must be supplied by
closure |
222 Locals []*Alloc | 220 Locals []*Alloc |
223 Blocks []*BasicBlock // basic blocks of the function; nil => external | 221 Blocks []*BasicBlock // basic blocks of the function; nil => external |
224 | 222 |
225 // The following fields are set transiently during building, | 223 // The following fields are set transiently during building, |
226 // then cleared. | 224 // then cleared. |
227 » syntax *funcSyntax // abstract syntax trees for Go sou
rce functions | 225 » currentBlock *BasicBlock // where to emit code |
228 » currentBlock *BasicBlock // where to emit code | 226 » objects map[types.Object]Value // addresses of local variables |
229 » objects map[types.Object]Value // addresses of local variables | 227 » results []*Alloc // tuple of named results |
230 » results []*Alloc // tuple of named results | 228 » // syntax *funcSyntax // abstract syntax trees for Go sou
rce functions |
231 » targets *targets // linked stack of branch targets | 229 » // targets *targets // linked stack of branch targets |
232 » lblocks map[*ast.Object]*lblock // labelled blocks | 230 » // lblocks map[*ast.Object]*lblock // labelled blocks |
233 } | 231 } |
234 | 232 |
235 // An SSA basic block. | 233 // An SSA basic block. |
236 // | 234 // |
237 // The final element of Instructions is always an explicit transfer of | 235 // The final element of Instrs is always an explicit transfer of |
238 // control (If, Jump or Ret). | 236 // control (If, Jump or Ret). |
239 // | 237 // |
240 // BasicBlocks and their Preds/Succs relation form a possibly cyclic | 238 // A block may contain no Instructions only if it is unreachable, |
241 // multigraph independent of the SSA Value graph. | 239 // i.e. Preds is nil. Empty blocks are typically pruned. |
242 // | 240 // |
243 // The order in which edges appear in Preds is significant to any Phi | 241 // BasicBlocks and their Preds/Succs relation form a (possibly cyclic) |
244 // nodes within Instructions. | 242 // graph independent of the SSA Value graph. It is illegal for |
| 243 // multiple edges to exist between the same pair of blocks. |
| 244 // |
| 245 // The order of Preds and Succs are significant (to Phi and If |
| 246 // instructions, respectively). |
245 // | 247 // |
246 type BasicBlock struct { | 248 type BasicBlock struct { |
247 Name string // label; no semantic significance | 249 Name string // label; no semantic significance |
248 Func *Function // containing function | 250 Func *Function // containing function |
249 Instrs []Instruction // instructions in order | 251 Instrs []Instruction // instructions in order |
250 Preds, Succs []*BasicBlock // predecessors and successors | 252 Preds, Succs []*BasicBlock // predecessors and successors |
251 } | 253 } |
252 | 254 |
253 // Pure values ---------------------------------------- | 255 // Pure values ---------------------------------------- |
254 | 256 |
255 // A Capture is a pointer to a lexically enclosing local variable. | 257 // A Capture is a pointer to a lexically enclosing local variable. |
256 // | 258 // |
257 // The referent of a capture is a Parameter, Alloc or another Capture | 259 // The referent of a capture is a Parameter, Alloc or another Capture |
258 // and is always considered potentially escaping, so Captures are | 260 // and is always considered potentially escaping, so Captures are |
259 // always addresses in the heap, and have pointer types. | 261 // always addresses in the heap, and have pointer types. |
260 // | 262 // |
261 // Capture implements the Value interface. | |
262 // | |
263 type Capture struct { | 263 type Capture struct { |
264 Name_ string | |
265 Type_ *types.Pointer | |
266 Outer Value // the Value captured from the enclosing context. | 264 Outer Value // the Value captured from the enclosing context. |
267 } | 265 } |
268 | 266 |
269 // A Parameter represents an input parameter of a function. | 267 // A Parameter represents an input parameter of a function. |
270 // | 268 // |
271 // Parameters are addresses and thus have pointer types. | 269 // Parameters are addresses and thus have pointer types. |
272 // TODO(adonovan): this will change. We should just spill parameters | 270 // TODO(adonovan): this will change. We should just spill parameters |
273 // to ordinary Alloc-style locals if they are ever used in an | 271 // to ordinary Alloc-style locals if they are ever used in an |
274 // addressable context. Then we can lose the Heap flag. | 272 // addressable context. Then we can lose the Heap flag. |
275 // | 273 // |
276 // In the common case where Heap=false, Parameters are pointers into | 274 // In the common case where Heap=false, Parameters are pointers into |
277 // the stack frame of the owning function. If the case where | 275 // the function's stack frame. If the case where Heap=true because a |
278 // Heap=true because a parameter's address may escape from its owning | 276 // parameter's address may escape from its function, Parameters are |
279 // function, Parameters are pointers into a space in the heap | 277 // pointers into a space in the heap implicitly allocated during the |
280 // implicitly allocated during the function call. (See also Alloc, | 278 // function call. (See also Alloc, which uses the Heap flag in a |
281 // which uses the Heap flag in a similar manner.) | 279 // similar manner.) |
282 // | |
283 // Parameter implements the Value interface. | |
284 // | 280 // |
285 type Parameter struct { | 281 type Parameter struct { |
286 Name_ string | 282 Name_ string |
287 Type_ *types.Pointer | 283 Type_ *types.Pointer |
288 Heap bool | 284 Heap bool |
289 } | 285 } |
290 | 286 |
291 // A Literal represents a literal nil, boolean, string or numeric | 287 // A Literal represents a literal nil, boolean, string or numeric |
292 // (integer, fraction or complex) value. | 288 // (integer, fraction or complex) value. |
293 // | 289 // |
294 // A literal's underlying Type() can be a basic type, possibly one of | 290 // A literal's underlying Type() can be a basic type, possibly one of |
295 // the "untyped" types. A nil literal can have any reference type: | 291 // the "untyped" types. A nil literal can have any reference type: |
296 // interface, map, channel, pointer, slice, or function---but not | 292 // interface, map, channel, pointer, slice, or function---but not |
297 // "untyped nil". | 293 // "untyped nil". |
298 // | 294 // |
299 // All source-level constant expressions are represented by a Literal | 295 // All source-level constant expressions are represented by a Literal |
300 // of equal type and value. | 296 // of equal type and value. |
301 // | 297 // |
302 // Value holds the exact value of the literal, independent of its | 298 // Value holds the exact value of the literal, independent of its |
303 // Type(), using the same representation as package go/types uses for | 299 // Type(), using the same representation as package go/types uses for |
304 // constants. | 300 // constants. |
305 // | 301 // |
306 // Literal implements the Value and Member interfaces. | |
307 // | |
308 // Example printed form: | 302 // Example printed form: |
309 // 42:int | 303 // 42:int |
310 // "hello":untyped string | 304 // "hello":untyped string |
311 // 3+4i:MyComplex | 305 // 3+4i:MyComplex |
312 // | 306 // |
313 type Literal struct { | 307 type Literal struct { |
314 Type_ types.Type | 308 Type_ types.Type |
315 Value interface{} | 309 Value interface{} |
316 } | 310 } |
317 | 311 |
318 // A Global is a named Value holding the address of a package-level | 312 // A Global is a named Value holding the address of a package-level |
319 // variable. | 313 // variable. |
320 // | |
321 // Global implements the Value and Member interface. | |
322 // | 314 // |
323 type Global struct { | 315 type Global struct { |
324 Name_ string | 316 Name_ string |
325 Type_ types.Type | 317 Type_ types.Type |
326 Pkg *Package | 318 Pkg *Package |
327 | 319 |
328 // The following fields are set transiently during building, | 320 // The following fields are set transiently during building, |
329 // then cleared. | 321 // then cleared. |
330 spec *ast.ValueSpec // explained at buildGlobal | 322 spec *ast.ValueSpec // explained at buildGlobal |
331 } | 323 } |
332 | 324 |
333 // A built-in function, e.g. len. | 325 // A built-in function, e.g. len. |
334 // | 326 // |
335 // Builtins are immutable values; they do not have addresses. | 327 // Builtins are immutable values; they do not have addresses. |
336 // | 328 // |
337 // Type() returns an inscrutable *types.builtin. Built-in functions | 329 // Type() returns an inscrutable *types.builtin. Built-in functions |
338 // may have polymorphic or variadic types that are not expressible in | 330 // may have polymorphic or variadic types that are not expressible in |
339 // Go's type system. | 331 // Go's type system. |
340 // | 332 // |
341 // The Name() of a Builtin determines which built-in function it | |
342 // denotes. | |
343 // | |
344 // Builtin implements the Value interface. | |
345 // | |
346 type Builtin struct { | 333 type Builtin struct { |
347 » Name_ string | 334 » Object *types.Func // canonical types.Universe object for this built-in |
348 » Type_ types.Type | |
349 } | 335 } |
350 | 336 |
351 // Value-defining instructions ---------------------------------------- | 337 // Value-defining instructions ---------------------------------------- |
352 | 338 |
353 // The Alloc instruction reserves space for a value of the given type, | 339 // The Alloc instruction reserves space for a value of the given type, |
354 // zero-initializes it, and yields its address. | 340 // zero-initializes it, and yields its address. |
355 // | 341 // |
356 // Alloc values are always addresses, and have pointer types, so the | 342 // Alloc values are always addresses, and have pointer types, so the |
357 // type of the allocated space is actually indirect(Type()). | 343 // type of the allocated space is actually indirect(Type()). |
358 // | 344 // |
359 // If Heap is false, Alloc allocates space in the function's | 345 // If Heap is false, Alloc allocates space in the function's |
360 // activation record (frame); we refer to an Alloc(Heap=false) as a | 346 // activation record (frame); we refer to an Alloc(Heap=false) as a |
361 // "local" alloc. Each local Alloc returns the same address each time | 347 // "local" alloc. Each local Alloc returns the same address each time |
362 // it is executed within the same activation; the space is | 348 // it is executed within the same activation; the space is |
363 // re-initialized to zero. | 349 // re-initialized to zero. |
364 // | 350 // |
365 // If Heap is true, Alloc allocates space in the heap, and returns; we | 351 // If Heap is true, Alloc allocates space in the heap, and returns; we |
366 // refer to an Alloc(Heap=true) as a "new" alloc. Each new Alloc | 352 // refer to an Alloc(Heap=true) as a "new" alloc. Each new Alloc |
367 // returns a different address each time it is executed. | 353 // returns a different address each time it is executed. |
368 // | 354 // |
369 // When Alloc is applied to a channel, map or slice type, it returns | 355 // When Alloc is applied to a channel, map or slice type, it returns |
370 // the address of an uninitialized (nil) reference of that kind; store | 356 // the address of an uninitialized (nil) reference of that kind; store |
371 // the result of MakeSlice, MakeMap or MakeChan in that location to | 357 // the result of MakeSlice, MakeMap or MakeChan in that location to |
372 // instantiate these types. | 358 // instantiate these types. |
373 // | 359 // |
374 // Alloc implements the Value and Instruction interfaces. | |
375 // | |
376 // Example printed form: | 360 // Example printed form: |
377 // t0 = local int | 361 // t0 = local int |
378 // t1 = new int | 362 // t1 = new int |
379 // | 363 // |
380 type Alloc struct { | 364 type Alloc struct { |
381 anInstruction | 365 anInstruction |
382 Name_ string | 366 Name_ string |
383 Type_ types.Type | 367 Type_ types.Type |
384 Heap bool | 368 Heap bool |
385 } | 369 } |
386 | 370 |
387 // Phi represents an SSA φ-node, which combines values that differ | 371 // Phi represents an SSA φ-node, which combines values that differ |
388 // across incoming control-flow edges and yields a new value. Within | 372 // across incoming control-flow edges and yields a new value. Within |
389 // a block, all φ-nodes must appear before all non-φ nodes. | 373 // a block, all φ-nodes must appear before all non-φ nodes. |
390 // | 374 // |
391 // Phi implements the Value and Instruction interfaces. | |
392 // | |
393 // Example printed form: | 375 // Example printed form: |
394 // t2 = phi [0.start: t0, 1.if.then: t1, ...] | 376 // t2 = phi [0.start: t0, 1.if.then: t1, ...] |
395 // | 377 // |
396 type Phi struct { | 378 type Phi struct { |
397 Register | 379 Register |
398 Edges []Value // Edges[i] is value for Block().Preds[i] | 380 Edges []Value // Edges[i] is value for Block().Preds[i] |
399 } | 381 } |
400 | 382 |
401 // Call represents a function or method call. | 383 // Call represents a function or method call. |
402 // | 384 // |
403 // The Call instruction yields the function result, if there is | 385 // The Call instruction yields the function result, if there is |
404 // exactly one, or a tuple (empty or len>1) whose components are | 386 // exactly one, or a tuple (empty or len>1) whose components are |
405 // accessed via Extract. | 387 // accessed via Extract. |
406 // | 388 // |
407 // See CallCommon for generic function call documentation. | 389 // See CallCommon for generic function call documentation. |
408 // | 390 // |
409 // Call implements the Value and Instruction interfaces. | |
410 // | |
411 // Example printed form: | 391 // Example printed form: |
412 // t2 = println(t0, t1) | 392 // t2 = println(t0, t1) |
413 // t4 = t3() | 393 // t4 = t3() |
414 // t7 = invoke t5.Println(...t6) | 394 // t7 = invoke t5.Println(...t6) |
415 // | 395 // |
416 type Call struct { | 396 type Call struct { |
417 Register | 397 Register |
418 CallCommon | 398 CallCommon |
419 } | 399 } |
420 | 400 |
421 // BinOp yields the result of binary operation X Op Y. | 401 // BinOp yields the result of binary operation X Op Y. |
422 // | |
423 // BinOp implements the Value and Instruction interfaces. | |
424 // | 402 // |
425 // Example printed form: | 403 // Example printed form: |
426 // t1 = t0 + 1:int | 404 // t1 = t0 + 1:int |
427 // | 405 // |
428 type BinOp struct { | 406 type BinOp struct { |
429 Register | 407 Register |
430 // One of: | 408 // One of: |
431 // ADD SUB MUL QUO REM + - * / % | 409 // ADD SUB MUL QUO REM + - * / % |
432 // AND OR XOR SHL SHR AND_NOT & | ^ << >> &~ | 410 // AND OR XOR SHL SHR AND_NOT & | ^ << >> &~ |
433 // EQL LSS GTR NEQ LEQ GEQ == != < <= < >= | 411 // EQL LSS GTR NEQ LEQ GEQ == != < <= < >= |
434 Op token.Token | 412 Op token.Token |
435 X, Y Value | 413 X, Y Value |
436 } | 414 } |
437 | 415 |
438 // UnOp yields the result of Op X. | 416 // UnOp yields the result of Op X. |
439 // ARROW is channel receive. | 417 // ARROW is channel receive. |
440 // MUL is pointer indirection (load). | 418 // MUL is pointer indirection (load). |
441 // | 419 // |
442 // If CommaOk and Op=ARROW, the result is a 2-tuple of the value above | 420 // If CommaOk and Op=ARROW, the result is a 2-tuple of the value above |
443 // and a boolean indicating the success of the receive. The | 421 // and a boolean indicating the success of the receive. The |
444 // components of the tuple are accessed using Extract. | 422 // components of the tuple are accessed using Extract. |
445 // | |
446 // UnOp implements the Value and Instruction interfaces. | |
447 // | 423 // |
448 // Example printed form: | 424 // Example printed form: |
449 // t0 = *x | 425 // t0 = *x |
450 // t2 = <-t1,ok | 426 // t2 = <-t1,ok |
451 // | 427 // |
452 type UnOp struct { | 428 type UnOp struct { |
453 Register | 429 Register |
454 Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^ | 430 Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^ |
455 X Value | 431 X Value |
456 CommaOk bool | 432 CommaOk bool |
(...skipping 13 matching lines...) Expand all Loading... |
470 // - adding/removing a name, same underlying types. | 446 // - adding/removing a name, same underlying types. |
471 // - channel type restriction, possibly adding/removing a name. | 447 // - channel type restriction, possibly adding/removing a name. |
472 // 2. explicit conversions (in addition to the above): | 448 // 2. explicit conversions (in addition to the above): |
473 // - changing a name, same underlying types. | 449 // - changing a name, same underlying types. |
474 // - between pointers to identical base types. | 450 // - between pointers to identical base types. |
475 // + conversions between real numeric types. | 451 // + conversions between real numeric types. |
476 // + conversions between complex numeric types. | 452 // + conversions between complex numeric types. |
477 // + integer/[]byte/[]rune -> string. | 453 // + integer/[]byte/[]rune -> string. |
478 // + string -> []byte/[]rune. | 454 // + string -> []byte/[]rune. |
479 // | 455 // |
480 // TODO(adonovan): document: makes copies of values. | |
481 // | |
482 // TODO(adonovan): split into two cases: | 456 // TODO(adonovan): split into two cases: |
483 // - rename value (ChangeType) | 457 // - rename value (ChangeType) |
484 // + value to type with different representation (Conv) | 458 // + value to type with different representation (Conv) |
485 // | 459 // |
486 // Conversions of untyped string/number/bool constants to a specific | 460 // Conversions of untyped string/number/bool constants to a specific |
487 // representation are eliminated during SSA construction. | 461 // representation are eliminated during SSA construction. |
488 // | 462 // |
489 // Conv implements the Value and Instruction interfaces. | |
490 // | |
491 // Example printed form: | 463 // Example printed form: |
492 // t1 = convert interface{} <- int (t0) | 464 // t1 = convert interface{} <- int (t0) |
493 // | 465 // |
494 type Conv struct { | 466 type Conv struct { |
495 Register | 467 Register |
496 X Value | 468 X Value |
497 } | 469 } |
498 | 470 |
499 // ChangeInterface constructs a value of one interface type from a | 471 // ChangeInterface constructs a value of one interface type from a |
500 // value of another interface type known to be assignable to it. | 472 // value of another interface type known to be assignable to it. |
501 // | 473 // |
502 // TODO(adonovan): document: makes copies of values. | |
503 // | |
504 // ChangeInterface implements the Value and Instruction interfaces. | |
505 // | |
506 // Example printed form: | 474 // Example printed form: |
507 // t1 = change interface interface{} <- I (t0) | 475 // t1 = change interface interface{} <- I (t0) |
508 // | 476 // |
509 type ChangeInterface struct { | 477 type ChangeInterface struct { |
510 Register | 478 Register |
511 X Value | 479 X Value |
512 } | 480 } |
513 | 481 |
514 // MakeInterface constructs an instance of an interface type from a | 482 // MakeInterface constructs an instance of an interface type from a |
515 // value and its method-set. | 483 // value and its method-set. |
516 // | 484 // |
517 // To construct the zero value of an interface type T, use: | 485 // To construct the zero value of an interface type T, use: |
518 // &Literal{types.nilType{}, T} | 486 // &Literal{types.nilType{}, T} |
519 // | 487 // |
520 // TODO(adonovan): document: makes copies of values. | |
521 // | |
522 // MakeInterface implements the Value and Instruction interfaces. | |
523 // | |
524 // Example printed form: | 488 // Example printed form: |
525 // t1 = make interface interface{} <- int (42:int) | 489 // t1 = make interface interface{} <- int (42:int) |
526 // | 490 // |
527 type MakeInterface struct { | 491 type MakeInterface struct { |
528 Register | 492 Register |
529 X Value | 493 X Value |
530 Methods MethodSet // method set of (non-interface) X iff converting to i
nterface | 494 Methods MethodSet // method set of (non-interface) X iff converting to i
nterface |
531 } | 495 } |
532 | 496 |
533 // A MakeClosure instruction yields an anonymous function value whose | 497 // A MakeClosure instruction yields an anonymous function value whose |
534 // code is Fn and whose lexical capture slots are populated by Bindings. | 498 // code is Fn and whose lexical capture slots are populated by Bindings. |
535 // | 499 // |
536 // By construction, all captured variables are addresses of variables | 500 // By construction, all captured variables are addresses of variables |
537 // allocated with 'new', i.e. Alloc(Heap=true). | 501 // allocated with 'new', i.e. Alloc(Heap=true). |
538 // | 502 // |
539 // Type() returns a *types.Signature. | 503 // Type() returns a *types.Signature. |
540 // | 504 // |
541 // TODO(adonovan): document: makes copies of values. | |
542 // | |
543 // MakeClosure implements the Value and Instruction interfaces. | |
544 // | |
545 // Example printed form: | 505 // Example printed form: |
546 // t0 = make closure anon@1.2 [x y z] | 506 // t0 = make closure anon@1.2 [x y z] |
547 // | 507 // |
548 type MakeClosure struct { | 508 type MakeClosure struct { |
549 Register | 509 Register |
550 Fn *Function | 510 Fn *Function |
551 Bindings []Value // values for each free variable in Fn.FreeVars | 511 Bindings []Value // values for each free variable in Fn.FreeVars |
552 } | 512 } |
553 | 513 |
554 // The MakeMap instruction creates a new hash-table-based map object | 514 // The MakeMap instruction creates a new hash-table-based map object |
555 // and yields a value of kind map. | 515 // and yields a value of kind map. |
556 // | 516 // |
557 // Type() returns a *types.Map. | 517 // Type() returns a *types.Map. |
558 // | 518 // |
559 // MakeMap implements the Value and Instruction interfaces. | |
560 // | |
561 // Example printed form: | 519 // Example printed form: |
562 // t1 = make map[string]int t0 | 520 // t1 = make map[string]int t0 |
563 // | 521 // |
564 type MakeMap struct { | 522 type MakeMap struct { |
565 Register | 523 Register |
566 Reserve Value // initial space reservation; nil => default | 524 Reserve Value // initial space reservation; nil => default |
567 } | 525 } |
568 | 526 |
569 // The MakeChan instruction creates a new channel object and yields a | 527 // The MakeChan instruction creates a new channel object and yields a |
570 // value of kind chan. | 528 // value of kind chan. |
571 // | 529 // |
572 // Type() returns a *types.Chan. | 530 // Type() returns a *types.Chan. |
573 // | 531 // |
574 // MakeChan implements the Value and Instruction interfaces. | |
575 // | |
576 // Example printed form: | 532 // Example printed form: |
577 // t0 = make chan int 0 | 533 // t0 = make chan int 0 |
578 // | 534 // |
579 type MakeChan struct { | 535 type MakeChan struct { |
580 Register | 536 Register |
581 Size Value // int; size of buffer; zero => synchronous. | 537 Size Value // int; size of buffer; zero => synchronous. |
582 } | 538 } |
583 | 539 |
584 // MakeSlice yields a slice of length Len backed by a newly allocated | 540 // MakeSlice yields a slice of length Len backed by a newly allocated |
585 // array of length Cap. | 541 // array of length Cap. |
586 // | 542 // |
| 543 // Both Len and Cap must be non-nil Values of integer type. |
| 544 // |
587 // (Alloc(types.Array) followed by Slice will not suffice because | 545 // (Alloc(types.Array) followed by Slice will not suffice because |
588 // Alloc can only create arrays of statically known length.) | 546 // Alloc can only create arrays of statically known length.) |
589 // | 547 // |
590 // Type() returns a *types.Slice. | 548 // Type() returns a *types.Slice. |
591 // | 549 // |
592 // MakeSlice implements the Value and Instruction interfaces. | |
593 // | |
594 // Example printed form: | 550 // Example printed form: |
595 // t1 = make slice []string 1:int t0 | 551 // t1 = make slice []string 1:int t0 |
596 // | 552 // |
597 type MakeSlice struct { | 553 type MakeSlice struct { |
598 Register | 554 Register |
599 Len Value | 555 Len Value |
600 Cap Value | 556 Cap Value |
601 } | 557 } |
602 | 558 |
603 // Slice yields a slice of an existing string, slice or *array X | 559 // Slice yields a slice of an existing string, slice or *array X |
604 // between optional integer bounds Low and High. | 560 // between optional integer bounds Low and High. |
605 // | 561 // |
606 // Type() returns string if the type of X was string, otherwise a | 562 // Type() returns string if the type of X was string, otherwise a |
607 // *types.Slice with the same element type as X. | 563 // *types.Slice with the same element type as X. |
608 // | 564 // |
609 // Slice implements the Value and Instruction interfaces. | |
610 // | |
611 // Example printed form: | 565 // Example printed form: |
612 // t1 = slice t0[1:] | 566 // t1 = slice t0[1:] |
613 // | 567 // |
614 type Slice struct { | 568 type Slice struct { |
615 Register | 569 Register |
616 X Value // slice, string, or *array | 570 X Value // slice, string, or *array |
617 Low, High Value // either may be nil | 571 Low, High Value // either may be nil |
618 } | 572 } |
619 | 573 |
620 // FieldAddr yields the address of Field of *struct X. | 574 // FieldAddr yields the address of Field of *struct X. |
621 // | 575 // |
622 // The field is identified by its index within the field list of the | 576 // The field is identified by its index within the field list of the |
623 // struct type of X. | 577 // struct type of X. |
624 // | 578 // |
625 // Type() returns a *types.Pointer. | 579 // Type() returns a *types.Pointer. |
626 // | |
627 // FieldAddr implements the Value and Instruction interfaces. | |
628 // | 580 // |
629 // Example printed form: | 581 // Example printed form: |
630 // t1 = &t0.name [#1] | 582 // t1 = &t0.name [#1] |
631 // | 583 // |
632 type FieldAddr struct { | 584 type FieldAddr struct { |
633 Register | 585 Register |
634 X Value // *struct | 586 X Value // *struct |
635 Field int // index into X.Type().(*types.Struct).Fields | 587 Field int // index into X.Type().(*types.Struct).Fields |
636 } | 588 } |
637 | 589 |
638 // Field yields the Field of struct X. | 590 // Field yields the Field of struct X. |
639 // | 591 // |
640 // The field is identified by its index within the field list of the | 592 // The field is identified by its index within the field list of the |
641 // struct type of X; by using numeric indices we avoid ambiguity of | 593 // struct type of X; by using numeric indices we avoid ambiguity of |
642 // package-local identifiers and permit compact representations. | 594 // package-local identifiers and permit compact representations. |
643 // | 595 // |
644 // Field implements the Value and Instruction interfaces. | |
645 // | |
646 // Example printed form: | 596 // Example printed form: |
647 // t1 = t0.name [#1] | 597 // t1 = t0.name [#1] |
648 // | 598 // |
649 type Field struct { | 599 type Field struct { |
650 Register | 600 Register |
651 X Value // struct | 601 X Value // struct |
652 Field int // index into X.Type().(*types.Struct).Fields | 602 Field int // index into X.Type().(*types.Struct).Fields |
653 } | 603 } |
654 | 604 |
655 // IndexAddr yields the address of the element at index Index of | 605 // IndexAddr yields the address of the element at index Index of |
656 // collection X. Index is an integer expression. | 606 // collection X. Index is an integer expression. |
657 // | 607 // |
658 // The elements of maps and strings are not addressable; use Lookup or | 608 // The elements of maps and strings are not addressable; use Lookup or |
659 // MapUpdate instead. | 609 // MapUpdate instead. |
660 // | 610 // |
661 // Type() returns a *types.Pointer. | 611 // Type() returns a *types.Pointer. |
662 // | 612 // |
663 // IndexAddr implements the Value and Instruction interfaces. | |
664 // | |
665 // Example printed form: | 613 // Example printed form: |
666 // t2 = &t0[t1] | 614 // t2 = &t0[t1] |
667 // | 615 // |
668 type IndexAddr struct { | 616 type IndexAddr struct { |
669 Register | 617 Register |
670 X Value // slice or *array, | 618 X Value // slice or *array, |
671 Index Value // numeric index | 619 Index Value // numeric index |
672 } | 620 } |
673 | 621 |
674 // Index yields element Index of array X. | 622 // Index yields element Index of array X. |
675 // | 623 // |
676 // TODO(adonovan): should we permit X to have type slice? | 624 // TODO(adonovan): permit X to have type slice. |
677 // Currently this requires IndexAddr followed by Load. | 625 // Currently this requires IndexAddr followed by Load. |
678 // | |
679 // Index implements the Value and Instruction interfaces. | |
680 // | 626 // |
681 // Example printed form: | 627 // Example printed form: |
682 // t2 = t0[t1] | 628 // t2 = t0[t1] |
683 // | 629 // |
684 type Index struct { | 630 type Index struct { |
685 Register | 631 Register |
686 X Value // array | 632 X Value // array |
687 Index Value // integer index | 633 Index Value // integer index |
688 } | 634 } |
689 | 635 |
690 // Lookup yields element Index of collection X, a map or string. | 636 // Lookup yields element Index of collection X, a map or string. |
691 // Index is an integer expression if X is a string or the appropriate | 637 // Index is an integer expression if X is a string or the appropriate |
692 // key type if X is a map. | 638 // key type if X is a map. |
693 // | 639 // |
694 // If CommaOk, the result is a 2-tuple of the value above and a | 640 // If CommaOk, the result is a 2-tuple of the value above and a |
695 // boolean indicating the result of a map membership test for the key. | 641 // boolean indicating the result of a map membership test for the key. |
696 // The components of the tuple are accessed using Extract. | 642 // The components of the tuple are accessed using Extract. |
697 // | |
698 // Lookup implements the Value and Instruction interfaces. | |
699 // | 643 // |
700 // Example printed form: | 644 // Example printed form: |
701 // t2 = t0[t1] | 645 // t2 = t0[t1] |
702 // t5 = t3[t4],ok | 646 // t5 = t3[t4],ok |
703 // | 647 // |
704 type Lookup struct { | 648 type Lookup struct { |
705 Register | 649 Register |
706 X Value // string or map | 650 X Value // string or map |
707 Index Value // numeric or key-typed index | 651 Index Value // numeric or key-typed index |
708 CommaOk bool // return a value,ok pair | 652 CommaOk bool // return a value,ok pair |
(...skipping 26 matching lines...) Expand all Loading... |
735 // | 679 // |
736 // If the chosen channel was used for a receive, 'recv' is set to the | 680 // If the chosen channel was used for a receive, 'recv' is set to the |
737 // received value; Otherwise it is unspecified. recv has no useful | 681 // received value; Otherwise it is unspecified. recv has no useful |
738 // type since it is conceptually the union of all possible received | 682 // type since it is conceptually the union of all possible received |
739 // values. | 683 // values. |
740 // | 684 // |
741 // The third component of the triple, recvOk, is a boolean whose value | 685 // The third component of the triple, recvOk, is a boolean whose value |
742 // is true iff the selected operation was a receive and the receive | 686 // is true iff the selected operation was a receive and the receive |
743 // successfully yielded a value. | 687 // successfully yielded a value. |
744 // | 688 // |
745 // TODO(adonovan): document: makes copy of received value if any. | |
746 // | |
747 // Select implements the Value and Instruction interfaces. | |
748 // | |
749 // Example printed form: | 689 // Example printed form: |
750 // t3 = select nonblocking [<-t0, t1<-t2, ...] | 690 // t3 = select nonblocking [<-t0, t1<-t2, ...] |
751 // t4 = select blocking [] | 691 // t4 = select blocking [] |
752 // | 692 // |
753 type Select struct { | 693 type Select struct { |
754 Register | 694 Register |
755 States []SelectState | 695 States []SelectState |
756 Blocking bool | 696 Blocking bool |
757 } | 697 } |
758 | 698 |
759 // Range yields an iterator over the domain and range of X. | 699 // Range yields an iterator over the domain and range of X. |
760 // Elements are accessed via Next. | 700 // Elements are accessed via Next. |
761 // | 701 // |
762 // Type() returns a *types.Result (tuple type). | 702 // Type() returns a *types.Result (tuple type). |
763 // | |
764 // Range implements the Value and Instruction interfaces. | |
765 // | 703 // |
766 // Example printed form: | 704 // Example printed form: |
767 // t0 = range "hello":string | 705 // t0 = range "hello":string |
768 // | 706 // |
769 type Range struct { | 707 type Range struct { |
770 Register | 708 Register |
771 X Value // array, *array, slice, string, map or chan | 709 X Value // array, *array, slice, string, map or chan |
772 } | 710 } |
773 | 711 |
774 // Next reads and advances the iterator Iter and returns a 3-tuple | 712 // Next reads and advances the iterator Iter and returns a 3-tuple |
775 // value (ok, k, v). If the iterator is not exhausted, ok is true and | 713 // value (ok, k, v). If the iterator is not exhausted, ok is true and |
776 // k and v are the next elements of the domain and range, | 714 // k and v are the next elements of the domain and range, |
777 // respectively. Otherwise ok is false and k and v are undefined. | 715 // respectively. Otherwise ok is false and k and v are undefined. |
778 // | 716 // |
779 // For channel iterators, k is the received value and v is always | 717 // For channel iterators, k is the received value and v is always |
780 // undefined. | 718 // undefined. |
781 // | 719 // |
782 // Components of the tuple are accessed using Extract. | 720 // Components of the tuple are accessed using Extract. |
783 // | 721 // |
784 // Type() returns a *types.Result (tuple type). | 722 // Type() returns a *types.Result (tuple type). |
785 // | 723 // |
786 // TODO(adonovan): document: copies value in returned tuple. | |
787 // | |
788 // Next implements the Value and Instruction interfaces. | |
789 // | |
790 // Example printed form: | 724 // Example printed form: |
791 // t1 = next t0 | 725 // t1 = next t0 |
792 // | 726 // |
793 type Next struct { | 727 type Next struct { |
794 Register | 728 Register |
795 Iter Value | 729 Iter Value |
796 } | 730 } |
797 | 731 |
798 // TypeAssert tests whether interface value X has type | 732 // TypeAssert tests whether interface value X has type |
799 // AssertedType. | 733 // AssertedType. |
800 // | 734 // |
801 // If CommaOk: on success it returns a pair (v, true) where v is a | 735 // If CommaOk: on success it returns a pair (v, true) where v is a |
802 // copy of value X; on failure it returns (z, false) where z is the | 736 // copy of value X; on failure it returns (z, false) where z is the |
803 // zero value of that type. The components of the pair must be | 737 // zero value of that type. The components of the pair must be |
804 // accessed using the Extract instruction. | 738 // accessed using the Extract instruction. |
805 // | 739 // |
806 // If !CommaOk, on success it returns just the single value v; on | 740 // If !CommaOk, on success it returns just the single value v; on |
807 // failure it panics. | 741 // failure it panics. |
808 // | 742 // |
809 // Type() reflects the actual type of the result, possibly a pair | 743 // Type() reflects the actual type of the result, possibly a pair |
810 // (types.Result); AssertedType is the asserted type. | 744 // (types.Result); AssertedType is the asserted type. |
811 // | 745 // |
812 // TypeAssert implements the Value and Instruction interfaces. | |
813 // | |
814 // Example printed form: | 746 // Example printed form: |
815 // t1 = typeassert t0.(int) | 747 // t1 = typeassert t0.(int) |
816 // t3 = typeassert,ok t2.(T) | 748 // t3 = typeassert,ok t2.(T) |
817 // | 749 // |
818 type TypeAssert struct { | 750 type TypeAssert struct { |
819 Register | 751 Register |
820 X Value | 752 X Value |
821 AssertedType types.Type | 753 AssertedType types.Type |
822 CommaOk bool | 754 CommaOk bool |
823 } | 755 } |
824 | 756 |
825 // Extract yields component Index of Tuple. | 757 // Extract yields component Index of Tuple. |
826 // | 758 // |
827 // This is used to access the results of instructions with multiple | 759 // This is used to access the results of instructions with multiple |
828 // return values, such as Call, TypeAssert, Next, UnOp(ARROW) and | 760 // return values, such as Call, TypeAssert, Next, UnOp(ARROW) and |
829 // IndexExpr(Map). | 761 // IndexExpr(Map). |
830 // | 762 // |
831 // Extract implements the Value and Instruction interfaces. | |
832 // | |
833 // Example printed form: | 763 // Example printed form: |
834 // t1 = extract t0 #1 | 764 // t1 = extract t0 #1 |
835 // | 765 // |
836 type Extract struct { | 766 type Extract struct { |
837 Register | 767 Register |
838 Tuple Value | 768 Tuple Value |
839 Index int | 769 Index int |
840 } | 770 } |
841 | 771 |
842 // Instructions executed for effect. They do not yield a value. ---------------
----- | 772 // Instructions executed for effect. They do not yield a value. ---------------
----- |
843 | 773 |
844 // Jump transfers control to the sole successor of its owning block. | 774 // Jump transfers control to the sole successor of its owning block. |
845 // | 775 // |
846 // A Jump instruction must be the last instruction of its containing | 776 // A Jump instruction must be the last instruction of its containing |
847 // BasicBlock. | 777 // BasicBlock. |
848 // | 778 // |
849 // Jump implements the Instruction interface. | |
850 // | |
851 // Example printed form: | 779 // Example printed form: |
852 // jump done | 780 // jump done |
853 // | 781 // |
854 type Jump struct { | 782 type Jump struct { |
855 anInstruction | 783 anInstruction |
856 } | 784 } |
857 | 785 |
858 // The If instruction transfers control to one of the two successors | 786 // The If instruction transfers control to one of the two successors |
859 // of its owning block, depending on the boolean value Cond. | 787 // of its owning block, depending on the boolean Cond: the first if |
| 788 // true, the second if false. |
860 // | 789 // |
861 // An If instruction must be the last instruction of its containing | 790 // An If instruction must be the last instruction of its containing |
862 // BasicBlock. | 791 // BasicBlock. |
863 // | |
864 // TODO(adonovan): move the comparison BinOps EQL LSS GTR NEQ LEQ GEQ | |
865 // into this operation; don't reify booleans for comparisons only to | |
866 // conditional-jump based on them. | |
867 // | |
868 // If implements the Instruction interface. | |
869 // | 792 // |
870 // Example printed form: | 793 // Example printed form: |
871 // if t0 goto done else body | 794 // if t0 goto done else body |
872 // | 795 // |
873 type If struct { | 796 type If struct { |
874 anInstruction | 797 anInstruction |
875 Cond Value | 798 Cond Value |
876 } | 799 } |
877 | 800 |
878 // Ret returns values and control back to the calling function. | 801 // Ret returns values and control back to the calling function. |
879 // | 802 // |
880 // len(Results) is always equal to the number of results in the | 803 // len(Results) is always equal to the number of results in the |
881 // function's signature. A source-level 'return' statement with no | 804 // function's signature. A source-level 'return' statement with no |
882 // operands in a multiple-return value function is desugared to make | 805 // operands in a multiple-return value function is desugared to make |
883 // the results explicit. | 806 // the results explicit. |
884 // | 807 // |
885 // If len(Results) > 1, Ret returns a tuple value with the specified | 808 // If len(Results) > 1, Ret returns a tuple value with the specified |
886 // components which the caller must access using Extract instructions. | 809 // components which the caller must access using Extract instructions. |
887 // | 810 // |
888 // There is no instruction to return a ready-made tuple like those | 811 // There is no instruction to return a ready-made tuple like those |
889 // returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or | 812 // returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or |
890 // a tail-call to a function with multiple result parameters. | 813 // a tail-call to a function with multiple result parameters. |
891 // TODO(adonovan): consider defining one; but: dis- and re-assembling | 814 // TODO(adonovan): consider defining one; but: dis- and re-assembling |
892 // the tuple is unavoidable if assignability conversions are required | 815 // the tuple is unavoidable if assignability conversions are required |
893 // on the components. | 816 // on the components. |
894 // | 817 // |
895 // Ret must be the last instruction of its containing BasicBlock. | 818 // Ret must be the last instruction of its containing BasicBlock. |
896 // Such a block has no successors. | 819 // Such a block has no successors. |
897 // | 820 // |
898 // Ret implements the Instruction interface. | |
899 // | |
900 // Example printed form: | 821 // Example printed form: |
901 // ret | 822 // ret |
902 // ret nil:I, 2:int | 823 // ret nil:I, 2:int |
903 // | 824 // |
904 type Ret struct { | 825 type Ret struct { |
905 anInstruction | 826 anInstruction |
906 Results []Value | 827 Results []Value |
907 } | 828 } |
908 | 829 |
909 // Go creates a new goroutine and calls the specified function | 830 // Go creates a new goroutine and calls the specified function |
910 // within it. | 831 // within it. |
911 // | 832 // |
912 // See CallCommon for generic function call documentation. | 833 // See CallCommon for generic function call documentation. |
913 // | 834 // |
914 // Go implements the Instruction interface. | |
915 // | |
916 // Example printed form: | 835 // Example printed form: |
917 // go println(t0, t1) | 836 // go println(t0, t1) |
918 // go t3() | 837 // go t3() |
919 // go invoke t5.Println(...t6) | 838 // go invoke t5.Println(...t6) |
920 // | 839 // |
921 type Go struct { | 840 type Go struct { |
922 anInstruction | 841 anInstruction |
923 CallCommon | 842 CallCommon |
924 } | 843 } |
925 | 844 |
926 // Defer pushes the specified call onto a stack of functions | 845 // Defer pushes the specified call onto a stack of functions |
927 // to be called immediately prior to returning from the | 846 // to be called immediately prior to returning from the |
928 // current function. | 847 // current function. |
929 // | 848 // |
930 // See CallCommon for generic function call documentation. | 849 // See CallCommon for generic function call documentation. |
931 // | 850 // |
932 // Defer implements the Instruction interface. | |
933 // | |
934 // Example printed form: | 851 // Example printed form: |
935 // defer println(t0, t1) | 852 // defer println(t0, t1) |
936 // defer t3() | 853 // defer t3() |
937 // defer invoke t5.Println(...t6) | 854 // defer invoke t5.Println(...t6) |
938 // | 855 // |
939 type Defer struct { | 856 type Defer struct { |
940 anInstruction | 857 anInstruction |
941 CallCommon | 858 CallCommon |
942 } | 859 } |
943 | 860 |
944 // Send sends X on channel Chan. | 861 // Send sends X on channel Chan. |
945 // | 862 // |
946 // Send implements the Instruction interface. | |
947 // | |
948 // Example printed form: | 863 // Example printed form: |
949 // send t0 <- t1 | 864 // send t0 <- t1 |
950 // | 865 // |
951 type Send struct { | 866 type Send struct { |
952 anInstruction | 867 anInstruction |
953 Chan, X Value | 868 Chan, X Value |
954 } | 869 } |
955 | 870 |
956 // Store stores Val at address Addr. | 871 // Store stores Val at address Addr. |
957 // Stores can be of arbitrary types. | 872 // Stores can be of arbitrary types. |
958 // | |
959 // Store implements the Instruction interface. | |
960 // | 873 // |
961 // Example printed form: | 874 // Example printed form: |
962 // *x = y | 875 // *x = y |
963 // | 876 // |
964 type Store struct { | 877 type Store struct { |
965 anInstruction | 878 anInstruction |
966 Addr Value | 879 Addr Value |
967 Val Value | 880 Val Value |
968 } | 881 } |
969 | 882 |
970 // MapUpdate updates the association of Map[Key] to Value. | 883 // MapUpdate updates the association of Map[Key] to Value. |
971 // | |
972 // MapUpdate implements the Instruction interface. | |
973 // | 884 // |
974 // Example printed form: | 885 // Example printed form: |
975 // t0[t1] = t2 | 886 // t0[t1] = t2 |
976 // | 887 // |
977 type MapUpdate struct { | 888 type MapUpdate struct { |
978 anInstruction | 889 anInstruction |
979 Map Value | 890 Map Value |
980 Key Value | 891 Key Value |
981 Value Value | 892 Value Value |
982 } | 893 } |
(...skipping 26 matching lines...) Expand all Loading... |
1009 Block_ *BasicBlock // the basic block of this instruction | 920 Block_ *BasicBlock // the basic block of this instruction |
1010 } | 921 } |
1011 | 922 |
1012 // CallCommon is a mix-in embedded by Go, Defer and Call to hold the | 923 // CallCommon is a mix-in embedded by Go, Defer and Call to hold the |
1013 // common parts of a function or method call. | 924 // common parts of a function or method call. |
1014 // | 925 // |
1015 // Each CallCommon exists in one of two modes, function call and | 926 // Each CallCommon exists in one of two modes, function call and |
1016 // interface method invocation, or "call" and "invoke" for short. | 927 // interface method invocation, or "call" and "invoke" for short. |
1017 // | 928 // |
1018 // 1. "call" mode: when Recv is nil, a CallCommon represents an | 929 // 1. "call" mode: when Recv is nil, a CallCommon represents an |
1019 // ordinary function call of the value in Func. | 930 // ordinary function call of the value in Func. |
1020 // | 931 // |
1021 // In the common case in which Func is a *Function, this indicates a | 932 // In the common case in which Func is a *Function, this indicates a |
1022 // statically dispatched call to a package-level function, an | 933 // statically dispatched call to a package-level function, an |
1023 // anonymous function, or a method of a named type. Also statically | 934 // anonymous function, or a method of a named type. Also statically |
1024 // dispatched, but less common, Func may be a *MakeClosure, indicating | 935 // dispatched, but less common, Func may be a *MakeClosure, indicating |
1025 // an immediately applied function literal with free variables. Any | 936 // an immediately applied function literal with free variables. Any |
1026 // other Value of Func indicates a dynamically dispatched function | 937 // other Value of Func indicates a dynamically dispatched function |
1027 // call. | 938 // call. |
1028 // | 939 // |
1029 // Args contains the arguments to the call. If Func is a method, | 940 // Args contains the arguments to the call. If Func is a method, |
1030 // Args[0] contains the receiver parameter. Recv and Method are not | 941 // Args[0] contains the receiver parameter. Recv and Method are not |
1031 // used in this mode. | 942 // used in this mode. |
1032 // | 943 // |
1033 // Example printed form: | 944 // Example printed form: |
1034 // t2 = println(t0, t1) | 945 // t2 = println(t0, t1) |
1035 // go t3() | 946 // go t3() |
1036 // defer t5(...t6) | 947 // defer t5(...t6) |
1037 // | 948 // |
1038 // 2. "invoke" mode: when Recv is non-nil, a CallCommon represents a | 949 // 2. "invoke" mode: when Recv is non-nil, a CallCommon represents a |
1039 // dynamically dispatched call to an interface method. In this | 950 // dynamically dispatched call to an interface method. In this |
1040 // mode, Recv is the interface value and Method is the index of the | 951 // mode, Recv is the interface value and Method is the index of the |
1041 // method within the interface type of the receiver. | 952 // method within the interface type of the receiver. |
1042 // | 953 // |
1043 // Recv is implicitly supplied to the concrete method implementation | 954 // Recv is implicitly supplied to the concrete method implementation |
1044 // as the receiver parameter; in other words, Args[0] holds not the | 955 // as the receiver parameter; in other words, Args[0] holds not the |
1045 // receiver but the first true argument. Func is not used in this | 956 // receiver but the first true argument. Func is not used in this |
1046 // mode. | 957 // mode. |
1047 // | 958 // |
1048 // Example printed form: | 959 // Example printed form: |
1049 // t1 = invoke t0.String() | 960 // t1 = invoke t0.String() |
1050 // go invoke t3.Run(t2) | 961 // go invoke t3.Run(t2) |
1051 // defer invoke t4.Handle(...t5) | 962 // defer invoke t4.Handle(...t5) |
1052 // | 963 // |
1053 // In both modes, HasEllipsis is true iff the last element of Args is | 964 // In both modes, HasEllipsis is true iff the last element of Args is |
1054 // a slice value containing zero or more arguments to a variadic | 965 // a slice value containing zero or more arguments to a variadic |
1055 // function. (This is not semantically significant since the type of | 966 // function. (This is not semantically significant since the type of |
1056 // the called function is sufficient to determine this, but it aids | 967 // the called function is sufficient to determine this, but it aids |
1057 // readability of the printed form.) | 968 // readability of the printed form.) |
1058 // | 969 // |
1059 // TODO(adonovan): document copying of arguments and receiver. | |
1060 // | |
1061 type CallCommon struct { | 970 type CallCommon struct { |
1062 » Recv Value // receiver, iff interface method invocation | 971 » Recv Value // receiver, iff interface method invocation |
1063 » Method int // index of interface method within Recv.Type
().(*types.Interface).Methods | 972 » Method int // index of interface method within Recv.Type().(*
types.Interface).Methods |
1064 » Func Value // target of call, iff function call | 973 » Func Value // target of call, iff function call |
1065 » Args []Value // actual parameters, including receiver in i
nvoke mode | 974 » Args []Value // actual parameters, including receiver in invoke
mode |
1066 » HasEllipsis bool // true iff last Args is a slice (needed?) | 975 » HasEllipsis bool // true iff last Args is a slice (needed?) |
1067 » Position token.Position // position of call expression [this will cha
nge] | 976 » Pos token.Pos // position of call expression |
1068 } | 977 } |
1069 | 978 |
1070 func (v *Builtin) Type() types.Type { return v.Type_ } | 979 func (v *Builtin) Type() types.Type { return v.Object.GetType() } |
1071 func (v *Builtin) Name() string { return v.Name_ } | 980 func (v *Builtin) Name() string { return v.Object.GetName() } |
1072 | 981 |
1073 func (v *Capture) Type() types.Type { return v.Type_ } | 982 func (v *Capture) Type() types.Type { return v.Outer.Type() } |
1074 func (v *Capture) Name() string { return v.Name_ } | 983 func (v *Capture) Name() string { return v.Outer.Name() } |
1075 | 984 |
1076 func (v *Global) Type() types.Type { return v.Type_ } | 985 func (v *Global) Type() types.Type { return v.Type_ } |
1077 func (v *Global) Name() string { return v.Name_ } // TODO(adonovan): print p
ackage-qualified when necessary? | 986 func (v *Global) Name() string { return v.Name_ } |
| 987 func (v *Global) String() string { return v.Name_ } // placeholder |
| 988 |
| 989 func (v *Function) Name() string { return v.Name_ } |
| 990 func (v *Function) Type() types.Type { return v.Signature } |
| 991 func (v *Function) String() string { return v.Name_ } // placeholder |
| 992 |
| 993 // FullName returns v's package-qualified name. |
| 994 func (v *Global) FullName() string { return fmt.Sprintf("%s.%s", v.Pkg.ImportPat
h, v.Name_) } |
| 995 |
| 996 func (v *Literal) Name() string { return "Literal" } // placeholder |
| 997 func (v *Literal) String() string { return "Literal" } // placeholder |
| 998 func (v *Literal) Type() types.Type { return v.Type_ } // placeholder |
1078 | 999 |
1079 func (v *Parameter) Type() types.Type { return v.Type_ } | 1000 func (v *Parameter) Type() types.Type { return v.Type_ } |
1080 func (v *Parameter) Name() string { return v.Name_ } | 1001 func (v *Parameter) Name() string { return v.Name_ } |
1081 | 1002 |
1082 func (v *Alloc) Type() types.Type { return v.Type_ } | 1003 func (v *Alloc) Type() types.Type { return v.Type_ } |
1083 func (v *Alloc) Name() string { return v.Name_ } | 1004 func (v *Alloc) Name() string { return v.Name_ } |
1084 | 1005 |
1085 func (v *Register) Type() types.Type { return v.Type_ } | 1006 func (v *Register) Type() types.Type { return v.Type_ } |
1086 func (v *Register) setType(typ types.Type) { v.Type_ = typ } | 1007 func (v *Register) setType(typ types.Type) { v.Type_ = typ } |
1087 func (v *Register) Name() string { return fmt.Sprintf("t%d", v.num) } | 1008 func (v *Register) Name() string { return fmt.Sprintf("t%d", v.num) } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 | 1043 |
1123 // Type returns the package-level type of the specified name, | 1044 // Type returns the package-level type of the specified name, |
1124 // or nil if not found. | 1045 // or nil if not found. |
1125 // | 1046 // |
1126 func (p *Package) Type(name string) (t *Type) { | 1047 func (p *Package) Type(name string) (t *Type) { |
1127 t, _ = p.Members[name].(*Type) | 1048 t, _ = p.Members[name].(*Type) |
1128 return | 1049 return |
1129 } | 1050 } |
1130 | 1051 |
1131 // "Implements" relation boilerplate. | 1052 // "Implements" relation boilerplate. |
| 1053 // Don't try to factor this using promotion and mix-ins: the long-hand |
| 1054 // form serves as better documentation, including in godoc. |
1132 | 1055 |
1133 func (*Alloc) ImplementsValue() {} | 1056 func (*Alloc) ImplementsValue() {} |
1134 func (*BinOp) ImplementsValue() {} | 1057 func (*BinOp) ImplementsValue() {} |
1135 func (*Builtin) ImplementsValue() {} | 1058 func (*Builtin) ImplementsValue() {} |
1136 func (*Call) ImplementsValue() {} | 1059 func (*Call) ImplementsValue() {} |
1137 func (*Capture) ImplementsValue() {} | 1060 func (*Capture) ImplementsValue() {} |
1138 func (*ChangeInterface) ImplementsValue() {} | 1061 func (*ChangeInterface) ImplementsValue() {} |
1139 func (*Conv) ImplementsValue() {} | 1062 func (*Conv) ImplementsValue() {} |
1140 func (*Extract) ImplementsValue() {} | 1063 func (*Extract) ImplementsValue() {} |
1141 func (*Field) ImplementsValue() {} | 1064 func (*Field) ImplementsValue() {} |
(...skipping 16 matching lines...) Expand all Loading... |
1158 func (*Select) ImplementsValue() {} | 1081 func (*Select) ImplementsValue() {} |
1159 func (*Slice) ImplementsValue() {} | 1082 func (*Slice) ImplementsValue() {} |
1160 func (*TypeAssert) ImplementsValue() {} | 1083 func (*TypeAssert) ImplementsValue() {} |
1161 func (*UnOp) ImplementsValue() {} | 1084 func (*UnOp) ImplementsValue() {} |
1162 | 1085 |
1163 func (*Function) ImplementsMember() {} | 1086 func (*Function) ImplementsMember() {} |
1164 func (*Global) ImplementsMember() {} | 1087 func (*Global) ImplementsMember() {} |
1165 func (*Literal) ImplementsMember() {} | 1088 func (*Literal) ImplementsMember() {} |
1166 func (*Type) ImplementsMember() {} | 1089 func (*Type) ImplementsMember() {} |
1167 | 1090 |
1168 func (anInstruction) ImplementsInstruction() {} | 1091 func (*Alloc) ImplementsInstruction() {} |
| 1092 func (*BinOp) ImplementsInstruction() {} |
| 1093 func (*Call) ImplementsInstruction() {} |
| 1094 func (*ChangeInterface) ImplementsInstruction() {} |
| 1095 func (*Conv) ImplementsInstruction() {} |
| 1096 func (*Defer) ImplementsInstruction() {} |
| 1097 func (*Extract) ImplementsInstruction() {} |
| 1098 func (*Field) ImplementsInstruction() {} |
| 1099 func (*FieldAddr) ImplementsInstruction() {} |
| 1100 func (*Go) ImplementsInstruction() {} |
| 1101 func (*If) ImplementsInstruction() {} |
| 1102 func (*Index) ImplementsInstruction() {} |
| 1103 func (*IndexAddr) ImplementsInstruction() {} |
| 1104 func (*Jump) ImplementsInstruction() {} |
| 1105 func (*Lookup) ImplementsInstruction() {} |
| 1106 func (*MakeChan) ImplementsInstruction() {} |
| 1107 func (*MakeClosure) ImplementsInstruction() {} |
| 1108 func (*MakeInterface) ImplementsInstruction() {} |
| 1109 func (*MakeMap) ImplementsInstruction() {} |
| 1110 func (*MakeSlice) ImplementsInstruction() {} |
| 1111 func (*MapUpdate) ImplementsInstruction() {} |
| 1112 func (*Next) ImplementsInstruction() {} |
| 1113 func (*Phi) ImplementsInstruction() {} |
| 1114 func (*Range) ImplementsInstruction() {} |
| 1115 func (*Ret) ImplementsInstruction() {} |
| 1116 func (*Select) ImplementsInstruction() {} |
| 1117 func (*Send) ImplementsInstruction() {} |
| 1118 func (*Slice) ImplementsInstruction() {} |
| 1119 func (*Store) ImplementsInstruction() {} |
| 1120 func (*TypeAssert) ImplementsInstruction() {} |
| 1121 func (*UnOp) ImplementsInstruction() {} |
LEFT | RIGHT |