github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/src/reflect/type.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 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 7 // with static type interface{} and extract its dynamic type information by 8 // calling TypeOf, which returns a Type. 9 // 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 12 // for that type. 13 // 14 // See "The Laws of Reflection" for an introduction to reflection in Go: 15 // http://golang.org/doc/articles/laws_of_reflection.html 16 package reflect 17 18 import ( 19 "runtime" 20 "strconv" 21 "sync" 22 "unsafe" 23 ) 24 25 // Type is the representation of a Go type. 26 // 27 // Not all methods apply to all kinds of types. Restrictions, 28 // if any, are noted in the documentation for each method. 29 // Use the Kind method to find out the kind of type before 30 // calling kind-specific methods. Calling a method 31 // inappropriate to the kind of type causes a run-time panic. 32 type Type interface { 33 // Methods applicable to all types. 34 35 // Align returns the alignment in bytes of a value of 36 // this type when allocated in memory. 37 Align() int 38 39 // FieldAlign returns the alignment in bytes of a value of 40 // this type when used as a field in a struct. 41 FieldAlign() int 42 43 // Method returns the i'th method in the type's method set. 44 // It panics if i is not in the range [0, NumMethod()). 45 // 46 // For a non-interface type T or *T, the returned Method's Type and Func 47 // fields describe a function whose first argument is the receiver. 48 // 49 // For an interface type, the returned Method's Type field gives the 50 // method signature, without a receiver, and the Func field is nil. 51 Method(int) Method 52 53 // MethodByName returns the method with that name in the type's 54 // method set and a boolean indicating if the method was found. 55 // 56 // For a non-interface type T or *T, the returned Method's Type and Func 57 // fields describe a function whose first argument is the receiver. 58 // 59 // For an interface type, the returned Method's Type field gives the 60 // method signature, without a receiver, and the Func field is nil. 61 MethodByName(string) (Method, bool) 62 63 // NumMethod returns the number of methods in the type's method set. 64 NumMethod() int 65 66 // Name returns the type's name within its package. 67 // It returns an empty string for unnamed types. 68 Name() string 69 70 // PkgPath returns a named type's package path, that is, the import path 71 // that uniquely identifies the package, such as "encoding/base64". 72 // If the type was predeclared (string, error) or unnamed (*T, struct{}, []int), 73 // the package path will be the empty string. 74 PkgPath() string 75 76 // Size returns the number of bytes needed to store 77 // a value of the given type; it is analogous to unsafe.Sizeof. 78 Size() uintptr 79 80 // String returns a string representation of the type. 81 // The string representation may use shortened package names 82 // (e.g., base64 instead of "encoding/base64") and is not 83 // guaranteed to be unique among types. To test for equality, 84 // compare the Types directly. 85 String() string 86 87 // Kind returns the specific kind of this type. 88 Kind() Kind 89 90 // Implements returns true if the type implements the interface type u. 91 Implements(u Type) bool 92 93 // AssignableTo returns true if a value of the type is assignable to type u. 94 AssignableTo(u Type) bool 95 96 // ConvertibleTo returns true if a value of the type is convertible to type u. 97 ConvertibleTo(u Type) bool 98 99 // Comparable returns true if values of this type are comparable. 100 Comparable() bool 101 102 // Methods applicable only to some types, depending on Kind. 103 // The methods allowed for each kind are: 104 // 105 // Int*, Uint*, Float*, Complex*: Bits 106 // Array: Elem, Len 107 // Chan: ChanDir, Elem 108 // Func: In, NumIn, Out, NumOut, IsVariadic. 109 // Map: Key, Elem 110 // Ptr: Elem 111 // Slice: Elem 112 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField 113 114 // Bits returns the size of the type in bits. 115 // It panics if the type's Kind is not one of the 116 // sized or unsized Int, Uint, Float, or Complex kinds. 117 Bits() int 118 119 // ChanDir returns a channel type's direction. 120 // It panics if the type's Kind is not Chan. 121 ChanDir() ChanDir 122 123 // IsVariadic returns true if a function type's final input parameter 124 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 125 // implicit actual type []T. 126 // 127 // For concreteness, if t represents func(x int, y ... float64), then 128 // 129 // t.NumIn() == 2 130 // t.In(0) is the reflect.Type for "int" 131 // t.In(1) is the reflect.Type for "[]float64" 132 // t.IsVariadic() == true 133 // 134 // IsVariadic panics if the type's Kind is not Func. 135 IsVariadic() bool 136 137 // Elem returns a type's element type. 138 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. 139 Elem() Type 140 141 // Field returns a struct type's i'th field. 142 // It panics if the type's Kind is not Struct. 143 // It panics if i is not in the range [0, NumField()). 144 Field(i int) StructField 145 146 // FieldByIndex returns the nested field corresponding 147 // to the index sequence. It is equivalent to calling Field 148 // successively for each index i. 149 // It panics if the type's Kind is not Struct. 150 FieldByIndex(index []int) StructField 151 152 // FieldByName returns the struct field with the given name 153 // and a boolean indicating if the field was found. 154 FieldByName(name string) (StructField, bool) 155 156 // FieldByNameFunc returns the first struct field with a name 157 // that satisfies the match function and a boolean indicating if 158 // the field was found. 159 FieldByNameFunc(match func(string) bool) (StructField, bool) 160 161 // In returns the type of a function type's i'th input parameter. 162 // It panics if the type's Kind is not Func. 163 // It panics if i is not in the range [0, NumIn()). 164 In(i int) Type 165 166 // Key returns a map type's key type. 167 // It panics if the type's Kind is not Map. 168 Key() Type 169 170 // Len returns an array type's length. 171 // It panics if the type's Kind is not Array. 172 Len() int 173 174 // NumField returns a struct type's field count. 175 // It panics if the type's Kind is not Struct. 176 NumField() int 177 178 // NumIn returns a function type's input parameter count. 179 // It panics if the type's Kind is not Func. 180 NumIn() int 181 182 // NumOut returns a function type's output parameter count. 183 // It panics if the type's Kind is not Func. 184 NumOut() int 185 186 // Out returns the type of a function type's i'th output parameter. 187 // It panics if the type's Kind is not Func. 188 // It panics if i is not in the range [0, NumOut()). 189 Out(i int) Type 190 191 common() *rtype 192 uncommon() *uncommonType 193 } 194 195 // BUG(rsc): FieldByName and related functions consider struct field names to be equal 196 // if the names are equal, even if they are unexported names originating 197 // in different packages. The practical effect of this is that the result of 198 // t.FieldByName("x") is not well defined if the struct type t contains 199 // multiple fields named x (embedded from different packages). 200 // FieldByName may return one of the fields named x or may report that there are none. 201 // See golang.org/issue/4876 for more details. 202 203 /* 204 * These data structures are known to the compiler (../../cmd/gc/reflect.c). 205 * A few are known to ../runtime/type.go to convey to debuggers. 206 * They are also known to ../runtime/type.h. 207 */ 208 209 // A Kind represents the specific kind of type that a Type represents. 210 // The zero Kind is not a valid kind. 211 type Kind uint 212 213 const ( 214 Invalid Kind = iota 215 Bool 216 Int 217 Int8 218 Int16 219 Int32 220 Int64 221 Uint 222 Uint8 223 Uint16 224 Uint32 225 Uint64 226 Uintptr 227 Float32 228 Float64 229 Complex64 230 Complex128 231 Array 232 Chan 233 Func 234 Interface 235 Map 236 Ptr 237 Slice 238 String 239 Struct 240 UnsafePointer 241 ) 242 243 // rtype is the common implementation of most values. 244 // It is embedded in other, public struct types, but always 245 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` 246 // so that code cannot convert from, say, *arrayType to *ptrType. 247 type rtype struct { 248 size uintptr 249 hash uint32 // hash of type; avoids computation in hash tables 250 _ uint8 // unused/padding 251 align uint8 // alignment of variable with this type 252 fieldAlign uint8 // alignment of struct field with this type 253 kind uint8 // enumeration for C 254 alg *typeAlg // algorithm table (../runtime/runtime.h:/Alg) 255 gc [2]unsafe.Pointer // garbage collection data 256 string *string // string form; unnecessary but undeniably useful 257 *uncommonType // (relatively) uncommon fields 258 ptrToThis *rtype // type for pointer to this type, if used in binary or has methods 259 zero unsafe.Pointer // pointer to zero value 260 } 261 262 type typeAlg struct { 263 // function for hashing objects of this type 264 // (ptr to object, size, seed) -> hash 265 hash func(unsafe.Pointer, uintptr, uintptr) uintptr 266 // function for comparing objects of this type 267 // (ptr to object A, ptr to object B, size) -> ==? 268 equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool 269 } 270 271 // Method on non-interface type 272 type method struct { 273 name *string // name of method 274 pkgPath *string // nil for exported Names; otherwise import path 275 mtyp *rtype // method type (without receiver) 276 typ *rtype // .(*FuncType) underneath (with receiver) 277 ifn unsafe.Pointer // fn used in interface call (one-word receiver) 278 tfn unsafe.Pointer // fn used for normal method call 279 } 280 281 // uncommonType is present only for types with names or methods 282 // (if T is a named type, the uncommonTypes for T and *T have methods). 283 // Using a pointer to this struct reduces the overall size required 284 // to describe an unnamed type with no methods. 285 type uncommonType struct { 286 name *string // name of type 287 pkgPath *string // import path; nil for built-in types like int, string 288 methods []method // methods associated with type 289 } 290 291 // ChanDir represents a channel type's direction. 292 type ChanDir int 293 294 const ( 295 RecvDir ChanDir = 1 << iota // <-chan 296 SendDir // chan<- 297 BothDir = RecvDir | SendDir // chan 298 ) 299 300 // arrayType represents a fixed array type. 301 type arrayType struct { 302 rtype `reflect:"array"` 303 elem *rtype // array element type 304 slice *rtype // slice type 305 len uintptr 306 } 307 308 // chanType represents a channel type. 309 type chanType struct { 310 rtype `reflect:"chan"` 311 elem *rtype // channel element type 312 dir uintptr // channel direction (ChanDir) 313 } 314 315 // funcType represents a function type. 316 type funcType struct { 317 rtype `reflect:"func"` 318 dotdotdot bool // last input parameter is ... 319 in []*rtype // input parameter types 320 out []*rtype // output parameter types 321 } 322 323 // imethod represents a method on an interface type 324 type imethod struct { 325 name *string // name of method 326 pkgPath *string // nil for exported Names; otherwise import path 327 typ *rtype // .(*FuncType) underneath 328 } 329 330 // interfaceType represents an interface type. 331 type interfaceType struct { 332 rtype `reflect:"interface"` 333 methods []imethod // sorted by hash 334 } 335 336 // mapType represents a map type. 337 type mapType struct { 338 rtype `reflect:"map"` 339 key *rtype // map key type 340 elem *rtype // map element (value) type 341 bucket *rtype // internal bucket structure 342 hmap *rtype // internal map header 343 keysize uint8 // size of key slot 344 indirectkey uint8 // store ptr to key instead of key itself 345 valuesize uint8 // size of value slot 346 indirectvalue uint8 // store ptr to value instead of value itself 347 bucketsize uint16 // size of bucket 348 } 349 350 // ptrType represents a pointer type. 351 type ptrType struct { 352 rtype `reflect:"ptr"` 353 elem *rtype // pointer element (pointed at) type 354 } 355 356 // sliceType represents a slice type. 357 type sliceType struct { 358 rtype `reflect:"slice"` 359 elem *rtype // slice element type 360 } 361 362 // Struct field 363 type structField struct { 364 name *string // nil for embedded fields 365 pkgPath *string // nil for exported Names; otherwise import path 366 typ *rtype // type of field 367 tag *string // nil if no tag 368 offset uintptr // byte offset of field within struct 369 } 370 371 // structType represents a struct type. 372 type structType struct { 373 rtype `reflect:"struct"` 374 fields []structField // sorted by offset 375 } 376 377 /* 378 * The compiler knows the exact layout of all the data structures above. 379 * The compiler does not know about the data structures and methods below. 380 */ 381 382 // Method represents a single method. 383 type Method struct { 384 // Name is the method name. 385 // PkgPath is the package path that qualifies a lower case (unexported) 386 // method name. It is empty for upper case (exported) method names. 387 // The combination of PkgPath and Name uniquely identifies a method 388 // in a method set. 389 // See http://golang.org/ref/spec#Uniqueness_of_identifiers 390 Name string 391 PkgPath string 392 393 Type Type // method type 394 Func Value // func with receiver as first argument 395 Index int // index for Type.Method 396 } 397 398 const ( 399 kindDirectIface = 1 << 5 400 kindGCProg = 1 << 6 // Type.gc points to GC program 401 kindNoPointers = 1 << 7 402 kindMask = (1 << 5) - 1 403 ) 404 405 func (k Kind) String() string { 406 if int(k) < len(kindNames) { 407 return kindNames[k] 408 } 409 return "kind" + strconv.Itoa(int(k)) 410 } 411 412 var kindNames = []string{ 413 Invalid: "invalid", 414 Bool: "bool", 415 Int: "int", 416 Int8: "int8", 417 Int16: "int16", 418 Int32: "int32", 419 Int64: "int64", 420 Uint: "uint", 421 Uint8: "uint8", 422 Uint16: "uint16", 423 Uint32: "uint32", 424 Uint64: "uint64", 425 Uintptr: "uintptr", 426 Float32: "float32", 427 Float64: "float64", 428 Complex64: "complex64", 429 Complex128: "complex128", 430 Array: "array", 431 Chan: "chan", 432 Func: "func", 433 Interface: "interface", 434 Map: "map", 435 Ptr: "ptr", 436 Slice: "slice", 437 String: "string", 438 Struct: "struct", 439 UnsafePointer: "unsafe.Pointer", 440 } 441 442 func (t *uncommonType) uncommon() *uncommonType { 443 return t 444 } 445 446 func (t *uncommonType) PkgPath() string { 447 if t == nil || t.pkgPath == nil { 448 return "" 449 } 450 return *t.pkgPath 451 } 452 453 func (t *uncommonType) Name() string { 454 if t == nil || t.name == nil { 455 return "" 456 } 457 return *t.name 458 } 459 460 func (t *rtype) String() string { return *t.string } 461 462 func (t *rtype) Size() uintptr { return t.size } 463 464 func (t *rtype) Bits() int { 465 if t == nil { 466 panic("reflect: Bits of nil Type") 467 } 468 k := t.Kind() 469 if k < Int || k > Complex128 { 470 panic("reflect: Bits of non-arithmetic Type " + t.String()) 471 } 472 return int(t.size) * 8 473 } 474 475 func (t *rtype) Align() int { return int(t.align) } 476 477 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) } 478 479 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 480 481 func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 } 482 483 func (t *rtype) common() *rtype { return t } 484 485 func (t *uncommonType) Method(i int) (m Method) { 486 if t == nil || i < 0 || i >= len(t.methods) { 487 panic("reflect: Method index out of range") 488 } 489 p := &t.methods[i] 490 if p.name != nil { 491 m.Name = *p.name 492 } 493 fl := flag(Func) 494 if p.pkgPath != nil { 495 m.PkgPath = *p.pkgPath 496 fl |= flagRO 497 } 498 mt := p.typ 499 m.Type = mt 500 fn := unsafe.Pointer(&p.tfn) 501 m.Func = Value{mt, fn, fl} 502 m.Index = i 503 return 504 } 505 506 func (t *uncommonType) NumMethod() int { 507 if t == nil { 508 return 0 509 } 510 return len(t.methods) 511 } 512 513 func (t *uncommonType) MethodByName(name string) (m Method, ok bool) { 514 if t == nil { 515 return 516 } 517 var p *method 518 for i := range t.methods { 519 p = &t.methods[i] 520 if p.name != nil && *p.name == name { 521 return t.Method(i), true 522 } 523 } 524 return 525 } 526 527 // TODO(rsc): 6g supplies these, but they are not 528 // as efficient as they could be: they have commonType 529 // as the receiver instead of *rtype. 530 func (t *rtype) NumMethod() int { 531 if t.Kind() == Interface { 532 tt := (*interfaceType)(unsafe.Pointer(t)) 533 return tt.NumMethod() 534 } 535 return t.uncommonType.NumMethod() 536 } 537 538 func (t *rtype) Method(i int) (m Method) { 539 if t.Kind() == Interface { 540 tt := (*interfaceType)(unsafe.Pointer(t)) 541 return tt.Method(i) 542 } 543 return t.uncommonType.Method(i) 544 } 545 546 func (t *rtype) MethodByName(name string) (m Method, ok bool) { 547 if t.Kind() == Interface { 548 tt := (*interfaceType)(unsafe.Pointer(t)) 549 return tt.MethodByName(name) 550 } 551 return t.uncommonType.MethodByName(name) 552 } 553 554 func (t *rtype) PkgPath() string { 555 return t.uncommonType.PkgPath() 556 } 557 558 func (t *rtype) Name() string { 559 return t.uncommonType.Name() 560 } 561 562 func (t *rtype) ChanDir() ChanDir { 563 if t.Kind() != Chan { 564 panic("reflect: ChanDir of non-chan type") 565 } 566 tt := (*chanType)(unsafe.Pointer(t)) 567 return ChanDir(tt.dir) 568 } 569 570 func (t *rtype) IsVariadic() bool { 571 if t.Kind() != Func { 572 panic("reflect: IsVariadic of non-func type") 573 } 574 tt := (*funcType)(unsafe.Pointer(t)) 575 return tt.dotdotdot 576 } 577 578 func (t *rtype) Elem() Type { 579 switch t.Kind() { 580 case Array: 581 tt := (*arrayType)(unsafe.Pointer(t)) 582 return toType(tt.elem) 583 case Chan: 584 tt := (*chanType)(unsafe.Pointer(t)) 585 return toType(tt.elem) 586 case Map: 587 tt := (*mapType)(unsafe.Pointer(t)) 588 return toType(tt.elem) 589 case Ptr: 590 tt := (*ptrType)(unsafe.Pointer(t)) 591 return toType(tt.elem) 592 case Slice: 593 tt := (*sliceType)(unsafe.Pointer(t)) 594 return toType(tt.elem) 595 } 596 panic("reflect: Elem of invalid type") 597 } 598 599 func (t *rtype) Field(i int) StructField { 600 if t.Kind() != Struct { 601 panic("reflect: Field of non-struct type") 602 } 603 tt := (*structType)(unsafe.Pointer(t)) 604 return tt.Field(i) 605 } 606 607 func (t *rtype) FieldByIndex(index []int) StructField { 608 if t.Kind() != Struct { 609 panic("reflect: FieldByIndex of non-struct type") 610 } 611 tt := (*structType)(unsafe.Pointer(t)) 612 return tt.FieldByIndex(index) 613 } 614 615 func (t *rtype) FieldByName(name string) (StructField, bool) { 616 if t.Kind() != Struct { 617 panic("reflect: FieldByName of non-struct type") 618 } 619 tt := (*structType)(unsafe.Pointer(t)) 620 return tt.FieldByName(name) 621 } 622 623 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 624 if t.Kind() != Struct { 625 panic("reflect: FieldByNameFunc of non-struct type") 626 } 627 tt := (*structType)(unsafe.Pointer(t)) 628 return tt.FieldByNameFunc(match) 629 } 630 631 func (t *rtype) In(i int) Type { 632 if t.Kind() != Func { 633 panic("reflect: In of non-func type") 634 } 635 tt := (*funcType)(unsafe.Pointer(t)) 636 return toType(tt.in[i]) 637 } 638 639 func (t *rtype) Key() Type { 640 if t.Kind() != Map { 641 panic("reflect: Key of non-map type") 642 } 643 tt := (*mapType)(unsafe.Pointer(t)) 644 return toType(tt.key) 645 } 646 647 func (t *rtype) Len() int { 648 if t.Kind() != Array { 649 panic("reflect: Len of non-array type") 650 } 651 tt := (*arrayType)(unsafe.Pointer(t)) 652 return int(tt.len) 653 } 654 655 func (t *rtype) NumField() int { 656 if t.Kind() != Struct { 657 panic("reflect: NumField of non-struct type") 658 } 659 tt := (*structType)(unsafe.Pointer(t)) 660 return len(tt.fields) 661 } 662 663 func (t *rtype) NumIn() int { 664 if t.Kind() != Func { 665 panic("reflect: NumIn of non-func type") 666 } 667 tt := (*funcType)(unsafe.Pointer(t)) 668 return len(tt.in) 669 } 670 671 func (t *rtype) NumOut() int { 672 if t.Kind() != Func { 673 panic("reflect: NumOut of non-func type") 674 } 675 tt := (*funcType)(unsafe.Pointer(t)) 676 return len(tt.out) 677 } 678 679 func (t *rtype) Out(i int) Type { 680 if t.Kind() != Func { 681 panic("reflect: Out of non-func type") 682 } 683 tt := (*funcType)(unsafe.Pointer(t)) 684 return toType(tt.out[i]) 685 } 686 687 func (d ChanDir) String() string { 688 switch d { 689 case SendDir: 690 return "chan<-" 691 case RecvDir: 692 return "<-chan" 693 case BothDir: 694 return "chan" 695 } 696 return "ChanDir" + strconv.Itoa(int(d)) 697 } 698 699 // Method returns the i'th method in the type's method set. 700 func (t *interfaceType) Method(i int) (m Method) { 701 if i < 0 || i >= len(t.methods) { 702 return 703 } 704 p := &t.methods[i] 705 m.Name = *p.name 706 if p.pkgPath != nil { 707 m.PkgPath = *p.pkgPath 708 } 709 m.Type = toType(p.typ) 710 m.Index = i 711 return 712 } 713 714 // NumMethod returns the number of interface methods in the type's method set. 715 func (t *interfaceType) NumMethod() int { return len(t.methods) } 716 717 // MethodByName method with the given name in the type's method set. 718 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) { 719 if t == nil { 720 return 721 } 722 var p *imethod 723 for i := range t.methods { 724 p = &t.methods[i] 725 if *p.name == name { 726 return t.Method(i), true 727 } 728 } 729 return 730 } 731 732 // A StructField describes a single field in a struct. 733 type StructField struct { 734 // Name is the field name. 735 // PkgPath is the package path that qualifies a lower case (unexported) 736 // field name. It is empty for upper case (exported) field names. 737 // See http://golang.org/ref/spec#Uniqueness_of_identifiers 738 Name string 739 PkgPath string 740 741 Type Type // field type 742 Tag StructTag // field tag string 743 Offset uintptr // offset within struct, in bytes 744 Index []int // index sequence for Type.FieldByIndex 745 Anonymous bool // is an embedded field 746 } 747 748 // A StructTag is the tag string in a struct field. 749 // 750 // By convention, tag strings are a concatenation of 751 // optionally space-separated key:"value" pairs. 752 // Each key is a non-empty string consisting of non-control 753 // characters other than space (U+0020 ' '), quote (U+0022 '"'), 754 // and colon (U+003A ':'). Each value is quoted using U+0022 '"' 755 // characters and Go string literal syntax. 756 type StructTag string 757 758 // Get returns the value associated with key in the tag string. 759 // If there is no such key in the tag, Get returns the empty string. 760 // If the tag does not have the conventional format, the value 761 // returned by Get is unspecified. 762 func (tag StructTag) Get(key string) string { 763 for tag != "" { 764 // skip leading space 765 i := 0 766 for i < len(tag) && tag[i] == ' ' { 767 i++ 768 } 769 tag = tag[i:] 770 if tag == "" { 771 break 772 } 773 774 // scan to colon. 775 // a space or a quote is a syntax error 776 i = 0 777 for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' { 778 i++ 779 } 780 if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 781 break 782 } 783 name := string(tag[:i]) 784 tag = tag[i+1:] 785 786 // scan quoted string to find value 787 i = 1 788 for i < len(tag) && tag[i] != '"' { 789 if tag[i] == '\\' { 790 i++ 791 } 792 i++ 793 } 794 if i >= len(tag) { 795 break 796 } 797 qvalue := string(tag[:i+1]) 798 tag = tag[i+1:] 799 800 if key == name { 801 value, _ := strconv.Unquote(qvalue) 802 return value 803 } 804 } 805 return "" 806 } 807 808 // Field returns the i'th struct field. 809 func (t *structType) Field(i int) (f StructField) { 810 if i < 0 || i >= len(t.fields) { 811 return 812 } 813 p := &t.fields[i] 814 f.Type = toType(p.typ) 815 if p.name != nil { 816 f.Name = *p.name 817 } else { 818 t := f.Type 819 if t.Kind() == Ptr { 820 t = t.Elem() 821 } 822 f.Name = t.Name() 823 f.Anonymous = true 824 } 825 if p.pkgPath != nil { 826 f.PkgPath = *p.pkgPath 827 } 828 if p.tag != nil { 829 f.Tag = StructTag(*p.tag) 830 } 831 f.Offset = p.offset 832 833 // NOTE(rsc): This is the only allocation in the interface 834 // presented by a reflect.Type. It would be nice to avoid, 835 // at least in the common cases, but we need to make sure 836 // that misbehaving clients of reflect cannot affect other 837 // uses of reflect. One possibility is CL 5371098, but we 838 // postponed that ugliness until there is a demonstrated 839 // need for the performance. This is issue 2320. 840 f.Index = []int{i} 841 return 842 } 843 844 // TODO(gri): Should there be an error/bool indicator if the index 845 // is wrong for FieldByIndex? 846 847 // FieldByIndex returns the nested field corresponding to index. 848 func (t *structType) FieldByIndex(index []int) (f StructField) { 849 f.Type = toType(&t.rtype) 850 for i, x := range index { 851 if i > 0 { 852 ft := f.Type 853 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct { 854 ft = ft.Elem() 855 } 856 f.Type = ft 857 } 858 f = f.Type.Field(x) 859 } 860 return 861 } 862 863 // A fieldScan represents an item on the fieldByNameFunc scan work list. 864 type fieldScan struct { 865 typ *structType 866 index []int 867 } 868 869 // FieldByNameFunc returns the struct field with a name that satisfies the 870 // match function and a boolean to indicate if the field was found. 871 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) { 872 // This uses the same condition that the Go language does: there must be a unique instance 873 // of the match at a given depth level. If there are multiple instances of a match at the 874 // same depth, they annihilate each other and inhibit any possible match at a lower level. 875 // The algorithm is breadth first search, one depth level at a time. 876 877 // The current and next slices are work queues: 878 // current lists the fields to visit on this depth level, 879 // and next lists the fields on the next lower level. 880 current := []fieldScan{} 881 next := []fieldScan{{typ: t}} 882 883 // nextCount records the number of times an embedded type has been 884 // encountered and considered for queueing in the 'next' slice. 885 // We only queue the first one, but we increment the count on each. 886 // If a struct type T can be reached more than once at a given depth level, 887 // then it annihilates itself and need not be considered at all when we 888 // process that next depth level. 889 var nextCount map[*structType]int 890 891 // visited records the structs that have been considered already. 892 // Embedded pointer fields can create cycles in the graph of 893 // reachable embedded types; visited avoids following those cycles. 894 // It also avoids duplicated effort: if we didn't find the field in an 895 // embedded type T at level 2, we won't find it in one at level 4 either. 896 visited := map[*structType]bool{} 897 898 for len(next) > 0 { 899 current, next = next, current[:0] 900 count := nextCount 901 nextCount = nil 902 903 // Process all the fields at this depth, now listed in 'current'. 904 // The loop queues embedded fields found in 'next', for processing during the next 905 // iteration. The multiplicity of the 'current' field counts is recorded 906 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. 907 for _, scan := range current { 908 t := scan.typ 909 if visited[t] { 910 // We've looked through this type before, at a higher level. 911 // That higher level would shadow the lower level we're now at, 912 // so this one can't be useful to us. Ignore it. 913 continue 914 } 915 visited[t] = true 916 for i := range t.fields { 917 f := &t.fields[i] 918 // Find name and type for field f. 919 var fname string 920 var ntyp *rtype 921 if f.name != nil { 922 fname = *f.name 923 } else { 924 // Anonymous field of type T or *T. 925 // Name taken from type. 926 ntyp = f.typ 927 if ntyp.Kind() == Ptr { 928 ntyp = ntyp.Elem().common() 929 } 930 fname = ntyp.Name() 931 } 932 933 // Does it match? 934 if match(fname) { 935 // Potential match 936 if count[t] > 1 || ok { 937 // Name appeared multiple times at this level: annihilate. 938 return StructField{}, false 939 } 940 result = t.Field(i) 941 result.Index = nil 942 result.Index = append(result.Index, scan.index...) 943 result.Index = append(result.Index, i) 944 ok = true 945 continue 946 } 947 948 // Queue embedded struct fields for processing with next level, 949 // but only if we haven't seen a match yet at this level and only 950 // if the embedded types haven't already been queued. 951 if ok || ntyp == nil || ntyp.Kind() != Struct { 952 continue 953 } 954 styp := (*structType)(unsafe.Pointer(ntyp)) 955 if nextCount[styp] > 0 { 956 nextCount[styp] = 2 // exact multiple doesn't matter 957 continue 958 } 959 if nextCount == nil { 960 nextCount = map[*structType]int{} 961 } 962 nextCount[styp] = 1 963 if count[t] > 1 { 964 nextCount[styp] = 2 // exact multiple doesn't matter 965 } 966 var index []int 967 index = append(index, scan.index...) 968 index = append(index, i) 969 next = append(next, fieldScan{styp, index}) 970 } 971 } 972 if ok { 973 break 974 } 975 } 976 return 977 } 978 979 // FieldByName returns the struct field with the given name 980 // and a boolean to indicate if the field was found. 981 func (t *structType) FieldByName(name string) (f StructField, present bool) { 982 // Quick check for top-level name, or struct without anonymous fields. 983 hasAnon := false 984 if name != "" { 985 for i := range t.fields { 986 tf := &t.fields[i] 987 if tf.name == nil { 988 hasAnon = true 989 continue 990 } 991 if *tf.name == name { 992 return t.Field(i), true 993 } 994 } 995 } 996 if !hasAnon { 997 return 998 } 999 return t.FieldByNameFunc(func(s string) bool { return s == name }) 1000 } 1001 1002 // TypeOf returns the reflection Type of the value in the interface{}. 1003 // TypeOf(nil) returns nil. 1004 func TypeOf(i interface{}) Type { 1005 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1006 return toType(eface.typ) 1007 } 1008 1009 // ptrMap is the cache for PtrTo. 1010 var ptrMap struct { 1011 sync.RWMutex 1012 m map[*rtype]*ptrType 1013 } 1014 1015 // PtrTo returns the pointer type with element t. 1016 // For example, if t represents type Foo, PtrTo(t) represents *Foo. 1017 func PtrTo(t Type) Type { 1018 return t.(*rtype).ptrTo() 1019 } 1020 1021 func (t *rtype) ptrTo() *rtype { 1022 if p := t.ptrToThis; p != nil { 1023 return p 1024 } 1025 1026 // Otherwise, synthesize one. 1027 // This only happens for pointers with no methods. 1028 // We keep the mapping in a map on the side, because 1029 // this operation is rare and a separate map lets us keep 1030 // the type structures in read-only memory. 1031 ptrMap.RLock() 1032 if m := ptrMap.m; m != nil { 1033 if p := m[t]; p != nil { 1034 ptrMap.RUnlock() 1035 return &p.rtype 1036 } 1037 } 1038 ptrMap.RUnlock() 1039 ptrMap.Lock() 1040 if ptrMap.m == nil { 1041 ptrMap.m = make(map[*rtype]*ptrType) 1042 } 1043 p := ptrMap.m[t] 1044 if p != nil { 1045 // some other goroutine won the race and created it 1046 ptrMap.Unlock() 1047 return &p.rtype 1048 } 1049 1050 // Create a new ptrType starting with the description 1051 // of an *unsafe.Pointer. 1052 p = new(ptrType) 1053 var iptr interface{} = (*unsafe.Pointer)(nil) 1054 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 1055 *p = *prototype 1056 1057 s := "*" + *t.string 1058 p.string = &s 1059 1060 // For the type structures linked into the binary, the 1061 // compiler provides a good hash of the string. 1062 // Create a good hash for the new string by using 1063 // the FNV-1 hash's mixing function to combine the 1064 // old hash and the new "*". 1065 p.hash = fnv1(t.hash, '*') 1066 1067 p.uncommonType = nil 1068 p.ptrToThis = nil 1069 p.zero = unsafe.Pointer(&make([]byte, p.size)[0]) 1070 p.elem = t 1071 1072 ptrMap.m[t] = p 1073 ptrMap.Unlock() 1074 return &p.rtype 1075 } 1076 1077 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 1078 func fnv1(x uint32, list ...byte) uint32 { 1079 for _, b := range list { 1080 x = x*16777619 ^ uint32(b) 1081 } 1082 return x 1083 } 1084 1085 func (t *rtype) Implements(u Type) bool { 1086 if u == nil { 1087 panic("reflect: nil type passed to Type.Implements") 1088 } 1089 if u.Kind() != Interface { 1090 panic("reflect: non-interface type passed to Type.Implements") 1091 } 1092 return implements(u.(*rtype), t) 1093 } 1094 1095 func (t *rtype) AssignableTo(u Type) bool { 1096 if u == nil { 1097 panic("reflect: nil type passed to Type.AssignableTo") 1098 } 1099 uu := u.(*rtype) 1100 return directlyAssignable(uu, t) || implements(uu, t) 1101 } 1102 1103 func (t *rtype) ConvertibleTo(u Type) bool { 1104 if u == nil { 1105 panic("reflect: nil type passed to Type.ConvertibleTo") 1106 } 1107 uu := u.(*rtype) 1108 return convertOp(uu, t) != nil 1109 } 1110 1111 func (t *rtype) Comparable() bool { 1112 return t.alg != nil && t.alg.equal != nil 1113 } 1114 1115 // implements returns true if the type V implements the interface type T. 1116 func implements(T, V *rtype) bool { 1117 if T.Kind() != Interface { 1118 return false 1119 } 1120 t := (*interfaceType)(unsafe.Pointer(T)) 1121 if len(t.methods) == 0 { 1122 return true 1123 } 1124 1125 // The same algorithm applies in both cases, but the 1126 // method tables for an interface type and a concrete type 1127 // are different, so the code is duplicated. 1128 // In both cases the algorithm is a linear scan over the two 1129 // lists - T's methods and V's methods - simultaneously. 1130 // Since method tables are stored in a unique sorted order 1131 // (alphabetical, with no duplicate method names), the scan 1132 // through V's methods must hit a match for each of T's 1133 // methods along the way, or else V does not implement T. 1134 // This lets us run the scan in overall linear time instead of 1135 // the quadratic time a naive search would require. 1136 // See also ../runtime/iface.c. 1137 if V.Kind() == Interface { 1138 v := (*interfaceType)(unsafe.Pointer(V)) 1139 i := 0 1140 for j := 0; j < len(v.methods); j++ { 1141 tm := &t.methods[i] 1142 vm := &v.methods[j] 1143 if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ { 1144 if i++; i >= len(t.methods) { 1145 return true 1146 } 1147 } 1148 } 1149 return false 1150 } 1151 1152 v := V.uncommon() 1153 if v == nil { 1154 return false 1155 } 1156 i := 0 1157 for j := 0; j < len(v.methods); j++ { 1158 tm := &t.methods[i] 1159 vm := &v.methods[j] 1160 if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ { 1161 if i++; i >= len(t.methods) { 1162 return true 1163 } 1164 } 1165 } 1166 return false 1167 } 1168 1169 // directlyAssignable returns true if a value x of type V can be directly 1170 // assigned (using memmove) to a value of type T. 1171 // http://golang.org/doc/go_spec.html#Assignability 1172 // Ignoring the interface rules (implemented elsewhere) 1173 // and the ideal constant rules (no ideal constants at run time). 1174 func directlyAssignable(T, V *rtype) bool { 1175 // x's type V is identical to T? 1176 if T == V { 1177 return true 1178 } 1179 1180 // Otherwise at least one of T and V must be unnamed 1181 // and they must have the same kind. 1182 if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() { 1183 return false 1184 } 1185 1186 // x's type T and V must have identical underlying types. 1187 return haveIdenticalUnderlyingType(T, V) 1188 } 1189 1190 func haveIdenticalUnderlyingType(T, V *rtype) bool { 1191 if T == V { 1192 return true 1193 } 1194 1195 kind := T.Kind() 1196 if kind != V.Kind() { 1197 return false 1198 } 1199 1200 // Non-composite types of equal kind have same underlying type 1201 // (the predefined instance of the type). 1202 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 1203 return true 1204 } 1205 1206 // Composite types. 1207 switch kind { 1208 case Array: 1209 return T.Elem() == V.Elem() && T.Len() == V.Len() 1210 1211 case Chan: 1212 // Special case: 1213 // x is a bidirectional channel value, T is a channel type, 1214 // and x's type V and T have identical element types. 1215 if V.ChanDir() == BothDir && T.Elem() == V.Elem() { 1216 return true 1217 } 1218 1219 // Otherwise continue test for identical underlying type. 1220 return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem() 1221 1222 case Func: 1223 t := (*funcType)(unsafe.Pointer(T)) 1224 v := (*funcType)(unsafe.Pointer(V)) 1225 if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) { 1226 return false 1227 } 1228 for i, typ := range t.in { 1229 if typ != v.in[i] { 1230 return false 1231 } 1232 } 1233 for i, typ := range t.out { 1234 if typ != v.out[i] { 1235 return false 1236 } 1237 } 1238 return true 1239 1240 case Interface: 1241 t := (*interfaceType)(unsafe.Pointer(T)) 1242 v := (*interfaceType)(unsafe.Pointer(V)) 1243 if len(t.methods) == 0 && len(v.methods) == 0 { 1244 return true 1245 } 1246 // Might have the same methods but still 1247 // need a run time conversion. 1248 return false 1249 1250 case Map: 1251 return T.Key() == V.Key() && T.Elem() == V.Elem() 1252 1253 case Ptr, Slice: 1254 return T.Elem() == V.Elem() 1255 1256 case Struct: 1257 t := (*structType)(unsafe.Pointer(T)) 1258 v := (*structType)(unsafe.Pointer(V)) 1259 if len(t.fields) != len(v.fields) { 1260 return false 1261 } 1262 for i := range t.fields { 1263 tf := &t.fields[i] 1264 vf := &v.fields[i] 1265 if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) { 1266 return false 1267 } 1268 if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) { 1269 return false 1270 } 1271 if tf.typ != vf.typ { 1272 return false 1273 } 1274 if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) { 1275 return false 1276 } 1277 if tf.offset != vf.offset { 1278 return false 1279 } 1280 } 1281 return true 1282 } 1283 1284 return false 1285 } 1286 1287 // typelinks is implemented in package runtime. 1288 // It returns a slice of all the 'typelink' information in the binary, 1289 // which is to say a slice of known types, sorted by string. 1290 // Note that strings are not unique identifiers for types: 1291 // there can be more than one with a given string. 1292 // Only types we might want to look up are included: 1293 // channels, maps, slices, and arrays. 1294 func typelinks() []*rtype 1295 1296 // typesByString returns the subslice of typelinks() whose elements have 1297 // the given string representation. 1298 // It may be empty (no known types with that string) or may have 1299 // multiple elements (multiple types with that string). 1300 func typesByString(s string) []*rtype { 1301 typ := typelinks() 1302 1303 // We are looking for the first index i where the string becomes >= s. 1304 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].string >= s). 1305 i, j := 0, len(typ) 1306 for i < j { 1307 h := i + (j-i)/2 // avoid overflow when computing h 1308 // i ≤ h < j 1309 if !(*typ[h].string >= s) { 1310 i = h + 1 // preserves f(i-1) == false 1311 } else { 1312 j = h // preserves f(j) == true 1313 } 1314 } 1315 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 1316 1317 // Having found the first, linear scan forward to find the last. 1318 // We could do a second binary search, but the caller is going 1319 // to do a linear scan anyway. 1320 j = i 1321 for j < len(typ) && *typ[j].string == s { 1322 j++ 1323 } 1324 1325 // This slice will be empty if the string is not found. 1326 return typ[i:j] 1327 } 1328 1329 // The lookupCache caches ChanOf, MapOf, and SliceOf lookups. 1330 var lookupCache struct { 1331 sync.RWMutex 1332 m map[cacheKey]*rtype 1333 } 1334 1335 // A cacheKey is the key for use in the lookupCache. 1336 // Four values describe any of the types we are looking for: 1337 // type kind, one or two subtypes, and an extra integer. 1338 type cacheKey struct { 1339 kind Kind 1340 t1 *rtype 1341 t2 *rtype 1342 extra uintptr 1343 } 1344 1345 // cacheGet looks for a type under the key k in the lookupCache. 1346 // If it finds one, it returns that type. 1347 // If not, it returns nil with the cache locked. 1348 // The caller is expected to use cachePut to unlock the cache. 1349 func cacheGet(k cacheKey) Type { 1350 lookupCache.RLock() 1351 t := lookupCache.m[k] 1352 lookupCache.RUnlock() 1353 if t != nil { 1354 return t 1355 } 1356 1357 lookupCache.Lock() 1358 t = lookupCache.m[k] 1359 if t != nil { 1360 lookupCache.Unlock() 1361 return t 1362 } 1363 1364 if lookupCache.m == nil { 1365 lookupCache.m = make(map[cacheKey]*rtype) 1366 } 1367 1368 return nil 1369 } 1370 1371 // cachePut stores the given type in the cache, unlocks the cache, 1372 // and returns the type. It is expected that the cache is locked 1373 // because cacheGet returned nil. 1374 func cachePut(k cacheKey, t *rtype) Type { 1375 lookupCache.m[k] = t 1376 lookupCache.Unlock() 1377 return t 1378 } 1379 1380 // ChanOf returns the channel type with the given direction and element type. 1381 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int. 1382 // 1383 // The gc runtime imposes a limit of 64 kB on channel element types. 1384 // If t's size is equal to or exceeds this limit, ChanOf panics. 1385 func ChanOf(dir ChanDir, t Type) Type { 1386 typ := t.(*rtype) 1387 1388 // Look in cache. 1389 ckey := cacheKey{Chan, typ, nil, uintptr(dir)} 1390 if ch := cacheGet(ckey); ch != nil { 1391 return ch 1392 } 1393 1394 // This restriction is imposed by the gc compiler and the runtime. 1395 if typ.size >= 1<<16 { 1396 lookupCache.Unlock() 1397 panic("reflect.ChanOf: element size too large") 1398 } 1399 1400 // Look in known types. 1401 // TODO: Precedence when constructing string. 1402 var s string 1403 switch dir { 1404 default: 1405 lookupCache.Unlock() 1406 panic("reflect.ChanOf: invalid dir") 1407 case SendDir: 1408 s = "chan<- " + *typ.string 1409 case RecvDir: 1410 s = "<-chan " + *typ.string 1411 case BothDir: 1412 s = "chan " + *typ.string 1413 } 1414 for _, tt := range typesByString(s) { 1415 ch := (*chanType)(unsafe.Pointer(tt)) 1416 if ch.elem == typ && ch.dir == uintptr(dir) { 1417 return cachePut(ckey, tt) 1418 } 1419 } 1420 1421 // Make a channel type. 1422 var ichan interface{} = (chan unsafe.Pointer)(nil) 1423 prototype := *(**chanType)(unsafe.Pointer(&ichan)) 1424 ch := new(chanType) 1425 *ch = *prototype 1426 ch.string = &s 1427 ch.hash = fnv1(typ.hash, 'c', byte(dir)) 1428 ch.elem = typ 1429 ch.uncommonType = nil 1430 ch.ptrToThis = nil 1431 ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0]) 1432 1433 return cachePut(ckey, &ch.rtype) 1434 } 1435 1436 func ismapkey(*rtype) bool // implemented in runtime 1437 1438 // MapOf returns the map type with the given key and element types. 1439 // For example, if k represents int and e represents string, 1440 // MapOf(k, e) represents map[int]string. 1441 // 1442 // If the key type is not a valid map key type (that is, if it does 1443 // not implement Go's == operator), MapOf panics. 1444 func MapOf(key, elem Type) Type { 1445 ktyp := key.(*rtype) 1446 etyp := elem.(*rtype) 1447 1448 if !ismapkey(ktyp) { 1449 panic("reflect.MapOf: invalid key type " + ktyp.String()) 1450 } 1451 1452 // Look in cache. 1453 ckey := cacheKey{Map, ktyp, etyp, 0} 1454 if mt := cacheGet(ckey); mt != nil { 1455 return mt 1456 } 1457 1458 // Look in known types. 1459 s := "map[" + *ktyp.string + "]" + *etyp.string 1460 for _, tt := range typesByString(s) { 1461 mt := (*mapType)(unsafe.Pointer(tt)) 1462 if mt.key == ktyp && mt.elem == etyp { 1463 return cachePut(ckey, tt) 1464 } 1465 } 1466 1467 // Make a map type. 1468 var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil) 1469 prototype := *(**mapType)(unsafe.Pointer(&imap)) 1470 mt := new(mapType) 1471 *mt = *prototype 1472 mt.string = &s 1473 mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash)) 1474 mt.key = ktyp 1475 mt.elem = etyp 1476 mt.bucket = bucketOf(ktyp, etyp) 1477 if ktyp.size > maxKeySize { 1478 mt.keysize = uint8(ptrSize) 1479 mt.indirectkey = 1 1480 } else { 1481 mt.keysize = uint8(ktyp.size) 1482 mt.indirectkey = 0 1483 } 1484 if etyp.size > maxValSize { 1485 mt.valuesize = uint8(ptrSize) 1486 mt.indirectvalue = 1 1487 } else { 1488 mt.valuesize = uint8(etyp.size) 1489 mt.indirectvalue = 0 1490 } 1491 mt.bucketsize = uint16(mt.bucket.size) 1492 mt.uncommonType = nil 1493 mt.ptrToThis = nil 1494 mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0]) 1495 1496 return cachePut(ckey, &mt.rtype) 1497 } 1498 1499 // gcProg is a helper type for generatation of GC pointer info. 1500 type gcProg struct { 1501 gc []byte 1502 size uintptr // size of type in bytes 1503 } 1504 1505 func (gc *gcProg) append(v byte) { 1506 gc.align(unsafe.Sizeof(uintptr(0))) 1507 gc.appendWord(v) 1508 } 1509 1510 // Appends t's type info to the current program. 1511 func (gc *gcProg) appendProg(t *rtype) { 1512 gc.align(uintptr(t.align)) 1513 if !t.pointers() { 1514 gc.size += t.size 1515 return 1516 } 1517 switch t.Kind() { 1518 default: 1519 panic("reflect: non-pointer type marked as having pointers") 1520 case Ptr, UnsafePointer, Chan, Func, Map: 1521 gc.appendWord(bitsPointer) 1522 case Slice: 1523 gc.appendWord(bitsPointer) 1524 gc.appendWord(bitsScalar) 1525 gc.appendWord(bitsScalar) 1526 case String: 1527 gc.appendWord(bitsPointer) 1528 gc.appendWord(bitsScalar) 1529 case Array: 1530 c := t.Len() 1531 e := t.Elem().common() 1532 for i := 0; i < c; i++ { 1533 gc.appendProg(e) 1534 } 1535 case Interface: 1536 gc.appendWord(bitsPointer) 1537 gc.appendWord(bitsPointer) 1538 case Struct: 1539 c := t.NumField() 1540 for i := 0; i < c; i++ { 1541 gc.appendProg(t.Field(i).Type.common()) 1542 } 1543 gc.align(uintptr(t.align)) 1544 } 1545 } 1546 1547 func (gc *gcProg) appendWord(v byte) { 1548 ptrsize := unsafe.Sizeof(uintptr(0)) 1549 if gc.size%ptrsize != 0 { 1550 panic("reflect: unaligned GC program") 1551 } 1552 nptr := gc.size / ptrsize 1553 for uintptr(len(gc.gc)) < nptr/2+1 { 1554 gc.gc = append(gc.gc, 0x44) // BitsScalar 1555 } 1556 gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2)) 1557 gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2) 1558 gc.size += ptrsize 1559 } 1560 1561 func (gc *gcProg) finalize() unsafe.Pointer { 1562 if gc.size == 0 { 1563 return nil 1564 } 1565 ptrsize := unsafe.Sizeof(uintptr(0)) 1566 gc.align(ptrsize) 1567 nptr := gc.size / ptrsize 1568 for uintptr(len(gc.gc)) < nptr/2+1 { 1569 gc.gc = append(gc.gc, 0x44) // BitsScalar 1570 } 1571 // If number of words is odd, repeat the mask twice. 1572 // Compiler does the same. 1573 if nptr%2 != 0 { 1574 for i := uintptr(0); i < nptr; i++ { 1575 gc.appendWord(extractGCWord(gc.gc, i)) 1576 } 1577 } 1578 return unsafe.Pointer(&gc.gc[0]) 1579 } 1580 1581 func extractGCWord(gc []byte, i uintptr) byte { 1582 return (gc[i/2] >> ((i%2)*4 + 2)) & 3 1583 } 1584 1585 func (gc *gcProg) align(a uintptr) { 1586 gc.size = align(gc.size, a) 1587 } 1588 1589 // These constants must stay in sync with ../runtime/mgc0.h. 1590 const ( 1591 bitsScalar = 1 1592 bitsPointer = 2 1593 1594 bitsIface = 2 1595 bitsEface = 3 1596 ) 1597 1598 // Make sure these routines stay in sync with ../../runtime/hashmap.go! 1599 // These types exist only for GC, so we only fill out GC relevant info. 1600 // Currently, that's just size and the GC program. We also fill in string 1601 // for possible debugging use. 1602 const ( 1603 bucketSize = 8 1604 maxKeySize = 128 1605 maxValSize = 128 1606 ) 1607 1608 func bucketOf(ktyp, etyp *rtype) *rtype { 1609 if ktyp.size > maxKeySize { 1610 ktyp = PtrTo(ktyp).(*rtype) 1611 } 1612 if etyp.size > maxValSize { 1613 etyp = PtrTo(etyp).(*rtype) 1614 } 1615 ptrsize := unsafe.Sizeof(uintptr(0)) 1616 1617 var gc gcProg 1618 // topbits 1619 for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ { 1620 gc.append(bitsScalar) 1621 } 1622 gc.append(bitsPointer) // overflow 1623 if runtime.GOARCH == "amd64p32" { 1624 gc.append(bitsScalar) 1625 } 1626 // keys 1627 for i := 0; i < bucketSize; i++ { 1628 gc.appendProg(ktyp) 1629 } 1630 // values 1631 for i := 0; i < bucketSize; i++ { 1632 gc.appendProg(etyp) 1633 } 1634 1635 b := new(rtype) 1636 b.size = gc.size 1637 b.gc[0] = gc.finalize() 1638 s := "bucket(" + *ktyp.string + "," + *etyp.string + ")" 1639 b.string = &s 1640 return b 1641 } 1642 1643 // SliceOf returns the slice type with element type t. 1644 // For example, if t represents int, SliceOf(t) represents []int. 1645 func SliceOf(t Type) Type { 1646 typ := t.(*rtype) 1647 1648 // Look in cache. 1649 ckey := cacheKey{Slice, typ, nil, 0} 1650 if slice := cacheGet(ckey); slice != nil { 1651 return slice 1652 } 1653 1654 // Look in known types. 1655 s := "[]" + *typ.string 1656 for _, tt := range typesByString(s) { 1657 slice := (*sliceType)(unsafe.Pointer(tt)) 1658 if slice.elem == typ { 1659 return cachePut(ckey, tt) 1660 } 1661 } 1662 1663 // Make a slice type. 1664 var islice interface{} = ([]unsafe.Pointer)(nil) 1665 prototype := *(**sliceType)(unsafe.Pointer(&islice)) 1666 slice := new(sliceType) 1667 *slice = *prototype 1668 slice.string = &s 1669 slice.hash = fnv1(typ.hash, '[') 1670 slice.elem = typ 1671 slice.uncommonType = nil 1672 slice.ptrToThis = nil 1673 slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0]) 1674 1675 return cachePut(ckey, &slice.rtype) 1676 } 1677 1678 // ArrayOf returns the array type with the given count and element type. 1679 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 1680 // 1681 // If the resulting type would be larger than the available address space, 1682 // ArrayOf panics. 1683 // 1684 // TODO(rsc): Unexported for now. Export once the alg field is set correctly 1685 // for the type. This may require significant work. 1686 // 1687 // TODO(rsc): TestArrayOf is also disabled. Re-enable. 1688 func arrayOf(count int, elem Type) Type { 1689 typ := elem.(*rtype) 1690 slice := SliceOf(elem) 1691 1692 // Look in cache. 1693 ckey := cacheKey{Array, typ, nil, uintptr(count)} 1694 if slice := cacheGet(ckey); slice != nil { 1695 return slice 1696 } 1697 1698 // Look in known types. 1699 s := "[" + strconv.Itoa(count) + "]" + *typ.string 1700 for _, tt := range typesByString(s) { 1701 slice := (*sliceType)(unsafe.Pointer(tt)) 1702 if slice.elem == typ { 1703 return cachePut(ckey, tt) 1704 } 1705 } 1706 1707 // Make an array type. 1708 var iarray interface{} = [1]unsafe.Pointer{} 1709 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 1710 array := new(arrayType) 1711 *array = *prototype 1712 // TODO: Set extra kind bits correctly. 1713 array.string = &s 1714 array.hash = fnv1(typ.hash, '[') 1715 for n := uint32(count); n > 0; n >>= 8 { 1716 array.hash = fnv1(array.hash, byte(n)) 1717 } 1718 array.hash = fnv1(array.hash, ']') 1719 array.elem = typ 1720 max := ^uintptr(0) / typ.size 1721 if uintptr(count) > max { 1722 panic("reflect.ArrayOf: array size would exceed virtual address space") 1723 } 1724 array.size = typ.size * uintptr(count) 1725 array.align = typ.align 1726 array.fieldAlign = typ.fieldAlign 1727 // TODO: array.alg 1728 // TODO: array.gc 1729 // TODO: 1730 array.uncommonType = nil 1731 array.ptrToThis = nil 1732 array.zero = unsafe.Pointer(&make([]byte, array.size)[0]) 1733 array.len = uintptr(count) 1734 array.slice = slice.(*rtype) 1735 1736 return cachePut(ckey, &array.rtype) 1737 } 1738 1739 // toType converts from a *rtype to a Type that can be returned 1740 // to the client of package reflect. In gc, the only concern is that 1741 // a nil *rtype must be replaced by a nil Type, but in gccgo this 1742 // function takes care of ensuring that multiple *rtype for the same 1743 // type are coalesced into a single Type. 1744 func toType(t *rtype) Type { 1745 if t == nil { 1746 return nil 1747 } 1748 return t 1749 } 1750 1751 type layoutKey struct { 1752 t *rtype // function signature 1753 rcvr *rtype // receiver type, or nil if none 1754 } 1755 1756 type layoutType struct { 1757 t *rtype 1758 argSize uintptr // size of arguments 1759 retOffset uintptr // offset of return values. 1760 stack *bitVector 1761 } 1762 1763 var layoutCache struct { 1764 sync.RWMutex 1765 m map[layoutKey]layoutType 1766 } 1767 1768 // funcLayout computes a struct type representing the layout of the 1769 // function arguments and return values for the function type t. 1770 // If rcvr != nil, rcvr specifies the type of the receiver. 1771 // The returned type exists only for GC, so we only fill out GC relevant info. 1772 // Currently, that's just size and the GC program. We also fill in 1773 // the name for possible debugging use. 1774 func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stack *bitVector) { 1775 if t.Kind() != Func { 1776 panic("reflect: funcLayout of non-func type") 1777 } 1778 if rcvr != nil && rcvr.Kind() == Interface { 1779 panic("reflect: funcLayout with interface receiver " + rcvr.String()) 1780 } 1781 k := layoutKey{t, rcvr} 1782 layoutCache.RLock() 1783 if x := layoutCache.m[k]; x.t != nil { 1784 layoutCache.RUnlock() 1785 return x.t, x.argSize, x.retOffset, x.stack 1786 } 1787 layoutCache.RUnlock() 1788 layoutCache.Lock() 1789 if x := layoutCache.m[k]; x.t != nil { 1790 layoutCache.Unlock() 1791 return x.t, x.argSize, x.retOffset, x.stack 1792 } 1793 1794 tt := (*funcType)(unsafe.Pointer(t)) 1795 1796 // compute gc program & stack bitmap for arguments 1797 stack = new(bitVector) 1798 var gc gcProg 1799 var offset uintptr 1800 if rcvr != nil { 1801 // Reflect uses the "interface" calling convention for 1802 // methods, where receivers take one word of argument 1803 // space no matter how big they actually are. 1804 if ifaceIndir(rcvr) { 1805 // we pass a pointer to the receiver. 1806 gc.append(bitsPointer) 1807 stack.append2(bitsPointer) 1808 } else if rcvr.pointers() { 1809 // rcvr is a one-word pointer object. Its gc program 1810 // is just what we need here. 1811 gc.append(bitsPointer) 1812 stack.append2(bitsPointer) 1813 } else { 1814 gc.append(bitsScalar) 1815 stack.append2(bitsScalar) 1816 } 1817 offset += ptrSize 1818 } 1819 for _, arg := range tt.in { 1820 gc.appendProg(arg) 1821 addTypeBits(stack, &offset, arg) 1822 } 1823 argSize = gc.size 1824 if runtime.GOARCH == "amd64p32" { 1825 gc.align(8) 1826 } 1827 gc.align(ptrSize) 1828 retOffset = gc.size 1829 for _, res := range tt.out { 1830 gc.appendProg(res) 1831 // stack map does not need result bits 1832 } 1833 gc.align(ptrSize) 1834 1835 // build dummy rtype holding gc program 1836 x := new(rtype) 1837 x.size = gc.size 1838 x.gc[0] = gc.finalize() 1839 var s string 1840 if rcvr != nil { 1841 s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")" 1842 } else { 1843 s = "funcargs(" + *t.string + ")" 1844 } 1845 x.string = &s 1846 1847 // cache result for future callers 1848 if layoutCache.m == nil { 1849 layoutCache.m = make(map[layoutKey]layoutType) 1850 } 1851 layoutCache.m[k] = layoutType{ 1852 t: x, 1853 argSize: argSize, 1854 retOffset: retOffset, 1855 stack: stack, 1856 } 1857 layoutCache.Unlock() 1858 return x, argSize, retOffset, stack 1859 } 1860 1861 // ifaceIndir reports whether t is stored indirectly in an interface value. 1862 func ifaceIndir(t *rtype) bool { 1863 return t.kind&kindDirectIface == 0 1864 } 1865 1866 // Layout matches runtime.BitVector (well enough). 1867 type bitVector struct { 1868 n uint32 // number of bits 1869 data []byte 1870 } 1871 1872 // append a bit pair to the bitmap. 1873 func (bv *bitVector) append2(bits uint8) { 1874 // assume bv.n is a multiple of 2, since append2 is the only operation. 1875 if bv.n%8 == 0 { 1876 bv.data = append(bv.data, 0) 1877 } 1878 bv.data[bv.n/8] |= bits << (bv.n % 8) 1879 bv.n += 2 1880 } 1881 1882 func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) { 1883 *offset = align(*offset, uintptr(t.align)) 1884 if t.kind&kindNoPointers != 0 { 1885 *offset += t.size 1886 return 1887 } 1888 1889 switch Kind(t.kind & kindMask) { 1890 case Chan, Func, Map, Ptr, Slice, String, UnsafePointer: 1891 // 1 pointer at start of representation 1892 for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { 1893 bv.append2(bitsScalar) 1894 } 1895 bv.append2(bitsPointer) 1896 1897 case Interface: 1898 // 2 pointers 1899 for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { 1900 bv.append2(bitsScalar) 1901 } 1902 bv.append2(bitsPointer) 1903 bv.append2(bitsPointer) 1904 1905 case Array: 1906 // repeat inner type 1907 tt := (*arrayType)(unsafe.Pointer(t)) 1908 for i := 0; i < int(tt.len); i++ { 1909 addTypeBits(bv, offset, tt.elem) 1910 } 1911 1912 case Struct: 1913 // apply fields 1914 tt := (*structType)(unsafe.Pointer(t)) 1915 start := *offset 1916 for i := range tt.fields { 1917 f := &tt.fields[i] 1918 off := start + f.offset 1919 addTypeBits(bv, &off, f.typ) 1920 } 1921 } 1922 1923 *offset += t.size 1924 }