From 26530fc103b92f8ea0f0b05c83cdc17f4a61a033 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Thu, 26 Sep 2024 11:29:05 +0200 Subject: [PATCH 1/8] fix(gnovm): add bug files --- bug/bug.gno | 23 +++++++++++++++++++++++ bug/bug.go | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 bug/bug.gno create mode 100644 bug/bug.go diff --git a/bug/bug.gno b/bug/bug.gno new file mode 100644 index 00000000000..0a6856be192 --- /dev/null +++ b/bug/bug.gno @@ -0,0 +1,23 @@ +package main + +import "fmt" + +type Role struct { + name string + permissions []string + users []string + next *Role + prev *Role +} + +func main() { + userRole := &Role{ + name: "user", + permissions: []string{}, + users: []string{}, + next: nil, + prev: nil, + } + + fmt.Printf("%v", userRole) +} diff --git a/bug/bug.go b/bug/bug.go new file mode 100644 index 00000000000..0a6856be192 --- /dev/null +++ b/bug/bug.go @@ -0,0 +1,23 @@ +package main + +import "fmt" + +type Role struct { + name string + permissions []string + users []string + next *Role + prev *Role +} + +func main() { + userRole := &Role{ + name: "user", + permissions: []string{}, + users: []string{}, + next: nil, + prev: nil, + } + + fmt.Printf("%v", userRole) +} From f7d7125e03f4c3c94a23b71efbb1e4e892197815 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Fri, 27 Sep 2024 12:23:36 +0200 Subject: [PATCH 2/8] fix(gno): add seen variable in struct type to avoid recursive errors --- bug/bug.gno | 27 +++++++++++++++++---------- gnovm/pkg/gnolang/gonative.go | 4 ++++ gnovm/pkg/gnolang/types.go | 1 + 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/bug/bug.gno b/bug/bug.gno index 0a6856be192..ed5024f83b5 100644 --- a/bug/bug.gno +++ b/bug/bug.gno @@ -3,20 +3,27 @@ package main import "fmt" type Role struct { - name string - permissions []string - users []string - next *Role - prev *Role + Name string + Permissions []string + Users []string + Next *Role + Prev *Role + PermissionData *Permission +} + +type Permission struct { + Name string + Resource string } func main() { userRole := &Role{ - name: "user", - permissions: []string{}, - users: []string{}, - next: nil, - prev: nil, + Name: "user", + Permissions: []string{}, + Users: []string{}, + Next: nil, + Prev: nil, + PermissionData: &Permission{"Hello", "Test"}, } fmt.Printf("%v", userRole) diff --git a/gnovm/pkg/gnolang/gonative.go b/gnovm/pkg/gnolang/gonative.go index 6127fa42b07..501a9b88d00 100644 --- a/gnovm/pkg/gnolang/gonative.go +++ b/gnovm/pkg/gnolang/gonative.go @@ -834,7 +834,11 @@ func gno2GoType(t Type) reflect.Type { et := gno2GoType(ct.Elem()) return reflect.SliceOf(et) case *StructType: + if ct.seen { + return reflect.StructOf([]reflect.StructField{}) + } gfs := make([]reflect.StructField, len(ct.Fields)) + ct.seen = true for i, field := range ct.Fields { gft := gno2GoType(field.Type) fn := string(field.Name) diff --git a/gnovm/pkg/gnolang/types.go b/gnovm/pkg/gnolang/types.go index b43f623ea99..d6d6d1085a0 100644 --- a/gnovm/pkg/gnolang/types.go +++ b/gnovm/pkg/gnolang/types.go @@ -734,6 +734,7 @@ type StructType struct { PkgPath string Fields []FieldType + seen bool typeid TypeID } From 423a87d905c7ef0d0dae5c9f450eb053bd026250 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:07:39 +0200 Subject: [PATCH 3/8] fix(gno): add seen stack to keep track of already processed struct --- bug/bug.gno | 4 +-- bug/bug2.gno | 50 +++++++++++++++++++++++++++++++++++ gnovm/pkg/gnolang/gonative.go | 27 ++++++++++--------- gnovm/pkg/gnolang/types.go | 1 - 4 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 bug/bug2.gno diff --git a/bug/bug.gno b/bug/bug.gno index ed5024f83b5..0f5dfdfe5e1 100644 --- a/bug/bug.gno +++ b/bug/bug.gno @@ -8,7 +8,7 @@ type Role struct { Users []string Next *Role Prev *Role - PermissionData *Permission + PermissionData Permission } type Permission struct { @@ -23,7 +23,7 @@ func main() { Users: []string{}, Next: nil, Prev: nil, - PermissionData: &Permission{"Hello", "Test"}, + PermissionData: Permission{"Hello", "Test"}, } fmt.Printf("%v", userRole) diff --git a/bug/bug2.gno b/bug/bug2.gno new file mode 100644 index 00000000000..7f797c64428 --- /dev/null +++ b/bug/bug2.gno @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" + "errors" + "io" + "time" +) + +type Header map[string][]string + +type Values map[string][]string + +type Request struct { + Method string + Proto string // "HTTP/1.0" + ProtoMajor int // 1 + ProtoMinor int // 0 + Header Header + ContentLength int64 + TransferEncoding []string + Close bool + Host string +} + +type Response struct { + Status string // e.g. "200 OK" + StatusCode int // e.g. 200 + Proto string // e.g. "HTTP/1.0" + ProtoMajor int // e.g. 1 + ProtoMinor int // e.g. 0 +} + +type extendedRequest struct { + Request2 Request + + Data string +} + +func main() { + r := extendedRequest{} + req := &r.Request2 + + fmt.Println(r) + fmt.Println(req) +} + +// Output: +// {{ 0 0 map[] 0 [] false map[] map[] map[] } } +// &{ 0 0 map[] 0 [] false map[] map[] map[] } diff --git a/gnovm/pkg/gnolang/gonative.go b/gnovm/pkg/gnolang/gonative.go index 501a9b88d00..e74274b5719 100644 --- a/gnovm/pkg/gnolang/gonative.go +++ b/gnovm/pkg/gnolang/gonative.go @@ -778,7 +778,7 @@ func go2GnoValue2(alloc *Allocator, store Store, rv reflect.Value, recursive boo // NOTE: Recursive types are not supported, as named types are not // supported. See https://github.com/golang/go/issues/20013 and // https://github.com/golang/go/issues/39717. -func gno2GoType(t Type) reflect.Type { +func gno2GoType(t Type, seen map[Type]reflect.Type) reflect.Type { // special case if t == Float32Type or Float64Type if t == Float32Type { return reflect.TypeOf(float32(0.0)) @@ -824,23 +824,26 @@ func gno2GoType(t Type) reflect.Type { panic("should not happen") } case *PointerType: - et := gno2GoType(ct.Elem()) + et := gno2GoType(ct.Elem(), seen) return reflect.PointerTo(et) case *ArrayType: ne := ct.Len - et := gno2GoType(ct.Elem()) + et := gno2GoType(ct.Elem(), seen) return reflect.ArrayOf(ne, et) case *SliceType: - et := gno2GoType(ct.Elem()) + et := gno2GoType(ct.Elem(), seen) return reflect.SliceOf(et) case *StructType: - if ct.seen { - return reflect.StructOf([]reflect.StructField{}) + if val, ok := seen[t]; ok { + return val } + + placeholder := reflect.TypeOf(struct{}{}) + seen[t] = placeholder + gfs := make([]reflect.StructField, len(ct.Fields)) - ct.seen = true for i, field := range ct.Fields { - gft := gno2GoType(field.Type) + gft := gno2GoType(field.Type, seen) fn := string(field.Name) pkgPath := "" if !isUpper(fn) { @@ -858,8 +861,8 @@ func gno2GoType(t Type) reflect.Type { } return reflect.StructOf(gfs) case *MapType: - kt := gno2GoType(ct.Key) - vt := gno2GoType(ct.Value) + kt := gno2GoType(ct.Key, seen) + vt := gno2GoType(ct.Value, seen) return reflect.MapOf(kt, vt) case *FuncType: panic("not yet supported") @@ -1054,7 +1057,7 @@ func gno2GoValue(tv *TypedValue, rv reflect.Value) (ret reflect.Value) { var rt reflect.Type bt := baseOf(tv.T) if !rv.IsValid() { - rt = gno2GoType(bt) + rt = gno2GoType(bt, make(map[Type]reflect.Type)) rv = reflect.New(rt).Elem() ret = rv } else if rv.Kind() == reflect.Interface { @@ -1063,7 +1066,7 @@ func gno2GoValue(tv *TypedValue, rv reflect.Value) (ret reflect.Value) { panic("should not happen") } } - rt = gno2GoType(bt) + rt = gno2GoType(bt, make(map[Type]reflect.Type)) rv1 := rv rv2 := reflect.New(rt).Elem() rv = rv2 // swaparoo diff --git a/gnovm/pkg/gnolang/types.go b/gnovm/pkg/gnolang/types.go index d6d6d1085a0..b43f623ea99 100644 --- a/gnovm/pkg/gnolang/types.go +++ b/gnovm/pkg/gnolang/types.go @@ -734,7 +734,6 @@ type StructType struct { PkgPath string Fields []FieldType - seen bool typeid TypeID } From 776daa105e141fc4784fa7dd4558e62594f0e4a4 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:23:21 +0200 Subject: [PATCH 4/8] chore: remove bug files --- bug/bug.gno | 30 --------------------- bug/bug.go | 23 ---------------- bug/bug2.gno | 50 ----------------------------------- gnovm/pkg/gnolang/gonative.go | 1 - 4 files changed, 104 deletions(-) delete mode 100644 bug/bug.gno delete mode 100644 bug/bug.go delete mode 100644 bug/bug2.gno diff --git a/bug/bug.gno b/bug/bug.gno deleted file mode 100644 index 0f5dfdfe5e1..00000000000 --- a/bug/bug.gno +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import "fmt" - -type Role struct { - Name string - Permissions []string - Users []string - Next *Role - Prev *Role - PermissionData Permission -} - -type Permission struct { - Name string - Resource string -} - -func main() { - userRole := &Role{ - Name: "user", - Permissions: []string{}, - Users: []string{}, - Next: nil, - Prev: nil, - PermissionData: Permission{"Hello", "Test"}, - } - - fmt.Printf("%v", userRole) -} diff --git a/bug/bug.go b/bug/bug.go deleted file mode 100644 index 0a6856be192..00000000000 --- a/bug/bug.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import "fmt" - -type Role struct { - name string - permissions []string - users []string - next *Role - prev *Role -} - -func main() { - userRole := &Role{ - name: "user", - permissions: []string{}, - users: []string{}, - next: nil, - prev: nil, - } - - fmt.Printf("%v", userRole) -} diff --git a/bug/bug2.gno b/bug/bug2.gno deleted file mode 100644 index 7f797c64428..00000000000 --- a/bug/bug2.gno +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "fmt" - "errors" - "io" - "time" -) - -type Header map[string][]string - -type Values map[string][]string - -type Request struct { - Method string - Proto string // "HTTP/1.0" - ProtoMajor int // 1 - ProtoMinor int // 0 - Header Header - ContentLength int64 - TransferEncoding []string - Close bool - Host string -} - -type Response struct { - Status string // e.g. "200 OK" - StatusCode int // e.g. 200 - Proto string // e.g. "HTTP/1.0" - ProtoMajor int // e.g. 1 - ProtoMinor int // e.g. 0 -} - -type extendedRequest struct { - Request2 Request - - Data string -} - -func main() { - r := extendedRequest{} - req := &r.Request2 - - fmt.Println(r) - fmt.Println(req) -} - -// Output: -// {{ 0 0 map[] 0 [] false map[] map[] map[] } } -// &{ 0 0 map[] 0 [] false map[] map[] map[] } diff --git a/gnovm/pkg/gnolang/gonative.go b/gnovm/pkg/gnolang/gonative.go index e74274b5719..fa5400dc6f5 100644 --- a/gnovm/pkg/gnolang/gonative.go +++ b/gnovm/pkg/gnolang/gonative.go @@ -840,7 +840,6 @@ func gno2GoType(t Type, seen map[Type]reflect.Type) reflect.Type { placeholder := reflect.TypeOf(struct{}{}) seen[t] = placeholder - gfs := make([]reflect.StructField, len(ct.Fields)) for i, field := range ct.Fields { gft := gno2GoType(field.Type, seen) From 7b775fcfaeacf5df49d84e07de29f8443bce6b9a Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:42:47 +0200 Subject: [PATCH 5/8] test: add test file --- gnovm/tests/files/a1.gno | 31 ++++++++++++++++---------- gnovm/tests/files/recursive_native.gno | 0 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 gnovm/tests/files/recursive_native.gno diff --git a/gnovm/tests/files/a1.gno b/gnovm/tests/files/a1.gno index cf177e071c0..f3e5bb42fa9 100644 --- a/gnovm/tests/files/a1.gno +++ b/gnovm/tests/files/a1.gno @@ -1,19 +1,26 @@ package main +import "fmt" + +type Role struct { + Name string + Permissions []string + Users []string + Next *Role + Prev *Role +} + func main() { - a := [6]int{1, 2, 3, 4, 5, 6} - println(a[1]) // 2 - for i, v := range a { - println(v) - if i == 3 { - break - } + userRole := &Role{ + Name: "user", + Permissions: []string{}, + Users: []string{}, + Next: nil, + Prev: nil, } + + fmt.Printf("%v", userRole) } // Output: -// 2 -// 1 -// 2 -// 3 -// 4 +// &{user [] [] } \ No newline at end of file diff --git a/gnovm/tests/files/recursive_native.gno b/gnovm/tests/files/recursive_native.gno new file mode 100644 index 00000000000..e69de29bb2d From 69ac182c9478e448d4d96cbcfa1f09a8505c150b Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:47:38 +0200 Subject: [PATCH 6/8] test: add test file --- gnovm/tests/files/recursive_native.gno | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gnovm/tests/files/recursive_native.gno b/gnovm/tests/files/recursive_native.gno index e69de29bb2d..f3e5bb42fa9 100644 --- a/gnovm/tests/files/recursive_native.gno +++ b/gnovm/tests/files/recursive_native.gno @@ -0,0 +1,26 @@ +package main + +import "fmt" + +type Role struct { + Name string + Permissions []string + Users []string + Next *Role + Prev *Role +} + +func main() { + userRole := &Role{ + Name: "user", + Permissions: []string{}, + Users: []string{}, + Next: nil, + Prev: nil, + } + + fmt.Printf("%v", userRole) +} + +// Output: +// &{user [] [] } \ No newline at end of file From 18f3df39049573094c61808f26024c8dae7a9899 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:47:55 +0200 Subject: [PATCH 7/8] test: add test file --- gnovm/tests/files/a1.gno | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/gnovm/tests/files/a1.gno b/gnovm/tests/files/a1.gno index f3e5bb42fa9..cf177e071c0 100644 --- a/gnovm/tests/files/a1.gno +++ b/gnovm/tests/files/a1.gno @@ -1,26 +1,19 @@ package main -import "fmt" - -type Role struct { - Name string - Permissions []string - Users []string - Next *Role - Prev *Role -} - func main() { - userRole := &Role{ - Name: "user", - Permissions: []string{}, - Users: []string{}, - Next: nil, - Prev: nil, + a := [6]int{1, 2, 3, 4, 5, 6} + println(a[1]) // 2 + for i, v := range a { + println(v) + if i == 3 { + break + } } - - fmt.Printf("%v", userRole) } // Output: -// &{user [] [] } \ No newline at end of file +// 2 +// 1 +// 2 +// 3 +// 4 From 49ff9dcaf2839cdb89bed9e15f3fd6d6bf592d23 Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 30 Sep 2024 10:48:42 +0200 Subject: [PATCH 8/8] test: add test file --- gnovm/tests/files/recursive_native.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnovm/tests/files/recursive_native.gno b/gnovm/tests/files/recursive_native.gno index f3e5bb42fa9..afe612221be 100644 --- a/gnovm/tests/files/recursive_native.gno +++ b/gnovm/tests/files/recursive_native.gno @@ -23,4 +23,4 @@ func main() { } // Output: -// &{user [] [] } \ No newline at end of file +// &{user [] [] }