gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
849 stars 345 forks source link

gno repl's `/func` crashes VM after two inputs #950

Closed ilgooz closed 9 months ago

ilgooz commented 1 year ago

M2 Chip on 6d137df03c59a0d78fe0f1336bd3a60d6e4209d9

It fails when I run println(1) after testing the demo (without calling exit) presented in the Usage section.

ilker@Ilkers-MacBook-Pro gno % gno repl
// Usage:
//   gno:1> /import "gno.land/p/demo/avl"     // import the p/demo/avl package
//   gno:2> /func a() string { return "a" }   // declare a new function named a
//   gno:3> /src                              // print current generated source
//   gno:4> println(a())                      // print the result of calling a()
//   gno:5> /exit
gno:1> /import "gno.land/p/demo/avl"
gno:2> /func a() string { return "a" }
gno:3> /src
// generated by 'gno repl'
package test
import "gno.land/p/demo/avl"
import "gno.land/p/demo/ufmt"
import "gno.land/p/demo/avl"
func a() string { return "a" }
func repl_4() {
// your code will be here
}
gno:4> println(a())
a
gno:5> println(1)
panic: StaticBlock.Define2(a) cannot change .T; was func()( string), new func()() [recovered]
    panic: test/repl_6.gno:6: StaticBlock.Define2(a) cannot change .T; was func()( string), new func()()

goroutine 1 [running]:
github.com/gnolang/gno/gnovm/pkg/gnolang.predefineNow.func1()
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/preprocess.go:2854 +0x220
panic({0x1011f8240, 0x140002a37c0})
    /opt/homebrew/Cellar/go/1.20.4/libexec/src/runtime/panic.go:884 +0x204
github.com/gnolang/gno/gnovm/pkg/gnolang.(*StaticBlock).Define2(0x1400029d620, 0x0, {0x1017adc48, 0x1}, {0x10130f138?, 0x1400071dc70}, {{0x10130f138, 0x1400071dc70}, {0x10130a270, 0x14000220bd0}, ...})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/nodes.go:1750 +0x6e4
github.com/gnolang/gno/gnovm/pkg/gnolang.(*StaticBlock).Define(...)
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/nodes.go:1708
github.com/gnolang/gno/gnovm/pkg/gnolang.tryPredefine({0x10131bff8, 0x14000168240}, {0x10131a078, 0x140005f1b80}, {0x101315558, 0x14000820000?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/preprocess.go:3125 +0xd60
github.com/gnolang/gno/gnovm/pkg/gnolang.predefineNow2({0x10131bff8, 0x14000168240}, {0x10131a078?, 0x140005f1b80}, {0x101315558, 0x14000820000?}, 0x200?)
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/preprocess.go:2870 +0xcc
github.com/gnolang/gno/gnovm/pkg/gnolang.predefineNow({0x10131bff8, 0x14000168240}, {0x10131a078, 0x140005f1b80}, {0x101315558, 0x14000820000})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/preprocess.go:2859 +0xd4
github.com/gnolang/gno/gnovm/pkg/gnolang.PredefineFileSet({0x10131bff8, 0x14000168240}, 0x1400029d600, 0x140001ab038)
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/preprocess.go:74 +0x394
github.com/gnolang/gno/gnovm/pkg/gnolang.(*Machine).runFiles(0x14000124a20, {0x14000358b60, 0x1, 0x1})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/machine.go:411 +0x1e8
github.com/gnolang/gno/gnovm/pkg/gnolang.(*Machine).RunFiles(...)
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/pkg/gnolang/machine.go:377
main.(*repl).handleInput(0x14000a35bc0, {0x1400080a4a0, 0xa})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/cmd/gno/repl.go:170 +0x67c
main.runRepl(0x140002fac00)
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/cmd/gno/repl.go:238 +0x590
main.execRepl(0x140002fac00, {0x101824c58?, 0x0?, 0x14000030050?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/cmd/gno/repl.go:100 +0xbc
main.newReplCmd.func1({0x0?, 0x0?}, {0x101824c58?, 0x140002f9488?, 0x0?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/cmd/gno/repl.go:39 +0x30
github.com/gnolang/gno/tm2/pkg/commands.(*Command).Run(0x0?, {0x10130d9e8?, 0x14000036068?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/tm2/pkg/commands/command.go:233 +0x17c
github.com/gnolang/gno/tm2/pkg/commands.(*Command).Run(0x140002f8e70?, {0x10130d9e8?, 0x14000036068?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/tm2/pkg/commands/command.go:237 +0x12c
github.com/gnolang/gno/tm2/pkg/commands.(*Command).ParseAndRun(0x14000100000?, {0x10130d9e8, 0x14000036068}, {0x14000030050?, 0x60?, 0x0?})
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/tm2/pkg/commands/command.go:118 +0x4c
main.main()
    /Users/ilker/Documents/code/src/github.com/ilgooz/gno/gnovm/cmd/gno/main.go:14 +0x74
ilker@Ilkers-MacBook-Pro gno % 
thehowl commented 1 year ago

This is because gnovm sees it as a re-definition. For this same reason, we're changing the name of the repl-function each time. So we'd need /func to run the definition of the func in the VM only once...

moul commented 1 year ago

Indeed, the current implementation lacks sophistication.

@mvertes, any suggestions to improve the flexibility and resilience of REPLs?

moul commented 11 months ago

@ajnavarro is it still the case with your PR?

ajnavarro commented 11 months ago

@moul It won't crash. I'm recovering VM's panics to avoid that in any case.

In that specific case, all evaluated expressions will work as intended.

moul commented 11 months ago

@ilgooz insuggeft you to bump gno and try the latest REPL!

thehowl commented 9 months ago

I believe this is fixed with #1044.

@ilgooz, if you encounter it again, feel free to re-open.