diff --git a/examples/gno.land/p/demo/avl/z_0_filetest.gno b/examples/gno.land/p/demo/avl/z_0_filetest.gno index e3f1363e205..4e6e8fe090e 100644 --- a/examples/gno.land/p/demo/avl/z_0_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_0_filetest.gno @@ -24,9 +24,9 @@ func main() { // Realm: // switchrealm["gno.land/r/test"] -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4]={ +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:3]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "ModTime": "7", // "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", // "RefCount": "1" @@ -38,8 +38,8 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "627e8e517e7ae5db0f3b753e2a32b607989198b6", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5" +// "Hash": "54bef18ac963dd67ad0634eac6b75a2c4a733b97", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4" // } // } // } @@ -162,8 +162,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "6da365f0d6cacbcdf53cd5a4b125803cddce08c2", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4" +// "Hash": "ce8be5b209e8f322bf1b15c854275064d5645741", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3" // }, // "Index": "0", // "TV": null @@ -210,7 +210,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "ff1a50d8489090af37a2c7766d659f0d717939b5", +// "Hash": "da7583511e84b52e256a57deabe5b390d875407d", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" // } // } @@ -237,6 +237,25 @@ func main() { // "Values": [ // { // "T": { +// "@type": "/gno.PointerType", +// "Elt": { +// "@type": "/gno.RefType", +// "ID": "gno.land/p/demo/avl.Node" +// } +// }, +// "V": { +// "@type": "/gno.PointerValue", +// "Base": { +// "@type": "/gno.RefValue", +// "Hash": "e925bb6bf884ece9620dd27f831dc510b5bc0e55", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" +// }, +// "Index": "0", +// "TV": null +// } +// }, +// { +// "T": { // "@type": "/gno.FuncType", // "Params": [], // "Results": [] @@ -246,11 +265,11 @@ func main() { // "Closure": { // "@type": "/gno.RefValue", // "Escaped": true, -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3" +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5" // }, // "FileName": "main.gno", // "IsMethod": false, -// "Name": "init.0", +// "Name": "init.1", // "NativeName": "", // "NativePkg": "", // "PkgPath": "gno.land/r/test", @@ -282,7 +301,7 @@ func main() { // "Closure": { // "@type": "/gno.RefValue", // "Escaped": true, -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3" +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5" // }, // "FileName": "main.gno", // "IsMethod": false, @@ -306,25 +325,6 @@ func main() { // "Results": [] // } // } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "ae86874f9b47fa5e64c30b3e92e9d07f2ec967a4", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" -// }, -// "Index": "0", -// "TV": null -// } // } // ] // } diff --git a/examples/gno.land/p/demo/avl/z_1_filetest.gno b/examples/gno.land/p/demo/avl/z_1_filetest.gno index a6d2205e240..fe39965f8e1 100644 --- a/examples/gno.land/p/demo/avl/z_1_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_1_filetest.gno @@ -143,8 +143,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "2f3adc5d0f2a3fe0331cfa93572a7abdde14c9aa", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8" +// "Hash": "b4d88f4e396525f5dd9b2f6599531cc7a9910fc2", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" // }, // "Index": "0", // "TV": null @@ -191,7 +191,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "fe20a19f956511f274dc77854e9e5468387260f4", +// "Hash": "e64dc27f430466fcf8c0bf21aea298161687ca6d", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13" // } // } @@ -235,8 +235,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "c89a71bdf045e8bde2059dc9d33839f916e02e5d", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" +// "Hash": "0798652a2645fc6cce744f50fc3b0c8b74644273", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5" // }, // "Index": "0", // "TV": null @@ -254,7 +254,7 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "90fa67f8c47db4b9b2a60425dff08d5a3385100f", +// "Hash": "45c144eab89443ba7649622f95f7b4afe4f1c2ed", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" // }, // "Index": "0", @@ -283,7 +283,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "83e42caaf53070dd95b5f859053eb51ed900bbda", +// "Hash": "f30d9cde2b4b6bb35e422712f4f2a60e3e0d6ebb", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" // } // } @@ -310,6 +310,25 @@ func main() { // "Values": [ // { // "T": { +// "@type": "/gno.PointerType", +// "Elt": { +// "@type": "/gno.RefType", +// "ID": "gno.land/p/demo/avl.Node" +// } +// }, +// "V": { +// "@type": "/gno.PointerValue", +// "Base": { +// "@type": "/gno.RefValue", +// "Hash": "38137d7532c4cf5c5d1997db211f4144946d2c94", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10" +// }, +// "Index": "0", +// "TV": null +// } +// }, +// { +// "T": { // "@type": "/gno.FuncType", // "Params": [], // "Results": [] @@ -319,11 +338,11 @@ func main() { // "Closure": { // "@type": "/gno.RefValue", // "Escaped": true, -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3" +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" // }, // "FileName": "main.gno", // "IsMethod": false, -// "Name": "init.0", +// "Name": "init.1", // "NativeName": "", // "NativePkg": "", // "PkgPath": "gno.land/r/test", @@ -355,7 +374,7 @@ func main() { // "Closure": { // "@type": "/gno.RefValue", // "Escaped": true, -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3" +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" // }, // "FileName": "main.gno", // "IsMethod": false, @@ -379,27 +398,8 @@ func main() { // "Results": [] // } // } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "1faa9fa4ba1935121a6d3f0a623772e9d4499b0a", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10" -// }, -// "Index": "0", -// "TV": null -// } // } // ] // } +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:3] // d[a8ada09dee16d791fd406d629fe29bb0ed084a30:4] -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:5] diff --git a/examples/gno.land/p/demo/avl/z_2_filetest.gno b/examples/gno.land/p/demo/avl/z_2_filetest.gno index 1d3f20651ed..4c518bcfca0 100644 --- a/examples/gno.land/p/demo/avl/z_2_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_2_filetest.gno @@ -142,8 +142,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "849a50d6c78d65742752e3c89ad8dd556e2e63cb", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" +// "Hash": "2f3adc5d0f2a3fe0331cfa93572a7abdde14c9aa", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8" // }, // "Index": "0", // "TV": null @@ -190,7 +190,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "a1160b0060ad752dbfe5fe436f7734bb19136150", +// "Hash": "6d04e651e14c3a835599a39c4092d3bf50a95b8e", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14" // } // } @@ -234,8 +234,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "fd95e08763159ac529e26986d652e752e78b6325", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" +// "Hash": "c89a71bdf045e8bde2059dc9d33839f916e02e5d", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" // }, // "Index": "0", // "TV": null @@ -253,7 +253,7 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "3ecdcf148fe2f9e97b72a3bedf303b2ba56d4f4b", +// "Hash": "71500837a7725bfb1acd92d2a7c2c522fb01dcba", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13" // }, // "Index": "0", @@ -272,7 +272,7 @@ func main() { // "ObjectInfo": { // "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "RefCount": "1" // }, // "Value": { @@ -282,12 +282,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "63126557dba88f8556f7a0ccbbfc1d218ae7a302", +// "Hash": "4ba75a3b7d996edbfd3c26c0538db48467fccc66", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" // } // } // } -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4]={ +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:3]={ // "Fields": [ // { // "T": { @@ -301,7 +301,7 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "425bc3bff1f4c36b175d055ed8b2c289123fcca1", +// "Hash": "76ac814ba85d9f87cff4964d34c81684f02b0584", // "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" // }, // "Index": "0", @@ -310,11 +310,11 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "ModTime": "10", // "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", // "RefCount": "1" // } // } +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:4] // d[a8ada09dee16d791fd406d629fe29bb0ed084a30:5] -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:6] diff --git a/examples/gno.land/r/demo/boards/z_4_filetest.gno b/examples/gno.land/r/demo/boards/z_4_filetest.gno index a8b932db892..f0620c28c9d 100644 --- a/examples/gno.land/r/demo/boards/z_4_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_4_filetest.gno @@ -336,7 +336,7 @@ func main() { // "Escaped": true, // "ObjectID": "336074805fc853987abe6f7fe3ad97a6a6f3077a:2" // }, -// "Index": "192", +// "Index": "182", // "TV": null // } // } @@ -497,7 +497,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "f56a463a97d103e183f1f368bf00a2ce99d4de88", +// "Hash": "0fd3352422af0a56a77ef2c9e88f479054e3d51f", // "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:131" // } // }, @@ -534,7 +534,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "0651ea376feea18422dbe079f9d7fcbe3dfd32ad", +// "Hash": "c45bbd47a46681a63af973db0ec2180922e4a8ae", // "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127" // } // } @@ -785,7 +785,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "1d70015c486ccc9bfb7c425152605fabc78be1dd", +// "Hash": "a416a751c3a45a1e5cba11e737c51340b081e372", // "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:86" // } // }, @@ -803,7 +803,7 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "b8ee1687a4f45886912ba624c8513a2a1526b94c", +// "Hash": "36299fccbc13f2a84c4629fad4cb940f0bd4b1c6", // "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:87" // } // }, diff --git a/examples/gno.land/r/demo/nft/z_0_filetest.gno b/examples/gno.land/r/demo/nft/z_0_filetest.gno index 0595e76a0ed..c72c9191b56 100644 --- a/examples/gno.land/r/demo/nft/z_0_filetest.gno +++ b/examples/gno.land/r/demo/nft/z_0_filetest.gno @@ -161,7 +161,7 @@ func main() { // "ObjectInfo": { // "ID": "67c479d3d51d4056b2f4111d5352912a00be311e:8", // "ModTime": "0", -// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:6", +// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:5", // "RefCount": "1" // }, // "Value": { @@ -176,7 +176,7 @@ func main() { // } // } // } -// u[67c479d3d51d4056b2f4111d5352912a00be311e:6]={ +// u[67c479d3d51d4056b2f4111d5352912a00be311e:5]={ // "Fields": [ // { // "T": { @@ -190,7 +190,7 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "75850e56fa2c3c8b6d6814b1f150919b75355752", +// "Hash": "b229b824842ec3e7f2341e33d0fa0ca77af2f480", // "ObjectID": "67c479d3d51d4056b2f4111d5352912a00be311e:8" // }, // "Index": "0", @@ -199,13 +199,13 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "67c479d3d51d4056b2f4111d5352912a00be311e:6", +// "ID": "67c479d3d51d4056b2f4111d5352912a00be311e:5", // "ModTime": "7", -// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:5", +// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:4", // "RefCount": "1" // } // } -// u[67c479d3d51d4056b2f4111d5352912a00be311e:5]={ +// u[67c479d3d51d4056b2f4111d5352912a00be311e:4]={ // "Fields": [ // {}, // { @@ -222,8 +222,8 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "700d932c087f30499941de2b589867dc17aaea5a", -// "ObjectID": "67c479d3d51d4056b2f4111d5352912a00be311e:6" +// "Hash": "1e0b9dddb406b4f50500a022266a4cb8a4ea38c6", +// "ObjectID": "67c479d3d51d4056b2f4111d5352912a00be311e:5" // } // }, // { @@ -233,15 +233,15 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "e06585aff551113920c929453ea40250f3cc01bc", -// "ObjectID": "67c479d3d51d4056b2f4111d5352912a00be311e:7" +// "Hash": "05ab6746ea84b55ca133806af215d99a1c4b045e", +// "ObjectID": "67c479d3d51d4056b2f4111d5352912a00be311e:6" // } // } // ], // "ObjectInfo": { -// "ID": "67c479d3d51d4056b2f4111d5352912a00be311e:5", +// "ID": "67c479d3d51d4056b2f4111d5352912a00be311e:4", // "ModTime": "7", -// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:4", +// "OwnerID": "67c479d3d51d4056b2f4111d5352912a00be311e:3", // "RefCount": "1" // } // } diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 79841682c13..782b0c75b83 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -1950,9 +1950,7 @@ func (m *Machine) PopAsPointer(lx Expr) PointerValue { lb := m.LastBlock() return lb.GetPointerToHeapUse(m.Store, lx.Path) case NameExprTypeHeapClosure: - // XXX - lb := m.LastBlock() - return lb.GetPointerTo(m.Store, lx.Path) + panic("should not happen") default: panic("unexpected NameExpr in PopAsPointer") } diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index 2f4eb895904..8526cecf53d 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -209,6 +209,13 @@ func (attr *Attributes) SetAttribute(key GnoAttribute, value interface{}) { attr.data[key] = value } +func (attr *Attributes) DelAttribute(key GnoAttribute) { + if attr.data == nil { + panic("should not happen, attribute is expected to be non-empty.") + } + delete(attr.data, key) +} + // ---------------------------------------- // Node @@ -223,6 +230,7 @@ type Node interface { HasAttribute(key GnoAttribute) bool GetAttribute(key GnoAttribute) interface{} SetAttribute(key GnoAttribute, value interface{}) + DelAttribute(key GnoAttribute) } // non-pointer receiver to help make immutable. @@ -607,11 +615,15 @@ func (ftxz FieldTypeExprs) IsNamed() bool { named := false for i, ftx := range ftxz { if i == 0 { - named = ftx.Name != "" + if ftx.Name == "" || strings.HasPrefix(string(ftx.Name), ".res_") { + named = false + } else { + named = true + } } else { if named && ftx.Name == "" { panic("[]FieldTypeExpr has inconsistent namedness (starts named)") - } else if !named && ftx.Name != "" { + } else if !named && (ftx.Name != "" || !strings.HasPrefix(string(ftx.Name), ".res_")) { panic("[]FieldTypeExpr has inconsistent namedness (starts unnamed)") } } diff --git a/gnovm/pkg/gnolang/op_call.go b/gnovm/pkg/gnolang/op_call.go index 12655f5689d..ef0fbc7667a 100644 --- a/gnovm/pkg/gnolang/op_call.go +++ b/gnovm/pkg/gnolang/op_call.go @@ -57,6 +57,19 @@ func (m *Machine) doOpCall() { // Create new block scope. clo := fr.Func.GetClosure(m.Store) b := m.Alloc.NewBlock(fr.Func.GetSource(m.Store), clo) + + // Copy *FuncValue.Captures into block + // NOTE: addHeapCapture in preprocess ensures order. + // XXX, actually copy + if len(fv.Captures) != 0 { + if len(fv.Captures) > len(b.Values) { + panic("should not happen, length of captured variables must not exceed the number of values") + } + for i := 0; i < len(fv.Captures); i++ { + b.Values[len(b.Values)-len(fv.Captures)+i] = fv.Captures[i].Copy(m.Alloc) + } + } + m.PushBlock(b) if fv.nativeBody == nil && fv.NativePkg != "" { // native function, unmarshaled so doesn't have nativeBody yet @@ -168,10 +181,6 @@ func (m *Machine) doOpCall() { // as a pointer, *StructValue, for example. b.Values[i] = pv.Copy(m.Alloc) } - // Copy *FuncValue.Captures into block - // NOTE: addHeapCapture in preprocess ensures order. - // XXX I think we can copy into the last len(.Captures) items of b.Values. - // XXX actually copy } func (m *Machine) doOpCallNativeBody() { @@ -292,6 +301,15 @@ func (m *Machine) doOpReturnCallDefers() { // Create new block scope for defer. clo := dfr.Func.GetClosure(m.Store) b := m.Alloc.NewBlock(fv.GetSource(m.Store), clo) + // copy values from captures + if len(fv.Captures) != 0 { + if len(fv.Captures) > len(b.Values) { + panic("should not happen, length of captured variables must not exceed the number of values") + } + for i := 0; i < len(fv.Captures); i++ { + b.Values[len(b.Values)-len(fv.Captures)+i] = fv.Captures[i].Copy(m.Alloc) + } + } m.PushBlock(b) if fv.nativeBody == nil { fbody := fv.GetBodyFromSource(m.Store) diff --git a/gnovm/pkg/gnolang/op_expressions.go b/gnovm/pkg/gnolang/op_expressions.go index d7d2994d6c8..7f91aed4701 100644 --- a/gnovm/pkg/gnolang/op_expressions.go +++ b/gnovm/pkg/gnolang/op_expressions.go @@ -753,6 +753,7 @@ func (m *Machine) doOpFuncLit() { ft := m.PopValue().V.(TypeValue).Type.(*FuncType) lb := m.LastBlock() m.Alloc.AllocateFunc() + // First copy closure captured heap values // to *FuncValue. Later during doOpCall a block // will be created that copies these values for @@ -763,6 +764,12 @@ func (m *Machine) doOpFuncLit() { // XXX check that ptr.TV is a heap item value. // it must be in the form of: // {T:heapItemType{},V:HeapItemValue{...}} + if _, ok := ptr.TV.T.(heapItemType); !ok { + panic("should not happen, should be heapItemType") + } + if _, ok := ptr.TV.V.(*HeapItemValue); !ok { + panic("should not happen, should be heapItemValue") + } captures = append(captures, *ptr.TV) } m.PushValue(TypedValue{ diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 2ecad2cb061..cda38549468 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -109,7 +109,6 @@ func PredefineFileSet(store Store, pn *PackageNode, fset *FileSet) { // Initialize static block info. func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { - // create stack of BlockNodes. var stack []BlockNode = make([]BlockNode, 0, 32) var last BlockNode = ctx @@ -136,7 +135,7 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { if ln == blankIdentifier { continue } - if isLocallyDefined(last, ln) { + if isLocallyDefined2(last, ln) { // already defined, do nothing } else { // if loop extern, will change to @@ -247,10 +246,18 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { case *RangeStmt: if n.Op == DEFINE { if n.Key != nil { - last.Predefine(false, n.Key.(*NameExpr).Name) + nx := n.Key.(*NameExpr) + if nx.Name != blankIdentifier { + nx.Type = NameExprTypeDefine + last.Predefine(false, nx.Name) + } } if n.Value != nil { - last.Predefine(false, n.Value.(*NameExpr).Name) + nx := n.Value.(*NameExpr) + if nx.Name != blankIdentifier { + nx.Type = NameExprTypeDefine + last.Predefine(false, nx.Name) + } } } case *FuncLitExpr: @@ -296,10 +303,12 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { } n.Predefine(false, pte.Name) } - for _, rte := range n.Type.Results { - if rte.Name != "" { - n.Predefine(false, rte.Name) + for i, rte := range n.Type.Results { + if rte.Name == "" { + rn := fmt.Sprintf(".res_%d", i) + rte.Name = Name(rn) } + n.Predefine(false, rte.Name) } } return n, TRANS_CONTINUE @@ -2291,10 +2300,28 @@ func findGotoLoopDefines(ctx BlockNode, bn BlockNode) { }() switch n := n.(type) { + case *ForStmt, *RangeStmt: + Transcribe(n, + func(ns []Node, ftype TransField, index int, n Node, stage TransStage) (Node, TransCtrl) { + switch stage { + case TRANS_ENTER: + switch n := n.(type) { + case *FuncLitExpr: + // inner funcs. + return n, TRANS_SKIP + case *FuncDecl: + panic("unexpected inner func decl") + case *NameExpr: + if n.Type == NameExprTypeDefine { + n.Type = NameExprTypeHeapDefine + } + } + } + return n, TRANS_CONTINUE + }) case *BranchStmt: switch n.Op { case GOTO: - // bn, depth, index := findGotoLabel(last, n.Label) bn, _, _ := findGotoLabel(last, n.Label) // already done in Preprocess: // n.Depth = depth @@ -2312,15 +2339,16 @@ func findGotoLoopDefines(ctx BlockNode, bn BlockNode) { // if labelLine >= gotoLine { // return n, TRANS_SKIP // } - var label = n.Label - var labelReached bool - var origGoto = n + var ( + label = n.Label + labelReached bool + origGoto = n + ) // Recurse and mark stmts as ATTR_GOTOLOOP_STMT. // NOTE: ATTR_GOTOLOOP_STMT is not used. Transcribe(bn, func(ns []Node, ftype TransField, index int, n Node, stage TransStage) (Node, TransCtrl) { - switch stage { case TRANS_ENTER: // Check to see if label reached. @@ -2412,7 +2440,6 @@ func findLoopUses1(ctx BlockNode, bn BlockNode) { } switch stage { - // ---------------------------------------- case TRANS_BLOCK: pushInitBlock(n.(BlockNode), &last, &stack) @@ -2432,7 +2459,7 @@ func findLoopUses1(ctx BlockNode, bn BlockNode) { // if the name is loop defined, lds, _ := dbn.GetAttribute(ATTR_LOOP_DEFINES).([]Name) if hasName(lds, n.Name) { - fle, _, found := findFirstClosure(stack, dbn) + fle, depth, found := findFirstClosure(stack, dbn) if found { // If across a closure, // mark name as loop used. @@ -2442,16 +2469,8 @@ func findLoopUses1(ctx BlockNode, bn BlockNode) { idx := addHeapCapture(dbn, fle, n.Name) // adjust NameExpr type. n.Type = NameExprTypeHeapUse - // XXX actually uncomment once - // the runtime works. Instead of using - // the values from the closure, will - // use values from function block. - // see XXX in op_call.go - // n.Path.Depth = uint8(depth) - // n.Path.Index = idx - if false { - println(idx) // XXX delete - } + n.Path.Depth = uint8(depth) + n.Path.Index = idx } else { if ftype == TRANS_REF_X { // if used as a reference, @@ -2481,7 +2500,6 @@ func findLoopUses1(ctx BlockNode, bn BlockNode) { // ---------------------------------------- case TRANS_LEAVE: - // Pop block from stack. // NOTE: DO NOT USE TRANS_SKIP WITHIN BLOCK // NODES, AS TRANS_LEAVE WILL BE SKIPPED; OR @@ -2500,7 +2518,7 @@ func findLoopUses1(ctx BlockNode, bn BlockNode) { func assertNotHasName(names []Name, name Name) { if hasName(names, name) { - panic("name already contained in names") + panic(fmt.Sprintf("name: %s already contained in names: %v", name, names)) } } @@ -2523,23 +2541,25 @@ func addAttrHeapUse(bn BlockNode, name Name) { } // adds ~name to fle static block and to heap captures atomically. -func addHeapCapture(dbn BlockNode, fle *FuncLitExpr, name Name) uint16 { +func addHeapCapture(dbn BlockNode, fle *FuncLitExpr, name Name) (idx uint16) { for _, ne := range fle.HeapCaptures { if ne.Name == name { // assert ~name also already defined. - idx, ok := fle.GetLocalIndex("~" + name) + var ok bool + idx, ok = fle.GetLocalIndex("~" + name) if !ok { panic("~name not added to fle atomically") } - return idx // already exists + return // already exists } } // define ~name to fle. - idx, ok := fle.GetLocalIndex("~" + name) + _, ok := fle.GetLocalIndex("~" + name) if ok { panic("~name already defined in fle") } + tv := dbn.GetValueRef(nil, name, true) fle.Define("~"+name, tv.Copy(nil)) @@ -2549,28 +2569,43 @@ func addHeapCapture(dbn BlockNode, fle *FuncLitExpr, name Name) uint16 { ne := NameExpr{ Path: vp, Name: name, - Type: NameExprTypeHeapClosure, + Type: NameExprTypeHeapClosure, // XXX, this is actually not used, remove? } fle.HeapCaptures = append(fle.HeapCaptures, ne) - return idx + + // find index after define + for i, n := range fle.GetBlockNames() { + if n == "~"+name { + idx = uint16(i) + return + } + } + + panic("should not happen, idx not found") } // finds the first FuncLitExpr in the stack at or after stop. // returns the depth of first closure, 1 if stop itself is a closure, // or 0 if not found. func findFirstClosure(stack []BlockNode, stop BlockNode) (fle *FuncLitExpr, depth int, found bool) { + redundant := 0 // count faux block for i := len(stack) - 1; i >= 0; i-- { stbn := stack[i] switch stbn := stbn.(type) { case *FuncLitExpr: + if stbn == stop { // if fle is stopBn, does not count, use last fle + return + } fle = stbn - depth = len(stack) - 1 - i + 1 // +1 since 1 is lowest. + depth = len(stack) - 1 - redundant - i + 1 // +1 since 1 is lowest. found = true + // even if found, continue iteration in case + // an earlier *FuncLitExpr is found. + case *IfCaseStmt, *SwitchClauseStmt: if stbn == stop { return } - // even if found, continue iteration in case - // an earlier *FuncLitExpr is found. + redundant++ default: if stbn == stop { return @@ -2581,7 +2616,7 @@ func findFirstClosure(stack []BlockNode, stop BlockNode) (fle *FuncLitExpr, dept } // Convert non-loop uses of loop names to NameExprTypeHeapUse. -// Alos, NameExprTypeHeapDefine gets demoted to NameExprTypeDefine if no actual +// Also, NameExprTypeHeapDefine gets demoted to NameExprTypeDefine if no actual // usage was found that warrants a NameExprTypeHeapDefine. func findLoopUses2(ctx BlockNode, bn BlockNode) { // create stack of BlockNodes. @@ -2598,7 +2633,6 @@ func findLoopUses2(ctx BlockNode, bn BlockNode) { } switch stage { - // ---------------------------------------- case TRANS_BLOCK: pushInitBlock(n.(BlockNode), &last, &stack) @@ -2640,12 +2674,6 @@ func findLoopUses2(ctx BlockNode, bn BlockNode) { n.Type = NameExprTypeDefine } } - case NameExprTypeHeapClosure: - // Adjust the ValuePath index based on use. - // Actually, was already adjusted in findLoopUses1. - // dbn := last.GetBlockNodeForPath(nil, n.Path) - // lus, _ := dbn.GetAttribute(ATTR_LOOP_USES).([]Name) - // ... } } return n, TRANS_CONTINUE @@ -2667,17 +2695,14 @@ func findLoopUses2(ctx BlockNode, bn BlockNode) { switch n := n.(type) { case BlockNode: - // In another clause above for NameExprTypeHeapClosure - // we set the index to ATTR_LOOP_USES, so a simple swap - // works here. lds, _ := n.GetAttribute(ATTR_LOOP_DEFINES).([]Name) lus, _ := n.GetAttribute(ATTR_LOOP_USES).([]Name) if len(lds) < len(lus) { panic("defines should be a superset of used-defines") } - n.SetAttribute(ATTR_LOOP_DEFINES, lus) - // XXX implement delete. - // n.DelAttribute(ATTR_LOOP_USES) + // no need anymore + n.DelAttribute(ATTR_LOOP_USES) + n.DelAttribute(ATTR_LOOP_DEFINES) } return n, TRANS_CONTINUE } @@ -2685,18 +2710,6 @@ func findLoopUses2(ctx BlockNode, bn BlockNode) { }) } -func indexOfName(ns []Name, name Name) uint16 { - for i, nn := range ns { - if nn == name { - if i >= math.MaxUint16 { - panic("ns is MaxUint16 or greater in length") - } - return uint16(i) - } - } - panic(fmt.Sprintln("name "+name+" not found in ns", ns)) -} - func isSwitchLabel(ns []Node, label Name) bool { for { swch := lastSwitch(ns) @@ -4250,6 +4263,16 @@ func isLocallyDefined(bn BlockNode, n Name) bool { return true } +// r := 0 +// r, ok := 1, true +func isLocallyDefined2(bn BlockNode, n Name) bool { + _, ok := bn.GetLocalIndex(n) + if !ok { + return false + } + return true +} + // ---------------------------------------- // setNodeLines & setNodeLocations @@ -4311,7 +4334,7 @@ func setNodeLocations(pkgPath string, fileName string, n Node) { // XXX check node lines, uniqueness of locations, // and also check location pkgpath and filename. func checkNodeLinesLocations(pkgPath string, fileName string, n Node) { - // XXX + // TODO: XXX } // ---------------------------------------- diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index ca8d8cce60b..3ee744402ac 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -2464,12 +2464,9 @@ func (b *Block) GetPointerToMaybeHeapUse(store Store, nx *NameExpr) PointerValue case NameExprTypeNormal: return b.GetPointerTo(store, nx.Path) case NameExprTypeHeapUse: - // XXX return b.GetPointerToHeapUse(store, nx.Path) case NameExprTypeHeapClosure: - // XXX this should panic after logic is complete, - // should not happen. - return b.GetPointerTo(store, nx.Path) + panic("should not happen with type heap closure") default: panic("unexpected NameExpr type for GetPointerToMaybeHeapUse") } @@ -2492,19 +2489,37 @@ func (b *Block) GetPointerToMaybeHeapDefine(store Store, nx *NameExpr) PointerVa // First defines a new HeapItemValue. // This gets called from NameExprTypeHeapDefine name expressions. func (b *Block) GetPointerToHeapDefine(store Store, path ValuePath) PointerValue { - // XXX create a new blank &HeapItemValue{} - // XXX assign it to b.GetPointerTo(store, path), - // XXX return pointer to Value, e.g. - // XXX PointerValue{Base:hiv,TV:&hiv.Value} or something like that. - return b.GetPointerTo(store, path) + ptr := b.GetPointerTo(store, path) + hiv := &HeapItemValue{} + // point to a heapItem + *ptr.TV = TypedValue{ + T: heapItemType{}, + V: hiv, + } + + return PointerValue{ + TV: &hiv.Value, + Base: hiv, + Index: 0, + } } // Assumes a HeapItemValue, and gets inner pointer. // This gets called from NameExprTypeHeapUse name expressions. func (b *Block) GetPointerToHeapUse(store Store, path ValuePath) PointerValue { - // XXX return PointerValue with base b.GetPointerto(store, path), - // XXX and TV to *HeapItemValue.Value - return b.GetPointerTo(store, path) + ptr := b.GetPointerTo(store, path) + if _, ok := ptr.TV.T.(heapItemType); !ok { + panic("should not happen, should be heapItemType") + } + if _, ok := ptr.TV.V.(*HeapItemValue); !ok { + panic("should not happen, should be HeapItemValue") + } + + return PointerValue{ + TV: &ptr.TV.V.(*HeapItemValue).Value, + Base: ptr.TV.V, + Index: 0, + } } // Result is used has lhs for any assignments to "_". diff --git a/gnovm/tests/files/assign_unnamed_type/more/realm_compositelit_filetest.gno b/gnovm/tests/files/assign_unnamed_type/more/realm_compositelit_filetest.gno index e3bcff26cfb..c2924656048 100644 --- a/gnovm/tests/files/assign_unnamed_type/more/realm_compositelit_filetest.gno +++ b/gnovm/tests/files/assign_unnamed_type/more/realm_compositelit_filetest.gno @@ -1,10 +1,6 @@ // PKGPATH: gno.land/r/test package test -import ( - "fmt" -) - type ( word uint nat []word @@ -225,7 +221,7 @@ func main() { // "BlockNode": null, // "Location": { // "File": "main.gno", -// "Line": "20", +// "Line": "16", // "Nonce": "0", // "PkgPath": "gno.land/r/test" // } diff --git a/gnovm/tests/files/closure19.gno b/gnovm/tests/files/closure19.gno deleted file mode 100644 index 42698058164..00000000000 --- a/gnovm/tests/files/closure19.gno +++ /dev/null @@ -1,22 +0,0 @@ -package main - -func main() { - var y, counter int - var f []func() - defer func() { - for _, ff := range f { - ff() - } - }() - - // this is actually an implicit for loop -LABEL_1: - if counter == 2 { - return - } - x := y - f = append(f, func() { println(x) }) - y++ - counter++ - goto LABEL_1 -} diff --git a/gnovm/tests/files/closure20.gno b/gnovm/tests/files/closure20.gno deleted file mode 100644 index 637d33b49fd..00000000000 --- a/gnovm/tests/files/closure20.gno +++ /dev/null @@ -1,22 +0,0 @@ -package main - -func main() { - var y, counter int - var f []func() - defer func() { - for _, ff := range f { - ff() - } - }() - - // this is actually an implicit for loop -LABEL_1: - if counter == 2 { - return - } - var x = y - f = append(f, func() { println(x) }) - y++ - counter++ - goto LABEL_1 -} diff --git a/gnovm/tests/files/closure20a.gno b/gnovm/tests/files/closure20a.gno deleted file mode 100644 index 0ee9f381954..00000000000 --- a/gnovm/tests/files/closure20a.gno +++ /dev/null @@ -1,22 +0,0 @@ -package main - -func main() { - var y, counter int - var f []func() - defer func() { - for _, ff := range f { - ff() - } - }() - - // this is actually an implicit for loop -LABEL_1: - if counter == 2 { - return - } - var _, x = 0, y - f = append(f, func() { println(x) }) - y++ - counter++ - goto LABEL_1 -} diff --git a/gnovm/tests/files/closure9.gno b/gnovm/tests/files/closure9.gno deleted file mode 100644 index aea537520df..00000000000 --- a/gnovm/tests/files/closure9.gno +++ /dev/null @@ -1,15 +0,0 @@ -package main - -func main() { - var fns []func() int - for i := 0; i < 3; i++ { - x := i - f := func() int { - return x - } - fns = append(fns, f) - } - for _, fn := range fns { - println(fn()) - } -} diff --git a/gnovm/tests/files/gotoloop3.gno b/gnovm/tests/files/gotoloop3.gno deleted file mode 100644 index 2f9af047a38..00000000000 --- a/gnovm/tests/files/gotoloop3.gno +++ /dev/null @@ -1,35 +0,0 @@ -package main - -func main() { - c := 0 - refs := []*int{} -loop: - i := 1 - refs = append(refs, &i) - i += 1 - c += 1 - if c < 10 { - goto loop - } - for _, ref := range refs { - println(*ref) - } -} - -// This does make 'i' NameExprTypeHeapDefine. -// You can tell by the preprocess printout of i and i<()~...>. - -// Preprocessed: -// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; i := (const (1 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) } } } - -// Output: -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 diff --git a/gnovm/tests/files/gotoloop4.gno b/gnovm/tests/files/gotoloop4.gno deleted file mode 100644 index c74f99e12fd..00000000000 --- a/gnovm/tests/files/gotoloop4.gno +++ /dev/null @@ -1,35 +0,0 @@ -package main - -func main() { - c := 0 - refs := []*int{} -loop: - var i int = 1 - refs = append(refs, &i) - i += 1 - c += 1 - if c < 10 { - goto loop - } - for _, ref := range refs { - println(*ref) - } -} - -// This does make 'i' NameExprTypeHeapDefine. -// You can tell by the preprocess printout of i and i<()~...>. - -// Preprocessed: -// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i (const-type int) = (const (1 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) } } } - -// Output: -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 diff --git a/gnovm/tests/files/heap_alloc_defer.gno b/gnovm/tests/files/heap_alloc_defer.gno new file mode 100644 index 00000000000..4e604293788 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_defer.gno @@ -0,0 +1,37 @@ +package main + +type Foo struct { + num int + f func() +} + +func main() { + s := []Foo{ + { + num: 1, + f: func() { println("hello") }, + }, + { + num: 2, + f: func() { println("hola") }, + }, + } + + // tt is heap defined every iteration, + // different with for loopvar spec. + for _, tt := range s { + f := func() { + println(tt.num) + } + f() + defer func() { + tt.f() + }() + } +} + +// Output: +// 1 +// 2 +// hola +// hello diff --git a/gnovm/tests/files/heap_alloc_defer2.gno b/gnovm/tests/files/heap_alloc_defer2.gno new file mode 100644 index 00000000000..34cb8924540 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_defer2.gno @@ -0,0 +1,30 @@ +package main + +type rand struct{} + +func (r *rand) Seed() { + println("seed...") +} + +func fromSeed() *rand { + return &rand{} +} + +// XXX, test order in correcit with defer +// [params, res_xxx, vars] +func genResult(s0 string, x int) (int, bool) { + z := 0 + println(z) + r := fromSeed() + defer func() { r.Seed() }() + + return -1, true +} + +func main() { + genResult("hey", 0) +} + +// Output: +// 0 +// seed... diff --git a/gnovm/tests/files/heap_alloc_forloop1.gno b/gnovm/tests/files/heap_alloc_forloop1.gno new file mode 100644 index 00000000000..c30f147df20 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop1.gno @@ -0,0 +1,31 @@ +package main + +import "fmt" + +var s1 []*int + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + for i := 0; i < 3; i++ { + s1 = append(s1, &i) + } +} + +func main() { + forLoopRef() +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 3 +// s1[1] is: 3 +// s1[2] is: 3 diff --git a/gnovm/tests/files/heap_alloc_forloop1a.gno b/gnovm/tests/files/heap_alloc_forloop1a.gno new file mode 100644 index 00000000000..4f0a942bea9 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop1a.gno @@ -0,0 +1,39 @@ +package main + +import "fmt" + +type Int int + +var s1 []*Int + +func inc2(j *Int) { + *j = *j + 2 // Just as an example, increment j by 2. +} + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + for i := Int(0); i < 10; inc2(&i) { + s1 = append(s1, &i) + } +} + +func main() { + forLoopRef() +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; import fmt fmt; type Int (const-type main.Int); var s1 []*(Int); func inc2(j *(Int)) { *(j) = *(j) + (const (2 main.Int)) }; func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); for i := (const (0 main.Int)); i<~VPBlock(1,0)> < (const (10 main.Int)); inc2(&(i<~VPBlock(1,0)>)) { s1 = (const (append func(x []*main.Int,args ...*main.Int)(res []*main.Int)))(s1, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 10 +// s1[1] is: 10 +// s1[2] is: 10 +// s1[3] is: 10 +// s1[4] is: 10 diff --git a/gnovm/tests/files/heap_alloc_forloop1b.gno b/gnovm/tests/files/heap_alloc_forloop1b.gno new file mode 100644 index 00000000000..b89a1af72c1 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop1b.gno @@ -0,0 +1,38 @@ +package main + +import "fmt" + +var s1 []*int +var a interface{} = 1 + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + for i := 0; i < 3; i++ { + r := i + r, ok := 0, true + println(ok, r) + s1 = append(s1, &i) + } +} + +func main() { + forLoopRef() +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); var a interface { } = (const (1 int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { r := i<~VPBlock(1,0)>; r, ok := (const (0 int)), (const (true bool)); (const (println func(xs ...interface{})()))(ok, r); s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + +// Output: +// true 0 +// true 0 +// true 0 +// s1[0] is: 3 +// s1[1] is: 3 +// s1[2] is: 3 diff --git a/gnovm/tests/files/heap_alloc_forloop2.gno b/gnovm/tests/files/heap_alloc_forloop2.gno new file mode 100644 index 00000000000..3dbd3fad129 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop2.gno @@ -0,0 +1,33 @@ +package main + +import "fmt" + +var s1 []*int + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + for i := 0; i < 3; i++ { + z := i + 1 + s1 = append(s1, &z) + } +} + +func main() { + forLoopRef() +} + +// This does make 'z' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of z and z<~...>. + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); for i := (const (0 int)); i < (const (3 int)); i++ { z := i + (const (1 int)); s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(z<~VPBlock(1,1)>)) } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 1 +// s1[1] is: 2 +// s1[2] is: 3 diff --git a/gnovm/tests/files/heap_alloc_forloop2a.gno b/gnovm/tests/files/heap_alloc_forloop2a.gno new file mode 100644 index 00000000000..b888e2dcf35 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop2a.gno @@ -0,0 +1,34 @@ +package main + +import "fmt" + +var s1 []*int + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + for i := 0; i < 3; i++ { + z := i + s1 = append(s1, &z) + z++ + } +} + +func main() { + forLoopRef() +} + +// This does make 'z' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of z and z<~...>. + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); for i := (const (0 int)); i < (const (3 int)); i++ { z := i; s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(z<~VPBlock(1,1)>)); z<~VPBlock(1,1)>++ } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 1 +// s1[1] is: 2 +// s1[2] is: 3 diff --git a/gnovm/tests/files/heap_alloc_forloop3.gno b/gnovm/tests/files/heap_alloc_forloop3.gno new file mode 100644 index 00000000000..4b02b3c9277 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop3.gno @@ -0,0 +1,33 @@ +package main + +type f func() + +var fs []f + +func forLoopClosure() { + defer func() { + for _, f := range fs { + f() + } + }() + + for i := 0; i < 3; i++ { + z := i + fs = append(fs, func() { println(z) }) + } +} + +func main() { + forLoopClosure() +} + +// This does make 'z' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of z and z<()~...>. + +// Preprocessed: +// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { z := i; fs = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs, (const-type main.f)(func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + +// Output: +// 0 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop3a.gno b/gnovm/tests/files/heap_alloc_forloop3a.gno new file mode 100644 index 00000000000..a6d4a42742a --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop3a.gno @@ -0,0 +1,38 @@ +package main + +type f func() + +var fs []f + +func forLoopClosure() { + defer func() { + for _, f := range fs { + f() + } + }() + + for i := 0; i < 3; i++ { + x := i + println(x) + z := i + fs = append(fs, func() { println(z) }) + } +} + +func main() { + forLoopClosure() +} + +// This does make 'z' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of z and z<()~...>. + +// Preprocessed: +// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; (const (println func(xs ...interface{})()))(x); z := i; fs = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs, (const-type main.f)(func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + +// Output: +// 0 +// 1 +// 2 +// 0 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop4.gno b/gnovm/tests/files/heap_alloc_forloop4.gno new file mode 100644 index 00000000000..11c588cb920 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop4.gno @@ -0,0 +1,31 @@ +package main + +type f func() + +var fs []f + +func forLoopClosure() { + defer func() { + for _, f := range fs { + f() + } + }() + + for i := 0; i < 3; i++ { + fs = append(fs, func() { println(i) }) + } +} + +func main() { + forLoopClosure() +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs, (const-type main.f)(func func(){ (const (println func(xs ...interface{})()))(i<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + +// Output: +// 3 +// 3 +// 3 diff --git a/gnovm/tests/files/heap_alloc_forloop5.gno b/gnovm/tests/files/heap_alloc_forloop5.gno new file mode 100644 index 00000000000..d658702a2de --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop5.gno @@ -0,0 +1,32 @@ +package main + +type f func() + +var fs []f + +func forLoopClosure() { + defer func() { + for _, f := range fs { + f() + } + }() + + for i := 0; i < 3; i++ { + fs = append(fs, func() { + z := i + println(z) + }) + } +} + +func main() { + forLoopClosure() +} + +// Preprocessed: +// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs, (const-type main.f)(func func(){ z := i<~VPBlock(1,1)>; (const (println func(xs ...interface{})()))(z) }>)) } }; func main() { forLoopClosure() } } + +// Output: +// 3 +// 3 +// 3 diff --git a/gnovm/tests/files/heap_alloc_forloop5a.gno b/gnovm/tests/files/heap_alloc_forloop5a.gno new file mode 100644 index 00000000000..d0be2b36226 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop5a.gno @@ -0,0 +1,33 @@ +package main + +type f func() + +var fs []f + +func forLoopClosure() { + defer func() { + for _, f := range fs { + f() + } + }() + + for i := 0; i < 3; i++ { + x := i + fs = append(fs, func() { + z := x + println(z) + }) + } +} + +func main() { + forLoopClosure() +} + +// Preprocessed: +// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; fs = (const (append func(x []main.f,args ...main.f)(res []main.f)))(fs, (const-type main.f)(func func(){ z := x<~VPBlock(1,1)>; (const (println func(xs ...interface{})()))(z) }>)) } }; func main() { forLoopClosure() } } + +// Output: +// 0 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop6.gno b/gnovm/tests/files/heap_alloc_forloop6.gno new file mode 100644 index 00000000000..b224812376e --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6.gno @@ -0,0 +1,25 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 3; i++ { + z := i + f := func() int { + return z + } + fns = append(fns, f) + } + + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (3 int)); i++ { z := i; f := func func() (const-type int){ return z<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop6a.gno b/gnovm/tests/files/heap_alloc_forloop6a.gno new file mode 100644 index 00000000000..511b6b7b44e --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6a.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 5; i++ { + f := func() int { + return i + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (5 int)); i<~VPBlock(1,0)>++ { f := func func() (const-type int){ return i<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 5 +// 5 +// 5 +// 5 +// 5 diff --git a/gnovm/tests/files/heap_alloc_forloop6b.gno b/gnovm/tests/files/heap_alloc_forloop6b.gno new file mode 100644 index 00000000000..d3ae6394ce8 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6b.gno @@ -0,0 +1,25 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 2; i++ { + x := i + y := 0 + f := func() int { + x += y + x += 1 + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; y := (const (0 int)); f := func func() (const-type int){ x<~VPBlock(1,1)> += y<~VPBlock(1,2)>; x<~VPBlock(1,1)> += (const (1 int)); return x<~VPBlock(1,1)> }, y<()~VPBlock(1,2)>>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop6c.gno b/gnovm/tests/files/heap_alloc_forloop6c.gno new file mode 100644 index 00000000000..c40ea307bc8 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6c.gno @@ -0,0 +1,23 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 2; i++ { + f := func() int { + return i + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (2 int)); i<~VPBlock(1,0)>++ { f := func func() (const-type int){ return i<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 2 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop6f.gno b/gnovm/tests/files/heap_alloc_forloop6f.gno new file mode 100644 index 00000000000..6a56b169fb1 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6f.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 5; i++ { + var x int + f := func() int { + return x + } + x = i + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (5 int)); i++ { var x (const-type int); f := func func() (const-type int){ return x<~VPBlock(1,1)> }>; x<~VPBlock(1,1)> = i; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4 diff --git a/gnovm/tests/files/heap_alloc_forloop6g.gno b/gnovm/tests/files/heap_alloc_forloop6g.gno new file mode 100644 index 00000000000..b0484f2125f --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6g.gno @@ -0,0 +1,27 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 5; i++ { + x := i + { // another block + f := func() int { + return x + } + fns = append(fns, f) + } + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (5 int)); i++ { x := i; { f := func func() (const-type int){ return x<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) } }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4 diff --git a/gnovm/tests/files/heap_alloc_forloop6h.gno b/gnovm/tests/files/heap_alloc_forloop6h.gno new file mode 100644 index 00000000000..7c7c1468017 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6h.gno @@ -0,0 +1,33 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 2; i++ { + x := i + for j := 0; j < 2; j++ { + y := j + f := func() int { + return x + y + } + fns = append(fns, f) + } + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; for j := (const (0 int)); j < (const (2 int)); j++ { y := j; f := func func() (const-type int){ return x<~VPBlock(1,1)> + y<~VPBlock(1,2)> }, y<()~VPBlock(1,1)>>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) } }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Go Output: +// 0 +// 1 +// 1 +// 2 + +// Output: +// 0 +// 1 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop6h0.gno b/gnovm/tests/files/heap_alloc_forloop6h0.gno new file mode 100644 index 00000000000..886baa305c3 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6h0.gno @@ -0,0 +1,27 @@ +package main + +func main() { + var fns []func() int + for i := 0; i < 2; i++ { + for j := 0; j < 2; j++ { + f := func() int { + return i + j + } + fns = append(fns, f) + } + } + for _, fn := range fns { + println(fn()) + } +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (2 int)); i<~VPBlock(1,0)>++ { for j := (const (0 int)); j<~VPBlock(1,0)> < (const (2 int)); j<~VPBlock(1,0)>++ { f := func func() (const-type int){ return i<~VPBlock(1,1)> + j<~VPBlock(1,2)> }, j<()~VPBlock(1,0)>>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) } }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 4 +// 4 +// 4 +// 4 diff --git a/gnovm/tests/files/heap_alloc_forloop6i.gno b/gnovm/tests/files/heap_alloc_forloop6i.gno new file mode 100644 index 00000000000..b2dcbcf45eb --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop6i.gno @@ -0,0 +1,34 @@ +package main + +func main() { + var fns []func() int + var x int + for i := 0; i < 2; i++ { + x = i + for j := 0; j < 2; j++ { + y := j + f := func() int { + return x + y + } + fns = append(fns, f) + } + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); var x (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x = i; for j := (const (0 int)); j < (const (2 int)); j++ { y := j; f := func func() (const-type int){ return x + y<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) } }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Go Output: +// 1 +// 2 +// 1 +// 2 + +// Output: +// 1 +// 2 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop7.gno b/gnovm/tests/files/heap_alloc_forloop7.gno new file mode 100644 index 00000000000..0be05c1d9f9 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop7.gno @@ -0,0 +1,28 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + f := func() int { + if true { + if true { + return x + } + } + return 0 + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; f := func func() (const-type int){ if (const (true bool)) { if (const (true bool)) { return x<~VPBlock(3,1)> } }; return (const (0 int)) }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_forloop7a.gno b/gnovm/tests/files/heap_alloc_forloop7a.gno new file mode 100644 index 00000000000..caeca2bd1bf --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop7a.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + f := func() int { + if true { + return x + } + return 0 + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; f := func func() (const-type int){ if (const (true bool)) { return x<~VPBlock(2,1)> }; return (const (0 int)) }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_forloop8.gno b/gnovm/tests/files/heap_alloc_forloop8.gno new file mode 100644 index 00000000000..e41a723c1df --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop8.gno @@ -0,0 +1,25 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + f := func() int { + { + return x + } + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; f := func func() (const-type int){ { return x<~VPBlock(2,1)> } }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_forloop8a.gno b/gnovm/tests/files/heap_alloc_forloop8a.gno new file mode 100644 index 00000000000..19d8d5a3129 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop8a.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + f := func() int { + for i := 0; i < 1; i++ { + x++ + } + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; f := func func() (const-type int){ for i := (const (0 int)); i < (const (1 int)); i++ { x<~VPBlock(2,1)>++ }; return x<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop8b.gno b/gnovm/tests/files/heap_alloc_forloop8b.gno new file mode 100644 index 00000000000..dc6a86e33c0 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop8b.gno @@ -0,0 +1,28 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + s := []int{1, 2} + + f := func() int { + for _, v := range s { + x += v + } + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; s := [](const-type int){(const (1 int)), (const (2 int))}; f := func func() (const-type int){ for _, v := range s<~VPBlock(2,1)> { x<~VPBlock(2,2)> += v }; return x<~VPBlock(1,2)> }, x<()~VPBlock(1,1)>>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 3 +// 4 diff --git a/gnovm/tests/files/heap_alloc_forloop8c.gno b/gnovm/tests/files/heap_alloc_forloop8c.gno new file mode 100644 index 00000000000..815a5b7ffb2 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop8c.gno @@ -0,0 +1,30 @@ +package main + +func main() { + var fns []func() int + + for i := 0; i < 2; i++ { + x := i + y := 1 + f := func() int { + switch y { + case 1: + x += 1 + default: + x += 0 + } + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); for i := (const (0 int)); i < (const (2 int)); i++ { x := i; y := (const (1 int)); f := func func() (const-type int){ switch y<~VPBlock(2,1)> { case (const (1 int)): x<~VPBlock(2,2)> += (const (1 int)); default: x<~VPBlock(2,2)> += (const (0 int)) }; return x<~VPBlock(1,2)> }, x<()~VPBlock(1,1)>>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_forloop9.gno b/gnovm/tests/files/heap_alloc_forloop9.gno new file mode 100644 index 00000000000..0a56b4b005b --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop9.gno @@ -0,0 +1,42 @@ +package main + +import "fmt" + +// recursive closure does not capture +func main() { + var fns []func(int) int + var recursiveFunc func(int) int + + for i := 0; i < 3; i++ { + recursiveFunc = func(num int) int { + x := i + println("value of x: ", x) + if num <= 0 { + return 1 + } + return num * recursiveFunc(num-1) + } + fns = append(fns, recursiveFunc) + } + + for i, r := range fns { + result := r(i) + fmt.Printf("Factorial of %d is: %d\n", i, result) + } +} + +// go 1.22 loop var is not supported for now. + +// Preprocessed: +// file{ package main; import fmt fmt; func main() { var fns []func(.arg_0 (const-type int)) (const-type int); var recursiveFunc func(.arg_0 (const-type int)) (const-type int); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { recursiveFunc = func func(num (const-type int)) (const-type int){ x := i<~VPBlock(1,3)>; (const (println func(xs ...interface{})()))((const ("value of x: " string)), x); if num <= (const (0 int)) { return (const (1 int)) }; return num * recursiveFunc(num - (const (1 int))) }>; fns = (const (append func(x []func(.arg_0 int)( int),args ...func(.arg_0 int)( int))(res []func(.arg_0 int)( int))))(fns, recursiveFunc) }; for i, r := range fns { result := r(i); fmt.Printf((const ("Factorial of %d is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(result)) } } } + +// Output: +// value of x: 3 +// Factorial of 0 is: 1 +// value of x: 3 +// value of x: 3 +// Factorial of 1 is: 1 +// value of x: 3 +// value of x: 3 +// value of x: 3 +// Factorial of 2 is: 2 diff --git a/gnovm/tests/files/heap_alloc_forloop9_1.gno b/gnovm/tests/files/heap_alloc_forloop9_1.gno new file mode 100644 index 00000000000..5e3b9af74f6 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop9_1.gno @@ -0,0 +1,25 @@ +package main + +func Search(n int, f func(int) bool) int { + f(1) + return 0 +} + +// TODO: identify this pattern, optimize. +func main() { + for x := 0; x < 2; x++ { + count := 0 + println(" first: count: ", count) + Search(1, func(i int) bool { count++; return i >= x }) + println("second: count: ", count) + } +} + +// Preprocessed: +// file{ package main; func Search(n (const-type int), f func(.arg_0 (const-type int)) (const-type bool)) (const-type int) { f((const (1 int))); return (const (0 int)) }; func main() { for x := (const (0 int)); x<~VPBlock(1,0)> < (const (2 int)); x<~VPBlock(1,0)>++ { count := (const (0 int)); (const (println func(xs ...interface{})()))((const (" first: count: " string)), count<~VPBlock(1,1)>); Search((const (1 int)), func func(i (const-type int)) (const-type bool){ count<~VPBlock(1,2)>++; return (const-type bool)(i >= x<~VPBlock(1,3)>) }, x<()~VPBlock(1,0)>>); (const (println func(xs ...interface{})()))((const ("second: count: " string)), count<~VPBlock(1,1)>) } } } + +// Output: +// first: count: 0 +// second: count: 1 +// first: count: 0 +// second: count: 1 diff --git a/gnovm/tests/files/heap_alloc_forloop9_2.gno b/gnovm/tests/files/heap_alloc_forloop9_2.gno new file mode 100644 index 00000000000..3b03b433256 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop9_2.gno @@ -0,0 +1,36 @@ +package main + +func main() { + var fns []func() int + + println("start for loop") + for i := 0; i < 2; i++ { + defer func() { + println("defer") + for _, fn := range fns { + println(fn()) + } + }() + + x := i + f := func() int { + return x + } + + fns = append(fns, f) + } + println("end for loop") +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); (const (println func(xs ...interface{})()))((const ("start for loop" string))); for i := (const (0 int)); i < (const (2 int)); i++ { defer func func(){ (const (println func(xs ...interface{})()))((const ("defer" string))); for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } }(); x := i; f := func func() (const-type int){ return x<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; (const (println func(xs ...interface{})()))((const ("end for loop" string))) } } + +// Output: +// start for loop +// end for loop +// defer +// 0 +// 1 +// defer +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_forloop9b.gno b/gnovm/tests/files/heap_alloc_forloop9b.gno new file mode 100644 index 00000000000..70308d9fda6 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_forloop9b.gno @@ -0,0 +1,28 @@ +package main + +func main() { + var y int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + for i := 0; i < 2; i++ { + for j := 0; j < 2; j++ { + x := y + f = append(f, func() { println(x) }) + y++ + } + } +} + +// Preprocessed: +// file{ package main; func main() { var y (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); for i := (const (0 int)); i < (const (2 int)); i++ { for j := (const (0 int)); j < (const (2 int)); j++ { x := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++ } } } } + +// Output: +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_gotoloop0.gno b/gnovm/tests/files/heap_alloc_gotoloop0.gno new file mode 100644 index 00000000000..d116af1f66a --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop0.gno @@ -0,0 +1,28 @@ +package main + +func main() { + var counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + // this is actually an implicit for loop +LABEL_1: + if counter == 2 { + return + } + x := counter + f = append(f, func() { println(x) }) + counter++ + goto LABEL_1 +} + +// Preprocessed: +// file{ package main; func main() { var counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); if counter == (const (2 int)) { return }; x := counter; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); counter++; goto LABEL_1<0,3> } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/gotoloop1.gno b/gnovm/tests/files/heap_alloc_gotoloop1.gno similarity index 100% rename from gnovm/tests/files/gotoloop1.gno rename to gnovm/tests/files/heap_alloc_gotoloop1.gno diff --git a/gnovm/tests/files/gotoloop2.gno b/gnovm/tests/files/heap_alloc_gotoloop2.gno similarity index 69% rename from gnovm/tests/files/gotoloop2.gno rename to gnovm/tests/files/heap_alloc_gotoloop2.gno index 9a6f8fbe075..9c54f0c85a5 100644 --- a/gnovm/tests/files/gotoloop2.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop2.gno @@ -4,7 +4,7 @@ func main() { c := 0 closures := []func(){} loop: - i := 1 + i := c closures = append(closures, func() { println(i) }) @@ -12,6 +12,7 @@ loop: if c < 10 { goto loop } + for _, cl := range closures { cl() } @@ -21,16 +22,16 @@ loop: // You can tell by the preprocess printout of i and i<()~...>. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; i := (const (1 int)); closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i<~VPBlock(2,2)>) }>); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, cl := range closures { cl() } } } +// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; i := c; closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i<~VPBlock(1,0)>) }>); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, cl := range closures { cl() } } } // Output: -// 1 -// 1 -// 1 -// 1 -// 1 -// 1 -// 1 -// 1 -// 1 -// 1 +// 0 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 diff --git a/gnovm/tests/files/heap_alloc_gotoloop3.gno b/gnovm/tests/files/heap_alloc_gotoloop3.gno new file mode 100644 index 00000000000..23a234ebf3d --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop3.gno @@ -0,0 +1,34 @@ +package main + +func main() { + c := 0 + refs := []*int{} +loop: + i := c + refs = append(refs, &i) + c += 1 + if c < 10 { + goto loop + } + for _, ref := range refs { + println(*ref) + } +} + +// This does make 'i' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of i and i<~...>. + +// Preprocessed: +// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; i := c; refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 diff --git a/gnovm/tests/files/heap_alloc_gotoloop4.gno b/gnovm/tests/files/heap_alloc_gotoloop4.gno new file mode 100644 index 00000000000..217876beff1 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop4.gno @@ -0,0 +1,34 @@ +package main + +func main() { + c := 0 + refs := []*int{} +loop: + var i int = c + refs = append(refs, &i) + c += 1 + if c < 10 { + goto loop + } + for _, ref := range refs { + println(*ref) + } +} + +// This does make 'i' NameExprTypeHeapDefine. +// You can tell by the preprocess printout of i and i<~...>. + +// Preprocessed: +// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i (const-type int) = c; refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 diff --git a/gnovm/tests/files/gotoloop5.gno b/gnovm/tests/files/heap_alloc_gotoloop5.gno similarity index 60% rename from gnovm/tests/files/gotoloop5.gno rename to gnovm/tests/files/heap_alloc_gotoloop5.gno index e66b06df931..8da188f8c74 100644 --- a/gnovm/tests/files/gotoloop5.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop5.gno @@ -4,7 +4,7 @@ func main() { c := 0 refs := []*int{} loop: - i, j := 1, 2 + i, j := c, 2 refs = append(refs, &i) i += 1 j += 1 @@ -21,19 +21,19 @@ loop: } // This does make 'i' NameExprTypeHeapDefine. -// You can tell by the preprocess printout of i and i<()~...>. +// You can tell by the preprocess printout of i and i<~...>. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; i, j := (const (1 int)), (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) } } } +// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; i, j := c, (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) } } } // Output: -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 +// 10 diff --git a/gnovm/tests/files/gotoloop6.gno b/gnovm/tests/files/heap_alloc_gotoloop6.gno similarity index 58% rename from gnovm/tests/files/gotoloop6.gno rename to gnovm/tests/files/heap_alloc_gotoloop6.gno index 58a045cec89..634c87ddf60 100644 --- a/gnovm/tests/files/gotoloop6.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop6.gno @@ -4,7 +4,7 @@ func main() { c := 0 refs := []*int{} loop: - var i, j int = 1, 2 + var i, j int = c, 2 refs = append(refs, &i) i += 1 j += 1 @@ -21,19 +21,19 @@ loop: } // This does make 'i' NameExprTypeHeapDefine. -// You can tell by the preprocess printout of i and i<()~...>. +// You can tell by the preprocess printout of i and i<~...>. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i, j (const-type int) = (const (1 int)), (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) } } } +// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i, j (const-type int) = c, (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) } } } // Output: -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 +// 10 diff --git a/gnovm/tests/files/gotoloop7.gno b/gnovm/tests/files/heap_alloc_gotoloop7.gno similarity index 63% rename from gnovm/tests/files/gotoloop7.gno rename to gnovm/tests/files/heap_alloc_gotoloop7.gno index 501150736dd..43b2d95422b 100644 --- a/gnovm/tests/files/gotoloop7.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop7.gno @@ -4,7 +4,7 @@ func main() { c := 0 refs := []*int{} loop: - var i, j int = 1, 2 + var i, j int = c, 2 refs = append(refs, &i) i += 1 j += 1 @@ -30,19 +30,19 @@ loop: } // This does make 'i' NameExprTypeHeapDefine. -// You can tell by the preprocess printout of i and i<()~...>. +// You can tell by the preprocess printout of i and i<~...>. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i, j (const-type int) = (const (1 int)), (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); thing := func func(){ i := (const (2 int)); j := (const (3 int)); (const (println func(xs ...interface{})()))(i); (const (println func(xs ...interface{})()))(j) }; if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) }; if (const (false bool)) { thing() } } } +// file{ package main; func main() { c := (const (0 int)); refs := []*((const-type int)){}; var i, j (const-type int) = c, (const (2 int)); refs = (const (append func(x []*int,args ...*int)(res []*int)))(refs, &(i<~VPBlock(1,2)>)); i<~VPBlock(1,2)> += (const (1 int)); j += (const (1 int)); c += (const (1 int)); thing := func func(){ i := (const (2 int)); j := (const (3 int)); (const (println func(xs ...interface{})()))(i); (const (println func(xs ...interface{})()))(j) }; if c < (const (10 int)) { goto loop<1,2> }; for _, ref := range refs { (const (println func(xs ...interface{})()))(*(ref)) }; if (const (false bool)) { (const (println func(xs ...interface{})()))(j) }; if (const (false bool)) { thing() } } } // Output: -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 -// 2 +// 1 +// 2 +// 3 +// 4 +// 5 +// 6 +// 7 +// 8 +// 9 +// 10 diff --git a/gnovm/tests/files/gotoloop8.gno b/gnovm/tests/files/heap_alloc_gotoloop8.gno similarity index 88% rename from gnovm/tests/files/gotoloop8.gno rename to gnovm/tests/files/heap_alloc_gotoloop8.gno index f3421048d41..a5e0f0422ad 100644 --- a/gnovm/tests/files/gotoloop8.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop8.gno @@ -22,7 +22,7 @@ loop2: // This one doesn't because the goto stmt doesn't go back far enough. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; goto loop1<0,3>; i := (const (1 int)); closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i) }); c += (const (1 int)); if c < (const (10 int)) { goto loop2<1,4> }; for _, cl := range closures { cl() } } } +// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; goto loop1<0,3>; i := (const (1 int)); closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i) }); c += (const (1 int)); if c < (const (10 int)) { goto loop2<1,4> }; for _, cl := range closures { cl() } } } // Output: // 1 diff --git a/gnovm/tests/files/gotoloop9.gno b/gnovm/tests/files/heap_alloc_gotoloop9.gno similarity index 89% rename from gnovm/tests/files/gotoloop9.gno rename to gnovm/tests/files/heap_alloc_gotoloop9.gno index 38204652216..45406e9cc4a 100644 --- a/gnovm/tests/files/gotoloop9.gno +++ b/gnovm/tests/files/heap_alloc_gotoloop9.gno @@ -20,7 +20,7 @@ loop2: // This one doesn't because the goto stmt doesn't go back far enough. // Preprocessed: -// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; i := (const (1 int)); closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i) }); c += (const (1 int)); if c < (const (10 int)) { goto loop2<1,3> }; for _, cl := range closures { cl() } } } +// file{ package main; func main() { c := (const (0 int)); closures := []func(){}; i := (const (1 int)); closures = (const (append func(x []func()(),args ...func()())(res []func()())))(closures, func func(){ (const (println func(xs ...interface{})()))(i) }); c += (const (1 int)); if c < (const (10 int)) { goto loop2<1,3> }; for _, cl := range closures { cl() } } } // Output: // 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_10.gno b/gnovm/tests/files/heap_alloc_gotoloop9_10.gno new file mode 100644 index 00000000000..c8a6b2b797b --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_10.gno @@ -0,0 +1,64 @@ +package main + +import "fmt" + +var s1 []*int +var s2 []*int + +// intersection loop +func main() { + defer func() { + for i, v := range s1 { + fmt.Printf("s1[%d] is %d\n", i, *v) + } + for i, v := range s2 { + fmt.Printf("s2[%d] is %d\n", i, *v) + } + }() + + // counter for loop + var c1, c2 int + +LOOP_1: + x := c1 + s1 = append(s1, &x) + println("loop_1", c1) + c1++ + +LOOP_2: + y := c2 + s2 = append(s2, &y) + println("loop_2", c2) + c2++ + + if c1 < 3 { + goto LOOP_1 + } + + if c2 < 6 { + goto LOOP_2 + } +} + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); var s2 []*((const-type int)); func main() { defer func func(){ for i, v := range s1 { fmt.Printf((const ("s1[%d] is %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(v))) }; for i, v := range s2 { fmt.Printf((const ("s2[%d] is %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(v))) } }(); var c1, c2 (const-type int); x := c1; s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(x<~VPBlock(1,2)>)); (const (println func(xs ...interface{})()))((const ("loop_1" string)), c1); c1++; y := c2; s2 = (const (append func(x []*int,args ...*int)(res []*int)))(s2, &(y<~VPBlock(1,3)>)); (const (println func(xs ...interface{})()))((const ("loop_2" string)), c2); c2++; if c1 < (const (3 int)) { goto LOOP_1<1,2> }; if c2 < (const (6 int)) { goto LOOP_2<1,6> } } } + +// Output: +// loop_1 0 +// loop_2 0 +// loop_1 1 +// loop_2 1 +// loop_1 2 +// loop_2 2 +// loop_2 3 +// loop_2 4 +// loop_2 5 +// s1[0] is 0 +// s1[1] is 1 +// s1[2] is 2 +// s2[0] is 0 +// s2[1] is 1 +// s2[2] is 2 +// s2[3] is 3 +// s2[4] is 4 +// s2[5] is 5 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_11.gno b/gnovm/tests/files/heap_alloc_gotoloop9_11.gno new file mode 100644 index 00000000000..fc43b931d78 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_11.gno @@ -0,0 +1,29 @@ +package main + +func main() { + var y, counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + // this is actually an implicit for loop +LABEL_1: + if counter == 2 { + return + } + var _, x = 0, y + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); if counter == (const (2 int)) { return }; var _, x = (const (0 int)), y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,3> } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_12.gno b/gnovm/tests/files/heap_alloc_gotoloop9_12.gno new file mode 100644 index 00000000000..da469f44069 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_12.gno @@ -0,0 +1,56 @@ +package main + +import "fmt" + +func main() { + counter0 := 0 + counter1 := 0 + + y := 0 + + var fs []func() + + defer func() { + for _, ff := range fs { + ff() + } + }() + +LOOP_START: + if counter0 < 2 { + counter1 = 0 + fmt.Printf("Outer loop start: counter0=%d\n", counter0) + + NESTED_LOOP_START: + if counter1 < 2 { + fmt.Printf(" Nested loop: counter1=%d\n", counter1) + counter1++ + goto NESTED_LOOP_START + } + + x := y + fs = append(fs, func() { println(x) }) + + fmt.Println("Exiting nested loop") + counter0++ + y++ + goto LOOP_START + } else { + return + } +} + +// Preprocessed: +// file{ package main; import fmt fmt; func main() { counter0 := (const (0 int)); counter1 := (const (0 int)); y := (const (0 int)); var fs []func(); defer func func(){ for _, ff := range fs { ff() } }(); if counter0 < (const (2 int)) { counter1 = (const (0 int)); fmt.Printf((const ("Outer loop start: counter0=%d\n" string)), (const-type gonative{interface {}})(counter0)); if counter1 < (const (2 int)) { fmt.Printf((const (" Nested loop: counter1=%d\n" string)), (const-type gonative{interface {}})(counter1)); counter1++; goto NESTED_LOOP_START<1,2> }; x := y; fs = (const (append func(x []func()(),args ...func()())(res []func()())))(fs, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); fmt.Println((const ("Exiting nested loop" string))); counter0++; y++; goto LOOP_START<1,5> } else { return } } } + +// Output: +// Outer loop start: counter0=0 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// Outer loop start: counter0=1 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_13.gno b/gnovm/tests/files/heap_alloc_gotoloop9_13.gno new file mode 100644 index 00000000000..563e10a9515 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_13.gno @@ -0,0 +1,41 @@ +package main + +func main() { + var y, counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + +LABEL_1: + x := y + if counter == 2 { + counter = 0 + goto LABEL_2 + } + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 + +LABEL_2: + if counter == 2 { + return + } + z := y + f = append(f, func() { println(z) }) + y++ + counter++ + goto LABEL_2 +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); x := y; if counter == (const (2 int)) { counter = (const (0 int)); goto LABEL_2<1,9> }; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,3>; if counter == (const (2 int)) { return }; z := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_2<0,9> } } + +// Output: +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_14.gno b/gnovm/tests/files/heap_alloc_gotoloop9_14.gno new file mode 100644 index 00000000000..b66a073faef --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_14.gno @@ -0,0 +1,43 @@ +package main + +func main() { + var y, counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + { + LABEL_1: + x := y + if counter == 2 { + counter = 0 + goto LABEL_2 + } + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 + } + +LABEL_2: + if counter == 2 { + return + } + z := y + f = append(f, func() { println(z) }) + y++ + counter++ + goto LABEL_2 +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); { x := y; if counter == (const (2 int)) { counter = (const (0 int)); goto LABEL_2<2,4> }; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,0> }; if counter == (const (2 int)) { return }; z := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_2<0,4> } } + +// Output: +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_15.gno b/gnovm/tests/files/heap_alloc_gotoloop9_15.gno new file mode 100644 index 00000000000..706ad6c29e6 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_15.gno @@ -0,0 +1,48 @@ +package main + +var y, counter int +var f []func() + +func main() { + defer func() { + for _, ff := range f { // XXX, why defer on this not work + ff() + } + }() +LABEL_1: + x := y + if counter == 2 { + counter = 0 + bar() + return + } + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 +} + +func bar() { + println("---bar---") +LABEL_2: + if counter == 2 { + println("---end---") + return + } + z := y + f = append(f, func() { println(z) }) + y++ + counter++ + goto LABEL_2 +} + +// Preprocessed: +// file{ package main; var y, counter (const-type int); var f []func(); func main() { defer func func(){ for _, ff := range f { ff() } }(); x := y; if counter == (const (2 int)) { counter = (const (0 int)); bar(); return }; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,1> }; func bar() { (const (println func(xs ...interface{})()))((const ("---bar---" string))); if counter == (const (2 int)) { (const (println func(xs ...interface{})()))((const ("---end---" string))); return }; z := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_2<0,1> } } + +// Output: +// ---bar--- +// ---end--- +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_15a.gno b/gnovm/tests/files/heap_alloc_gotoloop9_15a.gno new file mode 100644 index 00000000000..de5775b6759 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_15a.gno @@ -0,0 +1,46 @@ +package main + +var y, counter int +var f []func() + +func main() { +LABEL_1: + x := y + if counter == 2 { + counter = 0 + bar() + for _, ff := range f { // XXX, why defer on this not work + ff() + } + return + } + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 +} + +func bar() { + println("---bar---") +LABEL_2: + if counter == 2 { + println("---end---") + return + } + z := y + f = append(f, func() { println(z) }) + y++ + counter++ + goto LABEL_2 +} + +// Preprocessed: +// file{ package main; var y, counter (const-type int); var f []func(); func main() { x := y; if counter == (const (2 int)) { counter = (const (0 int)); bar(); for _, ff := range f { ff() }; return }; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,0> }; func bar() { (const (println func(xs ...interface{})()))((const ("---bar---" string))); if counter == (const (2 int)) { (const (println func(xs ...interface{})()))((const ("---end---" string))); return }; z := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(z<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_2<0,1> } } + +// Output: +// ---bar--- +// ---end--- +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_16.gno b/gnovm/tests/files/heap_alloc_gotoloop9_16.gno new file mode 100644 index 00000000000..bf9225ad2fe --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_16.gno @@ -0,0 +1,58 @@ +package main + +import "fmt" + +func main() { + counter0 := 0 + counter1 := 0 + + y := 0 + + var fs []func() + + defer func() { + for _, ff := range fs { + ff() + } + }() + +LOOP_START: + if counter0 < 2 { + x := y + counter1 = 0 + fmt.Printf("Outer loop start: counter0=%d\n", counter0) + + NESTED_LOOP_START: + if counter1 < 2 { + fmt.Printf(" Nested loop: counter1=%d\n", counter1) + fs = append(fs, func() { println(x) }) + + counter1++ + goto NESTED_LOOP_START + } + + fmt.Println("Exiting nested loop") + counter0++ + y++ + goto LOOP_START + } else { + return + } +} + +// Preprocessed: +// file{ package main; import fmt fmt; func main() { counter0 := (const (0 int)); counter1 := (const (0 int)); y := (const (0 int)); var fs []func(); defer func func(){ for _, ff := range fs { ff() } }(); if counter0 < (const (2 int)) { x := y; counter1 = (const (0 int)); fmt.Printf((const ("Outer loop start: counter0=%d\n" string)), (const-type gonative{interface {}})(counter0)); if counter1 < (const (2 int)) { fmt.Printf((const (" Nested loop: counter1=%d\n" string)), (const-type gonative{interface {}})(counter1)); fs = (const (append func(x []func()(),args ...func()())(res []func()())))(fs, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); counter1++; goto NESTED_LOOP_START<1,3> }; fmt.Println((const ("Exiting nested loop" string))); counter0++; y++; goto LOOP_START<1,5> } else { return } } } + +// Output: +// Outer loop start: counter0=0 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// Outer loop start: counter0=1 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// 0 +// 0 +// 1 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_17.gno b/gnovm/tests/files/heap_alloc_gotoloop9_17.gno new file mode 100644 index 00000000000..048306516d7 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_17.gno @@ -0,0 +1,58 @@ +package main + +import "fmt" + +func main() { + counter0 := 0 + counter1 := 0 + + y := 0 + + var fs []func() + + defer func() { + for _, ff := range fs { + ff() + } + }() + +LOOP_START: + x := y + if counter0 < 2 { + counter1 = 0 + fmt.Printf("Outer loop start: counter0=%d\n", counter0) + + NESTED_LOOP_START: + if counter1 < 2 { + fmt.Printf(" Nested loop: counter1=%d\n", counter1) + fs = append(fs, func() { println(x) }) + + counter1++ + goto NESTED_LOOP_START + } + + fmt.Println("Exiting nested loop") + counter0++ + y++ + goto LOOP_START + } else { + return + } +} + +// Preprocessed: +// file{ package main; import fmt fmt; func main() { counter0 := (const (0 int)); counter1 := (const (0 int)); y := (const (0 int)); var fs []func(); defer func func(){ for _, ff := range fs { ff() } }(); x := y; if counter0 < (const (2 int)) { counter1 = (const (0 int)); fmt.Printf((const ("Outer loop start: counter0=%d\n" string)), (const-type gonative{interface {}})(counter0)); if counter1 < (const (2 int)) { fmt.Printf((const (" Nested loop: counter1=%d\n" string)), (const-type gonative{interface {}})(counter1)); fs = (const (append func(x []func()(),args ...func()())(res []func()())))(fs, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); counter1++; goto NESTED_LOOP_START<1,2> }; fmt.Println((const ("Exiting nested loop" string))); counter0++; y++; goto LOOP_START<1,5> } else { return } } } + +// Output: +// Outer loop start: counter0=0 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// Outer loop start: counter0=1 +// Nested loop: counter1=0 +// Nested loop: counter1=1 +// Exiting nested loop +// 0 +// 0 +// 1 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_18.gno b/gnovm/tests/files/heap_alloc_gotoloop9_18.gno new file mode 100644 index 00000000000..0dc71e81090 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_18.gno @@ -0,0 +1,30 @@ +package main + +func main() { + var y, counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + { + LABEL_1: + if counter == 2 { + return + } + x := y + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 + } +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); { if counter == (const (2 int)) { return }; x := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,0> } } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_19.gno b/gnovm/tests/files/heap_alloc_gotoloop9_19.gno new file mode 100644 index 00000000000..23374c74bfe --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_19.gno @@ -0,0 +1,30 @@ +package main + +func main() { + var y, counter int + var f []func() func() int + defer func() { + for _, ff := range f { + println(ff()()) + } + }() + +LABEL_1: + if counter == 2 { + return + } + x := y + f = append(f, func() func() int { + return func() int { return x } + }) + y++ + counter++ + goto LABEL_1 +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func() func() (const-type int); defer func func(){ for _, ff := range f { (const (println func(xs ...interface{})()))(ff()()) } }(); if counter == (const (2 int)) { return }; x := y; f = (const (append func(x []func()( func()( int)),args ...func()( func()( int)))(res []func()( func()( int)))))(f, func func() func() (const-type int){ return func func() (const-type int){ return x<~VPBlock(2,1)> } }>); y++; counter++; goto LABEL_1<0,3> } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_20.gno b/gnovm/tests/files/heap_alloc_gotoloop9_20.gno new file mode 100644 index 00000000000..4f3337e002f --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_20.gno @@ -0,0 +1,32 @@ +package main + +func main() { + var y, counter int + var f []func() (int, func() int) + defer func() { + for _, ff := range f { + n, f := ff() + println(n + f()) + } + }() + +LABEL_1: + if counter == 2 { + return + } + x := y + z := y + f = append(f, func() (int, func() int) { + return z, func() int { return x } + }) + y++ + counter++ + goto LABEL_1 +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func() (const-type int), func() (const-type int); defer func func(){ for _, ff := range f { n, f := ff(); (const (println func(xs ...interface{})()))(n + f()) } }(); if counter == (const (2 int)) { return }; x := y; z := y; f = (const (append func(x []func()( int, func()( int)),args ...func()( int, func()( int)))(res []func()( int, func()( int)))))(f, func func() (const-type int), func() (const-type int){ return z<~VPBlock(1,2)>, func func() (const-type int){ return x<~VPBlock(2,3)> } }, x<()~VPBlock(1,3)>>); y++; counter++; goto LABEL_1<0,3> } } + +// Output: +// 0 +// 2 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_21.gno b/gnovm/tests/files/heap_alloc_gotoloop9_21.gno new file mode 100644 index 00000000000..916b6d925c0 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_21.gno @@ -0,0 +1,31 @@ +package main + +func main() { + var counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + f1 := func() { + LABEL_1: + if counter == 2 { + return + } + x := counter + f = append(f, func() { println(x) }) + counter++ + goto LABEL_1 + } + + f1() +} + +// Preprocessed: +// file{ package main; func main() { var counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); f1 := func func(){ if counter == (const (2 int)) { return }; x := counter; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); counter++; goto LABEL_1<0,0> }; f1() } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_21a.gno b/gnovm/tests/files/heap_alloc_gotoloop9_21a.gno new file mode 100644 index 00000000000..16fefe34d5e --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_21a.gno @@ -0,0 +1,33 @@ +package main + +func main() { + var counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + f1 := func() { + LABEL_1: + if counter == 2 { + return + } + x := counter + func() { + f = append(f, func() { println(x) }) + }() + counter++ + goto LABEL_1 + } + + f1() +} + +// Preprocessed: +// file{ package main; func main() { var counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); f1 := func func(){ if counter == (const (2 int)) { return }; x := counter; func func(){ f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(2,0)>) }) }>(); counter++; goto LABEL_1<0,0> }; f1() } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_21b.gno b/gnovm/tests/files/heap_alloc_gotoloop9_21b.gno new file mode 100644 index 00000000000..1d5f19d30c0 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_21b.gno @@ -0,0 +1,34 @@ +package main + +func main() { + var counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + f1 := func() { + LABEL_1: + if counter == 2 { + return + } + + func() { + x := counter + f = append(f, func() { println(x) }) + }() + counter++ + goto LABEL_1 + } + + f1() +} + +// Preprocessed: +// file{ package main; func main() { var counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); f1 := func func(){ if counter == (const (2 int)) { return }; func func(){ x := counter; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x) }) }(); counter++; goto LABEL_1<0,0> }; f1() } } + +// Output: +// 0 +// 1 diff --git a/gnovm/tests/files/heap_alloc_gotoloop9_22.gno b/gnovm/tests/files/heap_alloc_gotoloop9_22.gno new file mode 100644 index 00000000000..cda36093732 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_gotoloop9_22.gno @@ -0,0 +1,33 @@ +package main + +func main() { + var y, counter int + var f []func() + defer func() { + for _, ff := range f { + ff() + } + }() + + for i := 0; i < 2; i++ { + counter = 0 + LABEL_1: + if counter == 2 { + continue + } + x := y + f = append(f, func() { println(x) }) + y++ + counter++ + goto LABEL_1 + } +} + +// Preprocessed: +// file{ package main; func main() { var y, counter (const-type int); var f []func(); defer func func(){ for _, ff := range f { ff() } }(); for i := (const (0 int)); i < (const (2 int)); i++ { counter = (const (0 int)); if counter == (const (2 int)) { continue }; x := y; f = (const (append func(x []func()(),args ...func()())(res []func()())))(f, func func(){ (const (println func(xs ...interface{})()))(x<~VPBlock(1,0)>) }>); y++; counter++; goto LABEL_1<0,1> } } } + +// Output: +// 0 +// 1 +// 2 +// 3 diff --git a/gnovm/tests/files/heap_alloc_range1.gno b/gnovm/tests/files/heap_alloc_range1.gno new file mode 100644 index 00000000000..508be9ca507 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range1.gno @@ -0,0 +1,30 @@ +package main + +import "fmt" + +var s1 []*int + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + s := []int{0, 1, 2} + for i, _ := range s { + s1 = append(s1, &i) + } +} + +func main() { + forLoopRef() +} + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); s := [](const-type int){(const (0 int)), (const (1 int)), (const (2 int))}; for i, _ := range s { s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 0 +// s1[1] is: 1 +// s1[2] is: 2 diff --git a/gnovm/tests/files/heap_alloc_range2.gno b/gnovm/tests/files/heap_alloc_range2.gno new file mode 100644 index 00000000000..808759bb907 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range2.gno @@ -0,0 +1,30 @@ +package main + +import "fmt" + +var s1 []*int + +func forLoopRef() { + defer func() { + for i, e := range s1 { + fmt.Printf("s1[%d] is: %d\n", i, *e) + } + }() + + s := []int{0, 1, 2} + for _, v := range s { + s1 = append(s1, &v) + } +} + +func main() { + forLoopRef() +} + +// Preprocessed: +// file{ package main; import fmt fmt; var s1 []*((const-type int)); func forLoopRef() { defer func func(){ for i, e := range s1 { fmt.Printf((const ("s1[%d] is: %d\n" string)), (const-type gonative{interface {}})(i), (const-type gonative{interface {}})(*(e))) } }(); s := [](const-type int){(const (0 int)), (const (1 int)), (const (2 int))}; for _, v := range s { s1 = (const (append func(x []*int,args ...*int)(res []*int)))(s1, &(v<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + +// Output: +// s1[0] is: 0 +// s1[1] is: 1 +// s1[2] is: 2 diff --git a/gnovm/tests/files/heap_alloc_range3.gno b/gnovm/tests/files/heap_alloc_range3.gno new file mode 100644 index 00000000000..eb7974b56de --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range3.gno @@ -0,0 +1,23 @@ +package main + +func main() { + s := []int{1, 2} + + f := func() { + for i, v := range s { + println(i) + println(v) + } + } + + f() +} + +// Preprocessed: +// file{ package main; func main() { s := [](const-type int){(const (1 int)), (const (2 int))}; f := func func(){ for i, v := range s { (const (println func(xs ...interface{})()))(i); (const (println func(xs ...interface{})()))(v) } }; f() } } + +// Output: +// 0 +// 1 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_range4.gno b/gnovm/tests/files/heap_alloc_range4.gno new file mode 100644 index 00000000000..3fb687a1c6b --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4.gno @@ -0,0 +1,24 @@ +package main + +func main() { + var fns []func() int + s := []int{1, 2, 3} + for i, _ := range s { + x := i + f := func() int { + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); s := [](const-type int){(const (1 int)), (const (2 int)), (const (3 int))}; for i, _ := range s { x := i; f := func func() (const-type int){ return x<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_range4a.gno b/gnovm/tests/files/heap_alloc_range4a.gno new file mode 100644 index 00000000000..da5af10cb22 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4a.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + m := map[string]int{"a": 1, "b": 2} + for _, v := range m { + x := v + f := func() int { + if true { + return x + } + return 0 + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); m := map[(const-type string)] (const-type int){(const ("a" string)): (const (1 int)), (const ("b" string)): (const (2 int))}; for _, v := range m { x := v; f := func func() (const-type int){ if (const (true bool)) { return x<~VPBlock(2,1)> }; return (const (0 int)) }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_range4a1.gno b/gnovm/tests/files/heap_alloc_range4a1.gno new file mode 100644 index 00000000000..1771a601426 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4a1.gno @@ -0,0 +1,22 @@ +package main + +func main() { + var fns []func() int + m := map[string]int{"a": 1, "b": 2} + for _, v := range m { + f := func() int { + return v + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); m := map[(const-type string)] (const-type int){(const ("a" string)): (const (1 int)), (const ("b" string)): (const (2 int))}; for _, v := range m { f := func func() (const-type int){ return v<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_range4a2.gno b/gnovm/tests/files/heap_alloc_range4a2.gno new file mode 100644 index 00000000000..69f6ead2a2d --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4a2.gno @@ -0,0 +1,32 @@ +package main + +func main() { + var fns []func() int + y := 0 + m := map[string]int{"a": 1, "b": 2} + for _, v := range m { + x := v + f := func() int { + switch y { + case 0: + if true { + return x + } + default: + return 0 + } + return 0 + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); y := (const (0 int)); m := map[(const-type string)] (const-type int){(const ("a" string)): (const (1 int)), (const ("b" string)): (const (2 int))}; for _, v := range m { x := v; f := func func() (const-type int){ switch y { case (const (0 int)): if (const (true bool)) { return x<~VPBlock(3,1)> }; default: return (const (0 int)) }; return (const (0 int)) }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 1 +// 2 diff --git a/gnovm/tests/files/heap_alloc_range4b.gno b/gnovm/tests/files/heap_alloc_range4b.gno new file mode 100644 index 00000000000..d949fd90d0d --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4b.gno @@ -0,0 +1,26 @@ +package main + +func main() { + var fns []func() int + s := "hello" + for i, _ := range s { + x := i + f := func() int { + return x + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); s := (const ("hello" string)); for i, _ := range s { x := i; f := func func() (const-type int){ return x<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4 diff --git a/gnovm/tests/files/heap_alloc_range4b1.gno b/gnovm/tests/files/heap_alloc_range4b1.gno new file mode 100644 index 00000000000..6848f9010e4 --- /dev/null +++ b/gnovm/tests/files/heap_alloc_range4b1.gno @@ -0,0 +1,25 @@ +package main + +func main() { + var fns []func() int + s := "hello" + for i, _ := range s { + f := func() int { + return i + } + fns = append(fns, f) + } + for _, fn := range fns { + println(fn()) + } +} + +// Preprocessed: +// file{ package main; func main() { var fns []func() (const-type int); s := (const ("hello" string)); for i, _ := range s { f := func func() (const-type int){ return i<~VPBlock(1,1)> }>; fns = (const (append func(x []func()( int),args ...func()( int))(res []func()( int))))(fns, f) }; for _, fn := range fns { (const (println func(xs ...interface{})()))(fn()) } } } + +// Output: +// 0 +// 1 +// 2 +// 3 +// 4