1
2
3
4
5
6
7 package reflectlite
8
9 import (
10 "internal/unsafeheader"
11 "unsafe"
12 )
13
14
15
16
17
18
19
20
21
22
23
24
25 type Type interface {
26
27
28
29
30 Name() string
31
32
33
34
35
36
37 PkgPath() string
38
39
40
41 Size() uintptr
42
43
44 Kind() Kind
45
46
47 Implements(u Type) bool
48
49
50 AssignableTo(u Type) bool
51
52
53 Comparable() bool
54
55
56
57
58
59
60 String() string
61
62
63
64 Elem() Type
65
66 common() *rtype
67 uncommon() *uncommonType
68 }
69
70
75
76
77
78 type Kind uint
79
80 const (
81 Invalid Kind = iota
82 Bool
83 Int
84 Int8
85 Int16
86 Int32
87 Int64
88 Uint
89 Uint8
90 Uint16
91 Uint32
92 Uint64
93 Uintptr
94 Float32
95 Float64
96 Complex64
97 Complex128
98 Array
99 Chan
100 Func
101 Interface
102 Map
103 Ptr
104 Slice
105 String
106 Struct
107 UnsafePointer
108 )
109
110
111
112
113
114
115
116
117 type tflag uint8
118
119 const (
120
121
122
123
124
125
126
127
128
129
130
131 tflagUncommon tflag = 1 << 0
132
133
134
135
136
137 tflagExtraStar tflag = 1 << 1
138
139
140 tflagNamed tflag = 1 << 2
141
142
143
144 tflagRegularMemory tflag = 1 << 3
145 )
146
147
148
149
150
151 type rtype struct {
152 size uintptr
153 ptrdata uintptr
154 hash uint32
155 tflag tflag
156 align uint8
157 fieldAlign uint8
158 kind uint8
159
160
161 equal func(unsafe.Pointer, unsafe.Pointer) bool
162 gcdata *byte
163 str nameOff
164 ptrToThis typeOff
165 }
166
167
168 type method struct {
169 name nameOff
170 mtyp typeOff
171 ifn textOff
172 tfn textOff
173 }
174
175
176
177
178
179 type uncommonType struct {
180 pkgPath nameOff
181 mcount uint16
182 xcount uint16
183 moff uint32
184 _ uint32
185 }
186
187
188 type chanDir int
189
190 const (
191 recvDir chanDir = 1 << iota
192 sendDir
193 bothDir = recvDir | sendDir
194 )
195
196
197 type arrayType struct {
198 rtype
199 elem *rtype
200 slice *rtype
201 len uintptr
202 }
203
204
205 type chanType struct {
206 rtype
207 elem *rtype
208 dir uintptr
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222 type funcType struct {
223 rtype
224 inCount uint16
225 outCount uint16
226 }
227
228
229 type imethod struct {
230 name nameOff
231 typ typeOff
232 }
233
234
235 type interfaceType struct {
236 rtype
237 pkgPath name
238 methods []imethod
239 }
240
241
242 type mapType struct {
243 rtype
244 key *rtype
245 elem *rtype
246 bucket *rtype
247
248 hasher func(unsafe.Pointer, uintptr) uintptr
249 keysize uint8
250 valuesize uint8
251 bucketsize uint16
252 flags uint32
253 }
254
255
256 type ptrType struct {
257 rtype
258 elem *rtype
259 }
260
261
262 type sliceType struct {
263 rtype
264 elem *rtype
265 }
266
267
268 type structField struct {
269 name name
270 typ *rtype
271 offsetEmbed uintptr
272 }
273
274 func (f *structField) offset() uintptr {
275 return f.offsetEmbed >> 1
276 }
277
278 func (f *structField) embedded() bool {
279 return f.offsetEmbed&1 != 0
280 }
281
282
283 type structType struct {
284 rtype
285 pkgPath name
286 fields []structField
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 type name struct {
313 bytes *byte
314 }
315
316 func (n name) data(off int, whySafe string) *byte {
317 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
318 }
319
320 func (n name) isExported() bool {
321 return (*n.bytes)&(1<<0) != 0
322 }
323
324 func (n name) hasTag() bool {
325 return (*n.bytes)&(1<<1) != 0
326 }
327
328
329
330 func (n name) readVarint(off int) (int, int) {
331 v := 0
332 for i := 0; ; i++ {
333 x := *n.data(off+i, "read varint")
334 v += int(x&0x7f) << (7 * i)
335 if x&0x80 == 0 {
336 return i + 1, v
337 }
338 }
339 }
340
341 func (n name) name() (s string) {
342 if n.bytes == nil {
343 return
344 }
345 i, l := n.readVarint(1)
346 hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
347 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
348 hdr.Len = l
349 return
350 }
351
352 func (n name) tag() (s string) {
353 if !n.hasTag() {
354 return ""
355 }
356 i, l := n.readVarint(1)
357 i2, l2 := n.readVarint(1 + i + l)
358 hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
359 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
360 hdr.Len = l2
361 return
362 }
363
364 func (n name) pkgPath() string {
365 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
366 return ""
367 }
368 i, l := n.readVarint(1)
369 off := 1 + i + l
370 if n.hasTag() {
371 i2, l2 := n.readVarint(off)
372 off += i2 + l2
373 }
374 var nameOff int32
375
376
377 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
378 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
379 return pkgPathName.name()
380 }
381
382
386
387 const (
388 kindDirectIface = 1 << 5
389 kindGCProg = 1 << 6
390 kindMask = (1 << 5) - 1
391 )
392
393
394 func (k Kind) String() string {
395 if int(k) < len(kindNames) {
396 return kindNames[k]
397 }
398 return kindNames[0]
399 }
400
401 var kindNames = []string{
402 Invalid: "invalid",
403 Bool: "bool",
404 Int: "int",
405 Int8: "int8",
406 Int16: "int16",
407 Int32: "int32",
408 Int64: "int64",
409 Uint: "uint",
410 Uint8: "uint8",
411 Uint16: "uint16",
412 Uint32: "uint32",
413 Uint64: "uint64",
414 Uintptr: "uintptr",
415 Float32: "float32",
416 Float64: "float64",
417 Complex64: "complex64",
418 Complex128: "complex128",
419 Array: "array",
420 Chan: "chan",
421 Func: "func",
422 Interface: "interface",
423 Map: "map",
424 Ptr: "ptr",
425 Slice: "slice",
426 String: "string",
427 Struct: "struct",
428 UnsafePointer: "unsafe.Pointer",
429 }
430
431 func (t *uncommonType) methods() []method {
432 if t.mcount == 0 {
433 return nil
434 }
435 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
436 }
437
438 func (t *uncommonType) exportedMethods() []method {
439 if t.xcount == 0 {
440 return nil
441 }
442 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
443 }
444
445
446
447
448 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
449
450
451
452
453 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
454
455 type nameOff int32
456 type typeOff int32
457 type textOff int32
458
459 func (t *rtype) nameOff(off nameOff) name {
460 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
461 }
462
463 func (t *rtype) typeOff(off typeOff) *rtype {
464 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
465 }
466
467 func (t *rtype) uncommon() *uncommonType {
468 if t.tflag&tflagUncommon == 0 {
469 return nil
470 }
471 switch t.Kind() {
472 case Struct:
473 return &(*structTypeUncommon)(unsafe.Pointer(t)).u
474 case Ptr:
475 type u struct {
476 ptrType
477 u uncommonType
478 }
479 return &(*u)(unsafe.Pointer(t)).u
480 case Func:
481 type u struct {
482 funcType
483 u uncommonType
484 }
485 return &(*u)(unsafe.Pointer(t)).u
486 case Slice:
487 type u struct {
488 sliceType
489 u uncommonType
490 }
491 return &(*u)(unsafe.Pointer(t)).u
492 case Array:
493 type u struct {
494 arrayType
495 u uncommonType
496 }
497 return &(*u)(unsafe.Pointer(t)).u
498 case Chan:
499 type u struct {
500 chanType
501 u uncommonType
502 }
503 return &(*u)(unsafe.Pointer(t)).u
504 case Map:
505 type u struct {
506 mapType
507 u uncommonType
508 }
509 return &(*u)(unsafe.Pointer(t)).u
510 case Interface:
511 type u struct {
512 interfaceType
513 u uncommonType
514 }
515 return &(*u)(unsafe.Pointer(t)).u
516 default:
517 type u struct {
518 rtype
519 u uncommonType
520 }
521 return &(*u)(unsafe.Pointer(t)).u
522 }
523 }
524
525 func (t *rtype) String() string {
526 s := t.nameOff(t.str).name()
527 if t.tflag&tflagExtraStar != 0 {
528 return s[1:]
529 }
530 return s
531 }
532
533 func (t *rtype) Size() uintptr { return t.size }
534
535 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
536
537 func (t *rtype) pointers() bool { return t.ptrdata != 0 }
538
539 func (t *rtype) common() *rtype { return t }
540
541 func (t *rtype) exportedMethods() []method {
542 ut := t.uncommon()
543 if ut == nil {
544 return nil
545 }
546 return ut.exportedMethods()
547 }
548
549 func (t *rtype) NumMethod() int {
550 if t.Kind() == Interface {
551 tt := (*interfaceType)(unsafe.Pointer(t))
552 return tt.NumMethod()
553 }
554 return len(t.exportedMethods())
555 }
556
557 func (t *rtype) PkgPath() string {
558 if t.tflag&tflagNamed == 0 {
559 return ""
560 }
561 ut := t.uncommon()
562 if ut == nil {
563 return ""
564 }
565 return t.nameOff(ut.pkgPath).name()
566 }
567
568 func (t *rtype) hasName() bool {
569 return t.tflag&tflagNamed != 0
570 }
571
572 func (t *rtype) Name() string {
573 if !t.hasName() {
574 return ""
575 }
576 s := t.String()
577 i := len(s) - 1
578 for i >= 0 && s[i] != '.' {
579 i--
580 }
581 return s[i+1:]
582 }
583
584 func (t *rtype) chanDir() chanDir {
585 if t.Kind() != Chan {
586 panic("reflect: chanDir of non-chan type")
587 }
588 tt := (*chanType)(unsafe.Pointer(t))
589 return chanDir(tt.dir)
590 }
591
592 func (t *rtype) Elem() Type {
593 switch t.Kind() {
594 case Array:
595 tt := (*arrayType)(unsafe.Pointer(t))
596 return toType(tt.elem)
597 case Chan:
598 tt := (*chanType)(unsafe.Pointer(t))
599 return toType(tt.elem)
600 case Map:
601 tt := (*mapType)(unsafe.Pointer(t))
602 return toType(tt.elem)
603 case Ptr:
604 tt := (*ptrType)(unsafe.Pointer(t))
605 return toType(tt.elem)
606 case Slice:
607 tt := (*sliceType)(unsafe.Pointer(t))
608 return toType(tt.elem)
609 }
610 panic("reflect: Elem of invalid type")
611 }
612
613 func (t *rtype) In(i int) Type {
614 if t.Kind() != Func {
615 panic("reflect: In of non-func type")
616 }
617 tt := (*funcType)(unsafe.Pointer(t))
618 return toType(tt.in()[i])
619 }
620
621 func (t *rtype) Key() Type {
622 if t.Kind() != Map {
623 panic("reflect: Key of non-map type")
624 }
625 tt := (*mapType)(unsafe.Pointer(t))
626 return toType(tt.key)
627 }
628
629 func (t *rtype) Len() int {
630 if t.Kind() != Array {
631 panic("reflect: Len of non-array type")
632 }
633 tt := (*arrayType)(unsafe.Pointer(t))
634 return int(tt.len)
635 }
636
637 func (t *rtype) NumField() int {
638 if t.Kind() != Struct {
639 panic("reflect: NumField of non-struct type")
640 }
641 tt := (*structType)(unsafe.Pointer(t))
642 return len(tt.fields)
643 }
644
645 func (t *rtype) NumIn() int {
646 if t.Kind() != Func {
647 panic("reflect: NumIn of non-func type")
648 }
649 tt := (*funcType)(unsafe.Pointer(t))
650 return int(tt.inCount)
651 }
652
653 func (t *rtype) NumOut() int {
654 if t.Kind() != Func {
655 panic("reflect: NumOut of non-func type")
656 }
657 tt := (*funcType)(unsafe.Pointer(t))
658 return len(tt.out())
659 }
660
661 func (t *rtype) Out(i int) Type {
662 if t.Kind() != Func {
663 panic("reflect: Out of non-func type")
664 }
665 tt := (*funcType)(unsafe.Pointer(t))
666 return toType(tt.out()[i])
667 }
668
669 func (t *funcType) in() []*rtype {
670 uadd := unsafe.Sizeof(*t)
671 if t.tflag&tflagUncommon != 0 {
672 uadd += unsafe.Sizeof(uncommonType{})
673 }
674 if t.inCount == 0 {
675 return nil
676 }
677 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
678 }
679
680 func (t *funcType) out() []*rtype {
681 uadd := unsafe.Sizeof(*t)
682 if t.tflag&tflagUncommon != 0 {
683 uadd += unsafe.Sizeof(uncommonType{})
684 }
685 outCount := t.outCount & (1<<15 - 1)
686 if outCount == 0 {
687 return nil
688 }
689 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
690 }
691
692
693
694
695
696
697
698
699 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
700 return unsafe.Pointer(uintptr(p) + x)
701 }
702
703
704 func (t *interfaceType) NumMethod() int { return len(t.methods) }
705
706
707
708 func TypeOf(i interface{}) Type {
709 eface := *(*emptyInterface)(unsafe.Pointer(&i))
710 return toType(eface.typ)
711 }
712
713 func (t *rtype) Implements(u Type) bool {
714 if u == nil {
715 panic("reflect: nil type passed to Type.Implements")
716 }
717 if u.Kind() != Interface {
718 panic("reflect: non-interface type passed to Type.Implements")
719 }
720 return implements(u.(*rtype), t)
721 }
722
723 func (t *rtype) AssignableTo(u Type) bool {
724 if u == nil {
725 panic("reflect: nil type passed to Type.AssignableTo")
726 }
727 uu := u.(*rtype)
728 return directlyAssignable(uu, t) || implements(uu, t)
729 }
730
731 func (t *rtype) Comparable() bool {
732 return t.equal != nil
733 }
734
735
736 func implements(T, V *rtype) bool {
737 if T.Kind() != Interface {
738 return false
739 }
740 t := (*interfaceType)(unsafe.Pointer(T))
741 if len(t.methods) == 0 {
742 return true
743 }
744
745
746
747
748
749
750
751
752
753
754
755
756
757 if V.Kind() == Interface {
758 v := (*interfaceType)(unsafe.Pointer(V))
759 i := 0
760 for j := 0; j < len(v.methods); j++ {
761 tm := &t.methods[i]
762 tmName := t.nameOff(tm.name)
763 vm := &v.methods[j]
764 vmName := V.nameOff(vm.name)
765 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
766 if !tmName.isExported() {
767 tmPkgPath := tmName.pkgPath()
768 if tmPkgPath == "" {
769 tmPkgPath = t.pkgPath.name()
770 }
771 vmPkgPath := vmName.pkgPath()
772 if vmPkgPath == "" {
773 vmPkgPath = v.pkgPath.name()
774 }
775 if tmPkgPath != vmPkgPath {
776 continue
777 }
778 }
779 if i++; i >= len(t.methods) {
780 return true
781 }
782 }
783 }
784 return false
785 }
786
787 v := V.uncommon()
788 if v == nil {
789 return false
790 }
791 i := 0
792 vmethods := v.methods()
793 for j := 0; j < int(v.mcount); j++ {
794 tm := &t.methods[i]
795 tmName := t.nameOff(tm.name)
796 vm := vmethods[j]
797 vmName := V.nameOff(vm.name)
798 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
799 if !tmName.isExported() {
800 tmPkgPath := tmName.pkgPath()
801 if tmPkgPath == "" {
802 tmPkgPath = t.pkgPath.name()
803 }
804 vmPkgPath := vmName.pkgPath()
805 if vmPkgPath == "" {
806 vmPkgPath = V.nameOff(v.pkgPath).name()
807 }
808 if tmPkgPath != vmPkgPath {
809 continue
810 }
811 }
812 if i++; i >= len(t.methods) {
813 return true
814 }
815 }
816 }
817 return false
818 }
819
820
821
822
823
824
825 func directlyAssignable(T, V *rtype) bool {
826
827 if T == V {
828 return true
829 }
830
831
832
833 if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
834 return false
835 }
836
837
838 return haveIdenticalUnderlyingType(T, V, true)
839 }
840
841 func haveIdenticalType(T, V Type, cmpTags bool) bool {
842 if cmpTags {
843 return T == V
844 }
845
846 if T.Name() != V.Name() || T.Kind() != V.Kind() {
847 return false
848 }
849
850 return haveIdenticalUnderlyingType(T.common(), V.common(), false)
851 }
852
853 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
854 if T == V {
855 return true
856 }
857
858 kind := T.Kind()
859 if kind != V.Kind() {
860 return false
861 }
862
863
864
865 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
866 return true
867 }
868
869
870 switch kind {
871 case Array:
872 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
873
874 case Chan:
875
876
877
878 if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
879 return true
880 }
881
882
883 return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
884
885 case Func:
886 t := (*funcType)(unsafe.Pointer(T))
887 v := (*funcType)(unsafe.Pointer(V))
888 if t.outCount != v.outCount || t.inCount != v.inCount {
889 return false
890 }
891 for i := 0; i < t.NumIn(); i++ {
892 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
893 return false
894 }
895 }
896 for i := 0; i < t.NumOut(); i++ {
897 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
898 return false
899 }
900 }
901 return true
902
903 case Interface:
904 t := (*interfaceType)(unsafe.Pointer(T))
905 v := (*interfaceType)(unsafe.Pointer(V))
906 if len(t.methods) == 0 && len(v.methods) == 0 {
907 return true
908 }
909
910
911 return false
912
913 case Map:
914 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
915
916 case Ptr, Slice:
917 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
918
919 case Struct:
920 t := (*structType)(unsafe.Pointer(T))
921 v := (*structType)(unsafe.Pointer(V))
922 if len(t.fields) != len(v.fields) {
923 return false
924 }
925 if t.pkgPath.name() != v.pkgPath.name() {
926 return false
927 }
928 for i := range t.fields {
929 tf := &t.fields[i]
930 vf := &v.fields[i]
931 if tf.name.name() != vf.name.name() {
932 return false
933 }
934 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
935 return false
936 }
937 if cmpTags && tf.name.tag() != vf.name.tag() {
938 return false
939 }
940 if tf.offsetEmbed != vf.offsetEmbed {
941 return false
942 }
943 }
944 return true
945 }
946
947 return false
948 }
949
950 type structTypeUncommon struct {
951 structType
952 u uncommonType
953 }
954
955
956
957
958
959
960 func toType(t *rtype) Type {
961 if t == nil {
962 return nil
963 }
964 return t
965 }
966
967
968 func ifaceIndir(t *rtype) bool {
969 return t.kind&kindDirectIface == 0
970 }
971
View as plain text