github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/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 // https://golang.org/doc/articles/laws_of_reflection.html 16 package reflect 17 18 import ( 19 "runtime" 20 "strconv" 21 "sync" 22 "unicode" 23 "unicode/utf8" 24 "unsafe" 25 ) 26 27 // Type is the representation of a Go type. 28 // 29 // Not all methods apply to all kinds of types. Restrictions, 30 // if any, are noted in the documentation for each method. 31 // Use the Kind method to find out the kind of type before 32 // calling kind-specific methods. Calling a method 33 // inappropriate to the kind of type causes a run-time panic. 34 // 35 // Type values are comparable, such as with the == operator. 36 // Two Type values are equal if they represent identical types. 37 type Type interface { 38 // Methods applicable to all types. 39 40 // Align returns the alignment in bytes of a value of 41 // this type when allocated in memory. 42 Align() int 43 44 // FieldAlign returns the alignment in bytes of a value of 45 // this type when used as a field in a struct. 46 FieldAlign() int 47 48 // Method returns the i'th method in the type's method set. 49 // It panics if i is not in the range [0, NumMethod()). 50 // 51 // For a non-interface type T or *T, the returned Method's Type and Func 52 // fields describe a function whose first argument is the receiver. 53 // 54 // For an interface type, the returned Method's Type field gives the 55 // method signature, without a receiver, and the Func field is nil. 56 Method(int) Method 57 58 // MethodByName returns the method with that name in the type's 59 // method set and a boolean indicating if the method was found. 60 // 61 // For a non-interface type T or *T, the returned Method's Type and Func 62 // fields describe a function whose first argument is the receiver. 63 // 64 // For an interface type, the returned Method's Type field gives the 65 // method signature, without a receiver, and the Func field is nil. 66 MethodByName(string) (Method, bool) 67 68 // NumMethod returns the number of exported methods in the type's method set. 69 NumMethod() int 70 71 // Name returns the type's name within its package. 72 // It returns an empty string for unnamed types. 73 Name() string 74 75 // PkgPath returns a named type's package path, that is, the import path 76 // that uniquely identifies the package, such as "encoding/base64". 77 // If the type was predeclared (string, error) or unnamed (*T, struct{}, []int), 78 // the package path will be the empty string. 79 PkgPath() string 80 81 // Size returns the number of bytes needed to store 82 // a value of the given type; it is analogous to unsafe.Sizeof. 83 Size() uintptr 84 85 // String returns a string representation of the type. 86 // The string representation may use shortened package names 87 // (e.g., base64 instead of "encoding/base64") and is not 88 // guaranteed to be unique among types. To test for type identity, 89 // compare the Types directly. 90 String() string 91 92 // Kind returns the specific kind of this type. 93 Kind() Kind 94 95 // Implements reports whether the type implements the interface type u. 96 Implements(u Type) bool 97 98 // AssignableTo reports whether a value of the type is assignable to type u. 99 AssignableTo(u Type) bool 100 101 // ConvertibleTo reports whether a value of the type is convertible to type u. 102 ConvertibleTo(u Type) bool 103 104 // Comparable reports whether values of this type are comparable. 105 Comparable() bool 106 107 // Methods applicable only to some types, depending on Kind. 108 // The methods allowed for each kind are: 109 // 110 // Int*, Uint*, Float*, Complex*: Bits 111 // Array: Elem, Len 112 // Chan: ChanDir, Elem 113 // Func: In, NumIn, Out, NumOut, IsVariadic. 114 // Map: Key, Elem 115 // Ptr: Elem 116 // Slice: Elem 117 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField 118 119 // Bits returns the size of the type in bits. 120 // It panics if the type's Kind is not one of the 121 // sized or unsized Int, Uint, Float, or Complex kinds. 122 Bits() int 123 124 // ChanDir returns a channel type's direction. 125 // It panics if the type's Kind is not Chan. 126 ChanDir() ChanDir 127 128 // IsVariadic reports whether a function type's final input parameter 129 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 130 // implicit actual type []T. 131 // 132 // For concreteness, if t represents func(x int, y ... float64), then 133 // 134 // t.NumIn() == 2 135 // t.In(0) is the reflect.Type for "int" 136 // t.In(1) is the reflect.Type for "[]float64" 137 // t.IsVariadic() == true 138 // 139 // IsVariadic panics if the type's Kind is not Func. 140 IsVariadic() bool 141 142 // Elem returns a type's element type. 143 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. 144 Elem() Type 145 146 // Field returns a struct type's i'th field. 147 // It panics if the type's Kind is not Struct. 148 // It panics if i is not in the range [0, NumField()). 149 Field(i int) StructField 150 151 // FieldByIndex returns the nested field corresponding 152 // to the index sequence. It is equivalent to calling Field 153 // successively for each index i. 154 // It panics if the type's Kind is not Struct. 155 FieldByIndex(index []int) StructField 156 157 // FieldByName returns the struct field with the given name 158 // and a boolean indicating if the field was found. 159 FieldByName(name string) (StructField, bool) 160 161 // FieldByNameFunc returns the struct field with a name 162 // that satisfies the match function and a boolean indicating if 163 // the field was found. 164 // 165 // FieldByNameFunc considers the fields in the struct itself 166 // and then the fields in any anonymous structs, in breadth first order, 167 // stopping at the shallowest nesting depth containing one or more 168 // fields satisfying the match function. If multiple fields at that depth 169 // satisfy the match function, they cancel each other 170 // and FieldByNameFunc returns no match. 171 // This behavior mirrors Go's handling of name lookup in 172 // structs containing anonymous fields. 173 FieldByNameFunc(match func(string) bool) (StructField, bool) 174 175 // In returns the type of a function type's i'th input parameter. 176 // It panics if the type's Kind is not Func. 177 // It panics if i is not in the range [0, NumIn()). 178 In(i int) Type 179 180 // Key returns a map type's key type. 181 // It panics if the type's Kind is not Map. 182 Key() Type 183 184 // Len returns an array type's length. 185 // It panics if the type's Kind is not Array. 186 Len() int 187 188 // NumField returns a struct type's field count. 189 // It panics if the type's Kind is not Struct. 190 NumField() int 191 192 // NumIn returns a function type's input parameter count. 193 // It panics if the type's Kind is not Func. 194 NumIn() int 195 196 // NumOut returns a function type's output parameter count. 197 // It panics if the type's Kind is not Func. 198 NumOut() int 199 200 // Out returns the type of a function type's i'th output parameter. 201 // It panics if the type's Kind is not Func. 202 // It panics if i is not in the range [0, NumOut()). 203 Out(i int) Type 204 205 common() *rtype 206 uncommon() *uncommonType 207 } 208 209 // BUG(rsc): FieldByName and related functions consider struct field names to be equal 210 // if the names are equal, even if they are unexported names originating 211 // in different packages. The practical effect of this is that the result of 212 // t.FieldByName("x") is not well defined if the struct type t contains 213 // multiple fields named x (embedded from different packages). 214 // FieldByName may return one of the fields named x or may report that there are none. 215 // See golang.org/issue/4876 for more details. 216 217 /* 218 * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go). 219 * A few are known to ../runtime/type.go to convey to debuggers. 220 * They are also known to ../runtime/type.go. 221 */ 222 223 // A Kind represents the specific kind of type that a Type represents. 224 // The zero Kind is not a valid kind. 225 type Kind uint 226 227 const ( 228 Invalid Kind = iota 229 Bool 230 Int 231 Int8 232 Int16 233 Int32 234 Int64 235 Uint 236 Uint8 237 Uint16 238 Uint32 239 Uint64 240 Uintptr 241 Float32 242 Float64 243 Complex64 244 Complex128 245 Array 246 Chan 247 Func 248 Interface 249 Map 250 Ptr 251 Slice 252 String 253 Struct 254 UnsafePointer 255 ) 256 257 // tflag is used by an rtype to signal what extra type information is 258 // available in the memory directly following the rtype value. 259 // 260 // tflag values must be kept in sync with copies in: 261 // cmd/compile/internal/gc/reflect.go 262 // cmd/link/internal/ld/decodesym.go 263 // runtime/type.go 264 type tflag uint8 265 266 const ( 267 // tflagUncommon means that there is a pointer, *uncommonType, 268 // just beyond the outer type structure. 269 // 270 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 271 // then t has uncommonType data and it can be accessed as: 272 // 273 // type tUncommon struct { 274 // structType 275 // u uncommonType 276 // } 277 // u := &(*tUncommon)(unsafe.Pointer(t)).u 278 tflagUncommon tflag = 1 << 0 279 280 // tflagExtraStar means the name in the str field has an 281 // extraneous '*' prefix. This is because for most types T in 282 // a program, the type *T also exists and reusing the str data 283 // saves binary size. 284 tflagExtraStar tflag = 1 << 1 285 286 // tflagNamed means the type has a name. 287 tflagNamed tflag = 1 << 2 288 ) 289 290 // rtype is the common implementation of most values. 291 // It is embedded in other, public struct types, but always 292 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` 293 // so that code cannot convert from, say, *arrayType to *ptrType. 294 // 295 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 296 type rtype struct { 297 size uintptr 298 ptrdata uintptr // number of bytes in the type that can contain pointers 299 hash uint32 // hash of type; avoids computation in hash tables 300 tflag tflag // extra type information flags 301 align uint8 // alignment of variable with this type 302 fieldAlign uint8 // alignment of struct field with this type 303 kind uint8 // enumeration for C 304 alg *typeAlg // algorithm table 305 gcdata *byte // garbage collection data 306 str nameOff // string form 307 ptrToThis typeOff // type for pointer to this type, may be zero 308 } 309 310 // a copy of runtime.typeAlg 311 type typeAlg struct { 312 // function for hashing objects of this type 313 // (ptr to object, seed) -> hash 314 hash func(unsafe.Pointer, uintptr) uintptr 315 // function for comparing objects of this type 316 // (ptr to object A, ptr to object B) -> ==? 317 equal func(unsafe.Pointer, unsafe.Pointer) bool 318 } 319 320 // Method on non-interface type 321 type method struct { 322 name nameOff // name of method 323 mtyp typeOff // method type (without receiver) 324 ifn textOff // fn used in interface call (one-word receiver) 325 tfn textOff // fn used for normal method call 326 } 327 328 // uncommonType is present only for types with names or methods 329 // (if T is a named type, the uncommonTypes for T and *T have methods). 330 // Using a pointer to this struct reduces the overall size required 331 // to describe an unnamed type with no methods. 332 type uncommonType struct { 333 pkgPath nameOff // import path; empty for built-in types like int, string 334 mcount uint16 // number of methods 335 _ uint16 // unused 336 moff uint32 // offset from this uncommontype to [mcount]method 337 _ uint32 // unused 338 } 339 340 // ChanDir represents a channel type's direction. 341 type ChanDir int 342 343 const ( 344 RecvDir ChanDir = 1 << iota // <-chan 345 SendDir // chan<- 346 BothDir = RecvDir | SendDir // chan 347 ) 348 349 // arrayType represents a fixed array type. 350 type arrayType struct { 351 rtype `reflect:"array"` 352 elem *rtype // array element type 353 slice *rtype // slice type 354 len uintptr 355 } 356 357 // chanType represents a channel type. 358 type chanType struct { 359 rtype `reflect:"chan"` 360 elem *rtype // channel element type 361 dir uintptr // channel direction (ChanDir) 362 } 363 364 // funcType represents a function type. 365 // 366 // A *rtype for each in and out parameter is stored in an array that 367 // directly follows the funcType (and possibly its uncommonType). So 368 // a function type with one method, one input, and one output is: 369 // 370 // struct { 371 // funcType 372 // uncommonType 373 // [2]*rtype // [0] is in, [1] is out 374 // } 375 type funcType struct { 376 rtype `reflect:"func"` 377 inCount uint16 378 outCount uint16 // top bit is set if last input parameter is ... 379 } 380 381 // imethod represents a method on an interface type 382 type imethod struct { 383 name nameOff // name of method 384 typ typeOff // .(*FuncType) underneath 385 } 386 387 // interfaceType represents an interface type. 388 type interfaceType struct { 389 rtype `reflect:"interface"` 390 pkgPath name // import path 391 methods []imethod // sorted by hash 392 } 393 394 // mapType represents a map type. 395 type mapType struct { 396 rtype `reflect:"map"` 397 key *rtype // map key type 398 elem *rtype // map element (value) type 399 bucket *rtype // internal bucket structure 400 hmap *rtype // internal map header 401 keysize uint8 // size of key slot 402 indirectkey uint8 // store ptr to key instead of key itself 403 valuesize uint8 // size of value slot 404 indirectvalue uint8 // store ptr to value instead of value itself 405 bucketsize uint16 // size of bucket 406 reflexivekey bool // true if k==k for all keys 407 needkeyupdate bool // true if we need to update key on an overwrite 408 } 409 410 // ptrType represents a pointer type. 411 type ptrType struct { 412 rtype `reflect:"ptr"` 413 elem *rtype // pointer element (pointed at) type 414 } 415 416 // sliceType represents a slice type. 417 type sliceType struct { 418 rtype `reflect:"slice"` 419 elem *rtype // slice element type 420 } 421 422 // Struct field 423 type structField struct { 424 name name // name is always non-empty 425 typ *rtype // type of field 426 offsetAnon uintptr // byte offset of field<<1 | isAnonymous 427 } 428 429 func (f *structField) offset() uintptr { 430 return f.offsetAnon >> 1 431 } 432 433 func (f *structField) anon() bool { 434 return f.offsetAnon&1 != 0 435 } 436 437 // structType represents a struct type. 438 type structType struct { 439 rtype `reflect:"struct"` 440 pkgPath name 441 fields []structField // sorted by offset 442 } 443 444 // name is an encoded type name with optional extra data. 445 // 446 // The first byte is a bit field containing: 447 // 448 // 1<<0 the name is exported 449 // 1<<1 tag data follows the name 450 // 1<<2 pkgPath nameOff follows the name and tag 451 // 452 // The next two bytes are the data length: 453 // 454 // l := uint16(data[1])<<8 | uint16(data[2]) 455 // 456 // Bytes [3:3+l] are the string data. 457 // 458 // If tag data follows then bytes 3+l and 3+l+1 are the tag length, 459 // with the data following. 460 // 461 // If the import path follows, then 4 bytes at the end of 462 // the data form a nameOff. The import path is only set for concrete 463 // methods that are defined in a different package than their type. 464 // 465 // If a name starts with "*", then the exported bit represents 466 // whether the pointed to type is exported. 467 type name struct { 468 bytes *byte 469 } 470 471 func (n name) data(off int) *byte { 472 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off))) 473 } 474 475 func (n name) isExported() bool { 476 return (*n.bytes)&(1<<0) != 0 477 } 478 479 func (n name) nameLen() int { 480 return int(uint16(*n.data(1))<<8 | uint16(*n.data(2))) 481 } 482 483 func (n name) tagLen() int { 484 if *n.data(0)&(1<<1) == 0 { 485 return 0 486 } 487 off := 3 + n.nameLen() 488 return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1))) 489 } 490 491 func (n name) name() (s string) { 492 if n.bytes == nil { 493 return 494 } 495 b := (*[4]byte)(unsafe.Pointer(n.bytes)) 496 497 hdr := (*stringHeader)(unsafe.Pointer(&s)) 498 hdr.Data = unsafe.Pointer(&b[3]) 499 hdr.Len = int(b[1])<<8 | int(b[2]) 500 return s 501 } 502 503 func (n name) tag() (s string) { 504 tl := n.tagLen() 505 if tl == 0 { 506 return "" 507 } 508 nl := n.nameLen() 509 hdr := (*stringHeader)(unsafe.Pointer(&s)) 510 hdr.Data = unsafe.Pointer(n.data(3 + nl + 2)) 511 hdr.Len = tl 512 return s 513 } 514 515 func (n name) pkgPath() string { 516 if n.bytes == nil || *n.data(0)&(1<<2) == 0 { 517 return "" 518 } 519 off := 3 + n.nameLen() 520 if tl := n.tagLen(); tl > 0 { 521 off += 2 + tl 522 } 523 var nameOff int32 524 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off)))[:]) 525 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 526 return pkgPathName.name() 527 } 528 529 // round n up to a multiple of a. a must be a power of 2. 530 func round(n, a uintptr) uintptr { 531 return (n + a - 1) &^ (a - 1) 532 } 533 534 func newName(n, tag string, exported bool) name { 535 if len(n) > 1<<16-1 { 536 panic("reflect.nameFrom: name too long: " + n) 537 } 538 if len(tag) > 1<<16-1 { 539 panic("reflect.nameFrom: tag too long: " + tag) 540 } 541 542 var bits byte 543 l := 1 + 2 + len(n) 544 if exported { 545 bits |= 1 << 0 546 } 547 if len(tag) > 0 { 548 l += 2 + len(tag) 549 bits |= 1 << 1 550 } 551 552 b := make([]byte, l) 553 b[0] = bits 554 b[1] = uint8(len(n) >> 8) 555 b[2] = uint8(len(n)) 556 copy(b[3:], n) 557 if len(tag) > 0 { 558 tb := b[3+len(n):] 559 tb[0] = uint8(len(tag) >> 8) 560 tb[1] = uint8(len(tag)) 561 copy(tb[2:], tag) 562 } 563 564 return name{bytes: &b[0]} 565 } 566 567 /* 568 * The compiler knows the exact layout of all the data structures above. 569 * The compiler does not know about the data structures and methods below. 570 */ 571 572 // Method represents a single method. 573 type Method struct { 574 // Name is the method name. 575 // PkgPath is the package path that qualifies a lower case (unexported) 576 // method name. It is empty for upper case (exported) method names. 577 // The combination of PkgPath and Name uniquely identifies a method 578 // in a method set. 579 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 580 Name string 581 PkgPath string 582 583 Type Type // method type 584 Func Value // func with receiver as first argument 585 Index int // index for Type.Method 586 } 587 588 const ( 589 kindDirectIface = 1 << 5 590 kindGCProg = 1 << 6 // Type.gc points to GC program 591 kindNoPointers = 1 << 7 592 kindMask = (1 << 5) - 1 593 ) 594 595 func (k Kind) String() string { 596 if int(k) < len(kindNames) { 597 return kindNames[k] 598 } 599 return "kind" + strconv.Itoa(int(k)) 600 } 601 602 var kindNames = []string{ 603 Invalid: "invalid", 604 Bool: "bool", 605 Int: "int", 606 Int8: "int8", 607 Int16: "int16", 608 Int32: "int32", 609 Int64: "int64", 610 Uint: "uint", 611 Uint8: "uint8", 612 Uint16: "uint16", 613 Uint32: "uint32", 614 Uint64: "uint64", 615 Uintptr: "uintptr", 616 Float32: "float32", 617 Float64: "float64", 618 Complex64: "complex64", 619 Complex128: "complex128", 620 Array: "array", 621 Chan: "chan", 622 Func: "func", 623 Interface: "interface", 624 Map: "map", 625 Ptr: "ptr", 626 Slice: "slice", 627 String: "string", 628 Struct: "struct", 629 UnsafePointer: "unsafe.Pointer", 630 } 631 632 func (t *uncommonType) methods() []method { 633 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff)))[:t.mcount:t.mcount] 634 } 635 636 // resolveNameOff resolves a name offset from a base pointer. 637 // The (*rtype).nameOff method is a convenience wrapper for this function. 638 // Implemented in the runtime package. 639 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 640 641 // resolveTypeOff resolves an *rtype offset from a base type. 642 // The (*rtype).typeOff method is a convenience wrapper for this function. 643 // Implemented in the runtime package. 644 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 645 646 // resolveTextOff resolves an function pointer offset from a base type. 647 // The (*rtype).textOff method is a convenience wrapper for this function. 648 // Implemented in the runtime package. 649 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 650 651 // addReflectOff adds a pointer to the reflection lookup map in the runtime. 652 // It returns a new ID that can be used as a typeOff or textOff, and will 653 // be resolved correctly. Implemented in the runtime package. 654 func addReflectOff(ptr unsafe.Pointer) int32 655 656 // resolveReflectType adds a name to the reflection lookup map in the runtime. 657 // It returns a new nameOff that can be used to refer to the pointer. 658 func resolveReflectName(n name) nameOff { 659 return nameOff(addReflectOff(unsafe.Pointer(n.bytes))) 660 } 661 662 // resolveReflectType adds a *rtype to the reflection lookup map in the runtime. 663 // It returns a new typeOff that can be used to refer to the pointer. 664 func resolveReflectType(t *rtype) typeOff { 665 return typeOff(addReflectOff(unsafe.Pointer(t))) 666 } 667 668 // resolveReflectText adds a function pointer to the reflection lookup map in 669 // the runtime. It returns a new textOff that can be used to refer to the 670 // pointer. 671 func resolveReflectText(ptr unsafe.Pointer) textOff { 672 return textOff(addReflectOff(ptr)) 673 } 674 675 type nameOff int32 // offset to a name 676 type typeOff int32 // offset to an *rtype 677 type textOff int32 // offset from top of text section 678 679 func (t *rtype) nameOff(off nameOff) name { 680 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 681 } 682 683 func (t *rtype) typeOff(off typeOff) *rtype { 684 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 685 } 686 687 func (t *rtype) textOff(off textOff) unsafe.Pointer { 688 return resolveTextOff(unsafe.Pointer(t), int32(off)) 689 } 690 691 func (t *rtype) uncommon() *uncommonType { 692 if t.tflag&tflagUncommon == 0 { 693 return nil 694 } 695 switch t.Kind() { 696 case Struct: 697 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 698 case Ptr: 699 type u struct { 700 ptrType 701 u uncommonType 702 } 703 return &(*u)(unsafe.Pointer(t)).u 704 case Func: 705 type u struct { 706 funcType 707 u uncommonType 708 } 709 return &(*u)(unsafe.Pointer(t)).u 710 case Slice: 711 type u struct { 712 sliceType 713 u uncommonType 714 } 715 return &(*u)(unsafe.Pointer(t)).u 716 case Array: 717 type u struct { 718 arrayType 719 u uncommonType 720 } 721 return &(*u)(unsafe.Pointer(t)).u 722 case Chan: 723 type u struct { 724 chanType 725 u uncommonType 726 } 727 return &(*u)(unsafe.Pointer(t)).u 728 case Map: 729 type u struct { 730 mapType 731 u uncommonType 732 } 733 return &(*u)(unsafe.Pointer(t)).u 734 case Interface: 735 type u struct { 736 interfaceType 737 u uncommonType 738 } 739 return &(*u)(unsafe.Pointer(t)).u 740 default: 741 type u struct { 742 rtype 743 u uncommonType 744 } 745 return &(*u)(unsafe.Pointer(t)).u 746 } 747 } 748 749 func (t *rtype) String() string { 750 s := t.nameOff(t.str).name() 751 if t.tflag&tflagExtraStar != 0 { 752 return s[1:] 753 } 754 return s 755 } 756 757 func (t *rtype) Size() uintptr { return t.size } 758 759 func (t *rtype) Bits() int { 760 if t == nil { 761 panic("reflect: Bits of nil Type") 762 } 763 k := t.Kind() 764 if k < Int || k > Complex128 { 765 panic("reflect: Bits of non-arithmetic Type " + t.String()) 766 } 767 return int(t.size) * 8 768 } 769 770 func (t *rtype) Align() int { return int(t.align) } 771 772 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) } 773 774 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 775 776 func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 } 777 778 func (t *rtype) common() *rtype { return t } 779 780 var methodCache sync.Map // map[*rtype][]method 781 782 func (t *rtype) exportedMethods() []method { 783 methodsi, found := methodCache.Load(t) 784 if found { 785 return methodsi.([]method) 786 } 787 788 ut := t.uncommon() 789 if ut == nil { 790 return nil 791 } 792 allm := ut.methods() 793 allExported := true 794 for _, m := range allm { 795 name := t.nameOff(m.name) 796 if !name.isExported() { 797 allExported = false 798 break 799 } 800 } 801 var methods []method 802 if allExported { 803 methods = allm 804 } else { 805 methods = make([]method, 0, len(allm)) 806 for _, m := range allm { 807 name := t.nameOff(m.name) 808 if name.isExported() { 809 methods = append(methods, m) 810 } 811 } 812 methods = methods[:len(methods):len(methods)] 813 } 814 815 methodsi, _ = methodCache.LoadOrStore(t, methods) 816 return methodsi.([]method) 817 } 818 819 func (t *rtype) NumMethod() int { 820 if t.Kind() == Interface { 821 tt := (*interfaceType)(unsafe.Pointer(t)) 822 return tt.NumMethod() 823 } 824 if t.tflag&tflagUncommon == 0 { 825 return 0 // avoid methodCache synchronization 826 } 827 return len(t.exportedMethods()) 828 } 829 830 func (t *rtype) Method(i int) (m Method) { 831 if t.Kind() == Interface { 832 tt := (*interfaceType)(unsafe.Pointer(t)) 833 return tt.Method(i) 834 } 835 methods := t.exportedMethods() 836 if i < 0 || i >= len(methods) { 837 panic("reflect: Method index out of range") 838 } 839 p := methods[i] 840 pname := t.nameOff(p.name) 841 m.Name = pname.name() 842 fl := flag(Func) 843 mtyp := t.typeOff(p.mtyp) 844 ft := (*funcType)(unsafe.Pointer(mtyp)) 845 in := make([]Type, 0, 1+len(ft.in())) 846 in = append(in, t) 847 for _, arg := range ft.in() { 848 in = append(in, arg) 849 } 850 out := make([]Type, 0, len(ft.out())) 851 for _, ret := range ft.out() { 852 out = append(out, ret) 853 } 854 mt := FuncOf(in, out, ft.IsVariadic()) 855 m.Type = mt 856 tfn := t.textOff(p.tfn) 857 fn := unsafe.Pointer(&tfn) 858 m.Func = Value{mt.(*rtype), fn, fl} 859 860 m.Index = i 861 return m 862 } 863 864 func (t *rtype) MethodByName(name string) (m Method, ok bool) { 865 if t.Kind() == Interface { 866 tt := (*interfaceType)(unsafe.Pointer(t)) 867 return tt.MethodByName(name) 868 } 869 ut := t.uncommon() 870 if ut == nil { 871 return Method{}, false 872 } 873 utmethods := ut.methods() 874 for i := 0; i < int(ut.mcount); i++ { 875 p := utmethods[i] 876 pname := t.nameOff(p.name) 877 if pname.isExported() && pname.name() == name { 878 return t.Method(i), true 879 } 880 } 881 return Method{}, false 882 } 883 884 func (t *rtype) PkgPath() string { 885 if t.tflag&tflagNamed == 0 { 886 return "" 887 } 888 ut := t.uncommon() 889 if ut == nil { 890 return "" 891 } 892 return t.nameOff(ut.pkgPath).name() 893 } 894 895 func hasPrefix(s, prefix string) bool { 896 return len(s) >= len(prefix) && s[:len(prefix)] == prefix 897 } 898 899 func (t *rtype) Name() string { 900 if t.tflag&tflagNamed == 0 { 901 return "" 902 } 903 s := t.String() 904 i := len(s) - 1 905 for i >= 0 { 906 if s[i] == '.' { 907 break 908 } 909 i-- 910 } 911 return s[i+1:] 912 } 913 914 func (t *rtype) ChanDir() ChanDir { 915 if t.Kind() != Chan { 916 panic("reflect: ChanDir of non-chan type") 917 } 918 tt := (*chanType)(unsafe.Pointer(t)) 919 return ChanDir(tt.dir) 920 } 921 922 func (t *rtype) IsVariadic() bool { 923 if t.Kind() != Func { 924 panic("reflect: IsVariadic of non-func type") 925 } 926 tt := (*funcType)(unsafe.Pointer(t)) 927 return tt.outCount&(1<<15) != 0 928 } 929 930 func (t *rtype) Elem() Type { 931 switch t.Kind() { 932 case Array: 933 tt := (*arrayType)(unsafe.Pointer(t)) 934 return toType(tt.elem) 935 case Chan: 936 tt := (*chanType)(unsafe.Pointer(t)) 937 return toType(tt.elem) 938 case Map: 939 tt := (*mapType)(unsafe.Pointer(t)) 940 return toType(tt.elem) 941 case Ptr: 942 tt := (*ptrType)(unsafe.Pointer(t)) 943 return toType(tt.elem) 944 case Slice: 945 tt := (*sliceType)(unsafe.Pointer(t)) 946 return toType(tt.elem) 947 } 948 panic("reflect: Elem of invalid type") 949 } 950 951 func (t *rtype) Field(i int) StructField { 952 if t.Kind() != Struct { 953 panic("reflect: Field of non-struct type") 954 } 955 tt := (*structType)(unsafe.Pointer(t)) 956 return tt.Field(i) 957 } 958 959 func (t *rtype) FieldByIndex(index []int) StructField { 960 if t.Kind() != Struct { 961 panic("reflect: FieldByIndex of non-struct type") 962 } 963 tt := (*structType)(unsafe.Pointer(t)) 964 return tt.FieldByIndex(index) 965 } 966 967 func (t *rtype) FieldByName(name string) (StructField, bool) { 968 if t.Kind() != Struct { 969 panic("reflect: FieldByName of non-struct type") 970 } 971 tt := (*structType)(unsafe.Pointer(t)) 972 return tt.FieldByName(name) 973 } 974 975 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 976 if t.Kind() != Struct { 977 panic("reflect: FieldByNameFunc of non-struct type") 978 } 979 tt := (*structType)(unsafe.Pointer(t)) 980 return tt.FieldByNameFunc(match) 981 } 982 983 func (t *rtype) In(i int) Type { 984 if t.Kind() != Func { 985 panic("reflect: In of non-func type") 986 } 987 tt := (*funcType)(unsafe.Pointer(t)) 988 return toType(tt.in()[i]) 989 } 990 991 func (t *rtype) Key() Type { 992 if t.Kind() != Map { 993 panic("reflect: Key of non-map type") 994 } 995 tt := (*mapType)(unsafe.Pointer(t)) 996 return toType(tt.key) 997 } 998 999 func (t *rtype) Len() int { 1000 if t.Kind() != Array { 1001 panic("reflect: Len of non-array type") 1002 } 1003 tt := (*arrayType)(unsafe.Pointer(t)) 1004 return int(tt.len) 1005 } 1006 1007 func (t *rtype) NumField() int { 1008 if t.Kind() != Struct { 1009 panic("reflect: NumField of non-struct type") 1010 } 1011 tt := (*structType)(unsafe.Pointer(t)) 1012 return len(tt.fields) 1013 } 1014 1015 func (t *rtype) NumIn() int { 1016 if t.Kind() != Func { 1017 panic("reflect: NumIn of non-func type") 1018 } 1019 tt := (*funcType)(unsafe.Pointer(t)) 1020 return int(tt.inCount) 1021 } 1022 1023 func (t *rtype) NumOut() int { 1024 if t.Kind() != Func { 1025 panic("reflect: NumOut of non-func type") 1026 } 1027 tt := (*funcType)(unsafe.Pointer(t)) 1028 return len(tt.out()) 1029 } 1030 1031 func (t *rtype) Out(i int) Type { 1032 if t.Kind() != Func { 1033 panic("reflect: Out of non-func type") 1034 } 1035 tt := (*funcType)(unsafe.Pointer(t)) 1036 return toType(tt.out()[i]) 1037 } 1038 1039 func (t *funcType) in() []*rtype { 1040 uadd := unsafe.Sizeof(*t) 1041 if t.tflag&tflagUncommon != 0 { 1042 uadd += unsafe.Sizeof(uncommonType{}) 1043 } 1044 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd))[:t.inCount] 1045 } 1046 1047 func (t *funcType) out() []*rtype { 1048 uadd := unsafe.Sizeof(*t) 1049 if t.tflag&tflagUncommon != 0 { 1050 uadd += unsafe.Sizeof(uncommonType{}) 1051 } 1052 outCount := t.outCount & (1<<15 - 1) 1053 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd))[t.inCount : t.inCount+outCount] 1054 } 1055 1056 func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { 1057 return unsafe.Pointer(uintptr(p) + x) 1058 } 1059 1060 func (d ChanDir) String() string { 1061 switch d { 1062 case SendDir: 1063 return "chan<-" 1064 case RecvDir: 1065 return "<-chan" 1066 case BothDir: 1067 return "chan" 1068 } 1069 return "ChanDir" + strconv.Itoa(int(d)) 1070 } 1071 1072 // Method returns the i'th method in the type's method set. 1073 func (t *interfaceType) Method(i int) (m Method) { 1074 if i < 0 || i >= len(t.methods) { 1075 return 1076 } 1077 p := &t.methods[i] 1078 pname := t.nameOff(p.name) 1079 m.Name = pname.name() 1080 if !pname.isExported() { 1081 m.PkgPath = pname.pkgPath() 1082 if m.PkgPath == "" { 1083 m.PkgPath = t.pkgPath.name() 1084 } 1085 } 1086 m.Type = toType(t.typeOff(p.typ)) 1087 m.Index = i 1088 return 1089 } 1090 1091 // NumMethod returns the number of interface methods in the type's method set. 1092 func (t *interfaceType) NumMethod() int { return len(t.methods) } 1093 1094 // MethodByName method with the given name in the type's method set. 1095 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) { 1096 if t == nil { 1097 return 1098 } 1099 var p *imethod 1100 for i := range t.methods { 1101 p = &t.methods[i] 1102 if t.nameOff(p.name).name() == name { 1103 return t.Method(i), true 1104 } 1105 } 1106 return 1107 } 1108 1109 // A StructField describes a single field in a struct. 1110 type StructField struct { 1111 // Name is the field name. 1112 Name string 1113 // PkgPath is the package path that qualifies a lower case (unexported) 1114 // field name. It is empty for upper case (exported) field names. 1115 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 1116 PkgPath string 1117 1118 Type Type // field type 1119 Tag StructTag // field tag string 1120 Offset uintptr // offset within struct, in bytes 1121 Index []int // index sequence for Type.FieldByIndex 1122 Anonymous bool // is an embedded field 1123 } 1124 1125 // A StructTag is the tag string in a struct field. 1126 // 1127 // By convention, tag strings are a concatenation of 1128 // optionally space-separated key:"value" pairs. 1129 // Each key is a non-empty string consisting of non-control 1130 // characters other than space (U+0020 ' '), quote (U+0022 '"'), 1131 // and colon (U+003A ':'). Each value is quoted using U+0022 '"' 1132 // characters and Go string literal syntax. 1133 type StructTag string 1134 1135 // Get returns the value associated with key in the tag string. 1136 // If there is no such key in the tag, Get returns the empty string. 1137 // If the tag does not have the conventional format, the value 1138 // returned by Get is unspecified. To determine whether a tag is 1139 // explicitly set to the empty string, use Lookup. 1140 func (tag StructTag) Get(key string) string { 1141 v, _ := tag.Lookup(key) 1142 return v 1143 } 1144 1145 // Lookup returns the value associated with key in the tag string. 1146 // If the key is present in the tag the value (which may be empty) 1147 // is returned. Otherwise the returned value will be the empty string. 1148 // The ok return value reports whether the value was explicitly set in 1149 // the tag string. If the tag does not have the conventional format, 1150 // the value returned by Lookup is unspecified. 1151 func (tag StructTag) Lookup(key string) (value string, ok bool) { 1152 // When modifying this code, also update the validateStructTag code 1153 // in cmd/vet/structtag.go. 1154 1155 for tag != "" { 1156 // Skip leading space. 1157 i := 0 1158 for i < len(tag) && tag[i] == ' ' { 1159 i++ 1160 } 1161 tag = tag[i:] 1162 if tag == "" { 1163 break 1164 } 1165 1166 // Scan to colon. A space, a quote or a control character is a syntax error. 1167 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just 1168 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters 1169 // as it is simpler to inspect the tag's bytes than the tag's runes. 1170 i = 0 1171 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { 1172 i++ 1173 } 1174 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 1175 break 1176 } 1177 name := string(tag[:i]) 1178 tag = tag[i+1:] 1179 1180 // Scan quoted string to find value. 1181 i = 1 1182 for i < len(tag) && tag[i] != '"' { 1183 if tag[i] == '\\' { 1184 i++ 1185 } 1186 i++ 1187 } 1188 if i >= len(tag) { 1189 break 1190 } 1191 qvalue := string(tag[:i+1]) 1192 tag = tag[i+1:] 1193 1194 if key == name { 1195 value, err := strconv.Unquote(qvalue) 1196 if err != nil { 1197 break 1198 } 1199 return value, true 1200 } 1201 } 1202 return "", false 1203 } 1204 1205 // Field returns the i'th struct field. 1206 func (t *structType) Field(i int) (f StructField) { 1207 if i < 0 || i >= len(t.fields) { 1208 panic("reflect: Field index out of bounds") 1209 } 1210 p := &t.fields[i] 1211 f.Type = toType(p.typ) 1212 f.Name = p.name.name() 1213 f.Anonymous = p.anon() 1214 if !p.name.isExported() { 1215 f.PkgPath = p.name.pkgPath() 1216 if f.PkgPath == "" { 1217 f.PkgPath = t.pkgPath.name() 1218 } 1219 } 1220 if tag := p.name.tag(); tag != "" { 1221 f.Tag = StructTag(tag) 1222 } 1223 f.Offset = p.offset() 1224 1225 // NOTE(rsc): This is the only allocation in the interface 1226 // presented by a reflect.Type. It would be nice to avoid, 1227 // at least in the common cases, but we need to make sure 1228 // that misbehaving clients of reflect cannot affect other 1229 // uses of reflect. One possibility is CL 5371098, but we 1230 // postponed that ugliness until there is a demonstrated 1231 // need for the performance. This is issue 2320. 1232 f.Index = []int{i} 1233 return 1234 } 1235 1236 // TODO(gri): Should there be an error/bool indicator if the index 1237 // is wrong for FieldByIndex? 1238 1239 // FieldByIndex returns the nested field corresponding to index. 1240 func (t *structType) FieldByIndex(index []int) (f StructField) { 1241 f.Type = toType(&t.rtype) 1242 for i, x := range index { 1243 if i > 0 { 1244 ft := f.Type 1245 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct { 1246 ft = ft.Elem() 1247 } 1248 f.Type = ft 1249 } 1250 f = f.Type.Field(x) 1251 } 1252 return 1253 } 1254 1255 // A fieldScan represents an item on the fieldByNameFunc scan work list. 1256 type fieldScan struct { 1257 typ *structType 1258 index []int 1259 } 1260 1261 // FieldByNameFunc returns the struct field with a name that satisfies the 1262 // match function and a boolean to indicate if the field was found. 1263 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) { 1264 // This uses the same condition that the Go language does: there must be a unique instance 1265 // of the match at a given depth level. If there are multiple instances of a match at the 1266 // same depth, they annihilate each other and inhibit any possible match at a lower level. 1267 // The algorithm is breadth first search, one depth level at a time. 1268 1269 // The current and next slices are work queues: 1270 // current lists the fields to visit on this depth level, 1271 // and next lists the fields on the next lower level. 1272 current := []fieldScan{} 1273 next := []fieldScan{{typ: t}} 1274 1275 // nextCount records the number of times an embedded type has been 1276 // encountered and considered for queueing in the 'next' slice. 1277 // We only queue the first one, but we increment the count on each. 1278 // If a struct type T can be reached more than once at a given depth level, 1279 // then it annihilates itself and need not be considered at all when we 1280 // process that next depth level. 1281 var nextCount map[*structType]int 1282 1283 // visited records the structs that have been considered already. 1284 // Embedded pointer fields can create cycles in the graph of 1285 // reachable embedded types; visited avoids following those cycles. 1286 // It also avoids duplicated effort: if we didn't find the field in an 1287 // embedded type T at level 2, we won't find it in one at level 4 either. 1288 visited := map[*structType]bool{} 1289 1290 for len(next) > 0 { 1291 current, next = next, current[:0] 1292 count := nextCount 1293 nextCount = nil 1294 1295 // Process all the fields at this depth, now listed in 'current'. 1296 // The loop queues embedded fields found in 'next', for processing during the next 1297 // iteration. The multiplicity of the 'current' field counts is recorded 1298 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. 1299 for _, scan := range current { 1300 t := scan.typ 1301 if visited[t] { 1302 // We've looked through this type before, at a higher level. 1303 // That higher level would shadow the lower level we're now at, 1304 // so this one can't be useful to us. Ignore it. 1305 continue 1306 } 1307 visited[t] = true 1308 for i := range t.fields { 1309 f := &t.fields[i] 1310 // Find name and (for anonymous field) type for field f. 1311 fname := f.name.name() 1312 var ntyp *rtype 1313 if f.anon() { 1314 // Anonymous field of type T or *T. 1315 ntyp = f.typ 1316 if ntyp.Kind() == Ptr { 1317 ntyp = ntyp.Elem().common() 1318 } 1319 } 1320 1321 // Does it match? 1322 if match(fname) { 1323 // Potential match 1324 if count[t] > 1 || ok { 1325 // Name appeared multiple times at this level: annihilate. 1326 return StructField{}, false 1327 } 1328 result = t.Field(i) 1329 result.Index = nil 1330 result.Index = append(result.Index, scan.index...) 1331 result.Index = append(result.Index, i) 1332 ok = true 1333 continue 1334 } 1335 1336 // Queue embedded struct fields for processing with next level, 1337 // but only if we haven't seen a match yet at this level and only 1338 // if the embedded types haven't already been queued. 1339 if ok || ntyp == nil || ntyp.Kind() != Struct { 1340 continue 1341 } 1342 styp := (*structType)(unsafe.Pointer(ntyp)) 1343 if nextCount[styp] > 0 { 1344 nextCount[styp] = 2 // exact multiple doesn't matter 1345 continue 1346 } 1347 if nextCount == nil { 1348 nextCount = map[*structType]int{} 1349 } 1350 nextCount[styp] = 1 1351 if count[t] > 1 { 1352 nextCount[styp] = 2 // exact multiple doesn't matter 1353 } 1354 var index []int 1355 index = append(index, scan.index...) 1356 index = append(index, i) 1357 next = append(next, fieldScan{styp, index}) 1358 } 1359 } 1360 if ok { 1361 break 1362 } 1363 } 1364 return 1365 } 1366 1367 // FieldByName returns the struct field with the given name 1368 // and a boolean to indicate if the field was found. 1369 func (t *structType) FieldByName(name string) (f StructField, present bool) { 1370 // Quick check for top-level name, or struct without anonymous fields. 1371 hasAnon := false 1372 if name != "" { 1373 for i := range t.fields { 1374 tf := &t.fields[i] 1375 if tf.name.name() == name { 1376 return t.Field(i), true 1377 } 1378 if tf.anon() { 1379 hasAnon = true 1380 } 1381 } 1382 } 1383 if !hasAnon { 1384 return 1385 } 1386 return t.FieldByNameFunc(func(s string) bool { return s == name }) 1387 } 1388 1389 // TypeOf returns the reflection Type that represents the dynamic type of i. 1390 // If i is a nil interface value, TypeOf returns nil. 1391 func TypeOf(i interface{}) Type { 1392 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1393 return toType(eface.typ) 1394 } 1395 1396 // ptrMap is the cache for PtrTo. 1397 var ptrMap sync.Map // map[*rtype]*ptrType 1398 1399 // PtrTo returns the pointer type with element t. 1400 // For example, if t represents type Foo, PtrTo(t) represents *Foo. 1401 func PtrTo(t Type) Type { 1402 return t.(*rtype).ptrTo() 1403 } 1404 1405 func (t *rtype) ptrTo() *rtype { 1406 if t.ptrToThis != 0 { 1407 return t.typeOff(t.ptrToThis) 1408 } 1409 1410 // Check the cache. 1411 if pi, ok := ptrMap.Load(t); ok { 1412 return &pi.(*ptrType).rtype 1413 } 1414 1415 // Look in known types. 1416 s := "*" + t.String() 1417 for _, tt := range typesByString(s) { 1418 p := (*ptrType)(unsafe.Pointer(tt)) 1419 if p.elem != t { 1420 continue 1421 } 1422 pi, _ := ptrMap.LoadOrStore(t, p) 1423 return &pi.(*ptrType).rtype 1424 } 1425 1426 // Create a new ptrType starting with the description 1427 // of an *unsafe.Pointer. 1428 var iptr interface{} = (*unsafe.Pointer)(nil) 1429 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 1430 pp := *prototype 1431 1432 pp.str = resolveReflectName(newName(s, "", false)) 1433 pp.ptrToThis = 0 1434 1435 // For the type structures linked into the binary, the 1436 // compiler provides a good hash of the string. 1437 // Create a good hash for the new string by using 1438 // the FNV-1 hash's mixing function to combine the 1439 // old hash and the new "*". 1440 pp.hash = fnv1(t.hash, '*') 1441 1442 pp.elem = t 1443 1444 pi, _ := ptrMap.LoadOrStore(t, &pp) 1445 return &pi.(*ptrType).rtype 1446 } 1447 1448 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 1449 func fnv1(x uint32, list ...byte) uint32 { 1450 for _, b := range list { 1451 x = x*16777619 ^ uint32(b) 1452 } 1453 return x 1454 } 1455 1456 func (t *rtype) Implements(u Type) bool { 1457 if u == nil { 1458 panic("reflect: nil type passed to Type.Implements") 1459 } 1460 if u.Kind() != Interface { 1461 panic("reflect: non-interface type passed to Type.Implements") 1462 } 1463 return implements(u.(*rtype), t) 1464 } 1465 1466 func (t *rtype) AssignableTo(u Type) bool { 1467 if u == nil { 1468 panic("reflect: nil type passed to Type.AssignableTo") 1469 } 1470 uu := u.(*rtype) 1471 return directlyAssignable(uu, t) || implements(uu, t) 1472 } 1473 1474 func (t *rtype) ConvertibleTo(u Type) bool { 1475 if u == nil { 1476 panic("reflect: nil type passed to Type.ConvertibleTo") 1477 } 1478 uu := u.(*rtype) 1479 return convertOp(uu, t) != nil 1480 } 1481 1482 func (t *rtype) Comparable() bool { 1483 return t.alg != nil && t.alg.equal != nil 1484 } 1485 1486 // implements reports whether the type V implements the interface type T. 1487 func implements(T, V *rtype) bool { 1488 if T.Kind() != Interface { 1489 return false 1490 } 1491 t := (*interfaceType)(unsafe.Pointer(T)) 1492 if len(t.methods) == 0 { 1493 return true 1494 } 1495 1496 // The same algorithm applies in both cases, but the 1497 // method tables for an interface type and a concrete type 1498 // are different, so the code is duplicated. 1499 // In both cases the algorithm is a linear scan over the two 1500 // lists - T's methods and V's methods - simultaneously. 1501 // Since method tables are stored in a unique sorted order 1502 // (alphabetical, with no duplicate method names), the scan 1503 // through V's methods must hit a match for each of T's 1504 // methods along the way, or else V does not implement T. 1505 // This lets us run the scan in overall linear time instead of 1506 // the quadratic time a naive search would require. 1507 // See also ../runtime/iface.go. 1508 if V.Kind() == Interface { 1509 v := (*interfaceType)(unsafe.Pointer(V)) 1510 i := 0 1511 for j := 0; j < len(v.methods); j++ { 1512 tm := &t.methods[i] 1513 tmName := t.nameOff(tm.name) 1514 vm := &v.methods[j] 1515 vmName := V.nameOff(vm.name) 1516 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) { 1517 if !tmName.isExported() { 1518 tmPkgPath := tmName.pkgPath() 1519 if tmPkgPath == "" { 1520 tmPkgPath = t.pkgPath.name() 1521 } 1522 vmPkgPath := vmName.pkgPath() 1523 if vmPkgPath == "" { 1524 vmPkgPath = v.pkgPath.name() 1525 } 1526 if tmPkgPath != vmPkgPath { 1527 continue 1528 } 1529 } 1530 if i++; i >= len(t.methods) { 1531 return true 1532 } 1533 } 1534 } 1535 return false 1536 } 1537 1538 v := V.uncommon() 1539 if v == nil { 1540 return false 1541 } 1542 i := 0 1543 vmethods := v.methods() 1544 for j := 0; j < int(v.mcount); j++ { 1545 tm := &t.methods[i] 1546 tmName := t.nameOff(tm.name) 1547 vm := vmethods[j] 1548 vmName := V.nameOff(vm.name) 1549 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 1550 if !tmName.isExported() { 1551 tmPkgPath := tmName.pkgPath() 1552 if tmPkgPath == "" { 1553 tmPkgPath = t.pkgPath.name() 1554 } 1555 vmPkgPath := vmName.pkgPath() 1556 if vmPkgPath == "" { 1557 vmPkgPath = V.nameOff(v.pkgPath).name() 1558 } 1559 if tmPkgPath != vmPkgPath { 1560 continue 1561 } 1562 } 1563 if i++; i >= len(t.methods) { 1564 return true 1565 } 1566 } 1567 } 1568 return false 1569 } 1570 1571 // directlyAssignable reports whether a value x of type V can be directly 1572 // assigned (using memmove) to a value of type T. 1573 // https://golang.org/doc/go_spec.html#Assignability 1574 // Ignoring the interface rules (implemented elsewhere) 1575 // and the ideal constant rules (no ideal constants at run time). 1576 func directlyAssignable(T, V *rtype) bool { 1577 // x's type V is identical to T? 1578 if T == V { 1579 return true 1580 } 1581 1582 // Otherwise at least one of T and V must be unnamed 1583 // and they must have the same kind. 1584 if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() { 1585 return false 1586 } 1587 1588 // x's type T and V must have identical underlying types. 1589 return haveIdenticalUnderlyingType(T, V, true) 1590 } 1591 1592 func haveIdenticalType(T, V Type, cmpTags bool) bool { 1593 if cmpTags { 1594 return T == V 1595 } 1596 1597 if T.Name() != V.Name() || T.Kind() != V.Kind() { 1598 return false 1599 } 1600 1601 return haveIdenticalUnderlyingType(T.common(), V.common(), false) 1602 } 1603 1604 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { 1605 if T == V { 1606 return true 1607 } 1608 1609 kind := T.Kind() 1610 if kind != V.Kind() { 1611 return false 1612 } 1613 1614 // Non-composite types of equal kind have same underlying type 1615 // (the predefined instance of the type). 1616 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 1617 return true 1618 } 1619 1620 // Composite types. 1621 switch kind { 1622 case Array: 1623 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1624 1625 case Chan: 1626 // Special case: 1627 // x is a bidirectional channel value, T is a channel type, 1628 // and x's type V and T have identical element types. 1629 if V.ChanDir() == BothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) { 1630 return true 1631 } 1632 1633 // Otherwise continue test for identical underlying type. 1634 return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1635 1636 case Func: 1637 t := (*funcType)(unsafe.Pointer(T)) 1638 v := (*funcType)(unsafe.Pointer(V)) 1639 if t.outCount != v.outCount || t.inCount != v.inCount { 1640 return false 1641 } 1642 for i := 0; i < t.NumIn(); i++ { 1643 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) { 1644 return false 1645 } 1646 } 1647 for i := 0; i < t.NumOut(); i++ { 1648 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) { 1649 return false 1650 } 1651 } 1652 return true 1653 1654 case Interface: 1655 t := (*interfaceType)(unsafe.Pointer(T)) 1656 v := (*interfaceType)(unsafe.Pointer(V)) 1657 if len(t.methods) == 0 && len(v.methods) == 0 { 1658 return true 1659 } 1660 // Might have the same methods but still 1661 // need a run time conversion. 1662 return false 1663 1664 case Map: 1665 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1666 1667 case Ptr, Slice: 1668 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1669 1670 case Struct: 1671 t := (*structType)(unsafe.Pointer(T)) 1672 v := (*structType)(unsafe.Pointer(V)) 1673 if len(t.fields) != len(v.fields) { 1674 return false 1675 } 1676 for i := range t.fields { 1677 tf := &t.fields[i] 1678 vf := &v.fields[i] 1679 if tf.name.name() != vf.name.name() { 1680 return false 1681 } 1682 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) { 1683 return false 1684 } 1685 if cmpTags && tf.name.tag() != vf.name.tag() { 1686 return false 1687 } 1688 if tf.offsetAnon != vf.offsetAnon { 1689 return false 1690 } 1691 if !tf.name.isExported() { 1692 tp := tf.name.pkgPath() 1693 if tp == "" { 1694 tp = t.pkgPath.name() 1695 } 1696 vp := vf.name.pkgPath() 1697 if vp == "" { 1698 vp = v.pkgPath.name() 1699 } 1700 if tp != vp { 1701 return false 1702 } 1703 } 1704 } 1705 return true 1706 } 1707 1708 return false 1709 } 1710 1711 // typelinks is implemented in package runtime. 1712 // It returns a slice of the sections in each module, 1713 // and a slice of *rtype offsets in each module. 1714 // 1715 // The types in each module are sorted by string. That is, the first 1716 // two linked types of the first module are: 1717 // 1718 // d0 := sections[0] 1719 // t1 := (*rtype)(add(d0, offset[0][0])) 1720 // t2 := (*rtype)(add(d0, offset[0][1])) 1721 // 1722 // and 1723 // 1724 // t1.String() < t2.String() 1725 // 1726 // Note that strings are not unique identifiers for types: 1727 // there can be more than one with a given string. 1728 // Only types we might want to look up are included: 1729 // pointers, channels, maps, slices, and arrays. 1730 func typelinks() (sections []unsafe.Pointer, offset [][]int32) 1731 1732 func rtypeOff(section unsafe.Pointer, off int32) *rtype { 1733 return (*rtype)(add(section, uintptr(off))) 1734 } 1735 1736 // typesByString returns the subslice of typelinks() whose elements have 1737 // the given string representation. 1738 // It may be empty (no known types with that string) or may have 1739 // multiple elements (multiple types with that string). 1740 func typesByString(s string) []*rtype { 1741 sections, offset := typelinks() 1742 var ret []*rtype 1743 1744 for offsI, offs := range offset { 1745 section := sections[offsI] 1746 1747 // We are looking for the first index i where the string becomes >= s. 1748 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s). 1749 i, j := 0, len(offs) 1750 for i < j { 1751 h := i + (j-i)/2 // avoid overflow when computing h 1752 // i ≤ h < j 1753 if !(rtypeOff(section, offs[h]).String() >= s) { 1754 i = h + 1 // preserves f(i-1) == false 1755 } else { 1756 j = h // preserves f(j) == true 1757 } 1758 } 1759 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 1760 1761 // Having found the first, linear scan forward to find the last. 1762 // We could do a second binary search, but the caller is going 1763 // to do a linear scan anyway. 1764 for j := i; j < len(offs); j++ { 1765 typ := rtypeOff(section, offs[j]) 1766 if typ.String() != s { 1767 break 1768 } 1769 ret = append(ret, typ) 1770 } 1771 } 1772 return ret 1773 } 1774 1775 // The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups. 1776 var lookupCache sync.Map // map[cacheKey]*rtype 1777 1778 // A cacheKey is the key for use in the lookupCache. 1779 // Four values describe any of the types we are looking for: 1780 // type kind, one or two subtypes, and an extra integer. 1781 type cacheKey struct { 1782 kind Kind 1783 t1 *rtype 1784 t2 *rtype 1785 extra uintptr 1786 } 1787 1788 // The funcLookupCache caches FuncOf lookups. 1789 // FuncOf does not share the common lookupCache since cacheKey is not 1790 // sufficient to represent functions unambiguously. 1791 var funcLookupCache struct { 1792 sync.Mutex // Guards stores (but not loads) on m. 1793 1794 // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf. 1795 // Elements of m are append-only and thus safe for concurrent reading. 1796 m sync.Map 1797 } 1798 1799 // ChanOf returns the channel type with the given direction and element type. 1800 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int. 1801 // 1802 // The gc runtime imposes a limit of 64 kB on channel element types. 1803 // If t's size is equal to or exceeds this limit, ChanOf panics. 1804 func ChanOf(dir ChanDir, t Type) Type { 1805 typ := t.(*rtype) 1806 1807 // Look in cache. 1808 ckey := cacheKey{Chan, typ, nil, uintptr(dir)} 1809 if ch, ok := lookupCache.Load(ckey); ok { 1810 return ch.(*rtype) 1811 } 1812 1813 // This restriction is imposed by the gc compiler and the runtime. 1814 if typ.size >= 1<<16 { 1815 panic("reflect.ChanOf: element size too large") 1816 } 1817 1818 // Look in known types. 1819 // TODO: Precedence when constructing string. 1820 var s string 1821 switch dir { 1822 default: 1823 panic("reflect.ChanOf: invalid dir") 1824 case SendDir: 1825 s = "chan<- " + typ.String() 1826 case RecvDir: 1827 s = "<-chan " + typ.String() 1828 case BothDir: 1829 s = "chan " + typ.String() 1830 } 1831 for _, tt := range typesByString(s) { 1832 ch := (*chanType)(unsafe.Pointer(tt)) 1833 if ch.elem == typ && ch.dir == uintptr(dir) { 1834 ti, _ := lookupCache.LoadOrStore(ckey, tt) 1835 return ti.(Type) 1836 } 1837 } 1838 1839 // Make a channel type. 1840 var ichan interface{} = (chan unsafe.Pointer)(nil) 1841 prototype := *(**chanType)(unsafe.Pointer(&ichan)) 1842 ch := *prototype 1843 ch.tflag = 0 1844 ch.dir = uintptr(dir) 1845 ch.str = resolveReflectName(newName(s, "", false)) 1846 ch.hash = fnv1(typ.hash, 'c', byte(dir)) 1847 ch.elem = typ 1848 1849 ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype) 1850 return ti.(Type) 1851 } 1852 1853 func ismapkey(*rtype) bool // implemented in runtime 1854 1855 // MapOf returns the map type with the given key and element types. 1856 // For example, if k represents int and e represents string, 1857 // MapOf(k, e) represents map[int]string. 1858 // 1859 // If the key type is not a valid map key type (that is, if it does 1860 // not implement Go's == operator), MapOf panics. 1861 func MapOf(key, elem Type) Type { 1862 ktyp := key.(*rtype) 1863 etyp := elem.(*rtype) 1864 1865 if !ismapkey(ktyp) { 1866 panic("reflect.MapOf: invalid key type " + ktyp.String()) 1867 } 1868 1869 // Look in cache. 1870 ckey := cacheKey{Map, ktyp, etyp, 0} 1871 if mt, ok := lookupCache.Load(ckey); ok { 1872 return mt.(Type) 1873 } 1874 1875 // Look in known types. 1876 s := "map[" + ktyp.String() + "]" + etyp.String() 1877 for _, tt := range typesByString(s) { 1878 mt := (*mapType)(unsafe.Pointer(tt)) 1879 if mt.key == ktyp && mt.elem == etyp { 1880 ti, _ := lookupCache.LoadOrStore(ckey, tt) 1881 return ti.(Type) 1882 } 1883 } 1884 1885 // Make a map type. 1886 var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil) 1887 mt := **(**mapType)(unsafe.Pointer(&imap)) 1888 mt.str = resolveReflectName(newName(s, "", false)) 1889 mt.tflag = 0 1890 mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash)) 1891 mt.key = ktyp 1892 mt.elem = etyp 1893 mt.bucket = bucketOf(ktyp, etyp) 1894 if ktyp.size > maxKeySize { 1895 mt.keysize = uint8(ptrSize) 1896 mt.indirectkey = 1 1897 } else { 1898 mt.keysize = uint8(ktyp.size) 1899 mt.indirectkey = 0 1900 } 1901 if etyp.size > maxValSize { 1902 mt.valuesize = uint8(ptrSize) 1903 mt.indirectvalue = 1 1904 } else { 1905 mt.valuesize = uint8(etyp.size) 1906 mt.indirectvalue = 0 1907 } 1908 mt.bucketsize = uint16(mt.bucket.size) 1909 mt.reflexivekey = isReflexive(ktyp) 1910 mt.needkeyupdate = needKeyUpdate(ktyp) 1911 mt.ptrToThis = 0 1912 1913 ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype) 1914 return ti.(Type) 1915 } 1916 1917 type funcTypeFixed4 struct { 1918 funcType 1919 args [4]*rtype 1920 } 1921 type funcTypeFixed8 struct { 1922 funcType 1923 args [8]*rtype 1924 } 1925 type funcTypeFixed16 struct { 1926 funcType 1927 args [16]*rtype 1928 } 1929 type funcTypeFixed32 struct { 1930 funcType 1931 args [32]*rtype 1932 } 1933 type funcTypeFixed64 struct { 1934 funcType 1935 args [64]*rtype 1936 } 1937 type funcTypeFixed128 struct { 1938 funcType 1939 args [128]*rtype 1940 } 1941 1942 // FuncOf returns the function type with the given argument and result types. 1943 // For example if k represents int and e represents string, 1944 // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string. 1945 // 1946 // The variadic argument controls whether the function is variadic. FuncOf 1947 // panics if the in[len(in)-1] does not represent a slice and variadic is 1948 // true. 1949 func FuncOf(in, out []Type, variadic bool) Type { 1950 if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) { 1951 panic("reflect.FuncOf: last arg of variadic func must be slice") 1952 } 1953 1954 // Make a func type. 1955 var ifunc interface{} = (func())(nil) 1956 prototype := *(**funcType)(unsafe.Pointer(&ifunc)) 1957 n := len(in) + len(out) 1958 1959 var ft *funcType 1960 var args []*rtype 1961 switch { 1962 case n <= 4: 1963 fixed := new(funcTypeFixed4) 1964 args = fixed.args[:0:len(fixed.args)] 1965 ft = &fixed.funcType 1966 case n <= 8: 1967 fixed := new(funcTypeFixed8) 1968 args = fixed.args[:0:len(fixed.args)] 1969 ft = &fixed.funcType 1970 case n <= 16: 1971 fixed := new(funcTypeFixed16) 1972 args = fixed.args[:0:len(fixed.args)] 1973 ft = &fixed.funcType 1974 case n <= 32: 1975 fixed := new(funcTypeFixed32) 1976 args = fixed.args[:0:len(fixed.args)] 1977 ft = &fixed.funcType 1978 case n <= 64: 1979 fixed := new(funcTypeFixed64) 1980 args = fixed.args[:0:len(fixed.args)] 1981 ft = &fixed.funcType 1982 case n <= 128: 1983 fixed := new(funcTypeFixed128) 1984 args = fixed.args[:0:len(fixed.args)] 1985 ft = &fixed.funcType 1986 default: 1987 panic("reflect.FuncOf: too many arguments") 1988 } 1989 *ft = *prototype 1990 1991 // Build a hash and minimally populate ft. 1992 var hash uint32 1993 for _, in := range in { 1994 t := in.(*rtype) 1995 args = append(args, t) 1996 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 1997 } 1998 if variadic { 1999 hash = fnv1(hash, 'v') 2000 } 2001 hash = fnv1(hash, '.') 2002 for _, out := range out { 2003 t := out.(*rtype) 2004 args = append(args, t) 2005 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 2006 } 2007 if len(args) > 50 { 2008 panic("reflect.FuncOf does not support more than 50 arguments") 2009 } 2010 ft.tflag = 0 2011 ft.hash = hash 2012 ft.inCount = uint16(len(in)) 2013 ft.outCount = uint16(len(out)) 2014 if variadic { 2015 ft.outCount |= 1 << 15 2016 } 2017 2018 // Look in cache. 2019 if ts, ok := funcLookupCache.m.Load(hash); ok { 2020 for _, t := range ts.([]*rtype) { 2021 if haveIdenticalUnderlyingType(&ft.rtype, t, true) { 2022 return t 2023 } 2024 } 2025 } 2026 2027 // Not in cache, lock and retry. 2028 funcLookupCache.Lock() 2029 defer funcLookupCache.Unlock() 2030 if ts, ok := funcLookupCache.m.Load(hash); ok { 2031 for _, t := range ts.([]*rtype) { 2032 if haveIdenticalUnderlyingType(&ft.rtype, t, true) { 2033 return t 2034 } 2035 } 2036 } 2037 2038 addToCache := func(tt *rtype) Type { 2039 var rts []*rtype 2040 if rti, ok := funcLookupCache.m.Load(hash); ok { 2041 rts = rti.([]*rtype) 2042 } 2043 funcLookupCache.m.Store(hash, append(rts, tt)) 2044 return tt 2045 } 2046 2047 // Look in known types for the same string representation. 2048 str := funcStr(ft) 2049 for _, tt := range typesByString(str) { 2050 if haveIdenticalUnderlyingType(&ft.rtype, tt, true) { 2051 return addToCache(tt) 2052 } 2053 } 2054 2055 // Populate the remaining fields of ft and store in cache. 2056 ft.str = resolveReflectName(newName(str, "", false)) 2057 ft.ptrToThis = 0 2058 return addToCache(&ft.rtype) 2059 } 2060 2061 // funcStr builds a string representation of a funcType. 2062 func funcStr(ft *funcType) string { 2063 repr := make([]byte, 0, 64) 2064 repr = append(repr, "func("...) 2065 for i, t := range ft.in() { 2066 if i > 0 { 2067 repr = append(repr, ", "...) 2068 } 2069 if ft.IsVariadic() && i == int(ft.inCount)-1 { 2070 repr = append(repr, "..."...) 2071 repr = append(repr, (*sliceType)(unsafe.Pointer(t)).elem.String()...) 2072 } else { 2073 repr = append(repr, t.String()...) 2074 } 2075 } 2076 repr = append(repr, ')') 2077 out := ft.out() 2078 if len(out) == 1 { 2079 repr = append(repr, ' ') 2080 } else if len(out) > 1 { 2081 repr = append(repr, " ("...) 2082 } 2083 for i, t := range out { 2084 if i > 0 { 2085 repr = append(repr, ", "...) 2086 } 2087 repr = append(repr, t.String()...) 2088 } 2089 if len(out) > 1 { 2090 repr = append(repr, ')') 2091 } 2092 return string(repr) 2093 } 2094 2095 // isReflexive reports whether the == operation on the type is reflexive. 2096 // That is, x == x for all values x of type t. 2097 func isReflexive(t *rtype) bool { 2098 switch t.Kind() { 2099 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer: 2100 return true 2101 case Float32, Float64, Complex64, Complex128, Interface: 2102 return false 2103 case Array: 2104 tt := (*arrayType)(unsafe.Pointer(t)) 2105 return isReflexive(tt.elem) 2106 case Struct: 2107 tt := (*structType)(unsafe.Pointer(t)) 2108 for _, f := range tt.fields { 2109 if !isReflexive(f.typ) { 2110 return false 2111 } 2112 } 2113 return true 2114 default: 2115 // Func, Map, Slice, Invalid 2116 panic("isReflexive called on non-key type " + t.String()) 2117 } 2118 } 2119 2120 // needKeyUpdate reports whether map overwrites require the key to be copied. 2121 func needKeyUpdate(t *rtype) bool { 2122 switch t.Kind() { 2123 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, UnsafePointer: 2124 return false 2125 case Float32, Float64, Complex64, Complex128, Interface, String: 2126 // Float keys can be updated from +0 to -0. 2127 // String keys can be updated to use a smaller backing store. 2128 // Interfaces might have floats of strings in them. 2129 return true 2130 case Array: 2131 tt := (*arrayType)(unsafe.Pointer(t)) 2132 return needKeyUpdate(tt.elem) 2133 case Struct: 2134 tt := (*structType)(unsafe.Pointer(t)) 2135 for _, f := range tt.fields { 2136 if needKeyUpdate(f.typ) { 2137 return true 2138 } 2139 } 2140 return false 2141 default: 2142 // Func, Map, Slice, Invalid 2143 panic("needKeyUpdate called on non-key type " + t.String()) 2144 } 2145 } 2146 2147 // Make sure these routines stay in sync with ../../runtime/hashmap.go! 2148 // These types exist only for GC, so we only fill out GC relevant info. 2149 // Currently, that's just size and the GC program. We also fill in string 2150 // for possible debugging use. 2151 const ( 2152 bucketSize uintptr = 8 2153 maxKeySize uintptr = 128 2154 maxValSize uintptr = 128 2155 ) 2156 2157 func bucketOf(ktyp, etyp *rtype) *rtype { 2158 // See comment on hmap.overflow in ../runtime/hashmap.go. 2159 var kind uint8 2160 if ktyp.kind&kindNoPointers != 0 && etyp.kind&kindNoPointers != 0 && 2161 ktyp.size <= maxKeySize && etyp.size <= maxValSize { 2162 kind = kindNoPointers 2163 } 2164 2165 if ktyp.size > maxKeySize { 2166 ktyp = PtrTo(ktyp).(*rtype) 2167 } 2168 if etyp.size > maxValSize { 2169 etyp = PtrTo(etyp).(*rtype) 2170 } 2171 2172 // Prepare GC data if any. 2173 // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+2*ptrSize bytes, 2174 // or 2072 bytes, or 259 pointer-size words, or 33 bytes of pointer bitmap. 2175 // Note that since the key and value are known to be <= 128 bytes, 2176 // they're guaranteed to have bitmaps instead of GC programs. 2177 var gcdata *byte 2178 var ptrdata uintptr 2179 var overflowPad uintptr 2180 2181 // On NaCl, pad if needed to make overflow end at the proper struct alignment. 2182 // On other systems, align > ptrSize is not possible. 2183 if runtime.GOARCH == "amd64p32" && (ktyp.align > ptrSize || etyp.align > ptrSize) { 2184 overflowPad = ptrSize 2185 } 2186 size := bucketSize*(1+ktyp.size+etyp.size) + overflowPad + ptrSize 2187 if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 { 2188 panic("reflect: bad size computation in MapOf") 2189 } 2190 2191 if kind != kindNoPointers { 2192 nptr := (bucketSize*(1+ktyp.size+etyp.size) + ptrSize) / ptrSize 2193 mask := make([]byte, (nptr+7)/8) 2194 base := bucketSize / ptrSize 2195 2196 if ktyp.kind&kindNoPointers == 0 { 2197 if ktyp.kind&kindGCProg != 0 { 2198 panic("reflect: unexpected GC program in MapOf") 2199 } 2200 kmask := (*[16]byte)(unsafe.Pointer(ktyp.gcdata)) 2201 for i := uintptr(0); i < ktyp.ptrdata/ptrSize; i++ { 2202 if (kmask[i/8]>>(i%8))&1 != 0 { 2203 for j := uintptr(0); j < bucketSize; j++ { 2204 word := base + j*ktyp.size/ptrSize + i 2205 mask[word/8] |= 1 << (word % 8) 2206 } 2207 } 2208 } 2209 } 2210 base += bucketSize * ktyp.size / ptrSize 2211 2212 if etyp.kind&kindNoPointers == 0 { 2213 if etyp.kind&kindGCProg != 0 { 2214 panic("reflect: unexpected GC program in MapOf") 2215 } 2216 emask := (*[16]byte)(unsafe.Pointer(etyp.gcdata)) 2217 for i := uintptr(0); i < etyp.ptrdata/ptrSize; i++ { 2218 if (emask[i/8]>>(i%8))&1 != 0 { 2219 for j := uintptr(0); j < bucketSize; j++ { 2220 word := base + j*etyp.size/ptrSize + i 2221 mask[word/8] |= 1 << (word % 8) 2222 } 2223 } 2224 } 2225 } 2226 base += bucketSize * etyp.size / ptrSize 2227 base += overflowPad / ptrSize 2228 2229 word := base 2230 mask[word/8] |= 1 << (word % 8) 2231 gcdata = &mask[0] 2232 ptrdata = (word + 1) * ptrSize 2233 2234 // overflow word must be last 2235 if ptrdata != size { 2236 panic("reflect: bad layout computation in MapOf") 2237 } 2238 } 2239 2240 b := &rtype{ 2241 align: ptrSize, 2242 size: size, 2243 kind: kind, 2244 ptrdata: ptrdata, 2245 gcdata: gcdata, 2246 } 2247 if overflowPad > 0 { 2248 b.align = 8 2249 } 2250 s := "bucket(" + ktyp.String() + "," + etyp.String() + ")" 2251 b.str = resolveReflectName(newName(s, "", false)) 2252 return b 2253 } 2254 2255 // SliceOf returns the slice type with element type t. 2256 // For example, if t represents int, SliceOf(t) represents []int. 2257 func SliceOf(t Type) Type { 2258 typ := t.(*rtype) 2259 2260 // Look in cache. 2261 ckey := cacheKey{Slice, typ, nil, 0} 2262 if slice, ok := lookupCache.Load(ckey); ok { 2263 return slice.(Type) 2264 } 2265 2266 // Look in known types. 2267 s := "[]" + typ.String() 2268 for _, tt := range typesByString(s) { 2269 slice := (*sliceType)(unsafe.Pointer(tt)) 2270 if slice.elem == typ { 2271 ti, _ := lookupCache.LoadOrStore(ckey, tt) 2272 return ti.(Type) 2273 } 2274 } 2275 2276 // Make a slice type. 2277 var islice interface{} = ([]unsafe.Pointer)(nil) 2278 prototype := *(**sliceType)(unsafe.Pointer(&islice)) 2279 slice := *prototype 2280 slice.tflag = 0 2281 slice.str = resolveReflectName(newName(s, "", false)) 2282 slice.hash = fnv1(typ.hash, '[') 2283 slice.elem = typ 2284 slice.ptrToThis = 0 2285 2286 ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype) 2287 return ti.(Type) 2288 } 2289 2290 // The structLookupCache caches StructOf lookups. 2291 // StructOf does not share the common lookupCache since we need to pin 2292 // the memory associated with *structTypeFixedN. 2293 var structLookupCache struct { 2294 sync.Mutex // Guards stores (but not loads) on m. 2295 2296 // m is a map[uint32][]Type keyed by the hash calculated in StructOf. 2297 // Elements in m are append-only and thus safe for concurrent reading. 2298 m sync.Map 2299 } 2300 2301 type structTypeUncommon struct { 2302 structType 2303 u uncommonType 2304 } 2305 2306 // A *rtype representing a struct is followed directly in memory by an 2307 // array of method objects representing the methods attached to the 2308 // struct. To get the same layout for a run time generated type, we 2309 // need an array directly following the uncommonType memory. The types 2310 // structTypeFixed4, ...structTypeFixedN are used to do this. 2311 // 2312 // A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN. 2313 2314 // TODO(crawshaw): as these structTypeFixedN and funcTypeFixedN structs 2315 // have no methods, they could be defined at runtime using the StructOf 2316 // function. 2317 2318 type structTypeFixed4 struct { 2319 structType 2320 u uncommonType 2321 m [4]method 2322 } 2323 2324 type structTypeFixed8 struct { 2325 structType 2326 u uncommonType 2327 m [8]method 2328 } 2329 2330 type structTypeFixed16 struct { 2331 structType 2332 u uncommonType 2333 m [16]method 2334 } 2335 2336 type structTypeFixed32 struct { 2337 structType 2338 u uncommonType 2339 m [32]method 2340 } 2341 2342 // isLetter returns true if a given 'rune' is classified as a Letter. 2343 func isLetter(ch rune) bool { 2344 return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch) 2345 } 2346 2347 // isValidFieldName checks if a string is a valid (struct) field name or not. 2348 // 2349 // According to the language spec, a field name should be an identifier. 2350 // 2351 // identifier = letter { letter | unicode_digit } . 2352 // letter = unicode_letter | "_" . 2353 func isValidFieldName(fieldName string) bool { 2354 for i, c := range fieldName { 2355 if i == 0 && !isLetter(c) { 2356 return false 2357 } 2358 2359 if !(isLetter(c) || unicode.IsDigit(c)) { 2360 return false 2361 } 2362 } 2363 2364 return len(fieldName) > 0 2365 } 2366 2367 // StructOf returns the struct type containing fields. 2368 // The Offset and Index fields are ignored and computed as they would be 2369 // by the compiler. 2370 // 2371 // StructOf currently does not generate wrapper methods for embedded fields. 2372 // This limitation may be lifted in a future version. 2373 func StructOf(fields []StructField) Type { 2374 var ( 2375 hash = fnv1(0, []byte("struct {")...) 2376 size uintptr 2377 typalign uint8 2378 comparable = true 2379 hashable = true 2380 methods []method 2381 2382 fs = make([]structField, len(fields)) 2383 repr = make([]byte, 0, 64) 2384 fset = map[string]struct{}{} // fields' names 2385 2386 hasPtr = false // records whether at least one struct-field is a pointer 2387 hasGCProg = false // records whether a struct-field type has a GCProg 2388 ) 2389 2390 lastzero := uintptr(0) 2391 repr = append(repr, "struct {"...) 2392 for i, field := range fields { 2393 if field.Name == "" { 2394 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name") 2395 } 2396 if !isValidFieldName(field.Name) { 2397 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name") 2398 } 2399 if field.Type == nil { 2400 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type") 2401 } 2402 f := runtimeStructField(field) 2403 ft := f.typ 2404 if ft.kind&kindGCProg != 0 { 2405 hasGCProg = true 2406 } 2407 if ft.pointers() { 2408 hasPtr = true 2409 } 2410 2411 // Update string and hash 2412 name := f.name.name() 2413 hash = fnv1(hash, []byte(name)...) 2414 repr = append(repr, (" " + name)...) 2415 if f.anon() { 2416 // Embedded field 2417 if f.typ.Kind() == Ptr { 2418 // Embedded ** and *interface{} are illegal 2419 elem := ft.Elem() 2420 if k := elem.Kind(); k == Ptr || k == Interface { 2421 panic("reflect.StructOf: illegal anonymous field type " + ft.String()) 2422 } 2423 } 2424 2425 switch f.typ.Kind() { 2426 case Interface: 2427 ift := (*interfaceType)(unsafe.Pointer(ft)) 2428 for im, m := range ift.methods { 2429 if ift.nameOff(m.name).pkgPath() != "" { 2430 // TODO(sbinet). Issue 15924. 2431 panic("reflect: embedded interface with unexported method(s) not implemented") 2432 } 2433 2434 var ( 2435 mtyp = ift.typeOff(m.typ) 2436 ifield = i 2437 imethod = im 2438 ifn Value 2439 tfn Value 2440 ) 2441 2442 if ft.kind&kindDirectIface != 0 { 2443 tfn = MakeFunc(mtyp, func(in []Value) []Value { 2444 var args []Value 2445 var recv = in[0] 2446 if len(in) > 1 { 2447 args = in[1:] 2448 } 2449 return recv.Field(ifield).Method(imethod).Call(args) 2450 }) 2451 ifn = MakeFunc(mtyp, func(in []Value) []Value { 2452 var args []Value 2453 var recv = in[0] 2454 if len(in) > 1 { 2455 args = in[1:] 2456 } 2457 return recv.Field(ifield).Method(imethod).Call(args) 2458 }) 2459 } else { 2460 tfn = MakeFunc(mtyp, func(in []Value) []Value { 2461 var args []Value 2462 var recv = in[0] 2463 if len(in) > 1 { 2464 args = in[1:] 2465 } 2466 return recv.Field(ifield).Method(imethod).Call(args) 2467 }) 2468 ifn = MakeFunc(mtyp, func(in []Value) []Value { 2469 var args []Value 2470 var recv = Indirect(in[0]) 2471 if len(in) > 1 { 2472 args = in[1:] 2473 } 2474 return recv.Field(ifield).Method(imethod).Call(args) 2475 }) 2476 } 2477 2478 methods = append(methods, method{ 2479 name: resolveReflectName(ift.nameOff(m.name)), 2480 mtyp: resolveReflectType(mtyp), 2481 ifn: resolveReflectText(unsafe.Pointer(&ifn)), 2482 tfn: resolveReflectText(unsafe.Pointer(&tfn)), 2483 }) 2484 } 2485 case Ptr: 2486 ptr := (*ptrType)(unsafe.Pointer(ft)) 2487 if unt := ptr.uncommon(); unt != nil { 2488 if i > 0 && unt.mcount > 0 { 2489 // Issue 15924. 2490 panic("reflect: embedded type with methods not implemented if type is not first field") 2491 } 2492 for _, m := range unt.methods() { 2493 mname := ptr.nameOff(m.name) 2494 if mname.pkgPath() != "" { 2495 // TODO(sbinet). 2496 // Issue 15924. 2497 panic("reflect: embedded interface with unexported method(s) not implemented") 2498 } 2499 methods = append(methods, method{ 2500 name: resolveReflectName(mname), 2501 mtyp: resolveReflectType(ptr.typeOff(m.mtyp)), 2502 ifn: resolveReflectText(ptr.textOff(m.ifn)), 2503 tfn: resolveReflectText(ptr.textOff(m.tfn)), 2504 }) 2505 } 2506 } 2507 if unt := ptr.elem.uncommon(); unt != nil { 2508 for _, m := range unt.methods() { 2509 mname := ptr.nameOff(m.name) 2510 if mname.pkgPath() != "" { 2511 // TODO(sbinet) 2512 // Issue 15924. 2513 panic("reflect: embedded interface with unexported method(s) not implemented") 2514 } 2515 methods = append(methods, method{ 2516 name: resolveReflectName(mname), 2517 mtyp: resolveReflectType(ptr.elem.typeOff(m.mtyp)), 2518 ifn: resolveReflectText(ptr.elem.textOff(m.ifn)), 2519 tfn: resolveReflectText(ptr.elem.textOff(m.tfn)), 2520 }) 2521 } 2522 } 2523 default: 2524 if unt := ft.uncommon(); unt != nil { 2525 if i > 0 && unt.mcount > 0 { 2526 // Issue 15924. 2527 panic("reflect: embedded type with methods not implemented if type is not first field") 2528 } 2529 for _, m := range unt.methods() { 2530 mname := ft.nameOff(m.name) 2531 if mname.pkgPath() != "" { 2532 // TODO(sbinet) 2533 // Issue 15924. 2534 panic("reflect: embedded interface with unexported method(s) not implemented") 2535 } 2536 methods = append(methods, method{ 2537 name: resolveReflectName(mname), 2538 mtyp: resolveReflectType(ft.typeOff(m.mtyp)), 2539 ifn: resolveReflectText(ft.textOff(m.ifn)), 2540 tfn: resolveReflectText(ft.textOff(m.tfn)), 2541 }) 2542 2543 } 2544 } 2545 } 2546 } 2547 if _, dup := fset[name]; dup { 2548 panic("reflect.StructOf: duplicate field " + name) 2549 } 2550 fset[name] = struct{}{} 2551 2552 hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash)) 2553 2554 repr = append(repr, (" " + ft.String())...) 2555 if f.name.tagLen() > 0 { 2556 hash = fnv1(hash, []byte(f.name.tag())...) 2557 repr = append(repr, (" " + strconv.Quote(f.name.tag()))...) 2558 } 2559 if i < len(fields)-1 { 2560 repr = append(repr, ';') 2561 } 2562 2563 comparable = comparable && (ft.alg.equal != nil) 2564 hashable = hashable && (ft.alg.hash != nil) 2565 2566 offset := align(size, uintptr(ft.align)) 2567 if ft.align > typalign { 2568 typalign = ft.align 2569 } 2570 size = offset + ft.size 2571 f.offsetAnon |= offset << 1 2572 2573 if ft.size == 0 { 2574 lastzero = size 2575 } 2576 2577 fs[i] = f 2578 } 2579 2580 if size > 0 && lastzero == size { 2581 // This is a non-zero sized struct that ends in a 2582 // zero-sized field. We add an extra byte of padding, 2583 // to ensure that taking the address of the final 2584 // zero-sized field can't manufacture a pointer to the 2585 // next object in the heap. See issue 9401. 2586 size++ 2587 } 2588 2589 var typ *structType 2590 var ut *uncommonType 2591 2592 switch { 2593 case len(methods) == 0: 2594 t := new(structTypeUncommon) 2595 typ = &t.structType 2596 ut = &t.u 2597 case len(methods) <= 4: 2598 t := new(structTypeFixed4) 2599 typ = &t.structType 2600 ut = &t.u 2601 copy(t.m[:], methods) 2602 case len(methods) <= 8: 2603 t := new(structTypeFixed8) 2604 typ = &t.structType 2605 ut = &t.u 2606 copy(t.m[:], methods) 2607 case len(methods) <= 16: 2608 t := new(structTypeFixed16) 2609 typ = &t.structType 2610 ut = &t.u 2611 copy(t.m[:], methods) 2612 case len(methods) <= 32: 2613 t := new(structTypeFixed32) 2614 typ = &t.structType 2615 ut = &t.u 2616 copy(t.m[:], methods) 2617 default: 2618 panic("reflect.StructOf: too many methods") 2619 } 2620 ut.mcount = uint16(len(methods)) 2621 ut.moff = uint32(unsafe.Sizeof(uncommonType{})) 2622 2623 if len(fs) > 0 { 2624 repr = append(repr, ' ') 2625 } 2626 repr = append(repr, '}') 2627 hash = fnv1(hash, '}') 2628 str := string(repr) 2629 2630 // Round the size up to be a multiple of the alignment. 2631 size = align(size, uintptr(typalign)) 2632 2633 // Make the struct type. 2634 var istruct interface{} = struct{}{} 2635 prototype := *(**structType)(unsafe.Pointer(&istruct)) 2636 *typ = *prototype 2637 typ.fields = fs 2638 2639 // Look in cache. 2640 if ts, ok := structLookupCache.m.Load(hash); ok { 2641 for _, st := range ts.([]Type) { 2642 t := st.common() 2643 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2644 return t 2645 } 2646 } 2647 } 2648 2649 // Not in cache, lock and retry. 2650 structLookupCache.Lock() 2651 defer structLookupCache.Unlock() 2652 if ts, ok := structLookupCache.m.Load(hash); ok { 2653 for _, st := range ts.([]Type) { 2654 t := st.common() 2655 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2656 return t 2657 } 2658 } 2659 } 2660 2661 addToCache := func(t Type) Type { 2662 var ts []Type 2663 if ti, ok := structLookupCache.m.Load(hash); ok { 2664 ts = ti.([]Type) 2665 } 2666 structLookupCache.m.Store(hash, append(ts, t)) 2667 return t 2668 } 2669 2670 // Look in known types. 2671 for _, t := range typesByString(str) { 2672 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2673 // even if 't' wasn't a structType with methods, we should be ok 2674 // as the 'u uncommonType' field won't be accessed except when 2675 // tflag&tflagUncommon is set. 2676 return addToCache(t) 2677 } 2678 } 2679 2680 typ.str = resolveReflectName(newName(str, "", false)) 2681 typ.tflag = 0 2682 typ.hash = hash 2683 typ.size = size 2684 typ.align = typalign 2685 typ.fieldAlign = typalign 2686 typ.ptrToThis = 0 2687 if len(methods) > 0 { 2688 typ.tflag |= tflagUncommon 2689 } 2690 if !hasPtr { 2691 typ.kind |= kindNoPointers 2692 } else { 2693 typ.kind &^= kindNoPointers 2694 } 2695 2696 if hasGCProg { 2697 lastPtrField := 0 2698 for i, ft := range fs { 2699 if ft.typ.pointers() { 2700 lastPtrField = i 2701 } 2702 } 2703 prog := []byte{0, 0, 0, 0} // will be length of prog 2704 for i, ft := range fs { 2705 if i > lastPtrField { 2706 // gcprog should not include anything for any field after 2707 // the last field that contains pointer data 2708 break 2709 } 2710 // FIXME(sbinet) handle padding, fields smaller than a word 2711 elemGC := (*[1 << 30]byte)(unsafe.Pointer(ft.typ.gcdata))[:] 2712 elemPtrs := ft.typ.ptrdata / ptrSize 2713 switch { 2714 case ft.typ.kind&kindGCProg == 0 && ft.typ.ptrdata != 0: 2715 // Element is small with pointer mask; use as literal bits. 2716 mask := elemGC 2717 // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). 2718 var n uintptr 2719 for n := elemPtrs; n > 120; n -= 120 { 2720 prog = append(prog, 120) 2721 prog = append(prog, mask[:15]...) 2722 mask = mask[15:] 2723 } 2724 prog = append(prog, byte(n)) 2725 prog = append(prog, mask[:(n+7)/8]...) 2726 case ft.typ.kind&kindGCProg != 0: 2727 // Element has GC program; emit one element. 2728 elemProg := elemGC[4 : 4+*(*uint32)(unsafe.Pointer(&elemGC[0]))-1] 2729 prog = append(prog, elemProg...) 2730 } 2731 // Pad from ptrdata to size. 2732 elemWords := ft.typ.size / ptrSize 2733 if elemPtrs < elemWords { 2734 // Emit literal 0 bit, then repeat as needed. 2735 prog = append(prog, 0x01, 0x00) 2736 if elemPtrs+1 < elemWords { 2737 prog = append(prog, 0x81) 2738 prog = appendVarint(prog, elemWords-elemPtrs-1) 2739 } 2740 } 2741 } 2742 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4) 2743 typ.kind |= kindGCProg 2744 typ.gcdata = &prog[0] 2745 } else { 2746 typ.kind &^= kindGCProg 2747 bv := new(bitVector) 2748 addTypeBits(bv, 0, typ.common()) 2749 if len(bv.data) > 0 { 2750 typ.gcdata = &bv.data[0] 2751 } 2752 } 2753 typ.ptrdata = typeptrdata(typ.common()) 2754 typ.alg = new(typeAlg) 2755 if hashable { 2756 typ.alg.hash = func(p unsafe.Pointer, seed uintptr) uintptr { 2757 o := seed 2758 for _, ft := range typ.fields { 2759 pi := unsafe.Pointer(uintptr(p) + ft.offset()) 2760 o = ft.typ.alg.hash(pi, o) 2761 } 2762 return o 2763 } 2764 } 2765 2766 if comparable { 2767 typ.alg.equal = func(p, q unsafe.Pointer) bool { 2768 for _, ft := range typ.fields { 2769 pi := unsafe.Pointer(uintptr(p) + ft.offset()) 2770 qi := unsafe.Pointer(uintptr(q) + ft.offset()) 2771 if !ft.typ.alg.equal(pi, qi) { 2772 return false 2773 } 2774 } 2775 return true 2776 } 2777 } 2778 2779 switch { 2780 case len(fs) == 1 && !ifaceIndir(fs[0].typ): 2781 // structs of 1 direct iface type can be direct 2782 typ.kind |= kindDirectIface 2783 default: 2784 typ.kind &^= kindDirectIface 2785 } 2786 2787 return addToCache(&typ.rtype) 2788 } 2789 2790 func runtimeStructField(field StructField) structField { 2791 if field.PkgPath != "" { 2792 panic("reflect.StructOf: StructOf does not allow unexported fields") 2793 } 2794 2795 // Best-effort check for misuse. 2796 // Since PkgPath is empty, not much harm done if Unicode lowercase slips through. 2797 c := field.Name[0] 2798 if 'a' <= c && c <= 'z' || c == '_' { 2799 panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath") 2800 } 2801 2802 offsetAnon := uintptr(0) 2803 if field.Anonymous { 2804 offsetAnon |= 1 2805 } 2806 2807 resolveReflectType(field.Type.common()) // install in runtime 2808 return structField{ 2809 name: newName(field.Name, string(field.Tag), true), 2810 typ: field.Type.common(), 2811 offsetAnon: offsetAnon, 2812 } 2813 } 2814 2815 // typeptrdata returns the length in bytes of the prefix of t 2816 // containing pointer data. Anything after this offset is scalar data. 2817 // keep in sync with ../cmd/compile/internal/gc/reflect.go 2818 func typeptrdata(t *rtype) uintptr { 2819 if !t.pointers() { 2820 return 0 2821 } 2822 switch t.Kind() { 2823 case Struct: 2824 st := (*structType)(unsafe.Pointer(t)) 2825 // find the last field that has pointers. 2826 field := 0 2827 for i := range st.fields { 2828 ft := st.fields[i].typ 2829 if ft.pointers() { 2830 field = i 2831 } 2832 } 2833 f := st.fields[field] 2834 return f.offset() + f.typ.ptrdata 2835 2836 default: 2837 panic("reflect.typeptrdata: unexpected type, " + t.String()) 2838 } 2839 } 2840 2841 // See cmd/compile/internal/gc/reflect.go for derivation of constant. 2842 const maxPtrmaskBytes = 2048 2843 2844 // ArrayOf returns the array type with the given count and element type. 2845 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 2846 // 2847 // If the resulting type would be larger than the available address space, 2848 // ArrayOf panics. 2849 func ArrayOf(count int, elem Type) Type { 2850 typ := elem.(*rtype) 2851 2852 // Look in cache. 2853 ckey := cacheKey{Array, typ, nil, uintptr(count)} 2854 if array, ok := lookupCache.Load(ckey); ok { 2855 return array.(Type) 2856 } 2857 2858 // Look in known types. 2859 s := "[" + strconv.Itoa(count) + "]" + typ.String() 2860 for _, tt := range typesByString(s) { 2861 array := (*arrayType)(unsafe.Pointer(tt)) 2862 if array.elem == typ { 2863 ti, _ := lookupCache.LoadOrStore(ckey, tt) 2864 return ti.(Type) 2865 } 2866 } 2867 2868 // Make an array type. 2869 var iarray interface{} = [1]unsafe.Pointer{} 2870 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 2871 array := *prototype 2872 array.tflag = 0 2873 array.str = resolveReflectName(newName(s, "", false)) 2874 array.hash = fnv1(typ.hash, '[') 2875 for n := uint32(count); n > 0; n >>= 8 { 2876 array.hash = fnv1(array.hash, byte(n)) 2877 } 2878 array.hash = fnv1(array.hash, ']') 2879 array.elem = typ 2880 array.ptrToThis = 0 2881 if typ.size > 0 { 2882 max := ^uintptr(0) / typ.size 2883 if uintptr(count) > max { 2884 panic("reflect.ArrayOf: array size would exceed virtual address space") 2885 } 2886 } 2887 array.size = typ.size * uintptr(count) 2888 if count > 0 && typ.ptrdata != 0 { 2889 array.ptrdata = typ.size*uintptr(count-1) + typ.ptrdata 2890 } 2891 array.align = typ.align 2892 array.fieldAlign = typ.fieldAlign 2893 array.len = uintptr(count) 2894 array.slice = SliceOf(elem).(*rtype) 2895 2896 array.kind &^= kindNoPointers 2897 switch { 2898 case typ.kind&kindNoPointers != 0 || array.size == 0: 2899 // No pointers. 2900 array.kind |= kindNoPointers 2901 array.gcdata = nil 2902 array.ptrdata = 0 2903 2904 case count == 1: 2905 // In memory, 1-element array looks just like the element. 2906 array.kind |= typ.kind & kindGCProg 2907 array.gcdata = typ.gcdata 2908 array.ptrdata = typ.ptrdata 2909 2910 case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*ptrSize: 2911 // Element is small with pointer mask; array is still small. 2912 // Create direct pointer mask by turning each 1 bit in elem 2913 // into count 1 bits in larger mask. 2914 mask := make([]byte, (array.ptrdata/ptrSize+7)/8) 2915 elemMask := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] 2916 elemWords := typ.size / ptrSize 2917 for j := uintptr(0); j < typ.ptrdata/ptrSize; j++ { 2918 if (elemMask[j/8]>>(j%8))&1 != 0 { 2919 for i := uintptr(0); i < array.len; i++ { 2920 k := i*elemWords + j 2921 mask[k/8] |= 1 << (k % 8) 2922 } 2923 } 2924 } 2925 array.gcdata = &mask[0] 2926 2927 default: 2928 // Create program that emits one element 2929 // and then repeats to make the array. 2930 prog := []byte{0, 0, 0, 0} // will be length of prog 2931 elemGC := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] 2932 elemPtrs := typ.ptrdata / ptrSize 2933 if typ.kind&kindGCProg == 0 { 2934 // Element is small with pointer mask; use as literal bits. 2935 mask := elemGC 2936 // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). 2937 var n uintptr 2938 for n = elemPtrs; n > 120; n -= 120 { 2939 prog = append(prog, 120) 2940 prog = append(prog, mask[:15]...) 2941 mask = mask[15:] 2942 } 2943 prog = append(prog, byte(n)) 2944 prog = append(prog, mask[:(n+7)/8]...) 2945 } else { 2946 // Element has GC program; emit one element. 2947 elemProg := elemGC[4 : 4+*(*uint32)(unsafe.Pointer(&elemGC[0]))-1] 2948 prog = append(prog, elemProg...) 2949 } 2950 // Pad from ptrdata to size. 2951 elemWords := typ.size / ptrSize 2952 if elemPtrs < elemWords { 2953 // Emit literal 0 bit, then repeat as needed. 2954 prog = append(prog, 0x01, 0x00) 2955 if elemPtrs+1 < elemWords { 2956 prog = append(prog, 0x81) 2957 prog = appendVarint(prog, elemWords-elemPtrs-1) 2958 } 2959 } 2960 // Repeat count-1 times. 2961 if elemWords < 0x80 { 2962 prog = append(prog, byte(elemWords|0x80)) 2963 } else { 2964 prog = append(prog, 0x80) 2965 prog = appendVarint(prog, elemWords) 2966 } 2967 prog = appendVarint(prog, uintptr(count)-1) 2968 prog = append(prog, 0) 2969 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4) 2970 array.kind |= kindGCProg 2971 array.gcdata = &prog[0] 2972 array.ptrdata = array.size // overestimate but ok; must match program 2973 } 2974 2975 etyp := typ.common() 2976 esize := etyp.Size() 2977 ealg := etyp.alg 2978 2979 array.alg = new(typeAlg) 2980 if ealg.equal != nil { 2981 eequal := ealg.equal 2982 array.alg.equal = func(p, q unsafe.Pointer) bool { 2983 for i := 0; i < count; i++ { 2984 pi := arrayAt(p, i, esize) 2985 qi := arrayAt(q, i, esize) 2986 if !eequal(pi, qi) { 2987 return false 2988 } 2989 2990 } 2991 return true 2992 } 2993 } 2994 if ealg.hash != nil { 2995 ehash := ealg.hash 2996 array.alg.hash = func(ptr unsafe.Pointer, seed uintptr) uintptr { 2997 o := seed 2998 for i := 0; i < count; i++ { 2999 o = ehash(arrayAt(ptr, i, esize), o) 3000 } 3001 return o 3002 } 3003 } 3004 3005 switch { 3006 case count == 1 && !ifaceIndir(typ): 3007 // array of 1 direct iface type can be direct 3008 array.kind |= kindDirectIface 3009 default: 3010 array.kind &^= kindDirectIface 3011 } 3012 3013 ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype) 3014 return ti.(Type) 3015 } 3016 3017 func appendVarint(x []byte, v uintptr) []byte { 3018 for ; v >= 0x80; v >>= 7 { 3019 x = append(x, byte(v|0x80)) 3020 } 3021 x = append(x, byte(v)) 3022 return x 3023 } 3024 3025 // toType converts from a *rtype to a Type that can be returned 3026 // to the client of package reflect. In gc, the only concern is that 3027 // a nil *rtype must be replaced by a nil Type, but in gccgo this 3028 // function takes care of ensuring that multiple *rtype for the same 3029 // type are coalesced into a single Type. 3030 func toType(t *rtype) Type { 3031 if t == nil { 3032 return nil 3033 } 3034 return t 3035 } 3036 3037 type layoutKey struct { 3038 t *rtype // function signature 3039 rcvr *rtype // receiver type, or nil if none 3040 } 3041 3042 type layoutType struct { 3043 t *rtype 3044 argSize uintptr // size of arguments 3045 retOffset uintptr // offset of return values. 3046 stack *bitVector 3047 framePool *sync.Pool 3048 } 3049 3050 var layoutCache sync.Map // map[layoutKey]layoutType 3051 3052 // funcLayout computes a struct type representing the layout of the 3053 // function arguments and return values for the function type t. 3054 // If rcvr != nil, rcvr specifies the type of the receiver. 3055 // The returned type exists only for GC, so we only fill out GC relevant info. 3056 // Currently, that's just size and the GC program. We also fill in 3057 // the name for possible debugging use. 3058 func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stk *bitVector, framePool *sync.Pool) { 3059 if t.Kind() != Func { 3060 panic("reflect: funcLayout of non-func type") 3061 } 3062 if rcvr != nil && rcvr.Kind() == Interface { 3063 panic("reflect: funcLayout with interface receiver " + rcvr.String()) 3064 } 3065 k := layoutKey{t, rcvr} 3066 if lti, ok := layoutCache.Load(k); ok { 3067 lt := lti.(layoutType) 3068 return lt.t, lt.argSize, lt.retOffset, lt.stack, lt.framePool 3069 } 3070 3071 tt := (*funcType)(unsafe.Pointer(t)) 3072 3073 // compute gc program & stack bitmap for arguments 3074 ptrmap := new(bitVector) 3075 var offset uintptr 3076 if rcvr != nil { 3077 // Reflect uses the "interface" calling convention for 3078 // methods, where receivers take one word of argument 3079 // space no matter how big they actually are. 3080 if ifaceIndir(rcvr) || rcvr.pointers() { 3081 ptrmap.append(1) 3082 } 3083 offset += ptrSize 3084 } 3085 for _, arg := range tt.in() { 3086 offset += -offset & uintptr(arg.align-1) 3087 addTypeBits(ptrmap, offset, arg) 3088 offset += arg.size 3089 } 3090 argN := ptrmap.n 3091 argSize = offset 3092 if runtime.GOARCH == "amd64p32" { 3093 offset += -offset & (8 - 1) 3094 } 3095 offset += -offset & (ptrSize - 1) 3096 retOffset = offset 3097 for _, res := range tt.out() { 3098 offset += -offset & uintptr(res.align-1) 3099 addTypeBits(ptrmap, offset, res) 3100 offset += res.size 3101 } 3102 offset += -offset & (ptrSize - 1) 3103 3104 // build dummy rtype holding gc program 3105 x := &rtype{ 3106 align: ptrSize, 3107 size: offset, 3108 ptrdata: uintptr(ptrmap.n) * ptrSize, 3109 } 3110 if runtime.GOARCH == "amd64p32" { 3111 x.align = 8 3112 } 3113 if ptrmap.n > 0 { 3114 x.gcdata = &ptrmap.data[0] 3115 } else { 3116 x.kind |= kindNoPointers 3117 } 3118 ptrmap.n = argN 3119 3120 var s string 3121 if rcvr != nil { 3122 s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")" 3123 } else { 3124 s = "funcargs(" + t.String() + ")" 3125 } 3126 x.str = resolveReflectName(newName(s, "", false)) 3127 3128 // cache result for future callers 3129 framePool = &sync.Pool{New: func() interface{} { 3130 return unsafe_New(x) 3131 }} 3132 lti, _ := layoutCache.LoadOrStore(k, layoutType{ 3133 t: x, 3134 argSize: argSize, 3135 retOffset: retOffset, 3136 stack: ptrmap, 3137 framePool: framePool, 3138 }) 3139 lt := lti.(layoutType) 3140 return lt.t, lt.argSize, lt.retOffset, lt.stack, lt.framePool 3141 } 3142 3143 // ifaceIndir reports whether t is stored indirectly in an interface value. 3144 func ifaceIndir(t *rtype) bool { 3145 return t.kind&kindDirectIface == 0 3146 } 3147 3148 // Layout matches runtime.gobitvector (well enough). 3149 type bitVector struct { 3150 n uint32 // number of bits 3151 data []byte 3152 } 3153 3154 // append a bit to the bitmap. 3155 func (bv *bitVector) append(bit uint8) { 3156 if bv.n%8 == 0 { 3157 bv.data = append(bv.data, 0) 3158 } 3159 bv.data[bv.n/8] |= bit << (bv.n % 8) 3160 bv.n++ 3161 } 3162 3163 func addTypeBits(bv *bitVector, offset uintptr, t *rtype) { 3164 if t.kind&kindNoPointers != 0 { 3165 return 3166 } 3167 3168 switch Kind(t.kind & kindMask) { 3169 case Chan, Func, Map, Ptr, Slice, String, UnsafePointer: 3170 // 1 pointer at start of representation 3171 for bv.n < uint32(offset/uintptr(ptrSize)) { 3172 bv.append(0) 3173 } 3174 bv.append(1) 3175 3176 case Interface: 3177 // 2 pointers 3178 for bv.n < uint32(offset/uintptr(ptrSize)) { 3179 bv.append(0) 3180 } 3181 bv.append(1) 3182 bv.append(1) 3183 3184 case Array: 3185 // repeat inner type 3186 tt := (*arrayType)(unsafe.Pointer(t)) 3187 for i := 0; i < int(tt.len); i++ { 3188 addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem) 3189 } 3190 3191 case Struct: 3192 // apply fields 3193 tt := (*structType)(unsafe.Pointer(t)) 3194 for i := range tt.fields { 3195 f := &tt.fields[i] 3196 addTypeBits(bv, offset+f.offset(), f.typ) 3197 } 3198 } 3199 }