github.com/wfusion/gofusion@v1.1.14/common/utils/gomonkey/creflect/type.go (about) 1 // Customized reflect package for gomonkey,copy most code from go/src/reflect/type.go 2 3 package creflect 4 5 import ( 6 "reflect" 7 "unsafe" 8 ) 9 10 // rtype is the common implementation of most values. 11 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 12 type rtype struct { 13 size uintptr 14 ptrdata uintptr // number of bytes in the type that can contain pointers 15 hash uint32 // hash of type; avoids computation in hash tables 16 tflag tflag // extra type information flags 17 align uint8 // alignment of variable with this type 18 fieldAlign uint8 // alignment of struct field with this type 19 kind uint8 // enumeration for C 20 // function for comparing objects of this type 21 // (ptr to object A, ptr to object B) -> ==? 22 equal func(unsafe.Pointer, unsafe.Pointer) bool 23 gcdata *byte // garbage collection data 24 str nameOff // string form 25 ptrToThis typeOff // type for pointer to this type, may be zero 26 } 27 28 func Create(t reflect.Type) *rtype { 29 i := *(*funcValue)(unsafe.Pointer(&t)) 30 r := (*rtype)(i.p) 31 return r 32 } 33 34 type funcValue struct { 35 _ uintptr 36 p unsafe.Pointer 37 } 38 39 func funcPointer(v reflect.Method, ok bool) (unsafe.Pointer, bool) { 40 return (*funcValue)(unsafe.Pointer(&v.Func)).p, ok 41 } 42 func MethodByName(r reflect.Type, name string) (fn unsafe.Pointer, ok bool) { 43 t := Create(r) 44 if r.Kind() == reflect.Interface { 45 return funcPointer(r.MethodByName(name)) 46 } 47 ut := t.uncommon(r) 48 if ut == nil { 49 return nil, false 50 } 51 52 for _, p := range ut.methods() { 53 if t.nameOff(p.name).name() == name { 54 return t.Method(p), true 55 } 56 } 57 return nil, false 58 } 59 60 func (t *rtype) Method(p method) (fn unsafe.Pointer) { 61 tfn := t.textOff(p.tfn) 62 fn = unsafe.Pointer(&tfn) 63 return 64 } 65 66 type tflag uint8 67 type nameOff int32 // offset to a name 68 type typeOff int32 // offset to an *rtype 69 type textOff int32 // offset from top of text section 70 71 //go:linkname resolveTextOff reflect.resolveTextOff 72 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 73 74 func (t *rtype) textOff(off textOff) unsafe.Pointer { 75 return resolveTextOff(unsafe.Pointer(t), int32(off)) 76 } 77 78 //go:linkname resolveNameOff reflect.resolveNameOff 79 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 80 81 func (t *rtype) nameOff(off nameOff) name { 82 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 83 } 84 85 const ( 86 tflagUncommon tflag = 1 << 0 87 ) 88 89 // uncommonType is present only for defined types or types with methods 90 type uncommonType struct { 91 pkgPath nameOff // import path; empty for built-in types like int, string 92 mcount uint16 // number of methods 93 xcount uint16 // number of exported methods 94 moff uint32 // offset from this uncommontype to [mcount]method 95 _ uint32 // unused 96 } 97 98 // ptrType represents a pointer type. 99 type ptrType struct { 100 rtype 101 elem *rtype // pointer element (pointed at) type 102 } 103 104 // funcType represents a function type. 105 type funcType struct { 106 rtype 107 inCount uint16 108 outCount uint16 // top bit is set if last input parameter is ... 109 } 110 111 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 112 return unsafe.Pointer(uintptr(p) + x) 113 } 114 115 // interfaceType represents an interface type. 116 type interfaceType struct { 117 rtype 118 pkgPath name // import path 119 methods []imethod // sorted by hash 120 } 121 122 type imethod struct { 123 name nameOff // name of method 124 typ typeOff // .(*FuncType) underneath 125 } 126 127 type String struct { 128 Data unsafe.Pointer 129 Len int 130 } 131 132 func (t *rtype) uncommon(r reflect.Type) *uncommonType { 133 if t.tflag&tflagUncommon == 0 { 134 return nil 135 } 136 switch r.Kind() { 137 case reflect.Ptr: 138 type u struct { 139 ptrType 140 u uncommonType 141 } 142 return &(*u)(unsafe.Pointer(t)).u 143 case reflect.Func: 144 type u struct { 145 funcType 146 u uncommonType 147 } 148 return &(*u)(unsafe.Pointer(t)).u 149 case reflect.Interface: 150 type u struct { 151 interfaceType 152 u uncommonType 153 } 154 return &(*u)(unsafe.Pointer(t)).u 155 case reflect.Struct: 156 type u struct { 157 interfaceType 158 u uncommonType 159 } 160 return &(*u)(unsafe.Pointer(t)).u 161 default: 162 return nil 163 } 164 } 165 166 // Method on non-interface type 167 type method struct { 168 name nameOff // name of method 169 mtyp typeOff // method type (without receiver) 170 ifn textOff // fn used in interface call (one-word receiver) 171 tfn textOff // fn used for normal method call 172 } 173 174 func (t *uncommonType) methods() []method { 175 if t.mcount == 0 { 176 return nil 177 } 178 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 179 }