Skip to content

Commit 9e4f337

Browse files
committed
wip: pointer tagging (broken)
1 parent 6a2dd35 commit 9e4f337

File tree

2 files changed

+92
-108
lines changed

2 files changed

+92
-108
lines changed

compiler/interface.go

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -153,71 +153,56 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
153153
}
154154
switch typ := typ.(type) {
155155
case *types.Basic:
156-
typeFieldTypes = append(typeFieldTypes,
157-
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
158-
)
156+
typeFieldTypes = append(typeFieldTypes)
159157
case *types.Named:
160158
name := typ.Obj().Name()
161159
var pkgname string
162160
if pkg := typ.Obj().Pkg(); pkg != nil {
163161
pkgname = pkg.Name()
164162
}
163+
165164
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]),
168165
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]),
169168
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
170169
types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], int64(len(pkgname)+1+len(name)+1))),
171170
)
172171
case *types.Chan:
173172
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]),
176174
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
177175
)
178176
case *types.Slice:
179177
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]),
182178
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
183179
)
184180
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
189182
case *types.Array:
190183
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]),
193184
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
194185
types.NewVar(token.NoPos, nil, "length", types.Typ[types.Uintptr]),
195186
)
196187
case *types.Map:
197188
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]),
200189
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
201190
types.NewVar(token.NoPos, nil, "keyType", types.Typ[types.UnsafePointer]),
202191
)
203192
case *types.Struct:
204193
typeFieldTypes = append(typeFieldTypes,
205194
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]),
207196
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
208197
types.NewVar(token.NoPos, nil, "size", types.Typ[types.Uint32]),
209198
types.NewVar(token.NoPos, nil, "numFields", types.Typ[types.Uint16]),
210199
types.NewVar(token.NoPos, nil, "fields", types.NewArray(c.getRuntimeType("structField"), int64(typ.NumFields()))),
211200
)
212201
case *types.Interface:
213-
typeFieldTypes = append(typeFieldTypes,
214-
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
215-
)
202+
typeFieldTypes = append(typeFieldTypes)
216203
// TODO: methods
217204
case *types.Signature:
218-
typeFieldTypes = append(typeFieldTypes,
219-
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
220-
)
205+
typeFieldTypes = append(typeFieldTypes)
221206
// TODO: signature params and return values
222207
}
223208
if hasMethodSet {
@@ -239,7 +224,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
239224
metabyte := getTypeKind(typ)
240225
switch typ := typ.(type) {
241226
case *types.Basic:
242-
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
227+
typeFields = []llvm.Value{}
243228
case *types.Named:
244229
name := typ.Obj().Name()
245230
var pkgpath string
@@ -249,12 +234,16 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
249234
pkgname = pkg.Name()
250235
}
251236
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+
252241
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
258247
}
259248
metabyte |= 1 << 5 // "named" flag
260249
case *types.Chan:
@@ -270,33 +259,26 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
270259

271260
typeFields = []llvm.Value{
272261
llvm.ConstInt(c.ctx.Int16Type(), uint64(dir), false), // actually channel direction
273-
c.getTypeCode(types.NewPointer(typ)), // ptrTo
274262
c.getTypeCode(typ.Elem()), // elementType
275263
}
276264
case *types.Slice:
277265
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
281267
}
282268
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+
})
287273
case *types.Array:
288274
typeFields = []llvm.Value{
289-
llvm.ConstInt(c.ctx.Int16Type(), 0, false), // numMethods
290-
c.getTypeCode(types.NewPointer(typ)), // ptrTo
291275
c.getTypeCode(typ.Elem()), // elementType
292276
llvm.ConstInt(c.uintptrType, uint64(typ.Len()), false), // length
293277
}
294278
case *types.Map:
295279
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
300282
}
301283
case *types.Struct:
302284
var pkgpath string
@@ -307,11 +289,14 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
307289
}
308290
pkgPathPtr := c.pkgPathPtr(pkgpath)
309291

292+
// number of methods for a pointer of this type
293+
ptrms := c.program.MethodSets.MethodSet(types.NewPointer(typ))
294+
310295
llvmStructType := c.getLLVMType(typ)
311296
size := c.targetData.TypeStoreSize(llvmStructType)
312297
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
315300
pkgPathPtr,
316301
llvm.ConstInt(c.ctx.Int32Type(), uint64(size), false), // size
317302
llvm.ConstInt(c.ctx.Int16Type(), uint64(typ.NumFields()), false), // numFields
@@ -361,10 +346,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
361346
}
362347
typeFields = append(typeFields, llvm.ConstArray(structFieldType, fields))
363348
case *types.Interface:
364-
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
349+
typeFields = []llvm.Value{}
365350
// TODO: methods
366351
case *types.Signature:
367-
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
352+
typeFields = []llvm.Value{}
368353
// TODO: params, return values, etc
369354
}
370355
// Prepend metadata byte.
@@ -377,6 +362,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
377362
}, typeFields...)
378363
}
379364
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+
}
380369
globalValue := c.ctx.ConstStruct(typeFields, false)
381370
global.SetInitializer(globalValue)
382371
if isLocal {

0 commit comments

Comments
 (0)