From e8ec820d2e127c98b1b4032368ddec72e38affec Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 16 Feb 2022 18:43:12 +0300 Subject: [PATCH] vm: add `unload` command When execution fails it's the only way to change the prompt showing the last executed instruction. Example: ``` NEO-GO-VM > loadgo examples/engine/engine.go READY: loaded 117 instructions NEO-GO-VM 0 > run Error: at instruction 3 (SYSCALL): failed to invoke syscall 805851437: syscall not found NEO-GO-VM 8 > parse Error: missing argument NEO-GO-VM 8 > parse 123 Integer to Hex 7b Integer to Base64 ew== String to Hex 313233 String to Base64 MTIz NEO-GO-VM 8 > unload NEO-GO-VM > exit ``` --- pkg/vm/cli/cli.go | 16 ++++++++++++++++ pkg/vm/cli/cli_test.go | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pkg/vm/cli/cli.go b/pkg/vm/cli/cli.go index a7fb9f60f..3e696aaf0 100644 --- a/pkg/vm/cli/cli.go +++ b/pkg/vm/cli/cli.go @@ -136,6 +136,11 @@ both parameters are mandatory, example: > loadgo /path/to/file.go`, Action: handleLoadGo, }, + { + Name: "reset", + Usage: "Unload compiled script from the VM", + Action: handleReset, + }, { Name: "parse", Usage: "Parse provided argument and convert it into other possible formats", @@ -288,6 +293,11 @@ func getVMFromContext(app *cli.App) *vm.VM { return app.Metadata[vmKey].(*vm.VM) } +func setVMInContext(app *cli.App, v *vm.VM) { + old := getVMFromContext(app) + *old = *v +} + func getManifestFromContext(app *cli.App) *manifest.Manifest { return app.Metadata[manifestKey].(*manifest.Manifest) } @@ -466,6 +476,12 @@ func handleLoadGo(c *cli.Context) error { return nil } +func handleReset(c *cli.Context) error { + setVMInContext(c.App, vm.New()) + changePrompt(c.App) + return nil +} + func getManifestFromFile(name string) (*manifest.Manifest, error) { bs, err := ioutil.ReadFile(name) if err != nil { diff --git a/pkg/vm/cli/cli_test.go b/pkg/vm/cli/cli_test.go index de6525a47..7ee2a6333 100644 --- a/pkg/vm/cli/cli_test.go +++ b/pkg/vm/cli/cli_test.go @@ -641,3 +641,19 @@ func TestExit(t *testing.T) { e.runProg(t, "exit") require.True(t, e.exit.Load()) } + +func TestReset(t *testing.T) { + script := []byte{byte(opcode.PUSH1)} + e := newTestVMCLI(t) + e.runProg(t, + "loadhex "+hex.EncodeToString(script), + "ops", + "reset", + "ops") + + e.checkNextLine(t, "READY: loaded 1 instructions") + e.checkNextLine(t, "INDEX.*OPCODE.*PARAMETER") + e.checkNextLine(t, "0.*PUSH1.*") + e.checkNextLine(t, "") + e.checkError(t, fmt.Errorf("VM is not ready: no program loaded")) +}