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