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