Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(113)

Side by Side Diff: src/pkg/reflect/type.go

Issue 5650069: code review 5650069: runtime: delete Type and implementations (use reflect i... (Closed)
Patch Set: diff -r 002f08814913 https://go.googlecode.com/hg/ Created 12 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/encoding/gob/encode.go ('k') | src/pkg/reflect/value.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package reflect implements run-time reflection, allowing a program to 5 // Package reflect implements run-time reflection, allowing a program to
6 // manipulate objects with arbitrary types. The typical use is to take a value 6 // manipulate objects with arbitrary types. The typical use is to take a value
7 // with static type interface{} and extract its dynamic type information by 7 // with static type interface{} and extract its dynamic type information by
8 // calling TypeOf, which returns a Type. 8 // calling TypeOf, which returns a Type.
9 // 9 //
10 // A call to ValueOf returns a Value representing the run-time data. 10 // A call to ValueOf returns a Value representing the run-time data.
11 // Zero takes a Type and returns a Value representing a zero value 11 // Zero takes a Type and returns a Value representing a zero value
12 // for that type. 12 // for that type.
13 // 13 //
14 // See "The Laws of Reflection" for an introduction to reflection in Go: 14 // See "The Laws of Reflection" for an introduction to reflection in Go:
15 // http://blog.golang.org/2011/09/laws-of-reflection.html 15 // http://blog.golang.org/2011/09/laws-of-reflection.html
16 package reflect 16 package reflect
17 17
18 import ( 18 import (
19 "runtime"
20 "strconv" 19 "strconv"
21 "sync" 20 "sync"
22 "unsafe" 21 "unsafe"
23 ) 22 )
24 23
25 // Type is the representation of a Go type. 24 // Type is the representation of a Go type.
26 // 25 //
27 // Not all methods apply to all kinds of types. Restrictions, 26 // Not all methods apply to all kinds of types. Restrictions,
28 // if any, are noted in the documentation for each method. 27 // if any, are noted in the documentation for each method.
29 // Use the Kind method to find out the kind of type before 28 // Use the Kind method to find out the kind of type before
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 173
175 // NumOut returns a function type's output parameter count. 174 // NumOut returns a function type's output parameter count.
176 // It panics if the type's Kind is not Func. 175 // It panics if the type's Kind is not Func.
177 NumOut() int 176 NumOut() int
178 177
179 // Out returns the type of a function type's i'th output parameter. 178 // Out returns the type of a function type's i'th output parameter.
180 // It panics if the type's Kind is not Func. 179 // It panics if the type's Kind is not Func.
181 // It panics if i is not in the range [0, NumOut()). 180 // It panics if i is not in the range [0, NumOut()).
182 Out(i int) Type 181 Out(i int) Type
183 182
184 » runtimeType() *runtime.Type 183 » runtimeType() *runtimeType
185 common() *commonType 184 common() *commonType
186 uncommon() *uncommonType 185 uncommon() *uncommonType
187 } 186 }
188 187
189 // A Kind represents the specific kind of type that a Type represents. 188 // A Kind represents the specific kind of type that a Type represents.
190 // The zero Kind is not a valid kind. 189 // The zero Kind is not a valid kind.
191 type Kind uint 190 type Kind uint
192 191
193 const ( 192 const (
194 Invalid Kind = iota 193 Invalid Kind = iota
(...skipping 19 matching lines...) Expand all
214 Interface 213 Interface
215 Map 214 Map
216 Ptr 215 Ptr
217 Slice 216 Slice
218 String 217 String
219 Struct 218 Struct
220 UnsafePointer 219 UnsafePointer
221 ) 220 )
222 221
223 /* 222 /*
224 * Copy of data structures from ../runtime/type.go. 223 * These data structures are known to the compiler (../../cmd/gc/reflect.c).
225 * For comments, see the ones in that file. 224 * A few are known to ../runtime/type.go to convey to debuggers.
226 *
227 * These data structures are known to the compiler and the runtime.
228 *
229 * Putting these types in runtime instead of reflect means that
230 * reflect doesn't need to be autolinked into every binary, which
231 * simplifies bootstrapping and package dependencies.
232 * Unfortunately, it also means that reflect needs its own
233 * copy in order to access the private fields.
234 */ 225 */
235 226
227 // The compiler can only construct empty interface values at
228 // compile time; non-empty interface values get created
229 // during initialization. Type is an empty interface
230 // so that the compiler can lay out references as data.
231 // The underlying type is *reflect.ArrayType and so on.
232 type runtimeType interface{}
233
236 // commonType is the common implementation of most values. 234 // commonType is the common implementation of most values.
237 // It is embedded in other, public struct types, but always 235 // It is embedded in other, public struct types, but always
238 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` 236 // with a unique tag like `reflect:"array"` or `reflect:"ptr"`
239 // so that code cannot convert from, say, *arrayType to *ptrType. 237 // so that code cannot convert from, say, *arrayType to *ptrType.
240
241 type commonType struct { 238 type commonType struct {
242 » size uintptr 239 » size uintptr // size in bytes
243 » hash uint32 240 » hash uint32 // hash of type; avoids computation in hash t ables
244 » _ uint8 241 » _ uint8 // unused/padding
245 » align uint8 242 » align uint8 // alignment of variable with this type
246 » fieldAlign uint8 243 » fieldAlign uint8 // alignment of struct field with this type
247 » kind uint8 244 » kind uint8 // enumeration for C
248 » alg *uintptr 245 » alg *uintptr // algorithm table (../runtime/runtime.h:/Alg )
249 » string *string 246 » string *string // string form; unnecessary but undeniably u seful
250 » *uncommonType 247 » *uncommonType // (relatively) uncommon fields
251 » ptrToThis *runtime.Type 248 » ptrToThis *runtimeType // pointer to this type, if used in binary or has methods
252 } 249 }
253 250
251 // Method on non-interface type
254 type method struct { 252 type method struct {
255 » name *string 253 » name *string // name of method
256 » pkgPath *string 254 » pkgPath *string // nil for exported Names; otherwise import path
257 » mtyp *runtime.Type 255 » mtyp *runtimeType // method type (without receiver)
258 » typ *runtime.Type 256 » typ *runtimeType // .(*FuncType) underneath (with receiver)
259 » ifn unsafe.Pointer 257 » ifn unsafe.Pointer // fn used in interface call (one-word receiver)
260 » tfn unsafe.Pointer 258 » tfn unsafe.Pointer // fn used for normal method call
261 } 259 }
262 260
261 // uncommonType is present only for types with names or methods
262 // (if T is a named type, the uncommonTypes for T and *T have methods).
263 // Using a pointer to this struct reduces the overall size required
264 // to describe an unnamed type with no methods.
263 type uncommonType struct { 265 type uncommonType struct {
264 » name *string 266 » name *string // name of type
265 » pkgPath *string 267 » pkgPath *string // import path; nil for built-in types like int, string
266 » methods []method 268 » methods []method // methods associated with type
267 } 269 }
268 270
269 // ChanDir represents a channel type's direction. 271 // ChanDir represents a channel type's direction.
270 type ChanDir int 272 type ChanDir int
271 273
272 const ( 274 const (
273 » RecvDir ChanDir = 1 << iota 275 » RecvDir ChanDir = 1 << iota // <-chan
274 » SendDir 276 » SendDir // chan<-
275 » BothDir = RecvDir | SendDir 277 » BothDir = RecvDir | SendDir // chan
276 ) 278 )
277 279
278 // arrayType represents a fixed array type. 280 // arrayType represents a fixed array type.
279 type arrayType struct { 281 type arrayType struct {
280 commonType `reflect:"array"` 282 commonType `reflect:"array"`
281 » elem *runtime.Type 283 » elem *runtimeType // array element type
282 » slice *runtime.Type 284 » slice *runtimeType // slice type
283 len uintptr 285 len uintptr
284 } 286 }
285 287
286 // chanType represents a channel type. 288 // chanType represents a channel type.
287 type chanType struct { 289 type chanType struct {
288 commonType `reflect:"chan"` 290 commonType `reflect:"chan"`
289 » elem *runtime.Type 291 » elem *runtimeType // channel element type
290 » dir uintptr 292 » dir uintptr // channel direction (ChanDir)
291 } 293 }
292 294
293 // funcType represents a function type. 295 // funcType represents a function type.
294 type funcType struct { 296 type funcType struct {
295 commonType `reflect:"func"` 297 commonType `reflect:"func"`
296 » dotdotdot bool 298 » dotdotdot bool // last input parameter is ...
297 » in []*runtime.Type 299 » in []*runtimeType // input parameter types
298 » out []*runtime.Type 300 » out []*runtimeType // output parameter types
299 } 301 }
300 302
301 // imethod represents a method on an interface type 303 // imethod represents a method on an interface type
302 type imethod struct { 304 type imethod struct {
303 » name *string 305 » name *string // name of method
304 » pkgPath *string 306 » pkgPath *string // nil for exported Names; otherwise import path
305 » typ *runtime.Type 307 » typ *runtimeType // .(*FuncType) underneath
306 } 308 }
307 309
308 // interfaceType represents an interface type. 310 // interfaceType represents an interface type.
309 type interfaceType struct { 311 type interfaceType struct {
310 commonType `reflect:"interface"` 312 commonType `reflect:"interface"`
311 » methods []imethod 313 » methods []imethod // sorted by hash
312 } 314 }
313 315
314 // mapType represents a map type. 316 // mapType represents a map type.
315 type mapType struct { 317 type mapType struct {
316 commonType `reflect:"map"` 318 commonType `reflect:"map"`
317 » key *runtime.Type 319 » key *runtimeType // map key type
318 » elem *runtime.Type 320 » elem *runtimeType // map element (value) type
319 } 321 }
320 322
321 // ptrType represents a pointer type. 323 // ptrType represents a pointer type.
322 type ptrType struct { 324 type ptrType struct {
323 commonType `reflect:"ptr"` 325 commonType `reflect:"ptr"`
324 » elem *runtime.Type 326 » elem *runtimeType // pointer element (pointed at) type
325 } 327 }
326 328
327 // sliceType represents a slice type. 329 // sliceType represents a slice type.
328 type sliceType struct { 330 type sliceType struct {
329 commonType `reflect:"slice"` 331 commonType `reflect:"slice"`
330 » elem *runtime.Type 332 » elem *runtimeType // slice element type
331 } 333 }
332 334
333 // Struct field 335 // Struct field
334 type structField struct { 336 type structField struct {
335 » name *string 337 » name *string // nil for embedded fields
336 » pkgPath *string 338 » pkgPath *string // nil for exported Names; otherwise import path
337 » typ *runtime.Type 339 » typ *runtimeType // type of field
338 » tag *string 340 » tag *string // nil if no tag
339 » offset uintptr 341 » offset uintptr // byte offset of field within struct
340 } 342 }
341 343
342 // structType represents a struct type. 344 // structType represents a struct type.
343 type structType struct { 345 type structType struct {
344 commonType `reflect:"struct"` 346 commonType `reflect:"struct"`
345 » fields []structField 347 » fields []structField // sorted by offset
346 } 348 }
347 349
348 /* 350 /*
349 * The compiler knows the exact layout of all the data structures above. 351 * The compiler knows the exact layout of all the data structures above.
350 * The compiler does not know about the data structures and methods below. 352 * The compiler does not know about the data structures and methods below.
351 */ 353 */
352 354
353 // Method represents a single method. 355 // Method represents a single method.
354 type Method struct { 356 type Method struct {
355 PkgPath string // empty for uppercase Name 357 PkgPath string // empty for uppercase Name
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 // match function and a boolean to indicate if the field was found. 904 // match function and a boolean to indicate if the field was found.
903 func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr esent bool) { 905 func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr esent bool) {
904 if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd < inf { 906 if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd < inf {
905 ff.Index = ff.Index[0 : fd+1] 907 ff.Index = ff.Index[0 : fd+1]
906 f, present = ff, true 908 f, present = ff, true
907 } 909 }
908 return 910 return
909 } 911 }
910 912
911 // Convert runtime type to reflect type. 913 // Convert runtime type to reflect type.
912 func toCommonType(p *runtime.Type) *commonType { 914 func toCommonType(p *runtimeType) *commonType {
913 if p == nil { 915 if p == nil {
914 return nil 916 return nil
915 } 917 }
916 » type hdr struct { 918 » return (*p).(*commonType)
917 » » x interface{}
918 » » t commonType
919 » }
920 » x := unsafe.Pointer(p)
921 » return &(*hdr)(x).t
922 } 919 }
923 920
924 func toType(p *runtime.Type) Type { 921 func toType(p *runtimeType) Type {
925 if p == nil { 922 if p == nil {
926 return nil 923 return nil
927 } 924 }
928 » return toCommonType(p).toType() 925 » return (*p).(*commonType)
929 } 926 }
930 927
931 // TypeOf returns the reflection Type of the value in the interface{}. 928 // TypeOf returns the reflection Type of the value in the interface{}.
932 func TypeOf(i interface{}) Type { 929 func TypeOf(i interface{}) Type {
933 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 930 eface := *(*emptyInterface)(unsafe.Pointer(&i))
934 return toType(eface.typ) 931 return toType(eface.typ)
935 } 932 }
936 933
937 // ptrMap is the cache for PtrTo. 934 // ptrMap is the cache for PtrTo.
938 var ptrMap struct { 935 var ptrMap struct {
939 sync.RWMutex 936 sync.RWMutex
940 m map[*commonType]*ptrType 937 m map[*commonType]*ptrType
941 } 938 }
942 939
943 func (t *commonType) runtimeType() *runtime.Type { 940 func (t *commonType) runtimeType() *runtimeType {
944 » // The runtime.Type always precedes the commonType in memory. 941 » // The runtimeType always precedes the commonType in memory.
945 // Adjust pointer to find it. 942 // Adjust pointer to find it.
946 var rt struct { 943 var rt struct {
947 » » i runtime.Type 944 » » i runtimeType
948 ct commonType 945 ct commonType
949 } 946 }
950 » return (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsaf e.Offsetof(rt.ct))) 947 » return (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe .Offsetof(rt.ct)))
951 } 948 }
952 949
953 // PtrTo returns the pointer type with element t. 950 // PtrTo returns the pointer type with element t.
954 // For example, if t represents type Foo, PtrTo(t) represents *Foo. 951 // For example, if t represents type Foo, PtrTo(t) represents *Foo.
955 func PtrTo(t Type) Type { 952 func PtrTo(t Type) Type {
956 return t.(*commonType).ptrTo() 953 return t.(*commonType).ptrTo()
957 } 954 }
958 955
959 func (ct *commonType) ptrTo() *commonType { 956 func (ct *commonType) ptrTo() *commonType {
960 if p := ct.ptrToThis; p != nil { 957 if p := ct.ptrToThis; p != nil {
(...skipping 18 matching lines...) Expand all
979 ptrMap.m = make(map[*commonType]*ptrType) 976 ptrMap.m = make(map[*commonType]*ptrType)
980 } 977 }
981 p := ptrMap.m[ct] 978 p := ptrMap.m[ct]
982 if p != nil { 979 if p != nil {
983 // some other goroutine won the race and created it 980 // some other goroutine won the race and created it
984 ptrMap.Unlock() 981 ptrMap.Unlock()
985 return &p.commonType 982 return &p.commonType
986 } 983 }
987 984
988 var rt struct { 985 var rt struct {
989 » » i runtime.Type 986 » » i runtimeType
990 ptrType 987 ptrType
991 } 988 }
992 » rt.i = (*runtime.PtrType)(unsafe.Pointer(&rt.ptrType)) 989 » rt.i = &rt.commonType
993 990
994 // initialize p using *byte's ptrType as a prototype. 991 // initialize p using *byte's ptrType as a prototype.
995 // have to do assignment as ptrType, not runtime.PtrType,
996 // in order to write to unexported fields.
997 p = &rt.ptrType 992 p = &rt.ptrType
998 » bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.Pt rType))) 993 » var ibyte interface{} = (*byte)(nil)
994 » bp := (*ptrType)(unsafe.Pointer((**(**runtimeType)(unsafe.Pointer(&ibyte ))).(*commonType)))
999 *p = *bp 995 *p = *bp
1000 996
1001 s := "*" + *ct.string 997 s := "*" + *ct.string
1002 p.string = &s 998 p.string = &s
1003 999
1004 // For the type structures linked into the binary, the 1000 // For the type structures linked into the binary, the
1005 // compiler provides a good hash of the string. 1001 // compiler provides a good hash of the string.
1006 // Create a good hash for the new string by using 1002 // Create a good hash for the new string by using
1007 // the FNV-1 hash's mixing function to combine the 1003 // the FNV-1 hash's mixing function to combine the
1008 // old hash and the new "*". 1004 // old hash and the new "*".
1009 p.hash = ct.hash*16777619 ^ '*' 1005 p.hash = ct.hash*16777619 ^ '*'
1010 1006
1011 p.uncommonType = nil 1007 p.uncommonType = nil
1012 p.ptrToThis = nil 1008 p.ptrToThis = nil
1013 » p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - un safe.Offsetof(rt.ptrType))) 1009 » p.elem = (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - uns afe.Offsetof(rt.ptrType)))
1014 1010
1015 ptrMap.m[ct] = p 1011 ptrMap.m[ct] = p
1016 ptrMap.Unlock() 1012 ptrMap.Unlock()
1017 return &p.commonType 1013 return &p.commonType
1018 } 1014 }
1019 1015
1020 func (t *commonType) Implements(u Type) bool { 1016 func (t *commonType) Implements(u Type) bool {
1021 if u == nil { 1017 if u == nil {
1022 panic("reflect: nil type passed to Type.Implements") 1018 panic("reflect: nil type passed to Type.Implements")
1023 } 1019 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 if tf.name != vf.name || tf.pkgPath != vf.pkgPath || 1166 if tf.name != vf.name || tf.pkgPath != vf.pkgPath ||
1171 tf.typ != vf.typ || tf.tag != vf.tag || tf.offse t != vf.offset { 1167 tf.typ != vf.typ || tf.tag != vf.tag || tf.offse t != vf.offset {
1172 return false 1168 return false
1173 } 1169 }
1174 } 1170 }
1175 return true 1171 return true
1176 } 1172 }
1177 1173
1178 return false 1174 return false
1179 } 1175 }
OLDNEW
« no previous file with comments | « src/pkg/encoding/gob/encode.go ('k') | src/pkg/reflect/value.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b