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.Int32:
112 return types.Types[types.TINT32]
113 case reflect.Uint8:
114 return types.Types[types.TUINT8]
115 case reflect.Uint16:
116 return types.Types[types.TUINT16]
117 case reflect.Uint32:
118 return types.Types[types.TUINT32]
119 case reflect.Uintptr:
120 return types.Types[types.TUINTPTR]
121 case reflect.Ptr, reflect.Func, reflect.UnsafePointer:
122
123
124 return types.Types[types.TUNSAFEPTR]
125 case reflect.Slice:
126 return types.NewSlice(reflectToType(rt.Elem()))
127 case reflect.Array:
128 return types.NewArray(reflectToType(rt.Elem()), int64(rt.Len()))
129 case reflect.Struct:
130 fields := make([]*types.Field, rt.NumField())
131 for i := 0; i < rt.NumField(); i++ {
132 f := rt.Field(i)
133 ft := reflectToType(f.Type)
134 fields[i] = &types.Field{Sym: &types.Sym{Name: f.Name}, Type: ft}
135 }
136 return types.NewStruct(fields)
137 default:
138 base.Fatalf("unhandled kind %s", rt.Kind())
139 return nil
140 }
141 }
142
143
144
145 type Cursor struct {
146 lsym *obj.LSym
147 offset int64
148 typ *types.Type
149 }
150
151
152 func NewCursor(lsym *obj.LSym, off int64, t *types.Type) Cursor {
153 return Cursor{lsym: lsym, offset: off, typ: t}
154 }
155
156
157 func (c Cursor) WritePtr(target *obj.LSym) {
158 if c.typ.Kind() != types.TUNSAFEPTR {
159 base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
160 }
161 if target == nil {
162 objw.Uintptr(c.lsym, int(c.offset), 0)
163 } else {
164 objw.SymPtr(c.lsym, int(c.offset), target, 0)
165 }
166 }
167 func (c Cursor) WritePtrWeak(target *obj.LSym) {
168 if c.typ.Kind() != types.TUINTPTR {
169 base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
170 }
171 objw.SymPtrWeak(c.lsym, int(c.offset), target, 0)
172 }
173 func (c Cursor) WriteUintptr(val uint64) {
174 if c.typ.Kind() != types.TUINTPTR {
175 base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
176 }
177 objw.Uintptr(c.lsym, int(c.offset), val)
178 }
179 func (c Cursor) WriteUint32(val uint32) {
180 if c.typ.Kind() != types.TUINT32 {
181 base.Fatalf("can't write uint32, it has kind %s", c.typ.Kind())
182 }
183 objw.Uint32(c.lsym, int(c.offset), val)
184 }
185 func (c Cursor) WriteUint16(val uint16) {
186 if c.typ.Kind() != types.TUINT16 {
187 base.Fatalf("can't write uint16, it has kind %s", c.typ.Kind())
188 }
189 objw.Uint16(c.lsym, int(c.offset), val)
190 }
191 func (c Cursor) WriteUint8(val uint8) {
192 if c.typ.Kind() != types.TUINT8 {
193 base.Fatalf("can't write uint8, it has kind %s", c.typ.Kind())
194 }
195 objw.Uint8(c.lsym, int(c.offset), val)
196 }
197 func (c Cursor) WriteInt(val int64) {
198 if c.typ.Kind() != types.TINT {
199 base.Fatalf("can't write int, it has kind %s", c.typ.Kind())
200 }
201 objw.Uintptr(c.lsym, int(c.offset), uint64(val))
202 }
203 func (c Cursor) WriteInt32(val int32) {
204 if c.typ.Kind() != types.TINT32 {
205 base.Fatalf("can't write int32, it has kind %s", c.typ.Kind())
206 }
207 objw.Uint32(c.lsym, int(c.offset), uint32(val))
208 }
209 func (c Cursor) WriteBool(val bool) {
210 if c.typ.Kind() != types.TBOOL {
211 base.Fatalf("can't write bool, it has kind %s", c.typ.Kind())
212 }
213 objw.Bool(c.lsym, int(c.offset), val)
214 }
215
216
217
218 func (c Cursor) WriteSymPtrOff(target *obj.LSym, weak bool) {
219 if c.typ.Kind() != types.TINT32 && c.typ.Kind() != types.TUINT32 {
220 base.Fatalf("can't write SymPtr, it has kind %s", c.typ.Kind())
221 }
222 if target == nil {
223 objw.Uint32(c.lsym, int(c.offset), 0)
224 } else if weak {
225 objw.SymPtrWeakOff(c.lsym, int(c.offset), target)
226 } else {
227 objw.SymPtrOff(c.lsym, int(c.offset), target)
228 }
229 }
230
231
232 func (c Cursor) WriteSlice(target *obj.LSym, off, len, cap int64) {
233 if c.typ.Kind() != types.TSLICE {
234 base.Fatalf("can't write slice, it has kind %s", c.typ.Kind())
235 }
236 objw.SymPtr(c.lsym, int(c.offset), target, int(off))
237 objw.Uintptr(c.lsym, int(c.offset)+types.PtrSize, uint64(len))
238 objw.Uintptr(c.lsym, int(c.offset)+2*types.PtrSize, uint64(cap))
239
240
241 if len != cap {
242 base.Fatalf("len != cap (%d != %d)", len, cap)
243 }
244 }
245
246
247
248 func (c Cursor) Reloc(rel obj.Reloc) {
249 rel.Off = int32(c.offset)
250 rel.Siz = uint8(c.typ.Size())
251 c.lsym.AddRel(base.Ctxt, rel)
252 }
253
254
255 func (c Cursor) Field(name string) Cursor {
256 if c.typ.Kind() != types.TSTRUCT {
257 base.Fatalf("can't call Field on non-struct %v", c.typ)
258 }
259 for _, f := range c.typ.Fields() {
260 if f.Sym.Name == name {
261 return Cursor{lsym: c.lsym, offset: c.offset + f.Offset, typ: f.Type}
262 }
263 }
264 base.Fatalf("couldn't find field %s in %v", name, c.typ)
265 return Cursor{}
266 }
267
268 func (c Cursor) Elem(i int64) Cursor {
269 if c.typ.Kind() != types.TARRAY {
270 base.Fatalf("can't call Elem on non-array %v", c.typ)
271 }
272 if i < 0 || i >= c.typ.NumElem() {
273 base.Fatalf("element access out of bounds [%d] in [0:%d]", i, c.typ.NumElem())
274 }
275 elem := c.typ.Elem()
276 return Cursor{lsym: c.lsym, offset: c.offset + i*elem.Size(), typ: elem}
277 }
278
279 type ArrayCursor struct {
280 c Cursor
281 n int
282 }
283
284
285 func NewArrayCursor(lsym *obj.LSym, off int64, t *types.Type, n int) ArrayCursor {
286 return ArrayCursor{
287 c: NewCursor(lsym, off, t),
288 n: n,
289 }
290 }
291
292
293 func (a ArrayCursor) Elem(i int) Cursor {
294 if i < 0 || i >= a.n {
295 base.Fatalf("element index %d out of range [0:%d]", i, a.n)
296 }
297 return Cursor{lsym: a.c.lsym, offset: a.c.offset + int64(i)*a.c.typ.Size(), typ: a.c.typ}
298 }
299
300
301
302
303 func (c Cursor) ModifyArray(n int) (ArrayCursor, int64) {
304 if c.typ.Kind() != types.TARRAY {
305 base.Fatalf("can't call ModifyArray on non-array %v", c.typ)
306 }
307 k := c.typ.NumElem()
308 return ArrayCursor{c: Cursor{lsym: c.lsym, offset: c.offset, typ: c.typ.Elem()}, n: n}, (int64(n) - k) * c.typ.Elem().Size()
309 }
310
View as plain text