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