github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/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 hasPtr bool 1504 } 1505 1506 func (gc *gcProg) append(v byte) { 1507 gc.align(unsafe.Sizeof(uintptr(0))) 1508 gc.appendWord(v) 1509 } 1510 1511 // Appends t's type info to the current program. 1512 func (gc *gcProg) appendProg(t *rtype) { 1513 gc.align(uintptr(t.align)) 1514 if !t.pointers() { 1515 gc.size += t.size 1516 return 1517 } 1518 switch t.Kind() { 1519 default: 1520 panic("reflect: non-pointer type marked as having pointers") 1521 case Ptr, UnsafePointer, Chan, Func, Map: 1522 gc.appendWord(bitsPointer) 1523 case Slice: 1524 gc.appendWord(bitsPointer) 1525 gc.appendWord(bitsScalar) 1526 gc.appendWord(bitsScalar) 1527 case String: 1528 gc.appendWord(bitsPointer) 1529 gc.appendWord(bitsScalar) 1530 case Array: 1531 c := t.Len() 1532 e := t.Elem().common() 1533 for i := 0; i < c; i++ { 1534 gc.appendProg(e) 1535 } 1536 case Interface: 1537 gc.appendWord(bitsMultiWord) 1538 if t.NumMethod() == 0 { 1539 gc.appendWord(bitsEface) 1540 } else { 1541 gc.appendWord(bitsIface) 1542 } 1543 case Struct: 1544 c := t.NumField() 1545 for i := 0; i < c; i++ { 1546 gc.appendProg(t.Field(i).Type.common()) 1547 } 1548 gc.align(uintptr(t.align)) 1549 } 1550 } 1551 1552 func (gc *gcProg) appendWord(v byte) { 1553 ptrsize := unsafe.Sizeof(uintptr(0)) 1554 if gc.size%ptrsize != 0 { 1555 panic("reflect: unaligned GC program") 1556 } 1557 nptr := gc.size / ptrsize 1558 for uintptr(len(gc.gc)) < nptr/2+1 { 1559 gc.gc = append(gc.gc, 0x44) // BitsScalar 1560 } 1561 gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2)) 1562 gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2) 1563 gc.size += ptrsize 1564 if v == bitsPointer { 1565 gc.hasPtr = true 1566 } 1567 } 1568 1569 func (gc *gcProg) finalize() (unsafe.Pointer, bool) { 1570 if gc.size == 0 { 1571 return nil, false 1572 } 1573 ptrsize := unsafe.Sizeof(uintptr(0)) 1574 gc.align(ptrsize) 1575 nptr := gc.size / ptrsize 1576 for uintptr(len(gc.gc)) < nptr/2+1 { 1577 gc.gc = append(gc.gc, 0x44) // BitsScalar 1578 } 1579 // If number of words is odd, repeat the mask twice. 1580 // Compiler does the same. 1581 if nptr%2 != 0 { 1582 for i := uintptr(0); i < nptr; i++ { 1583 gc.appendWord(extractGCWord(gc.gc, i)) 1584 } 1585 } 1586 return unsafe.Pointer(&gc.gc[0]), gc.hasPtr 1587 } 1588 1589 func extractGCWord(gc []byte, i uintptr) byte { 1590 return (gc[i/2] >> ((i%2)*4 + 2)) & 3 1591 } 1592 1593 func (gc *gcProg) align(a uintptr) { 1594 gc.size = align(gc.size, a) 1595 } 1596 1597 // These constants must stay in sync with ../runtime/mgc0.h. 1598 const ( 1599 bitsScalar = 1 1600 bitsPointer = 2 1601 bitsMultiWord = 3 1602 1603 bitsIface = 2 1604 bitsEface = 3 1605 ) 1606 1607 // Make sure these routines stay in sync with ../../runtime/hashmap.go! 1608 // These types exist only for GC, so we only fill out GC relevant info. 1609 // Currently, that's just size and the GC program. We also fill in string 1610 // for possible debugging use. 1611 const ( 1612 bucketSize = 8 1613 maxKeySize = 128 1614 maxValSize = 128 1615 ) 1616 1617 func bucketOf(ktyp, etyp *rtype) *rtype { 1618 if ktyp.size > maxKeySize { 1619 ktyp = PtrTo(ktyp).(*rtype) 1620 } 1621 if etyp.size > maxValSize { 1622 etyp = PtrTo(etyp).(*rtype) 1623 } 1624 ptrsize := unsafe.Sizeof(uintptr(0)) 1625 1626 var gc gcProg 1627 // topbits 1628 for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ { 1629 gc.append(bitsScalar) 1630 } 1631 // keys 1632 for i := 0; i < bucketSize; i++ { 1633 gc.appendProg(ktyp) 1634 } 1635 // values 1636 for i := 0; i < bucketSize; i++ { 1637 gc.appendProg(etyp) 1638 } 1639 // overflow 1640 gc.append(bitsPointer) 1641 if runtime.GOARCH == "amd64p32" { 1642 gc.append(bitsScalar) 1643 } 1644 1645 b := new(rtype) 1646 b.size = gc.size 1647 b.gc[0], _ = gc.finalize() 1648 s := "bucket(" + *ktyp.string + "," + *etyp.string + ")" 1649 b.string = &s 1650 return b 1651 } 1652 1653 // SliceOf returns the slice type with element type t. 1654 // For example, if t represents int, SliceOf(t) represents []int. 1655 func SliceOf(t Type) Type { 1656 typ := t.(*rtype) 1657 1658 // Look in cache. 1659 ckey := cacheKey{Slice, typ, nil, 0} 1660 if slice := cacheGet(ckey); slice != nil { 1661 return slice 1662 } 1663 1664 // Look in known types. 1665 s := "[]" + *typ.string 1666 for _, tt := range typesByString(s) { 1667 slice := (*sliceType)(unsafe.Pointer(tt)) 1668 if slice.elem == typ { 1669 return cachePut(ckey, tt) 1670 } 1671 } 1672 1673 // Make a slice type. 1674 var islice interface{} = ([]unsafe.Pointer)(nil) 1675 prototype := *(**sliceType)(unsafe.Pointer(&islice)) 1676 slice := new(sliceType) 1677 *slice = *prototype 1678 slice.string = &s 1679 slice.hash = fnv1(typ.hash, '[') 1680 slice.elem = typ 1681 slice.uncommonType = nil 1682 slice.ptrToThis = nil 1683 slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0]) 1684 1685 return cachePut(ckey, &slice.rtype) 1686 } 1687 1688 // ArrayOf returns the array type with the given count and element type. 1689 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 1690 // 1691 // If the resulting type would be larger than the available address space, 1692 // ArrayOf panics. 1693 // 1694 // TODO(rsc): Unexported for now. Export once the alg field is set correctly 1695 // for the type. This may require significant work. 1696 // 1697 // TODO(rsc): TestArrayOf is also disabled. Re-enable. 1698 func arrayOf(count int, elem Type) Type { 1699 typ := elem.(*rtype) 1700 slice := SliceOf(elem) 1701 1702 // Look in cache. 1703 ckey := cacheKey{Array, typ, nil, uintptr(count)} 1704 if slice := cacheGet(ckey); slice != nil { 1705 return slice 1706 } 1707 1708 // Look in known types. 1709 s := "[" + strconv.Itoa(count) + "]" + *typ.string 1710 for _, tt := range typesByString(s) { 1711 slice := (*sliceType)(unsafe.Pointer(tt)) 1712 if slice.elem == typ { 1713 return cachePut(ckey, tt) 1714 } 1715 } 1716 1717 // Make an array type. 1718 var iarray interface{} = [1]unsafe.Pointer{} 1719 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 1720 array := new(arrayType) 1721 *array = *prototype 1722 // TODO: Set extra kind bits correctly. 1723 array.string = &s 1724 array.hash = fnv1(typ.hash, '[') 1725 for n := uint32(count); n > 0; n >>= 8 { 1726 array.hash = fnv1(array.hash, byte(n)) 1727 } 1728 array.hash = fnv1(array.hash, ']') 1729 array.elem = typ 1730 max := ^uintptr(0) / typ.size 1731 if uintptr(count) > max { 1732 panic("reflect.ArrayOf: array size would exceed virtual address space") 1733 } 1734 array.size = typ.size * uintptr(count) 1735 array.align = typ.align 1736 array.fieldAlign = typ.fieldAlign 1737 // TODO: array.alg 1738 // TODO: array.gc 1739 // TODO: 1740 array.uncommonType = nil 1741 array.ptrToThis = nil 1742 array.zero = unsafe.Pointer(&make([]byte, array.size)[0]) 1743 array.len = uintptr(count) 1744 array.slice = slice.(*rtype) 1745 1746 return cachePut(ckey, &array.rtype) 1747 } 1748 1749 // toType converts from a *rtype to a Type that can be returned 1750 // to the client of package reflect. In gc, the only concern is that 1751 // a nil *rtype must be replaced by a nil Type, but in gccgo this 1752 // function takes care of ensuring that multiple *rtype for the same 1753 // type are coalesced into a single Type. 1754 func toType(t *rtype) Type { 1755 if t == nil { 1756 return nil 1757 } 1758 return t 1759 } 1760 1761 type layoutKey struct { 1762 t *rtype // function signature 1763 rcvr *rtype // receiver type, or nil if none 1764 } 1765 1766 type layoutType struct { 1767 t *rtype 1768 argSize uintptr // size of arguments 1769 retOffset uintptr // offset of return values. 1770 stack *bitVector 1771 } 1772 1773 var layoutCache struct { 1774 sync.RWMutex 1775 m map[layoutKey]layoutType 1776 } 1777 1778 // funcLayout computes a struct type representing the layout of the 1779 // function arguments and return values for the function type t. 1780 // If rcvr != nil, rcvr specifies the type of the receiver. 1781 // The returned type exists only for GC, so we only fill out GC relevant info. 1782 // Currently, that's just size and the GC program. We also fill in 1783 // the name for possible debugging use. 1784 func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stack *bitVector) { 1785 if t.Kind() != Func { 1786 panic("reflect: funcLayout of non-func type") 1787 } 1788 if rcvr != nil && rcvr.Kind() == Interface { 1789 panic("reflect: funcLayout with interface receiver " + rcvr.String()) 1790 } 1791 k := layoutKey{t, rcvr} 1792 layoutCache.RLock() 1793 if x := layoutCache.m[k]; x.t != nil { 1794 layoutCache.RUnlock() 1795 return x.t, x.argSize, x.retOffset, x.stack 1796 } 1797 layoutCache.RUnlock() 1798 layoutCache.Lock() 1799 if x := layoutCache.m[k]; x.t != nil { 1800 layoutCache.Unlock() 1801 return x.t, x.argSize, x.retOffset, x.stack 1802 } 1803 1804 tt := (*funcType)(unsafe.Pointer(t)) 1805 1806 // compute gc program & stack bitmap for arguments 1807 stack = new(bitVector) 1808 var gc gcProg 1809 var offset uintptr 1810 if rcvr != nil { 1811 // Reflect uses the "interface" calling convention for 1812 // methods, where receivers take one word of argument 1813 // space no matter how big they actually are. 1814 if ifaceIndir(rcvr) { 1815 // we pass a pointer to the receiver. 1816 gc.append(bitsPointer) 1817 stack.append2(bitsPointer) 1818 } else if rcvr.pointers() { 1819 // rcvr is a one-word pointer object. Its gc program 1820 // is just what we need here. 1821 gc.append(bitsPointer) 1822 stack.append2(bitsPointer) 1823 } else { 1824 gc.append(bitsScalar) 1825 stack.append2(bitsScalar) 1826 } 1827 offset += ptrSize 1828 } 1829 for _, arg := range tt.in { 1830 gc.appendProg(arg) 1831 addTypeBits(stack, &offset, arg) 1832 } 1833 argSize = gc.size 1834 if runtime.GOARCH == "amd64p32" { 1835 gc.align(8) 1836 } 1837 gc.align(ptrSize) 1838 retOffset = gc.size 1839 for _, res := range tt.out { 1840 gc.appendProg(res) 1841 // stack map does not need result bits 1842 } 1843 gc.align(ptrSize) 1844 1845 // build dummy rtype holding gc program 1846 x := new(rtype) 1847 x.size = gc.size 1848 var hasPtr bool 1849 x.gc[0], hasPtr = gc.finalize() 1850 if !hasPtr { 1851 x.kind |= kindNoPointers 1852 } 1853 var s string 1854 if rcvr != nil { 1855 s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")" 1856 } else { 1857 s = "funcargs(" + *t.string + ")" 1858 } 1859 x.string = &s 1860 1861 // cache result for future callers 1862 if layoutCache.m == nil { 1863 layoutCache.m = make(map[layoutKey]layoutType) 1864 } 1865 layoutCache.m[k] = layoutType{ 1866 t: x, 1867 argSize: argSize, 1868 retOffset: retOffset, 1869 stack: stack, 1870 } 1871 layoutCache.Unlock() 1872 return x, argSize, retOffset, stack 1873 } 1874 1875 // ifaceIndir reports whether t is stored indirectly in an interface value. 1876 func ifaceIndir(t *rtype) bool { 1877 return t.kind&kindDirectIface == 0 1878 } 1879 1880 // Layout matches runtime.BitVector (well enough). 1881 type bitVector struct { 1882 n uint32 // number of bits 1883 data []byte 1884 } 1885 1886 // append a bit pair to the bitmap. 1887 func (bv *bitVector) append2(bits uint8) { 1888 // assume bv.n is a multiple of 2, since append2 is the only operation. 1889 if bv.n%8 == 0 { 1890 bv.data = append(bv.data, 0) 1891 } 1892 bv.data[bv.n/8] |= bits << (bv.n % 8) 1893 bv.n += 2 1894 } 1895 1896 func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) { 1897 *offset = align(*offset, uintptr(t.align)) 1898 if t.kind&kindNoPointers != 0 { 1899 *offset += t.size 1900 return 1901 } 1902 1903 switch Kind(t.kind & kindMask) { 1904 case Chan, Func, Map, Ptr, Slice, String, UnsafePointer: 1905 // 1 pointer at start of representation 1906 for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { 1907 bv.append2(bitsScalar) 1908 } 1909 bv.append2(bitsPointer) 1910 1911 case Interface: 1912 // 2 pointers 1913 for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { 1914 bv.append2(bitsScalar) 1915 } 1916 bv.append2(bitsPointer) 1917 bv.append2(bitsPointer) 1918 1919 case Array: 1920 // repeat inner type 1921 tt := (*arrayType)(unsafe.Pointer(t)) 1922 for i := 0; i < int(tt.len); i++ { 1923 addTypeBits(bv, offset, tt.elem) 1924 } 1925 1926 case Struct: 1927 // apply fields 1928 tt := (*structType)(unsafe.Pointer(t)) 1929 start := *offset 1930 for i := range tt.fields { 1931 f := &tt.fields[i] 1932 off := start + f.offset 1933 addTypeBits(bv, &off, f.typ) 1934 } 1935 } 1936 1937 *offset += t.size 1938 }