mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 04:23:41 +00:00
compiler,reflect: fix pkgpath for struct fields
This commit is contained in:
+34
-19
@@ -84,6 +84,27 @@ func (b *builder) extractValueFromInterface(itf llvm.Value, llvmType llvm.Type)
|
||||
return b.emitPointerUnpack(valuePtr, []llvm.Type{llvmType})[0]
|
||||
}
|
||||
|
||||
func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
|
||||
pkgpathName := "reflect/types.type.pkgpath.empty"
|
||||
if pkgpath != "" {
|
||||
pkgpathName = "reflect/types.type.pkgpath:" + pkgpath
|
||||
}
|
||||
|
||||
pkgpathInitializer := c.ctx.ConstString(pkgpath+"\x00", false)
|
||||
pkgpathGlobal := llvm.AddGlobal(c.mod, pkgpathInitializer.Type(), pkgpathName)
|
||||
pkgpathGlobal.SetInitializer(pkgpathInitializer)
|
||||
pkgpathGlobal.SetAlignment(1)
|
||||
pkgpathGlobal.SetUnnamedAddr(true)
|
||||
pkgpathGlobal.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||
pkgpathGlobal.SetGlobalConstant(true)
|
||||
pkgPathPtr := llvm.ConstGEP(pkgpathGlobal.GlobalValueType(), pkgpathGlobal, []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
})
|
||||
|
||||
return pkgPathPtr
|
||||
}
|
||||
|
||||
// getTypeCode returns a reference to a type code.
|
||||
// A type code is a pointer to a constant global that describes the type.
|
||||
// This function returns a pointer to the 'kind' field (which might not be the
|
||||
@@ -141,6 +162,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||
typeFieldTypes = append(typeFieldTypes,
|
||||
types.NewVar(token.NoPos, nil, "numFields", types.Typ[types.Uint16]),
|
||||
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "fields", types.NewArray(c.getRuntimeType("structField"), int64(typ.NumFields()))),
|
||||
)
|
||||
case *types.Interface:
|
||||
@@ -173,31 +195,15 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
|
||||
case *types.Named:
|
||||
name := typ.Obj().Name()
|
||||
|
||||
pkg := typ.Obj().Pkg()
|
||||
var pkgpath string
|
||||
pkgpathName := "reflect/types.type.pkgpath.empty"
|
||||
if pkg != nil {
|
||||
if pkg := typ.Obj().Pkg(); pkg != nil {
|
||||
pkgpath = pkg.Path()
|
||||
pkgpathName = "reflect/types.type.pkgpath:" + pkgpath
|
||||
}
|
||||
|
||||
pkgpathInitializer := c.ctx.ConstString(pkgpath+"\x00", false)
|
||||
pkgpathGlobal := llvm.AddGlobal(c.mod, pkgpathInitializer.Type(), pkgpathName)
|
||||
pkgpathGlobal.SetInitializer(pkgpathInitializer)
|
||||
pkgpathGlobal.SetAlignment(1)
|
||||
pkgpathGlobal.SetUnnamedAddr(true)
|
||||
pkgpathGlobal.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||
pkgpathGlobal.SetGlobalConstant(true)
|
||||
pkgpathPtr := llvm.ConstGEP(pkgpathGlobal.GlobalValueType(), pkgpathGlobal, []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
})
|
||||
|
||||
pkgPathPtr := c.pkgPathPtr(pkgpath)
|
||||
typeFields = []llvm.Value{
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
c.getTypeCode(typ.Underlying()), // underlying
|
||||
pkgpathPtr, // pkgpath pointer
|
||||
pkgPathPtr, // pkgpath pointer
|
||||
c.ctx.ConstString(name+"\x00", false), // name
|
||||
}
|
||||
metabyte |= 1 << 5 // "named" flag
|
||||
@@ -226,9 +232,18 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||
c.getTypeCode(typ.Key()), // key
|
||||
}
|
||||
case *types.Struct:
|
||||
var pkgpath string
|
||||
if typ.NumFields() > 0 {
|
||||
if pkg := typ.Field(0).Pkg(); pkg != nil {
|
||||
pkgpath = pkg.Path()
|
||||
}
|
||||
}
|
||||
pkgPathPtr := c.pkgPathPtr(pkgpath)
|
||||
|
||||
typeFields = []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int16Type(), uint64(typ.NumFields()), false), // numFields
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
pkgPathPtr,
|
||||
}
|
||||
structFieldType := c.getLLVMRuntimeType("structField")
|
||||
var fields []llvm.Value
|
||||
|
||||
Reference in New Issue
Block a user