aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/interface.go
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2023-03-08 12:28:51 -0800
committerAyke <[email protected]>2023-03-15 21:53:57 +0100
commit344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1 (patch)
treeacf992732b20db4e11c3da53c9b8ba507cd4dc16 /compiler/interface.go
parent1626b50457c5941e6747b0da1f77aa311b91bda6 (diff)
downloadtinygo-344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1.tar.gz
tinygo-344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1.zip
compiler,reflect: fix pkgpath for struct fields
Diffstat (limited to 'compiler/interface.go')
-rw-r--r--compiler/interface.go53
1 files changed, 34 insertions, 19 deletions
diff --git a/compiler/interface.go b/compiler/interface.go
index b57c59744..d6ed420db 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -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