-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlink_reflect.go
117 lines (98 loc) · 2.78 KB
/
link_reflect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package jzon
import (
"unsafe"
)
/*
* WARNING:
* The linked functions in this file should be used with EXTREMELY careful
*/
//go:linkname unsafe_New reflect.unsafe_New
func unsafe_New(rtype rtype) unsafe.Pointer
//go:linkname typedmemclrpartial reflect.typedmemclrpartial
//go:noescape
func typedmemclrpartial(t rtype, ptr unsafe.Pointer, off, size uintptr)
//go:linkname unsafe_NewArray reflect.unsafe_NewArray
func unsafe_NewArray(rtype rtype, length int) unsafe.Pointer
//go:linkname typedslicecopy reflect.typedslicecopy
//go:noescape
func typedslicecopy(rtyp rtype, dst, src sliceHeader) int
//go:linkname makemap reflect.makemap
func makemap(rtype rtype, cap int) unsafe.Pointer
//go:linkname typedmemmove reflect.typedmemmove
//go:noescape
func typedmemmove(rtype rtype, dst, src unsafe.Pointer)
//go:linkname mapassign reflect.mapassign
//go:noescape
func mapassign(t rtype, m, key, val unsafe.Pointer)
//go:linkname maplen reflect.maplen
//go:noescape
func maplen(m unsafe.Pointer) int
//go:linkname ifaceIndir reflect.ifaceIndir
func ifaceIndir(t rtype) bool
type hiter struct {
key unsafe.Pointer
elem unsafe.Pointer
t unsafe.Pointer
h unsafe.Pointer
buckets unsafe.Pointer
bptr unsafe.Pointer
overflow unsafe.Pointer
oldoverflow unsafe.Pointer
startBucket uintptr
offset uint8
wrapped bool
B uint8
i uint8
bucket uintptr
checkBucket uintptr
}
//go:noescape
//go:linkname mapiternext reflect.mapiternext
func mapiternext(it *hiter)
func unsafeMakeSlice(elemRType rtype, length, cap int) unsafe.Pointer {
return unsafe.Pointer(&sliceHeader{
Data: uintptr(unsafe_NewArray(elemRType, cap)),
Len: length,
Cap: cap,
})
}
func unsafeMakeMap(rtype rtype, cap int) unsafe.Pointer {
m := makemap(rtype, cap)
return unsafe.Pointer(&m)
}
// see reflect.add
func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
return unsafe.Pointer(uintptr(p) + x)
}
// see reflect.grow
func unsafeGrowSlice(elemRType rtype, ptr unsafe.Pointer, newLength int) unsafe.Pointer {
sh := (*sliceHeader)(ptr)
if newLength < sh.Cap {
sh.Len = newLength
return ptr
}
newCap := sh.Cap
if sh.Cap == 0 {
newCap = newLength
} else {
for newCap < newLength {
if newCap < 1024 {
newCap <<= 1
} else {
newCap += newCap >> 2
}
}
}
newHeader := (*sliceHeader)(unsafeMakeSlice(elemRType, newLength, newCap))
typedslicecopy(elemRType, *newHeader, *sh)
return unsafe.Pointer(newHeader)
}
func unsafeSliceChildPtr(ptr unsafe.Pointer, elemSize uintptr, index int) unsafe.Pointer {
sh := (*sliceHeader)(ptr)
return add(unsafe.Pointer(sh.Data), uintptr(index)*elemSize, "index < len")
}
//go:nosplit
func noescape(p unsafe.Pointer) unsafe.Pointer {
x := uintptr(p)
return unsafe.Pointer(x ^ 0)
}