typeinfo.mx raw
1 package json
2
3 import "unsafe"
4
5 type jKind uint8
6
7 const (
8 jkInvalid jKind = iota
9 jkBool
10 jkInt
11 jkInt8
12 jkInt16
13 jkInt32
14 jkInt64
15 jkUint
16 jkUint8
17 jkUint16
18 jkUint32
19 jkUint64
20 jkUintptr
21 jkFloat32
22 jkFloat64
23 jkComplex64
24 jkComplex128
25 jkBytes // 17: unified string=[]byte
26 jkUnsafePointer
27 jkChan
28 jkInterface
29 jkPointer
30 jkSlice
31 jkArray
32 jkFunc
33 jkMap
34 jkStruct
35 )
36
37 const (
38 _kindMask = 31
39 _flagNamed = 32
40 )
41
42 const (
43 _sfAnonymous = 1 << iota
44 _sfHasTag
45 _sfExported
46 )
47
48 type _ifacePair struct {
49 typecode unsafe.Pointer
50 value unsafe.Pointer
51 }
52
53 type _rawType struct {
54 meta uint8
55 }
56
57 type _elemType struct {
58 _rawType
59 numMethod uint16
60 ptrTo *_rawType
61 elem *_rawType
62 }
63
64 type _ptrType struct {
65 _rawType
66 numMethod uint16
67 elem *_rawType
68 }
69
70 type _structType struct {
71 _rawType
72 numMethod uint16
73 ptrTo *_rawType
74 pkgpath *byte
75 size uint32
76 numField uint16
77 fields [1]_structFieldDesc
78 }
79
80 type _structFieldDesc struct {
81 fieldType *_rawType
82 data unsafe.Pointer
83 }
84
85 type _sliceHeader struct {
86 data unsafe.Pointer
87 len int
88 cap int
89 }
90
91 func (t *_rawType) kind() jKind {
92 if t == nil {
93 return jkInvalid
94 }
95 if uintptr(unsafe.Pointer(t))&0b11 != 0 {
96 return jkPointer
97 }
98 return jKind(t.meta & _kindMask)
99 }
100
101 func (t *_rawType) isNamed() bool {
102 if uintptr(unsafe.Pointer(t))&0b11 != 0 {
103 return false
104 }
105 return t.meta&_flagNamed != 0
106 }
107
108 func (t *_rawType) underlying() *_rawType {
109 if t.isNamed() {
110 return (*_elemType)(unsafe.Pointer(t)).elem
111 }
112 return t
113 }
114
115 func (t *_rawType) size() uintptr {
116 switch t.kind() {
117 case jkBool, jkInt8, jkUint8:
118 return 1
119 case jkInt16, jkUint16:
120 return 2
121 case jkInt32, jkUint32, jkFloat32:
122 return 4
123 case jkInt64, jkUint64, jkFloat64:
124 return 8
125 case jkInt, jkUint:
126 return unsafe.Sizeof(int(0))
127 case jkUintptr:
128 return unsafe.Sizeof(uintptr(0))
129 case jkBytes:
130 return unsafe.Sizeof("")
131 case jkUnsafePointer, jkChan, jkMap, jkPointer:
132 return unsafe.Sizeof(uintptr(0))
133 case jkSlice:
134 return unsafe.Sizeof([]int{})
135 case jkInterface:
136 return unsafe.Sizeof(interface{}(nil))
137 case jkStruct:
138 return uintptr((*_structType)(unsafe.Pointer(t.underlying())).size)
139 default:
140 return 0
141 }
142 }
143
144 func (t *_rawType) elem() *_rawType {
145 if tag := uintptr(unsafe.Pointer(t)) & 0b11; tag != 0 {
146 return (*_rawType)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - 1))
147 }
148 u := t.underlying()
149 if u.kind() == jkPointer {
150 return (*_ptrType)(unsafe.Pointer(u)).elem
151 }
152 return (*_elemType)(unsafe.Pointer(u)).elem
153 }
154
155 func (t *_rawType) numField() int {
156 return int((*_structType)(unsafe.Pointer(t.underlying())).numField)
157 }
158
159 func (t *_rawType) fieldDesc(i int) *_structFieldDesc {
160 st := (*_structType)(unsafe.Pointer(t.underlying()))
161 return (*_structFieldDesc)(unsafe.Add(
162 unsafe.Pointer(&st.fields[0]),
163 uintptr(i)*unsafe.Sizeof(_structFieldDesc{}),
164 ))
165 }
166
167 func (t *_rawType) fieldType(i int) *_rawType {
168 return t.fieldDesc(i).fieldType
169 }
170
171 func (t *_rawType) fieldData(i int) (flags uint8, offset uintptr, name []byte, tag []byte) {
172 fd := t.fieldDesc(i)
173 p := (*byte)(fd.data)
174
175 flags = *p
176 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
177
178 var shift uint
179 for {
180 b := *p
181 offset |= uintptr(b&0x7f) << shift
182 if b&0x80 == 0 {
183 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
184 break
185 }
186 shift += 7
187 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
188 }
189
190 nameStart := unsafe.Pointer(p)
191 nameLen := 0
192 for *p != 0 {
193 nameLen++
194 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
195 }
196 name = unsafe.Slice((*byte)(nameStart), nameLen)
197 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
198
199 if flags&_sfHasTag != 0 {
200 tagLen := int(*p)
201 p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
202 tag = unsafe.Slice((*byte)(unsafe.Pointer(p)), tagLen)
203 }
204 return
205 }
206
207 func (t *_rawType) fieldOffset(i int) uintptr {
208 _, off, _, _ := t.fieldData(i)
209 return off
210 }
211
212 func (t *_rawType) fieldTag(i int) []byte {
213 _, _, _, tag := t.fieldData(i)
214 return tag
215 }
216
217 func (t *_rawType) fieldExported(i int) bool {
218 flags, _, _, _ := t.fieldData(i)
219 return flags&_sfExported != 0
220 }
221
222 func (t *_rawType) fieldName(i int) []byte {
223 _, _, name, _ := t.fieldData(i)
224 return name
225 }
226
227 func (t *_rawType) typeName() []byte {
228 if !t.isNamed() {
229 return nil
230 }
231 type _namedType struct {
232 _rawType
233 numMethod uint16
234 ptrTo *_rawType
235 elem *_rawType
236 pkg *byte
237 name [1]byte
238 }
239 nt := (*_namedType)(unsafe.Pointer(t))
240 p := &nt.name[0]
241 n := 0
242 for *(*byte)(unsafe.Add(unsafe.Pointer(p), uintptr(n))) != 0 {
243 n++
244 }
245 return unsafe.Slice(p, n)
246 }
247
248 func typeCodeOf(val any) *_rawType {
249 return (*_rawType)((*_ifacePair)(unsafe.Pointer(&val)).typecode)
250 }
251
252 func dataOf(val any) unsafe.Pointer {
253 iface := (*_ifacePair)(unsafe.Pointer(&val))
254 t := (*_rawType)(iface.typecode)
255 if t.size() <= unsafe.Sizeof(uintptr(0)) {
256 return unsafe.Pointer(&iface.value)
257 }
258 return iface.value
259 }
260
261 func derefPtr(val any) (*_rawType, unsafe.Pointer) {
262 iface := (*_ifacePair)(unsafe.Pointer(&val))
263 t := (*_rawType)(iface.typecode)
264 if t.kind() != jkPointer {
265 return nil, nil
266 }
267 elemType := t.elem()
268 dataPtr := iface.value
269 return elemType, dataPtr
270 }
271
272 func ptrToIface(t *_rawType, ptr unsafe.Pointer) any {
273 var ptrType *_rawType
274 if t.isNamed() {
275 ptrType = (*_elemType)(unsafe.Pointer(t)).ptrTo
276 } else {
277 switch t.kind() {
278 case jkStruct:
279 ptrType = (*_structType)(unsafe.Pointer(t)).ptrTo
280 default:
281 ptrType = (*_elemType)(unsafe.Pointer(t)).ptrTo
282 }
283 }
284 if ptrType == nil {
285 return nil
286 }
287 iface := _ifacePair{typecode: unsafe.Pointer(ptrType), value: ptr}
288 return *(*any)(unsafe.Pointer(&iface))
289 }
290
291 func valToIface(t *_rawType, ptr unsafe.Pointer) any {
292 iface := _ifacePair{typecode: unsafe.Pointer(t), value: ptr}
293 if t.size() <= unsafe.Sizeof(uintptr(0)) {
294 iface.value = *(*unsafe.Pointer)(ptr)
295 }
296 return *(*any)(unsafe.Pointer(&iface))
297 }
298
299 func isZeroValue(typ *_rawType, ptr unsafe.Pointer) bool {
300 sz := typ.size()
301 for i := uintptr(0); i < sz; i++ {
302 if *(*byte)(unsafe.Add(ptr, i)) != 0 {
303 return false
304 }
305 }
306 return true
307 }
308
309 func makeSliceOf(elemType *_rawType, length, capacity int) unsafe.Pointer {
310 elemSize := elemType.size()
311 buf := []byte{:int(elemSize)*capacity}
312 var dataPtr unsafe.Pointer
313 if len(buf) > 0 {
314 dataPtr = unsafe.Pointer(&buf[0])
315 }
316 p := &_sliceHeader{data: dataPtr, len: length, cap: capacity}
317 return unsafe.Pointer(p)
318 }
319
320 func sliceAppend(slicePtr unsafe.Pointer, elemType *_rawType) unsafe.Pointer {
321 hdr := (*_sliceHeader)(slicePtr)
322 elemSize := elemType.size()
323 if hdr.len >= hdr.cap {
324 newCap := hdr.cap * 2
325 if newCap < 4 {
326 newCap = 4
327 }
328 newBuf := []byte{:int(elemSize)*newCap}
329 var newData unsafe.Pointer
330 if len(newBuf) > 0 {
331 newData = unsafe.Pointer(&newBuf[0])
332 }
333 if hdr.data != nil && hdr.len > 0 {
334 memcpy(newData, hdr.data, elemSize*uintptr(hdr.len))
335 }
336 hdr.data = newData
337 hdr.cap = newCap
338 }
339 hdr.len++
340 return slicePtr
341 }
342
343 func sliceIndex(slicePtr unsafe.Pointer, elemType *_rawType, i int) unsafe.Pointer {
344 hdr := (*_sliceHeader)(slicePtr)
345 return unsafe.Add(hdr.data, elemType.size()*uintptr(i))
346 }
347
348 //go:linkname memcpy runtime.memcpy
349 func memcpy(dst, src unsafe.Pointer, n uintptr)
350