github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/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 // Type information of an interface is stored as a pointer to a global in the 6 // interface type (runtime._interface). This is called a type struct. 7 // It always starts with a byte that contains both the type kind and a few 8 // flags. In most cases it also contains a pointer to another type struct 9 // (ptrTo), that is the pointer type of the current type (for example, type int 10 // also has a pointer to the type *int). The exception is pointer types, to 11 // avoid infinite recursion. 12 // 13 // The layouts specifically look like this: 14 // - basic types (Bool..UnsafePointer): 15 // meta uint8 // actually: kind + flags 16 // ptrTo *typeStruct 17 // - channels and slices (see elemType): 18 // meta uint8 19 // nmethods uint16 (0) 20 // ptrTo *typeStruct 21 // elementType *typeStruct // the type that you get with .Elem() 22 // - pointer types (see ptrType, this doesn't include chan, map, etc): 23 // meta uint8 24 // nmethods uint16 25 // elementType *typeStruct 26 // - array types (see arrayType) 27 // meta uint8 28 // nmethods uint16 (0) 29 // ptrTo *typeStruct 30 // elem *typeStruct // element type of the array 31 // arrayLen uintptr // length of the array (this is part of the type) 32 // slicePtr *typeStruct // pointer to []T type 33 // - map types (this is still missing the key and element types) 34 // meta uint8 35 // nmethods uint16 (0) 36 // ptrTo *typeStruct 37 // elem *typeStruct 38 // key *typeStruct 39 // - struct types (see structType): 40 // meta uint8 41 // nmethods uint16 42 // ptrTo *typeStruct 43 // size uint32 44 // pkgpath *byte // package path; null terminated 45 // numField uint16 46 // fields [...]structField // the remaining fields are all of type structField 47 // - interface types (this is missing the interface methods): 48 // meta uint8 49 // ptrTo *typeStruct 50 // - signature types (this is missing input and output parameters): 51 // meta uint8 52 // ptrTo *typeStruct 53 // - named types 54 // meta uint8 55 // nmethods uint16 // number of methods 56 // ptrTo *typeStruct 57 // elem *typeStruct // underlying type 58 // pkgpath *byte // pkgpath; null terminated 59 // name [1]byte // actual name; null terminated 60 // 61 // The type struct is essentially a union of all the above types. Which it is, 62 // can be determined by looking at the meta byte. 63 64 package reflect 65 66 import ( 67 "internal/itoa" 68 "unsafe" 69 ) 70 71 // Flags stored in the first byte of the struct field byte array. Must be kept 72 // up to date with compiler/interface.go. 73 const ( 74 structFieldFlagAnonymous = 1 << iota 75 structFieldFlagHasTag 76 structFieldFlagIsExported 77 structFieldFlagIsEmbedded 78 ) 79 80 type Kind uint8 81 82 // Copied from reflect/type.go 83 // https://golang.org/src/reflect/type.go?s=8302:8316#L217 84 // These constants must match basicTypes and the typeKind* constants in 85 // compiler/interface.go 86 const ( 87 Invalid Kind = iota 88 Bool 89 Int 90 Int8 91 Int16 92 Int32 93 Int64 94 Uint 95 Uint8 96 Uint16 97 Uint32 98 Uint64 99 Uintptr 100 Float32 101 Float64 102 Complex64 103 Complex128 104 String 105 UnsafePointer 106 Chan 107 Interface 108 Pointer 109 Slice 110 Array 111 Func 112 Map 113 Struct 114 ) 115 116 // Ptr is the old name for the Pointer kind. 117 const Ptr = Pointer 118 119 func (k Kind) String() string { 120 switch k { 121 case Invalid: 122 return "invalid" 123 case Bool: 124 return "bool" 125 case Int: 126 return "int" 127 case Int8: 128 return "int8" 129 case Int16: 130 return "int16" 131 case Int32: 132 return "int32" 133 case Int64: 134 return "int64" 135 case Uint: 136 return "uint" 137 case Uint8: 138 return "uint8" 139 case Uint16: 140 return "uint16" 141 case Uint32: 142 return "uint32" 143 case Uint64: 144 return "uint64" 145 case Uintptr: 146 return "uintptr" 147 case Float32: 148 return "float32" 149 case Float64: 150 return "float64" 151 case Complex64: 152 return "complex64" 153 case Complex128: 154 return "complex128" 155 case String: 156 return "string" 157 case UnsafePointer: 158 return "unsafe.Pointer" 159 case Chan: 160 return "chan" 161 case Interface: 162 return "interface" 163 case Pointer: 164 return "ptr" 165 case Slice: 166 return "slice" 167 case Array: 168 return "array" 169 case Func: 170 return "func" 171 case Map: 172 return "map" 173 case Struct: 174 return "struct" 175 default: 176 return "kind" + itoa.Itoa(int(int8(k))) 177 } 178 } 179 180 // Copied from reflect/type.go 181 // https://go.dev/src/reflect/type.go?#L348 182 183 // ChanDir represents a channel type's direction. 184 type ChanDir int 185 186 const ( 187 RecvDir ChanDir = 1 << iota // <-chan 188 SendDir // chan<- 189 BothDir = RecvDir | SendDir // chan 190 ) 191 192 // Method represents a single method. 193 type Method struct { 194 // Name is the method name. 195 Name string 196 197 // PkgPath is the package path that qualifies a lower case (unexported) 198 // method name. It is empty for upper case (exported) method names. 199 // The combination of PkgPath and Name uniquely identifies a method 200 // in a method set. 201 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 202 PkgPath string 203 204 Type Type // method type 205 Func Value // func with receiver as first argument 206 Index int // index for Type.Method 207 } 208 209 // The following Type type has been copied almost entirely from 210 // https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212. 211 // Some methods have been commented out as they haven't yet been implemented. 212 213 // Type is the representation of a Go type. 214 // 215 // Not all methods apply to all kinds of types. Restrictions, 216 // if any, are noted in the documentation for each method. 217 // Use the Kind method to find out the kind of type before 218 // calling kind-specific methods. Calling a method 219 // inappropriate to the kind of type causes a run-time panic. 220 // 221 // Type values are comparable, such as with the == operator, 222 // so they can be used as map keys. 223 // Two Type values are equal if they represent identical types. 224 type Type interface { 225 // Methods applicable to all types. 226 227 // Align returns the alignment in bytes of a value of 228 // this type when allocated in memory. 229 Align() int 230 231 // FieldAlign returns the alignment in bytes of a value of 232 // this type when used as a field in a struct. 233 FieldAlign() int 234 235 // Method returns the i'th method in the type's method set. 236 // It panics if i is not in the range [0, NumMethod()). 237 // 238 // For a non-interface type T or *T, the returned Method's Type and Func 239 // fields describe a function whose first argument is the receiver. 240 // 241 // For an interface type, the returned Method's Type field gives the 242 // method signature, without a receiver, and the Func field is nil. 243 // 244 // Only exported methods are accessible and they are sorted in 245 // lexicographic order. 246 Method(int) Method 247 248 // MethodByName returns the method with that name in the type's 249 // method set and a boolean indicating if the method was found. 250 // 251 // For a non-interface type T or *T, the returned Method's Type and Func 252 // fields describe a function whose first argument is the receiver. 253 // 254 // For an interface type, the returned Method's Type field gives the 255 // method signature, without a receiver, and the Func field is nil. 256 MethodByName(string) (Method, bool) 257 258 // NumMethod returns the number of exported methods in the type's method set. 259 NumMethod() int 260 261 // Name returns the type's name within its package for a defined type. 262 // For other (non-defined) types it returns the empty string. 263 Name() string 264 265 // PkgPath returns a defined type's package path, that is, the import path 266 // that uniquely identifies the package, such as "encoding/base64". 267 // If the type was predeclared (string, error) or not defined (*T, struct{}, 268 // []int, or A where A is an alias for a non-defined type), the package path 269 // will be the empty string. 270 PkgPath() string 271 272 // Size returns the number of bytes needed to store 273 // a value of the given type; it is analogous to unsafe.Sizeof. 274 Size() uintptr 275 276 // String returns a string representation of the type. 277 // The string representation may use shortened package names 278 // (e.g., base64 instead of "encoding/base64") and is not 279 // guaranteed to be unique among types. To test for type identity, 280 // compare the Types directly. 281 String() string 282 283 // Kind returns the specific kind of this type. 284 Kind() Kind 285 286 // Implements reports whether the type implements the interface type u. 287 Implements(u Type) bool 288 289 // AssignableTo reports whether a value of the type is assignable to type u. 290 AssignableTo(u Type) bool 291 292 // ConvertibleTo reports whether a value of the type is convertible to type u. 293 ConvertibleTo(u Type) bool 294 295 // Comparable reports whether values of this type are comparable. 296 Comparable() bool 297 298 // Methods applicable only to some types, depending on Kind. 299 // The methods allowed for each kind are: 300 // 301 // Int*, Uint*, Float*, Complex*: Bits 302 // Array: Elem, Len 303 // Chan: ChanDir, Elem 304 // Func: In, NumIn, Out, NumOut, IsVariadic. 305 // Map: Key, Elem 306 // Pointer: Elem 307 // Slice: Elem 308 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField 309 310 // Bits returns the size of the type in bits. 311 // It panics if the type's Kind is not one of the 312 // sized or unsized Int, Uint, Float, or Complex kinds. 313 Bits() int 314 315 // ChanDir returns a channel type's direction. 316 // It panics if the type's Kind is not Chan. 317 ChanDir() ChanDir 318 319 // IsVariadic reports whether a function type's final input parameter 320 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 321 // implicit actual type []T. 322 // 323 // For concreteness, if t represents func(x int, y ... float64), then 324 // 325 // t.NumIn() == 2 326 // t.In(0) is the reflect.Type for "int" 327 // t.In(1) is the reflect.Type for "[]float64" 328 // t.IsVariadic() == true 329 // 330 // IsVariadic panics if the type's Kind is not Func. 331 IsVariadic() bool 332 333 // Elem returns a type's element type. 334 // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice. 335 Elem() Type 336 337 // Field returns a struct type's i'th field. 338 // It panics if the type's Kind is not Struct. 339 // It panics if i is not in the range [0, NumField()). 340 Field(i int) StructField 341 342 // FieldByIndex returns the nested field corresponding 343 // to the index sequence. It is equivalent to calling Field 344 // successively for each index i. 345 // It panics if the type's Kind is not Struct. 346 FieldByIndex(index []int) StructField 347 348 // FieldByName returns the struct field with the given name 349 // and a boolean indicating if the field was found. 350 FieldByName(name string) (StructField, bool) 351 352 // FieldByNameFunc returns the struct field with a name 353 // that satisfies the match function and a boolean indicating if 354 // the field was found. 355 // 356 // FieldByNameFunc considers the fields in the struct itself 357 // and then the fields in any embedded structs, in breadth first order, 358 // stopping at the shallowest nesting depth containing one or more 359 // fields satisfying the match function. If multiple fields at that depth 360 // satisfy the match function, they cancel each other 361 // and FieldByNameFunc returns no match. 362 // This behavior mirrors Go's handling of name lookup in 363 // structs containing embedded fields. 364 FieldByNameFunc(match func(string) bool) (StructField, bool) 365 366 // In returns the type of a function type's i'th input parameter. 367 // It panics if the type's Kind is not Func. 368 // It panics if i is not in the range [0, NumIn()). 369 In(i int) Type 370 371 // Key returns a map type's key type. 372 // It panics if the type's Kind is not Map. 373 Key() Type 374 375 // Len returns an array type's length. 376 // It panics if the type's Kind is not Array. 377 Len() int 378 379 // NumField returns a struct type's field count. 380 // It panics if the type's Kind is not Struct. 381 NumField() int 382 383 // NumIn returns a function type's input parameter count. 384 // It panics if the type's Kind is not Func. 385 NumIn() int 386 387 // NumOut returns a function type's output parameter count. 388 // It panics if the type's Kind is not Func. 389 NumOut() int 390 391 // Out returns the type of a function type's i'th output parameter. 392 // It panics if the type's Kind is not Func. 393 // It panics if i is not in the range [0, NumOut()). 394 Out(i int) Type 395 } 396 397 // Constants for the 'meta' byte. 398 const ( 399 kindMask = 31 // mask to apply to the meta byte to get the Kind value 400 flagNamed = 32 // flag that is set if this is a named type 401 flagComparable = 64 // flag that is set if this type is comparable 402 flagIsBinary = 128 // flag that is set if this type uses the hashmap binary algorithm 403 ) 404 405 // The base type struct. All type structs start with this. 406 type rawType struct { 407 meta uint8 // metadata byte, contains kind and flags (see contants above) 408 } 409 410 // All types that have an element type: named, chan, slice, array, map (but not 411 // pointer because it doesn't have ptrTo). 412 type elemType struct { 413 rawType 414 numMethod uint16 415 ptrTo *rawType 416 elem *rawType 417 } 418 419 type ptrType struct { 420 rawType 421 numMethod uint16 422 elem *rawType 423 } 424 425 type arrayType struct { 426 rawType 427 numMethod uint16 428 ptrTo *rawType 429 elem *rawType 430 arrayLen uintptr 431 slicePtr *rawType 432 } 433 434 type mapType struct { 435 rawType 436 numMethod uint16 437 ptrTo *rawType 438 elem *rawType 439 key *rawType 440 } 441 442 type namedType struct { 443 rawType 444 numMethod uint16 445 ptrTo *rawType 446 elem *rawType 447 pkg *byte 448 name [1]byte 449 } 450 451 // Type for struct types. The numField value is intentionally put before ptrTo 452 // for better struct packing on 32-bit and 64-bit architectures. On these 453 // architectures, the ptrTo field still has the same offset as in all the other 454 // type structs. 455 // The fields array isn't necessarily 1 structField long, instead it is as long 456 // as numFields. The array is given a length of 1 to satisfy the Go type 457 // checker. 458 type structType struct { 459 rawType 460 numMethod uint16 461 ptrTo *rawType 462 pkgpath *byte 463 size uint32 464 numField uint16 465 fields [1]structField // the remaining fields are all of type structField 466 } 467 468 type structField struct { 469 fieldType *rawType 470 data unsafe.Pointer // various bits of information, packed in a byte array 471 } 472 473 // Equivalent to (go/types.Type).Underlying(): if this is a named type return 474 // the underlying type, else just return the type itself. 475 func (t *rawType) underlying() *rawType { 476 if t.isNamed() { 477 return (*elemType)(unsafe.Pointer(t)).elem 478 } 479 return t 480 } 481 482 func (t *rawType) ptrtag() uintptr { 483 return uintptr(unsafe.Pointer(t)) & 0b11 484 } 485 486 func (t *rawType) isNamed() bool { 487 if tag := t.ptrtag(); tag != 0 { 488 return false 489 } 490 491 return t.meta&flagNamed != 0 492 } 493 494 func TypeOf(i interface{}) Type { 495 if i == nil { 496 return nil 497 } 498 typecode, _ := decomposeInterface(i) 499 return (*rawType)(typecode) 500 } 501 502 func PtrTo(t Type) Type { return PointerTo(t) } 503 504 func PointerTo(t Type) Type { 505 return pointerTo(t.(*rawType)) 506 } 507 508 func pointerTo(t *rawType) *rawType { 509 if t.isNamed() { 510 return (*elemType)(unsafe.Pointer(t)).ptrTo 511 } 512 513 switch t.Kind() { 514 case Pointer: 515 if tag := t.ptrtag(); tag < 3 { 516 return (*rawType)(unsafe.Add(unsafe.Pointer(t), 1)) 517 } 518 519 // TODO(dgryski): This is blocking https://github.com/tinygo-org/tinygo/issues/3131 520 // We need to be able to create types that match existing types to prevent typecode equality. 521 panic("reflect: cannot make *****T type") 522 case Struct: 523 return (*structType)(unsafe.Pointer(t)).ptrTo 524 default: 525 return (*elemType)(unsafe.Pointer(t)).ptrTo 526 } 527 } 528 529 func (t *rawType) String() string { 530 if t.isNamed() { 531 s := t.name() 532 if s[0] == '.' { 533 return s[1:] 534 } 535 return s 536 } 537 538 switch t.Kind() { 539 case Chan: 540 elem := t.elem().String() 541 switch t.ChanDir() { 542 case SendDir: 543 return "chan<- " + elem 544 case RecvDir: 545 return "<-chan " + elem 546 case BothDir: 547 if elem[0] == '<' { 548 // typ is recv chan, need parentheses as "<-" associates with leftmost 549 // chan possible, see: 550 // * https://golang.org/ref/spec#Channel_types 551 // * https://github.com/golang/go/issues/39897 552 return "chan (" + elem + ")" 553 } 554 return "chan " + elem 555 } 556 557 case Pointer: 558 return "*" + t.elem().String() 559 case Slice: 560 return "[]" + t.elem().String() 561 case Array: 562 return "[" + itoa.Itoa(t.Len()) + "]" + t.elem().String() 563 case Map: 564 return "map[" + t.key().String() + "]" + t.elem().String() 565 case Struct: 566 numField := t.NumField() 567 if numField == 0 { 568 return "struct {}" 569 } 570 s := "struct {" 571 for i := 0; i < numField; i++ { 572 f := t.rawField(i) 573 s += " " + f.Name + " " + f.Type.String() 574 if f.Tag != "" { 575 s += " " + quote(string(f.Tag)) 576 } 577 // every field except the last needs a semicolon 578 if i < numField-1 { 579 s += ";" 580 } 581 } 582 s += " }" 583 return s 584 case Interface: 585 // TODO(dgryski): Needs actual method set info 586 return "interface {}" 587 default: 588 return t.Kind().String() 589 } 590 591 return t.Kind().String() 592 } 593 594 func (t *rawType) Kind() Kind { 595 if t == nil { 596 return Invalid 597 } 598 599 if tag := t.ptrtag(); tag != 0 { 600 return Pointer 601 } 602 603 return Kind(t.meta & kindMask) 604 } 605 606 var ( 607 errTypeElem = &TypeError{"Elem"} 608 errTypeKey = &TypeError{"Key"} 609 errTypeField = &TypeError{"Field"} 610 errTypeBits = &TypeError{"Bits"} 611 errTypeLen = &TypeError{"Len"} 612 errTypeNumField = &TypeError{"NumField"} 613 errTypeChanDir = &TypeError{"ChanDir"} 614 errTypeFieldByName = &TypeError{"FieldByName"} 615 errTypeFieldByIndex = &TypeError{"FieldByIndex"} 616 ) 617 618 // Elem returns the element type for channel, slice and array types, the 619 // pointed-to value for pointer types, and the key type for map types. 620 func (t *rawType) Elem() Type { 621 return t.elem() 622 } 623 624 func (t *rawType) elem() *rawType { 625 if tag := t.ptrtag(); tag != 0 { 626 return (*rawType)(unsafe.Add(unsafe.Pointer(t), -1)) 627 } 628 629 underlying := t.underlying() 630 switch underlying.Kind() { 631 case Pointer: 632 return (*ptrType)(unsafe.Pointer(underlying)).elem 633 case Chan, Slice, Array, Map: 634 return (*elemType)(unsafe.Pointer(underlying)).elem 635 default: 636 panic(errTypeElem) 637 } 638 } 639 640 func (t *rawType) key() *rawType { 641 underlying := t.underlying() 642 if underlying.Kind() != Map { 643 panic(errTypeKey) 644 } 645 return (*mapType)(unsafe.Pointer(underlying)).key 646 } 647 648 // Field returns the type of the i'th field of this struct type. It panics if t 649 // is not a struct type. 650 func (t *rawType) Field(i int) StructField { 651 field := t.rawField(i) 652 return StructField{ 653 Name: field.Name, 654 PkgPath: field.PkgPath, 655 Type: field.Type, // note: converts rawType to Type 656 Tag: field.Tag, 657 Anonymous: field.Anonymous, 658 Offset: field.Offset, 659 Index: []int{i}, 660 } 661 } 662 663 func rawStructFieldFromPointer(descriptor *structType, fieldType *rawType, data unsafe.Pointer, flagsByte uint8, name string, offset uint32) rawStructField { 664 // Read the field tag, if there is one. 665 var tag string 666 if flagsByte&structFieldFlagHasTag != 0 { 667 data = unsafe.Add(data, 1) // C: data+1 668 tagLen := uintptr(*(*byte)(data)) 669 data = unsafe.Add(data, 1) // C: data+1 670 tag = *(*string)(unsafe.Pointer(&stringHeader{ 671 data: data, 672 len: tagLen, 673 })) 674 } 675 676 // Set the PkgPath to some (arbitrary) value if the package path is not 677 // exported. 678 pkgPath := "" 679 if flagsByte&structFieldFlagIsExported == 0 { 680 // This field is unexported. 681 pkgPath = readStringZ(unsafe.Pointer(descriptor.pkgpath)) 682 } 683 684 return rawStructField{ 685 Name: name, 686 PkgPath: pkgPath, 687 Type: fieldType, 688 Tag: StructTag(tag), 689 Anonymous: flagsByte&structFieldFlagAnonymous != 0, 690 Offset: uintptr(offset), 691 } 692 } 693 694 // rawField returns nearly the same value as Field but without converting the 695 // Type member to an interface. 696 // 697 // For internal use only. 698 func (t *rawType) rawField(n int) rawStructField { 699 if t.Kind() != Struct { 700 panic(errTypeField) 701 } 702 descriptor := (*structType)(unsafe.Pointer(t.underlying())) 703 if uint(n) >= uint(descriptor.numField) { 704 panic("reflect: field index out of range") 705 } 706 707 // Iterate over all the fields to calculate the offset. 708 // This offset could have been stored directly in the array (to make the 709 // lookup faster), but by calculating it on-the-fly a bit of storage can be 710 // saved. 711 field := (*structField)(unsafe.Add(unsafe.Pointer(&descriptor.fields[0]), uintptr(n)*unsafe.Sizeof(structField{}))) 712 data := field.data 713 714 // Read some flags of this field, like whether the field is an embedded 715 // field. See structFieldFlagAnonymous and similar flags. 716 flagsByte := *(*byte)(data) 717 data = unsafe.Add(data, 1) 718 offset, lenOffs := uvarint32(unsafe.Slice((*byte)(data), maxVarintLen32)) 719 data = unsafe.Add(data, lenOffs) 720 721 name := readStringZ(data) 722 data = unsafe.Add(data, len(name)) 723 724 return rawStructFieldFromPointer(descriptor, field.fieldType, data, flagsByte, name, offset) 725 } 726 727 // rawFieldByNameFunc returns nearly the same value as FieldByNameFunc but without converting the 728 // Type member to an interface. 729 // 730 // For internal use only. 731 func (t *rawType) rawFieldByNameFunc(match func(string) bool) (rawStructField, []int, bool) { 732 if t.Kind() != Struct { 733 panic(errTypeField) 734 } 735 736 type fieldWalker struct { 737 t *rawType 738 index []int 739 } 740 741 queue := make([]fieldWalker, 0, 4) 742 queue = append(queue, fieldWalker{t, nil}) 743 744 for len(queue) > 0 { 745 type result struct { 746 r rawStructField 747 index []int 748 } 749 750 var found []result 751 var nextlevel []fieldWalker 752 753 // For all the structs at this level.. 754 for _, ll := range queue { 755 // Iterate over all the fields looking for the matching name 756 // Also calculate field offset. 757 758 descriptor := (*structType)(unsafe.Pointer(ll.t.underlying())) 759 field := &descriptor.fields[0] 760 761 for i := uint16(0); i < descriptor.numField; i++ { 762 data := field.data 763 764 // Read some flags of this field, like whether the field is an embedded 765 // field. See structFieldFlagAnonymous and similar flags. 766 flagsByte := *(*byte)(data) 767 data = unsafe.Add(data, 1) 768 769 offset, lenOffs := uvarint32(unsafe.Slice((*byte)(data), maxVarintLen32)) 770 data = unsafe.Add(data, lenOffs) 771 772 name := readStringZ(data) 773 data = unsafe.Add(data, len(name)) 774 if match(name) { 775 found = append(found, result{ 776 rawStructFieldFromPointer(descriptor, field.fieldType, data, flagsByte, name, offset), 777 append(ll.index, int(i)), 778 }) 779 } 780 781 structOrPtrToStruct := field.fieldType.Kind() == Struct || (field.fieldType.Kind() == Pointer && field.fieldType.elem().Kind() == Struct) 782 if flagsByte&structFieldFlagIsEmbedded == structFieldFlagIsEmbedded && structOrPtrToStruct { 783 embedded := field.fieldType 784 if embedded.Kind() == Pointer { 785 embedded = embedded.elem() 786 } 787 788 nextlevel = append(nextlevel, fieldWalker{ 789 t: embedded, 790 index: append(ll.index, int(i)), 791 }) 792 } 793 794 // update offset/field pointer if there *is* a next field 795 if i < descriptor.numField-1 { 796 // Increment pointer to the next field. 797 field = (*structField)(unsafe.Add(unsafe.Pointer(field), unsafe.Sizeof(structField{}))) 798 } 799 } 800 } 801 802 // found multiple hits at this level 803 if len(found) > 1 { 804 return rawStructField{}, nil, false 805 } 806 807 // found the field we were looking for 808 if len(found) == 1 { 809 r := found[0] 810 return r.r, r.index, true 811 } 812 813 // else len(found) == 0, move on to the next level 814 queue = append(queue[:0], nextlevel...) 815 } 816 817 // didn't find it 818 return rawStructField{}, nil, false 819 } 820 821 // Bits returns the number of bits that this type uses. It is only valid for 822 // arithmetic types (integers, floats, and complex numbers). For other types, it 823 // will panic. 824 func (t *rawType) Bits() int { 825 kind := t.Kind() 826 if kind >= Int && kind <= Complex128 { 827 return int(t.Size()) * 8 828 } 829 panic(errTypeBits) 830 } 831 832 // Len returns the number of elements in this array. It panics of the type kind 833 // is not Array. 834 func (t *rawType) Len() int { 835 if t.Kind() != Array { 836 panic(errTypeLen) 837 } 838 839 return int((*arrayType)(unsafe.Pointer(t.underlying())).arrayLen) 840 } 841 842 // NumField returns the number of fields of a struct type. It panics for other 843 // type kinds. 844 func (t *rawType) NumField() int { 845 if t.Kind() != Struct { 846 panic(errTypeNumField) 847 } 848 return int((*structType)(unsafe.Pointer(t.underlying())).numField) 849 } 850 851 // Size returns the size in bytes of a given type. It is similar to 852 // unsafe.Sizeof. 853 func (t *rawType) Size() uintptr { 854 switch t.Kind() { 855 case Bool, Int8, Uint8: 856 return 1 857 case Int16, Uint16: 858 return 2 859 case Int32, Uint32: 860 return 4 861 case Int64, Uint64: 862 return 8 863 case Int, Uint: 864 return unsafe.Sizeof(int(0)) 865 case Uintptr: 866 return unsafe.Sizeof(uintptr(0)) 867 case Float32: 868 return 4 869 case Float64: 870 return 8 871 case Complex64: 872 return 8 873 case Complex128: 874 return 16 875 case String: 876 return unsafe.Sizeof("") 877 case UnsafePointer, Chan, Map, Pointer: 878 return unsafe.Sizeof(uintptr(0)) 879 case Slice: 880 return unsafe.Sizeof([]int{}) 881 case Interface: 882 return unsafe.Sizeof(interface{}(nil)) 883 case Func: 884 var f func() 885 return unsafe.Sizeof(f) 886 case Array: 887 return t.elem().Size() * uintptr(t.Len()) 888 case Struct: 889 u := t.underlying() 890 return uintptr((*structType)(unsafe.Pointer(u)).size) 891 default: 892 panic("unimplemented: size of type") 893 } 894 } 895 896 // Align returns the alignment of this type. It is similar to calling 897 // unsafe.Alignof. 898 func (t *rawType) Align() int { 899 switch t.Kind() { 900 case Bool, Int8, Uint8: 901 return int(unsafe.Alignof(int8(0))) 902 case Int16, Uint16: 903 return int(unsafe.Alignof(int16(0))) 904 case Int32, Uint32: 905 return int(unsafe.Alignof(int32(0))) 906 case Int64, Uint64: 907 return int(unsafe.Alignof(int64(0))) 908 case Int, Uint: 909 return int(unsafe.Alignof(int(0))) 910 case Uintptr: 911 return int(unsafe.Alignof(uintptr(0))) 912 case Float32: 913 return int(unsafe.Alignof(float32(0))) 914 case Float64: 915 return int(unsafe.Alignof(float64(0))) 916 case Complex64: 917 return int(unsafe.Alignof(complex64(0))) 918 case Complex128: 919 return int(unsafe.Alignof(complex128(0))) 920 case String: 921 return int(unsafe.Alignof("")) 922 case UnsafePointer, Chan, Map, Pointer: 923 return int(unsafe.Alignof(uintptr(0))) 924 case Slice: 925 return int(unsafe.Alignof([]int(nil))) 926 case Interface: 927 return int(unsafe.Alignof(interface{}(nil))) 928 case Func: 929 var f func() 930 return int(unsafe.Alignof(f)) 931 case Struct: 932 numField := t.NumField() 933 alignment := 1 934 for i := 0; i < numField; i++ { 935 fieldAlignment := t.rawField(i).Type.Align() 936 if fieldAlignment > alignment { 937 alignment = fieldAlignment 938 } 939 } 940 return alignment 941 case Array: 942 return t.elem().Align() 943 default: 944 panic("unimplemented: alignment of type") 945 } 946 } 947 948 // FieldAlign returns the alignment if this type is used in a struct field. It 949 // is currently an alias for Align() but this might change in the future. 950 func (t *rawType) FieldAlign() int { 951 return t.Align() 952 } 953 954 // AssignableTo returns whether a value of type t can be assigned to a variable 955 // of type u. 956 func (t *rawType) AssignableTo(u Type) bool { 957 if t == u.(*rawType) { 958 return true 959 } 960 961 if u.Kind() == Interface && u.NumMethod() == 0 { 962 return true 963 } 964 965 if u.Kind() == Interface { 966 panic("reflect: unimplemented: AssignableTo with interface") 967 } 968 return false 969 } 970 971 func (t *rawType) Implements(u Type) bool { 972 if u.Kind() != Interface { 973 panic("reflect: non-interface type passed to Type.Implements") 974 } 975 return t.AssignableTo(u) 976 } 977 978 // Comparable returns whether values of this type can be compared to each other. 979 func (t *rawType) Comparable() bool { 980 return (t.meta & flagComparable) == flagComparable 981 } 982 983 // isbinary() returns if the hashmapAlgorithmBinary functions can be used on this type 984 func (t *rawType) isBinary() bool { 985 return (t.meta & flagIsBinary) == flagIsBinary 986 } 987 988 func (t *rawType) ChanDir() ChanDir { 989 if t.Kind() != Chan { 990 panic(errTypeChanDir) 991 } 992 993 dir := int((*elemType)(unsafe.Pointer(t)).numMethod) 994 995 // nummethod is overloaded for channel to store channel direction 996 return ChanDir(dir) 997 } 998 999 func (t *rawType) ConvertibleTo(u Type) bool { 1000 panic("unimplemented: (reflect.Type).ConvertibleTo()") 1001 } 1002 1003 func (t *rawType) IsVariadic() bool { 1004 panic("unimplemented: (reflect.Type).IsVariadic()") 1005 } 1006 1007 func (t *rawType) NumIn() int { 1008 panic("unimplemented: (reflect.Type).NumIn()") 1009 } 1010 1011 func (t *rawType) NumOut() int { 1012 panic("unimplemented: (reflect.Type).NumOut()") 1013 } 1014 1015 func (t *rawType) NumMethod() int { 1016 1017 if t.isNamed() { 1018 return int((*namedType)(unsafe.Pointer(t)).numMethod) 1019 } 1020 1021 switch t.Kind() { 1022 case Pointer: 1023 return int((*ptrType)(unsafe.Pointer(t)).numMethod) 1024 case Struct: 1025 return int((*structType)(unsafe.Pointer(t)).numMethod) 1026 } 1027 1028 // Other types have no methods attached. Note we don't panic here. 1029 return 0 1030 } 1031 1032 // Read and return a null terminated string starting from data. 1033 func readStringZ(data unsafe.Pointer) string { 1034 start := data 1035 var len uintptr 1036 for *(*byte)(data) != 0 { 1037 len++ 1038 data = unsafe.Add(data, 1) // C: data++ 1039 } 1040 1041 return *(*string)(unsafe.Pointer(&stringHeader{ 1042 data: start, 1043 len: len, 1044 })) 1045 } 1046 1047 func (t *rawType) name() string { 1048 ntype := (*namedType)(unsafe.Pointer(t)) 1049 return readStringZ(unsafe.Pointer(&ntype.name[0])) 1050 } 1051 1052 func (t *rawType) Name() string { 1053 if t.isNamed() { 1054 name := t.name() 1055 for i := 0; i < len(name); i++ { 1056 if name[i] == '.' { 1057 return name[i+1:] 1058 } 1059 } 1060 panic("corrupt name data") 1061 } 1062 1063 if t.Kind() <= UnsafePointer { 1064 return t.Kind().String() 1065 } 1066 1067 return "" 1068 } 1069 1070 func (t *rawType) Key() Type { 1071 return t.key() 1072 } 1073 1074 func (t rawType) In(i int) Type { 1075 panic("unimplemented: (reflect.Type).In()") 1076 } 1077 1078 func (t rawType) Out(i int) Type { 1079 panic("unimplemented: (reflect.Type).Out()") 1080 } 1081 1082 func (t rawType) Method(i int) Method { 1083 panic("unimplemented: (reflect.Type).Method()") 1084 } 1085 1086 func (t rawType) MethodByName(name string) (Method, bool) { 1087 panic("unimplemented: (reflect.Type).MethodByName()") 1088 } 1089 1090 func (t *rawType) PkgPath() string { 1091 if t.isNamed() { 1092 ntype := (*namedType)(unsafe.Pointer(t)) 1093 return readStringZ(unsafe.Pointer(ntype.pkg)) 1094 } 1095 1096 return "" 1097 } 1098 1099 func (t *rawType) FieldByName(name string) (StructField, bool) { 1100 if t.Kind() != Struct { 1101 panic(errTypeFieldByName) 1102 } 1103 1104 field, index, ok := t.rawFieldByNameFunc(func(n string) bool { return n == name }) 1105 if !ok { 1106 return StructField{}, false 1107 } 1108 1109 return StructField{ 1110 Name: field.Name, 1111 PkgPath: field.PkgPath, 1112 Type: field.Type, // note: converts rawType to Type 1113 Tag: field.Tag, 1114 Anonymous: field.Anonymous, 1115 Offset: field.Offset, 1116 Index: index, 1117 }, true 1118 } 1119 1120 func (t *rawType) FieldByNameFunc(match func(string) bool) (StructField, bool) { 1121 if t.Kind() != Struct { 1122 panic(TypeError{"FieldByNameFunc"}) 1123 } 1124 1125 field, index, ok := t.rawFieldByNameFunc(match) 1126 if !ok { 1127 return StructField{}, false 1128 } 1129 1130 return StructField{ 1131 Name: field.Name, 1132 PkgPath: field.PkgPath, 1133 Type: field.Type, // note: converts rawType to Type 1134 Tag: field.Tag, 1135 Anonymous: field.Anonymous, 1136 Offset: field.Offset, 1137 Index: index, 1138 }, true 1139 } 1140 1141 func (t *rawType) FieldByIndex(index []int) StructField { 1142 ftype := t 1143 var field rawStructField 1144 1145 for _, n := range index { 1146 structOrPtrToStruct := ftype.Kind() == Struct || (ftype.Kind() == Pointer && ftype.elem().Kind() == Struct) 1147 if !structOrPtrToStruct { 1148 panic(errTypeFieldByIndex) 1149 } 1150 1151 if ftype.Kind() == Pointer { 1152 ftype = ftype.elem() 1153 } 1154 1155 field = ftype.rawField(n) 1156 ftype = field.Type 1157 } 1158 1159 return StructField{ 1160 Name: field.Name, 1161 PkgPath: field.PkgPath, 1162 Type: field.Type, // note: converts rawType to Type 1163 Tag: field.Tag, 1164 Anonymous: field.Anonymous, 1165 Offset: field.Offset, 1166 Index: index, 1167 } 1168 } 1169 1170 // A StructField describes a single field in a struct. 1171 type StructField struct { 1172 // Name indicates the field name. 1173 Name string 1174 1175 // PkgPath is the package path where the struct containing this field is 1176 // declared for unexported fields, or the empty string for exported fields. 1177 PkgPath string 1178 1179 Type Type 1180 Tag StructTag // field tag string 1181 Offset uintptr 1182 Index []int // index sequence for Type.FieldByIndex 1183 Anonymous bool 1184 } 1185 1186 // IsExported reports whether the field is exported. 1187 func (f StructField) IsExported() bool { 1188 return f.PkgPath == "" 1189 } 1190 1191 // rawStructField is the same as StructField but with the Type member replaced 1192 // with rawType. For internal use only. Avoiding this conversion to the Type 1193 // interface improves code size in many cases. 1194 type rawStructField struct { 1195 Name string 1196 PkgPath string 1197 Type *rawType 1198 Tag StructTag 1199 Offset uintptr 1200 Anonymous bool 1201 } 1202 1203 // A StructTag is the tag string in a struct field. 1204 type StructTag string 1205 1206 // TODO: it would be feasible to do the key/value splitting at compile time, 1207 // avoiding the code size cost of doing it at runtime 1208 1209 // Get returns the value associated with key in the tag string. 1210 func (tag StructTag) Get(key string) string { 1211 v, _ := tag.Lookup(key) 1212 return v 1213 } 1214 1215 // Lookup returns the value associated with key in the tag string. 1216 func (tag StructTag) Lookup(key string) (value string, ok bool) { 1217 for tag != "" { 1218 // Skip leading space. 1219 i := 0 1220 for i < len(tag) && tag[i] == ' ' { 1221 i++ 1222 } 1223 tag = tag[i:] 1224 if tag == "" { 1225 break 1226 } 1227 1228 // Scan to colon. A space, a quote or a control character is a syntax error. 1229 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just 1230 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters 1231 // as it is simpler to inspect the tag's bytes than the tag's runes. 1232 i = 0 1233 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { 1234 i++ 1235 } 1236 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 1237 break 1238 } 1239 name := string(tag[:i]) 1240 tag = tag[i+1:] 1241 1242 // Scan quoted string to find value. 1243 i = 1 1244 for i < len(tag) && tag[i] != '"' { 1245 if tag[i] == '\\' { 1246 i++ 1247 } 1248 i++ 1249 } 1250 if i >= len(tag) { 1251 break 1252 } 1253 qvalue := string(tag[:i+1]) 1254 tag = tag[i+1:] 1255 1256 if key == name { 1257 value, err := unquote(qvalue) 1258 if err != nil { 1259 break 1260 } 1261 return value, true 1262 } 1263 } 1264 return "", false 1265 } 1266 1267 // TypeError is the error that is used in a panic when invoking a method on a 1268 // type that is not applicable to that type. 1269 type TypeError struct { 1270 Method string 1271 } 1272 1273 func (e *TypeError) Error() string { 1274 return "reflect: call of reflect.Type." + e.Method + " on invalid type" 1275 } 1276 1277 func align(offset uintptr, alignment uintptr) uintptr { 1278 return (offset + alignment - 1) &^ (alignment - 1) 1279 } 1280 1281 func SliceOf(t Type) Type { 1282 panic("unimplemented: reflect.SliceOf()") 1283 } 1284 1285 func ArrayOf(n int, t Type) Type { 1286 panic("unimplemented: reflect.ArrayOf()") 1287 } 1288 1289 func StructOf([]StructField) Type { 1290 panic("unimplemented: reflect.StructOf()") 1291 } 1292 1293 func MapOf(key, value Type) Type { 1294 panic("unimplemented: reflect.MapOf()") 1295 } 1296 1297 func FuncOf(in, out []Type, variadic bool) Type { 1298 panic("unimplemented: reflect.FuncOf()") 1299 } 1300 1301 const maxVarintLen32 = 5 1302 1303 // encoding/binary.Uvarint, specialized for uint32 1304 func uvarint32(buf []byte) (uint32, int) { 1305 var x uint32 1306 var s uint 1307 for i, b := range buf { 1308 if b < 0x80 { 1309 return x | uint32(b)<<s, i + 1 1310 } 1311 x |= uint32(b&0x7f) << s 1312 s += 7 1313 } 1314 return 0, 0 1315 } 1316 1317 // TypeFor returns the [Type] that represents the type argument T. 1318 func TypeFor[T any]() Type { 1319 // This function was copied from the Go 1.22 source tree. 1320 return TypeOf((*T)(nil)).Elem() 1321 }