@@ -153,71 +153,56 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
153
153
}
154
154
switch typ := typ .(type ) {
155
155
case * types.Basic :
156
- typeFieldTypes = append (typeFieldTypes ,
157
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
158
- )
156
+ typeFieldTypes = append (typeFieldTypes )
159
157
case * types.Named :
160
158
name := typ .Obj ().Name ()
161
159
var pkgname string
162
160
if pkg := typ .Obj ().Pkg (); pkg != nil {
163
161
pkgname = pkg .Name ()
164
162
}
163
+
165
164
typeFieldTypes = append (typeFieldTypes ,
166
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
167
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
168
165
types .NewVar (token .NoPos , nil , "underlying" , types .Typ [types .UnsafePointer ]),
166
+ types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
167
+ types .NewVar (token .NoPos , nil , "ptrNumMethods" , types .Typ [types .Uint16 ]),
169
168
types .NewVar (token .NoPos , nil , "pkgpath" , types .Typ [types .UnsafePointer ]),
170
169
types .NewVar (token .NoPos , nil , "name" , types .NewArray (types .Typ [types .Int8 ], int64 (len (pkgname )+ 1 + len (name )+ 1 ))),
171
170
)
172
171
case * types.Chan :
173
172
typeFieldTypes = append (typeFieldTypes ,
174
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]), // reuse for select chan direction
175
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
173
+ types .NewVar (token .NoPos , nil , "dir" , types .Typ [types .Uint16 ]),
176
174
types .NewVar (token .NoPos , nil , "elementType" , types .Typ [types .UnsafePointer ]),
177
175
)
178
176
case * types.Slice :
179
177
typeFieldTypes = append (typeFieldTypes ,
180
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
181
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
182
178
types .NewVar (token .NoPos , nil , "elementType" , types .Typ [types .UnsafePointer ]),
183
179
)
184
180
case * types.Pointer :
185
- typeFieldTypes = append (typeFieldTypes ,
186
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
187
- types .NewVar (token .NoPos , nil , "elementType" , types .Typ [types .UnsafePointer ]),
188
- )
181
+ // nothing
189
182
case * types.Array :
190
183
typeFieldTypes = append (typeFieldTypes ,
191
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
192
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
193
184
types .NewVar (token .NoPos , nil , "elementType" , types .Typ [types .UnsafePointer ]),
194
185
types .NewVar (token .NoPos , nil , "length" , types .Typ [types .Uintptr ]),
195
186
)
196
187
case * types.Map :
197
188
typeFieldTypes = append (typeFieldTypes ,
198
- types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
199
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
200
189
types .NewVar (token .NoPos , nil , "elementType" , types .Typ [types .UnsafePointer ]),
201
190
types .NewVar (token .NoPos , nil , "keyType" , types .Typ [types .UnsafePointer ]),
202
191
)
203
192
case * types.Struct :
204
193
typeFieldTypes = append (typeFieldTypes ,
205
194
types .NewVar (token .NoPos , nil , "numMethods" , types .Typ [types .Uint16 ]),
206
- types .NewVar (token .NoPos , nil , "ptrTo " , types .Typ [types .UnsafePointer ]),
195
+ types .NewVar (token .NoPos , nil , "ptrNumMethods " , types .Typ [types .Uint16 ]),
207
196
types .NewVar (token .NoPos , nil , "pkgpath" , types .Typ [types .UnsafePointer ]),
208
197
types .NewVar (token .NoPos , nil , "size" , types .Typ [types .Uint32 ]),
209
198
types .NewVar (token .NoPos , nil , "numFields" , types .Typ [types .Uint16 ]),
210
199
types .NewVar (token .NoPos , nil , "fields" , types .NewArray (c .getRuntimeType ("structField" ), int64 (typ .NumFields ()))),
211
200
)
212
201
case * types.Interface :
213
- typeFieldTypes = append (typeFieldTypes ,
214
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
215
- )
202
+ typeFieldTypes = append (typeFieldTypes )
216
203
// TODO: methods
217
204
case * types.Signature :
218
- typeFieldTypes = append (typeFieldTypes ,
219
- types .NewVar (token .NoPos , nil , "ptrTo" , types .Typ [types .UnsafePointer ]),
220
- )
205
+ typeFieldTypes = append (typeFieldTypes )
221
206
// TODO: signature params and return values
222
207
}
223
208
if hasMethodSet {
@@ -239,7 +224,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
239
224
metabyte := getTypeKind (typ )
240
225
switch typ := typ .(type ) {
241
226
case * types.Basic :
242
- typeFields = []llvm.Value {c . getTypeCode ( types . NewPointer ( typ )) }
227
+ typeFields = []llvm.Value {}
243
228
case * types.Named :
244
229
name := typ .Obj ().Name ()
245
230
var pkgpath string
@@ -249,12 +234,16 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
249
234
pkgname = pkg .Name ()
250
235
}
251
236
pkgPathPtr := c .pkgPathPtr (pkgpath )
237
+
238
+ // number of methods for a pointer of this type
239
+ ptrms := c .program .MethodSets .MethodSet (types .NewPointer (typ ))
240
+
252
241
typeFields = []llvm.Value {
253
- llvm . ConstInt ( c . ctx . Int16Type (), uint64 ( ms . Len ()), false ), // numMethods
254
- c . getTypeCode ( types . NewPointer ( typ )), // ptrTo
255
- c . getTypeCode ( typ . Underlying ()), // underlying
256
- pkgPathPtr , // pkgpath pointer
257
- c .ctx .ConstString (pkgname + "." + name + "\x00 " , false ), // name
242
+ c . getTypeCode ( typ . Underlying ()), // underlying
243
+ llvm . ConstInt ( c . ctx . Int16Type (), uint64 ( ms . Len ( )), false ), // numMethods
244
+ llvm . ConstInt ( c . ctx . Int16Type (), uint64 ( ptrms . Len ()), false ), // ptrNumMethods
245
+ pkgPathPtr , // pkgpath pointer
246
+ c .ctx .ConstString (pkgname + "." + name + "\x00 " , false ), // name
258
247
}
259
248
metabyte |= 1 << 5 // "named" flag
260
249
case * types.Chan :
@@ -270,33 +259,26 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
270
259
271
260
typeFields = []llvm.Value {
272
261
llvm .ConstInt (c .ctx .Int16Type (), uint64 (dir ), false ), // actually channel direction
273
- c .getTypeCode (types .NewPointer (typ )), // ptrTo
274
262
c .getTypeCode (typ .Elem ()), // elementType
275
263
}
276
264
case * types.Slice :
277
265
typeFields = []llvm.Value {
278
- llvm .ConstInt (c .ctx .Int16Type (), 0 , false ), // numMethods
279
- c .getTypeCode (types .NewPointer (typ )), // ptrTo
280
- c .getTypeCode (typ .Elem ()), // elementType
266
+ c .getTypeCode (typ .Elem ()), // elementType
281
267
}
282
268
case * types.Pointer :
283
- typeFields = []llvm. Value {
284
- llvm .ConstInt (c .ctx . Int16Type (), uint64 ( ms . Len ()), false ), // numMethods
285
- c . getTypeCode ( typ . Elem () ),
286
- }
269
+ ptr := c . getTypeCode ( typ . Elem ())
270
+ return llvm .ConstGEP (c .i8ptrType , ptr , []llvm. Value {
271
+ llvm . ConstInt ( llvm . Int32Type (), 1 , false ),
272
+ })
287
273
case * types.Array :
288
274
typeFields = []llvm.Value {
289
- llvm .ConstInt (c .ctx .Int16Type (), 0 , false ), // numMethods
290
- c .getTypeCode (types .NewPointer (typ )), // ptrTo
291
275
c .getTypeCode (typ .Elem ()), // elementType
292
276
llvm .ConstInt (c .uintptrType , uint64 (typ .Len ()), false ), // length
293
277
}
294
278
case * types.Map :
295
279
typeFields = []llvm.Value {
296
- llvm .ConstInt (c .ctx .Int16Type (), 0 , false ), // numMethods
297
- c .getTypeCode (types .NewPointer (typ )), // ptrTo
298
- c .getTypeCode (typ .Elem ()), // elem
299
- c .getTypeCode (typ .Key ()), // key
280
+ c .getTypeCode (typ .Elem ()), // elem
281
+ c .getTypeCode (typ .Key ()), // key
300
282
}
301
283
case * types.Struct :
302
284
var pkgpath string
@@ -307,11 +289,14 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
307
289
}
308
290
pkgPathPtr := c .pkgPathPtr (pkgpath )
309
291
292
+ // number of methods for a pointer of this type
293
+ ptrms := c .program .MethodSets .MethodSet (types .NewPointer (typ ))
294
+
310
295
llvmStructType := c .getLLVMType (typ )
311
296
size := c .targetData .TypeStoreSize (llvmStructType )
312
297
typeFields = []llvm.Value {
313
- llvm .ConstInt (c .ctx .Int16Type (), uint64 (ms .Len ()), false ), // numMethods
314
- c . getTypeCode ( types . NewPointer ( typ )), // ptrTo
298
+ llvm .ConstInt (c .ctx .Int16Type (), uint64 (ms .Len ()), false ), // numMethods
299
+ llvm . ConstInt ( c . ctx . Int16Type (), uint64 ( ptrms . Len ( )), false ), // ptrNumMethods
315
300
pkgPathPtr ,
316
301
llvm .ConstInt (c .ctx .Int32Type (), uint64 (size ), false ), // size
317
302
llvm .ConstInt (c .ctx .Int16Type (), uint64 (typ .NumFields ()), false ), // numFields
@@ -361,10 +346,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
361
346
}
362
347
typeFields = append (typeFields , llvm .ConstArray (structFieldType , fields ))
363
348
case * types.Interface :
364
- typeFields = []llvm.Value {c . getTypeCode ( types . NewPointer ( typ )) }
349
+ typeFields = []llvm.Value {}
365
350
// TODO: methods
366
351
case * types.Signature :
367
- typeFields = []llvm.Value {c . getTypeCode ( types . NewPointer ( typ )) }
352
+ typeFields = []llvm.Value {}
368
353
// TODO: params, return values, etc
369
354
}
370
355
// Prepend metadata byte.
@@ -377,6 +362,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
377
362
}, typeFields ... )
378
363
}
379
364
alignment := c .targetData .TypeAllocSize (c .i8ptrType )
365
+ // We need at least 4-byte alignment for pointer tagging
366
+ if alignment < 4 {
367
+ alignment = 4
368
+ }
380
369
globalValue := c .ctx .ConstStruct (typeFields , false )
381
370
global .SetInitializer (globalValue )
382
371
if isLocal {
0 commit comments