1
2
3
4
5
6
7
8
9
10
11
12 package rttype
13
14 import (
15 "cmd/compile/internal/base"
16 "cmd/compile/internal/objw"
17 "cmd/compile/internal/types"
18 "cmd/internal/obj"
19 "internal/abi"
20 "reflect"
21 )
22
23
24 var Type *types.Type
25
26 var ArrayType *types.Type
27 var ChanType *types.Type
28 var FuncType *types.Type
29 var InterfaceType *types.Type
30 var OldMapType *types.Type
31 var SwissMapType *types.Type
32 var PtrType *types.Type
33 var SliceType *types.Type
34 var StructType *types.Type
35
36
37 var IMethod *types.Type
38 var Method *types.Type
39 var StructField *types.Type
40 var UncommonType *types.Type
41
42
43 var InterfaceSwitch *types.Type
44 var TypeAssert *types.Type
45
46
47 var ITab *types.Type
48
49 func Init() {
50
51
52
53 Type = FromReflect(reflect.TypeOf(abi.Type{}))
54 ArrayType = FromReflect(reflect.TypeOf(abi.ArrayType{}))
55 ChanType = FromReflect(reflect.TypeOf(abi.ChanType{}))
56 FuncType = FromReflect(reflect.TypeOf(abi.FuncType{}))
57 InterfaceType = FromReflect(reflect.TypeOf(abi.InterfaceType{}))
58 OldMapType = FromReflect(reflect.TypeOf(abi.OldMapType{}))
59 SwissMapType = FromReflect(reflect.TypeOf(abi.SwissMapType{}))
60 PtrType = FromReflect(reflect.TypeOf(abi.PtrType{}))
61 SliceType = FromReflect(reflect.TypeOf(abi.SliceType{}))
62 StructType = FromReflect(reflect.TypeOf(abi.StructType{}))
63
64 IMethod = FromReflect(reflect.TypeOf(abi.Imethod{}))
65 Method = FromReflect(reflect.TypeOf(abi.Method{}))
66 StructField = FromReflect(reflect.TypeOf(abi.StructField{}))
67 UncommonType = FromReflect(reflect.TypeOf(abi.UncommonType{}))
68
69 InterfaceSwitch = FromReflect(reflect.TypeOf(abi.InterfaceSwitch{}))
70 TypeAssert = FromReflect(reflect.TypeOf(abi.TypeAssert{}))
71
72 ITab = FromReflect(reflect.TypeOf(abi.ITab{}))
73
74
75
76
77 ptrSize := types.PtrSize
78 if got, want := int64(abi.CommonSize(ptrSize)), Type.Size(); got != want {
79 base.Fatalf("abi.CommonSize() == %d, want %d", got, want)
80 }
81 if got, want := int64(abi.StructFieldSize(ptrSize)), StructField.Size(); got != want {
82 base.Fatalf("abi.StructFieldSize() == %d, want %d", got, want)
83 }
84 if got, want := int64(abi.UncommonSize()), UncommonType.Size(); got != want {
85 base.Fatalf("abi.UncommonSize() == %d, want %d", got, want)
86 }
87 if got, want := int64(abi.TFlagOff(ptrSize)), Type.OffsetOf("TFlag"); got != want {
88 base.Fatalf("abi.TFlagOff() == %d, want %d", got, want)
89 }
90 if got, want := int64(abi.ITabTypeOff(ptrSize)), ITab.OffsetOf("Type"); got != want {
91 base.Fatalf("abi.ITabTypeOff() == %d, want %d", got, want)
92 }
93 }
94
95
96 func FromReflect(rt reflect.Type) *types.Type {
97 t := reflectToType(rt)
98 types.CalcSize(t)
99 return t
100 }
101
102
103
104
105 func reflectToType(rt reflect.Type) *types.Type {
106 switch rt.Kind() {
107 case reflect.Bool:
108 return types.Types[types.TBOOL]
109 case reflect.Int:
110 return types.Types[types.TINT]
111 case reflect.Int8:
112 return types.Types[types.TINT8]
113 case reflect.Int16:
114 return types.Types[types.TINT16]
115 case reflect.Int32:
116 return types.Types[types.TINT32]
117 case reflect.Uint8:
118 return types.Types[types.TUINT8]
119 case reflect.Uint16:
120 return types.Types[types.TUINT16]
121 case reflect.Uint32:
122 return types.Types[types.TUINT32]
123 case reflect.Float32:
124 return types.Types[types.TFLOAT32]
125 case reflect.Float64:
126 return types.Types[types.TFLOAT64]
127 case reflect.Uintptr:
128 return types.Types[types.TUINTPTR]
129 case reflect.Ptr:
130 return types.NewPtr(reflectToType(rt.Elem()))
131 case reflect.Func, reflect.UnsafePointer:
132
133
134 return types.Types[types.TUNSAFEPTR]
135 case reflect.Slice:
136 return types.NewSlice(reflectToType(rt.Elem()))
137 case reflect.Array:
138 return types.NewArray(reflectToType(rt.Elem()), int64(rt.Len()))
139 case reflect.Struct:
140 fields := make([]*types.Field, rt.NumField())
141 for i := 0; i < rt.NumField(); i++ {
142 f := rt.Field(i)
143 ft := reflectToType(f.Type)
144 fields[i] = &types.Field{Sym: &types.Sym{Name: f.Name}, Type: ft}
145 }
146 return types.NewStruct(fields)
147 case reflect.Chan:
148 return types.NewChan(reflectToType(rt.Elem()), types.ChanDir(rt.ChanDir()))
149 case reflect.String:
150 return types.Types[types.TSTRING]
151 case reflect.Complex128:
152 return types.Types[types.TCOMPLEX128]
153 default:
154 base.Fatalf("unhandled kind %s", rt.Kind())
155 return nil
156 }
157 }
158
159
160
161 type Cursor struct {
162 lsym *obj.LSym
163 offset int64
164 typ *types.Type
165 }
166
167
168 func NewCursor(lsym *obj.LSym, off int64, t *types.Type) Cursor {
169 return Cursor{lsym: lsym, offset: off, typ: t}
170 }
171
172
173 func (c Cursor) WritePtr(target *obj.LSym) {
174 if c.typ.Kind() != types.TUNSAFEPTR && c.typ.Kind() != types.TPTR {
175 base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
176 }
177 if target == nil {
178 objw.Uintptr(c.lsym, int(c.offset), 0)
179 } else {
180 objw.SymPtr(c.lsym, int(c.offset), target, 0)
181 }
182 }
183 func (c Cursor) WritePtrWeak(target *obj.LSym) {
184 if c.typ.Kind() != types.TUINTPTR {
185 base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
186 }
187 objw.SymPtrWeak(c.lsym, int(c.offset), target, 0)
188 }
189 func (c Cursor) WriteUintptr(val uint64) {
190 if c.typ.Kind() != types.TUINTPTR {
191 base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
192 }
193 objw.Uintptr(c.lsym, int(c.offset), val)
194 }
195 func (c Cursor) WriteUint32(val uint32) {
196 if c.typ.Kind() != types.TUINT32 {
197 base.Fatalf("can't write uint32, it has kind %s", c.typ.Kind())
198 }
199 objw.Uint32(c.lsym, int(c.offset), val)
200 }
201 func (c Cursor) WriteUint16(val uint16) {
202 if c.typ.Kind() != types.TUINT16 {
203 base.Fatalf("can't write uint16, it has kind %s", c.typ.Kind())
204 }
205 objw.Uint16(c.lsym, int(c.offset), val)
206 }
207 func (c Cursor) WriteUint8(val uint8) {
208 if c.typ.Kind() != types.TUINT8 {
209 base.Fatalf("can't write uint8, it has kind %s", c.typ.Kind())
210 }
211 objw.Uint8(c.lsym, int(c.offset), val)
212 }
213 func (c Cursor) WriteInt(val int64) {
214 if c.typ.Kind() != types.TINT {
215 base.Fatalf("can't write int, it has kind %s", c.typ.Kind())
216 }
217 objw.Uintptr(c.lsym, int(c.offset), uint64(val))
218 }
219 func (c Cursor) WriteInt32(val int32) {
220 if c.typ.Kind() != types.TINT32 {
221 base.Fatalf("can't write int32, it has kind %s", c.typ.Kind())
222 }
223 objw.Uint32(c.lsym, int(c.offset), uint32(val))
224 }
225 func (c Cursor) WriteBool(val bool) {
226 if c.typ.Kind() != types.TBOOL {
227 base.Fatalf("can't write bool, it has kind %s", c.typ.Kind())
228 }
229 objw.Bool(c.lsym, int(c.offset), val)
230 }
231
232
233
234 func (c Cursor) WriteSymPtrOff(target *obj.LSym, weak bool) {
235 if c.typ.Kind() != types.TINT32 && c.typ.Kind() != types.TUINT32 {
236 base.Fatalf("can't write SymPtr, it has kind %s", c.typ.Kind())
237 }
238 if target == nil {
239 objw.Uint32(c.lsym, int(c.offset), 0)
240 } else if weak {
241 objw.SymPtrWeakOff(c.lsym, int(c.offset), target)
242 } else {
243 objw.SymPtrOff(c.lsym, int(c.offset), target)
244 }
245 }
246
247
248 func (c Cursor) WriteSlice(target *obj.LSym, off, len, cap int64) {
249 if c.typ.Kind() != types.TSLICE {
250 base.Fatalf("can't write slice, it has kind %s", c.typ.Kind())
251 }
252 objw.SymPtr(c.lsym, int(c.offset), target, int(off))
253 objw.Uintptr(c.lsym, int(c.offset)+types.PtrSize, uint64(len))
254 objw.Uintptr(c.lsym, int(c.offset)+2*types.PtrSize, uint64(cap))
255
256
257 if len != cap {
258 base.Fatalf("len != cap (%d != %d)", len, cap)
259 }
260 }
261
262
263
264 func (c Cursor) Reloc(rel obj.Reloc) {
265 rel.Off = int32(c.offset)
266 rel.Siz = uint8(c.typ.Size())
267 c.lsym.AddRel(base.Ctxt, rel)
268 }
269
270
271 func (c Cursor) Field(name string) Cursor {
272 if c.typ.Kind() != types.TSTRUCT {
273 base.Fatalf("can't call Field on non-struct %v", c.typ)
274 }
275 for _, f := range c.typ.Fields() {
276 if f.Sym.Name == name {
277 return Cursor{lsym: c.lsym, offset: c.offset + f.Offset, typ: f.Type}
278 }
279 }
280 base.Fatalf("couldn't find field %s in %v", name, c.typ)
281 return Cursor{}
282 }
283
284 func (c Cursor) Elem(i int64) Cursor {
285 if c.typ.Kind() != types.TARRAY {
286 base.Fatalf("can't call Elem on non-array %v", c.typ)
287 }
288 if i < 0 || i >= c.typ.NumElem() {
289 base.Fatalf("element access out of bounds [%d] in [0:%d]", i, c.typ.NumElem())
290 }
291 elem := c.typ.Elem()
292 return Cursor{lsym: c.lsym, offset: c.offset + i*elem.Size(), typ: elem}
293 }
294
295 type ArrayCursor struct {
296 c Cursor
297 n int
298 }
299
300
301 func NewArrayCursor(lsym *obj.LSym, off int64, t *types.Type, n int) ArrayCursor {
302 return ArrayCursor{
303 c: NewCursor(lsym, off, t),
304 n: n,
305 }
306 }
307
308
309 func (a ArrayCursor) Elem(i int) Cursor {
310 if i < 0 || i >= a.n {
311 base.Fatalf("element index %d out of range [0:%d]", i, a.n)
312 }
313 return Cursor{lsym: a.c.lsym, offset: a.c.offset + int64(i)*a.c.typ.Size(), typ: a.c.typ}
314 }
315
316
317
318
319 func (c Cursor) ModifyArray(n int) (ArrayCursor, int64) {
320 if c.typ.Kind() != types.TARRAY {
321 base.Fatalf("can't call ModifyArray on non-array %v", c.typ)
322 }
323 k := c.typ.NumElem()
324 return ArrayCursor{c: Cursor{lsym: c.lsym, offset: c.offset, typ: c.typ.Elem()}, n: n}, (int64(n) - k) * c.typ.Elem().Size()
325 }
326
View as plain text