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