Skip to content

Commit

Permalink
fix(gno): add seen stack to keep track of already processed struct
Browse files Browse the repository at this point in the history
  • Loading branch information
MikaelVallenet committed Sep 30, 2024
1 parent f7d7125 commit 423a87d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 15 deletions.
4 changes: 2 additions & 2 deletions bug/bug.gno
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Role struct {
Users []string
Next *Role
Prev *Role
PermissionData *Permission
PermissionData Permission
}

type Permission struct {
Expand All @@ -23,7 +23,7 @@ func main() {
Users: []string{},
Next: nil,
Prev: nil,
PermissionData: &Permission{"Hello", "Test"},
PermissionData: Permission{"Hello", "Test"},
}

fmt.Printf("%v", userRole)
Expand Down
50 changes: 50 additions & 0 deletions bug/bug2.gno
Original file line number Diff line number Diff line change
@@ -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[] <nil> 0 [] false map[] map[] map[] <nil>} }
// &{ 0 0 map[] <nil> 0 [] false map[] map[] map[] <nil>}
27 changes: 15 additions & 12 deletions gnovm/pkg/gnolang/gonative.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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) {
Expand All @@ -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")
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion gnovm/pkg/gnolang/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,6 @@ type StructType struct {
PkgPath string
Fields []FieldType

seen bool
typeid TypeID
}

Expand Down

0 comments on commit 423a87d

Please sign in to comment.