...
1
16
17 package rt
18
19 import (
20 `reflect`
21 `unsafe`
22 )
23
24 var (
25 reflectRtypeItab = findReflectRtypeItab()
26 )
27
28
29 const (
30 F_direct = 1 << 5
31 F_kind_mask = (1 << 5) - 1
32 )
33
34
35 const (
36 tflagUncommon uint8 = 1 << 0
37 tflagExtraStar uint8 = 1 << 1
38 tflagNamed uint8 = 1 << 2
39 tflagRegularMemory uint8 = 1 << 3
40 )
41
42 type GoType struct {
43 Size uintptr
44 PtrData uintptr
45 Hash uint32
46 Flags uint8
47 Align uint8
48 FieldAlign uint8
49 KindFlags uint8
50 Traits unsafe.Pointer
51 GCData *byte
52 Str int32
53 PtrToSelf int32
54 }
55
56 func (self *GoType) IsNamed() bool {
57 return (self.Flags & tflagNamed) != 0
58 }
59
60 func (self *GoType) Kind() reflect.Kind {
61 return reflect.Kind(self.KindFlags & F_kind_mask)
62 }
63
64 func (self *GoType) Pack() (t reflect.Type) {
65 (*GoIface)(unsafe.Pointer(&t)).Itab = reflectRtypeItab
66 (*GoIface)(unsafe.Pointer(&t)).Value = unsafe.Pointer(self)
67 return
68 }
69
70 func (self *GoType) String() string {
71 return self.Pack().String()
72 }
73
74 func (self *GoType) Indirect() bool {
75 return self.KindFlags & F_direct == 0
76 }
77
78 type GoMap struct {
79 Count int
80 Flags uint8
81 B uint8
82 Overflow uint16
83 Hash0 uint32
84 Buckets unsafe.Pointer
85 OldBuckets unsafe.Pointer
86 Evacuate uintptr
87 Extra unsafe.Pointer
88 }
89
90 type GoMapIterator struct {
91 K unsafe.Pointer
92 V unsafe.Pointer
93 T *GoMapType
94 H *GoMap
95 Buckets unsafe.Pointer
96 Bptr *unsafe.Pointer
97 Overflow *[]unsafe.Pointer
98 OldOverflow *[]unsafe.Pointer
99 StartBucket uintptr
100 Offset uint8
101 Wrapped bool
102 B uint8
103 I uint8
104 Bucket uintptr
105 CheckBucket uintptr
106 }
107
108 type GoItab struct {
109 it unsafe.Pointer
110 Vt *GoType
111 hv uint32
112 _ [4]byte
113 fn [1]uintptr
114 }
115
116 type GoIface struct {
117 Itab *GoItab
118 Value unsafe.Pointer
119 }
120
121 type GoEface struct {
122 Type *GoType
123 Value unsafe.Pointer
124 }
125
126 func (self GoEface) Pack() (v interface{}) {
127 *(*GoEface)(unsafe.Pointer(&v)) = self
128 return
129 }
130
131 type GoPtrType struct {
132 GoType
133 Elem *GoType
134 }
135
136 type GoMapType struct {
137 GoType
138 Key *GoType
139 Elem *GoType
140 Bucket *GoType
141 Hasher func(unsafe.Pointer, uintptr) uintptr
142 KeySize uint8
143 ElemSize uint8
144 BucketSize uint16
145 Flags uint32
146 }
147
148 func (self *GoMapType) IndirectElem() bool {
149 return self.Flags & 2 != 0
150 }
151
152 type GoStructType struct {
153 GoType
154 Pkg *byte
155 Fields []GoStructField
156 }
157
158 type GoStructField struct {
159 Name *byte
160 Type *GoType
161 OffEmbed uintptr
162 }
163
164 type GoInterfaceType struct {
165 GoType
166 PkgPath *byte
167 Methods []GoInterfaceMethod
168 }
169
170 type GoInterfaceMethod struct {
171 Name int32
172 Type int32
173 }
174
175 type GoSlice struct {
176 Ptr unsafe.Pointer
177 Len int
178 Cap int
179 }
180
181 type GoString struct {
182 Ptr unsafe.Pointer
183 Len int
184 }
185
186 func PtrElem(t *GoType) *GoType {
187 return (*GoPtrType)(unsafe.Pointer(t)).Elem
188 }
189
190 func MapType(t *GoType) *GoMapType {
191 return (*GoMapType)(unsafe.Pointer(t))
192 }
193
194 func IfaceType(t *GoType) *GoInterfaceType {
195 return (*GoInterfaceType)(unsafe.Pointer(t))
196 }
197
198 func UnpackType(t reflect.Type) *GoType {
199 return (*GoType)((*GoIface)(unsafe.Pointer(&t)).Value)
200 }
201
202 func UnpackEface(v interface{}) GoEface {
203 return *(*GoEface)(unsafe.Pointer(&v))
204 }
205
206 func UnpackIface(v interface{}) GoIface {
207 return *(*GoIface)(unsafe.Pointer(&v))
208 }
209
210 func findReflectRtypeItab() *GoItab {
211 v := reflect.TypeOf(struct{}{})
212 return (*GoIface)(unsafe.Pointer(&v)).Itab
213 }
214
215 func AssertI2I2(t *GoType, i GoIface) (r GoIface) {
216 inter := IfaceType(t)
217 tab := i.Itab
218 if tab == nil {
219 return
220 }
221 if (*GoInterfaceType)(tab.it) != inter {
222 tab = Getitab(inter, tab.Vt, true)
223 if tab == nil {
224 return
225 }
226 }
227 r.Itab = tab
228 r.Value = i.Value
229 return
230 }
231
232
233
234 func Getitab(inter *GoInterfaceType, typ *GoType, canfail bool) *GoItab
235
View as plain text