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