aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler
diff options
context:
space:
mode:
authorfrenkel26 <[email protected]>2024-05-28 15:09:59 +0300
committerGitHub <[email protected]>2024-05-28 14:09:59 +0200
commitf7c0466f78fe97c578f298de639fd5248cc91ee4 (patch)
treebd196d5c649f3f15a27e01d7a1d7630cfa40130b /compiler
parent81ce7fb738142361afba119f1f531cf6ffddc6d1 (diff)
downloadtinygo-f7c0466f78fe97c578f298de639fd5248cc91ee4.tar.gz
tinygo-f7c0466f78fe97c578f298de639fd5248cc91ee4.zip
compiler,reflect: fix NumMethods for Interface type
Diffstat (limited to 'compiler')
-rw-r--r--compiler/interface.go15
-rw-r--r--compiler/testdata/interface.ll2
2 files changed, 10 insertions, 7 deletions
diff --git a/compiler/interface.go b/compiler/interface.go
index 564e3a414..b6dffd643 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -124,16 +124,19 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
ms := c.program.MethodSets.MethodSet(typ)
hasMethodSet := ms.Len() != 0
- if _, ok := typ.Underlying().(*types.Interface); ok {
+ _, isInterface := typ.Underlying().(*types.Interface)
+ if isInterface {
hasMethodSet = false
}
+ // As defined in https://pkg.go.dev/reflect#Type:
+ // NumMethod returns the number of methods accessible using Method.
+ // For a non-interface type, it returns the number of exported methods.
+ // For an interface type, it returns the number of exported and unexported methods.
var numMethods int
- if hasMethodSet {
- for i := 0; i < ms.Len(); i++ {
- if ms.At(i).Obj().Exported() {
- numMethods++
- }
+ for i := 0; i < ms.Len(); i++ {
+ if isInterface || ms.At(i).Obj().Exported() {
+ numMethods++
}
}
diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll
index ff3a04d91..801f370d5 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 -62, ptr @"reflect/types.type:pointer:basic:int" }, align 4
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:named:error" }, align 4
-@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 0, 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:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, 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 84, 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 -43, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4