aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2023-03-13 14:49:51 -0700
committerRon Evans <[email protected]>2023-03-19 17:45:43 +0100
commit876f08979f0aee9b6ebb66603c76cdcc1e4729eb (patch)
tree986c11854d0ee1805ddbc28dcf21cdf89e7701a1
parentf2cc98caa57846ecdbcc35f61d13fa6a1d6ea2e9 (diff)
downloadtinygo-876f08979f0aee9b6ebb66603c76cdcc1e4729eb.tar.gz
tinygo-876f08979f0aee9b6ebb66603c76cdcc1e4729eb.zip
compiler,reflect: sort out pkg path vs pkg name for named types
-rw-r--r--compiler/interface.go11
-rw-r--r--compiler/testdata/interface.ll2
-rw-r--r--src/reflect/type.go24
-rw-r--r--src/reflect/value_test.go5
4 files changed, 31 insertions, 11 deletions
diff --git a/compiler/interface.go b/compiler/interface.go
index bc2cbf336..2d6c4a7f7 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -134,12 +134,17 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
)
case *types.Named:
+ name := typ.Obj().Name()
+ var pkgname string
+ if pkg := typ.Obj().Pkg(); pkg != nil {
+ pkgname = pkg.Name()
+ }
typeFieldTypes = append(typeFieldTypes,
types.NewVar(token.NoPos, nil, "numMethods", types.Typ[types.Uint16]),
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
types.NewVar(token.NoPos, nil, "underlying", types.Typ[types.UnsafePointer]),
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
- types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], 1+int64(len(typ.Obj().Name())))),
+ types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], int64(len(pkgname)+1+len(name)+1))),
)
case *types.Chan, *types.Slice:
typeFieldTypes = append(typeFieldTypes,
@@ -205,8 +210,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
case *types.Named:
name := typ.Obj().Name()
var pkgpath string
+ var pkgname string
if pkg := typ.Obj().Pkg(); pkg != nil {
pkgpath = pkg.Path()
+ pkgname = pkg.Name()
}
pkgPathPtr := c.pkgPathPtr(pkgpath)
typeFields = []llvm.Value{
@@ -214,7 +221,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
c.getTypeCode(types.NewPointer(typ)), // ptrTo
c.getTypeCode(typ.Underlying()), // underlying
pkgPathPtr, // pkgpath pointer
- c.ctx.ConstString(name+"\x00", false), // name
+ c.ctx.ConstString(pkgname+"."+name+"\x00", false), // name
}
metabyte |= 1 << 5 // "named" flag
case *types.Chan:
diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll
index 4322b5543..de37341a3 100644
--- a/compiler/testdata/interface.ll
+++ b/compiler/testdata/interface.ll
@@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi"
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 2, ptr @"reflect/types.type:pointer:basic:int" }, align 4
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 21, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 21, i16 0, ptr @"reflect/types.type:named:error" }, align 4
-@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [6 x i8] } { i8 52, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [6 x i8] c"error\00" }, align 4
+@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 52, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 20, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 21, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 79ca6e5f1..cc79a7095 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -504,13 +504,11 @@ func pointerTo(t *rawType) *rawType {
func (t *rawType) String() string {
if t.isNamed() {
- path := t.PkgPath()
- slash := len(path) - 1
- for slash >= 0 && path[slash] != '/' {
- slash--
+ s := t.name()
+ if s[0] == '.' {
+ return s[1:]
}
- shortened := path[slash+1:]
- return shortened + "." + t.Name()
+ return s
}
switch t.Kind() {
@@ -1037,10 +1035,20 @@ func readStringZ(data unsafe.Pointer) string {
}))
}
+func (t *rawType) name() string {
+ ntype := (*namedType)(unsafe.Pointer(t))
+ return readStringZ(unsafe.Pointer(&ntype.name[0]))
+}
+
func (t *rawType) Name() string {
if t.isNamed() {
- ntype := (*namedType)(unsafe.Pointer(t))
- return readStringZ(unsafe.Pointer(&ntype.name[0]))
+ name := t.name()
+ for i := 0; i < len(name); i++ {
+ if name[i] == '.' {
+ return name[i+1:]
+ }
+ }
+ panic("corrupt name data")
}
if t.Kind() <= UnsafePointer {
diff --git a/src/reflect/value_test.go b/src/reflect/value_test.go
index 5c36f25d4..c915a36db 100644
--- a/src/reflect/value_test.go
+++ b/src/reflect/value_test.go
@@ -243,6 +243,11 @@ func TestNamedTypes(t *testing.T) {
t.Errorf("TypeOf.String()=%v, want %v", got, want)
}
+ errorType := TypeOf((*error)(nil)).Elem()
+ if s := errorType.String(); s != "error" {
+ t.Errorf("error type = %v, want error", s)
+ }
+
m := make(map[[4]uint16]string)
if got, want := TypeOf(m).String(), "map[[4]uint16]string"; got != want {