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