diff options
author | Damian Gryski <[email protected]> | 2023-03-08 12:28:51 -0800 |
---|---|---|
committer | Ayke <[email protected]> | 2023-03-15 21:53:57 +0100 |
commit | 344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1 (patch) | |
tree | acf992732b20db4e11c3da53c9b8ba507cd4dc16 /compiler/interface.go | |
parent | 1626b50457c5941e6747b0da1f77aa311b91bda6 (diff) | |
download | tinygo-344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1.tar.gz tinygo-344e493ac8fa3a3f3bcfcd0ec91e237f01d01dc1.zip |
compiler,reflect: fix pkgpath for struct fields
Diffstat (limited to 'compiler/interface.go')
-rw-r--r-- | compiler/interface.go | 53 |
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 |