1 package reflect2
2
3 import (
4 "reflect"
5 "runtime"
6 "sync"
7 "unsafe"
8 )
9
10 type Type interface {
11 Kind() reflect.Kind
12
13 New() interface{}
14
15 UnsafeNew() unsafe.Pointer
16
17 PackEFace(ptr unsafe.Pointer) interface{}
18
19 Indirect(obj interface{}) interface{}
20
21 UnsafeIndirect(ptr unsafe.Pointer) interface{}
22
23 Type1() reflect.Type
24 Implements(thatType Type) bool
25 String() string
26 RType() uintptr
27
28 LikePtr() bool
29 IsNullable() bool
30 IsNil(obj interface{}) bool
31 UnsafeIsNil(ptr unsafe.Pointer) bool
32 Set(obj interface{}, val interface{})
33 UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
34 AssignableTo(anotherType Type) bool
35 }
36
37 type ListType interface {
38 Type
39 Elem() Type
40 SetIndex(obj interface{}, index int, elem interface{})
41 UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
42 GetIndex(obj interface{}, index int) interface{}
43 UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
44 }
45
46 type ArrayType interface {
47 ListType
48 Len() int
49 }
50
51 type SliceType interface {
52 ListType
53 MakeSlice(length int, cap int) interface{}
54 UnsafeMakeSlice(length int, cap int) unsafe.Pointer
55 Grow(obj interface{}, newLength int)
56 UnsafeGrow(ptr unsafe.Pointer, newLength int)
57 Append(obj interface{}, elem interface{})
58 UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
59 LengthOf(obj interface{}) int
60 UnsafeLengthOf(ptr unsafe.Pointer) int
61 SetNil(obj interface{})
62 UnsafeSetNil(ptr unsafe.Pointer)
63 Cap(obj interface{}) int
64 UnsafeCap(ptr unsafe.Pointer) int
65 }
66
67 type StructType interface {
68 Type
69 NumField() int
70 Field(i int) StructField
71 FieldByName(name string) StructField
72 FieldByIndex(index []int) StructField
73 FieldByNameFunc(match func(string) bool) StructField
74 }
75
76 type StructField interface {
77 Offset() uintptr
78 Name() string
79 PkgPath() string
80 Type() Type
81 Tag() reflect.StructTag
82 Index() []int
83 Anonymous() bool
84 Set(obj interface{}, value interface{})
85 UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
86 Get(obj interface{}) interface{}
87 UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
88 }
89
90 type MapType interface {
91 Type
92 Key() Type
93 Elem() Type
94 MakeMap(cap int) interface{}
95 UnsafeMakeMap(cap int) unsafe.Pointer
96 SetIndex(obj interface{}, key interface{}, elem interface{})
97 UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
98 TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
99 GetIndex(obj interface{}, key interface{}) interface{}
100 UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
101 Iterate(obj interface{}) MapIterator
102 UnsafeIterate(obj unsafe.Pointer) MapIterator
103 }
104
105 type MapIterator interface {
106 HasNext() bool
107 Next() (key interface{}, elem interface{})
108 UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
109 }
110
111 type PtrType interface {
112 Type
113 Elem() Type
114 }
115
116 type InterfaceType interface {
117 NumMethod() int
118 }
119
120 type Config struct {
121 UseSafeImplementation bool
122 }
123
124 type API interface {
125 TypeOf(obj interface{}) Type
126 Type2(type1 reflect.Type) Type
127 }
128
129 var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
130 var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
131
132 type frozenConfig struct {
133 useSafeImplementation bool
134 cache *sync.Map
135 }
136
137 func (cfg Config) Froze() *frozenConfig {
138 return &frozenConfig{
139 useSafeImplementation: cfg.UseSafeImplementation,
140 cache: new(sync.Map),
141 }
142 }
143
144 func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
145 cacheKey := uintptr(unpackEFace(obj).rtype)
146 typeObj, found := cfg.cache.Load(cacheKey)
147 if found {
148 return typeObj.(Type)
149 }
150 return cfg.Type2(reflect.TypeOf(obj))
151 }
152
153 func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
154 if type1 == nil {
155 return nil
156 }
157 cacheKey := uintptr(unpackEFace(type1).data)
158 typeObj, found := cfg.cache.Load(cacheKey)
159 if found {
160 return typeObj.(Type)
161 }
162 type2 := cfg.wrapType(type1)
163 cfg.cache.Store(cacheKey, type2)
164 return type2
165 }
166
167 func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
168 safeType := safeType{Type: type1, cfg: cfg}
169 switch type1.Kind() {
170 case reflect.Struct:
171 if cfg.useSafeImplementation {
172 return &safeStructType{safeType}
173 }
174 return newUnsafeStructType(cfg, type1)
175 case reflect.Array:
176 if cfg.useSafeImplementation {
177 return &safeSliceType{safeType}
178 }
179 return newUnsafeArrayType(cfg, type1)
180 case reflect.Slice:
181 if cfg.useSafeImplementation {
182 return &safeSliceType{safeType}
183 }
184 return newUnsafeSliceType(cfg, type1)
185 case reflect.Map:
186 if cfg.useSafeImplementation {
187 return &safeMapType{safeType}
188 }
189 return newUnsafeMapType(cfg, type1)
190 case reflect.Ptr, reflect.Chan, reflect.Func:
191 if cfg.useSafeImplementation {
192 return &safeMapType{safeType}
193 }
194 return newUnsafePtrType(cfg, type1)
195 case reflect.Interface:
196 if cfg.useSafeImplementation {
197 return &safeMapType{safeType}
198 }
199 if type1.NumMethod() == 0 {
200 return newUnsafeEFaceType(cfg, type1)
201 }
202 return newUnsafeIFaceType(cfg, type1)
203 default:
204 if cfg.useSafeImplementation {
205 return &safeType
206 }
207 return newUnsafeType(cfg, type1)
208 }
209 }
210
211 func TypeOf(obj interface{}) Type {
212 return ConfigUnsafe.TypeOf(obj)
213 }
214
215 func TypeOfPtr(obj interface{}) PtrType {
216 return TypeOf(obj).(PtrType)
217 }
218
219 func Type2(type1 reflect.Type) Type {
220 if type1 == nil {
221 return nil
222 }
223 return ConfigUnsafe.Type2(type1)
224 }
225
226 func PtrTo(typ Type) Type {
227 return Type2(reflect.PtrTo(typ.Type1()))
228 }
229
230 func PtrOf(obj interface{}) unsafe.Pointer {
231 return unpackEFace(obj).data
232 }
233
234 func RTypeOf(obj interface{}) uintptr {
235 return uintptr(unpackEFace(obj).rtype)
236 }
237
238 func IsNil(obj interface{}) bool {
239 if obj == nil {
240 return true
241 }
242 return unpackEFace(obj).data == nil
243 }
244
245 func IsNullable(kind reflect.Kind) bool {
246 switch kind {
247 case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
248 return true
249 }
250 return false
251 }
252
253 func likePtrKind(kind reflect.Kind) bool {
254 switch kind {
255 case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
256 return true
257 }
258 return false
259 }
260
261 func likePtrType(typ reflect.Type) bool {
262 if likePtrKind(typ.Kind()) {
263 return true
264 }
265 if typ.Kind() == reflect.Struct {
266 if typ.NumField() != 1 {
267 return false
268 }
269 return likePtrType(typ.Field(0).Type)
270 }
271 if typ.Kind() == reflect.Array {
272 if typ.Len() != 1 {
273 return false
274 }
275 return likePtrType(typ.Elem())
276 }
277 return false
278 }
279
280
281
282
283
284
285
286 func NoEscape(p unsafe.Pointer) unsafe.Pointer {
287 x := uintptr(p)
288 return unsafe.Pointer(x ^ 0)
289 }
290
291 func UnsafeCastString(str string) []byte {
292 bytes := make([]byte, 0)
293 stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
294 sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
295 sliceHeader.Data = stringHeader.Data
296 sliceHeader.Cap = stringHeader.Len
297 sliceHeader.Len = stringHeader.Len
298 runtime.KeepAlive(str)
299 return bytes
300 }
301
View as plain text