From 884428ab935f3f5e21637b0c10815c46eeb962d2 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 12 Oct 2022 13:16:19 +0300 Subject: [PATCH] cli: add 'jump' command Close #2606. --- cli/vm/cli.go | 46 +++++++++++++++++++++++++++++++++++++++------- cli/vm/cli_test.go | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/cli/vm/cli.go b/cli/vm/cli.go index afd0aa087..a83ca6e6f 100644 --- a/cli/vm/cli.go +++ b/cli/vm/cli.go @@ -92,6 +92,15 @@ var commands = []cli.Command{ > break 12`, Action: handleBreak, }, + { + Name: "jump", + Usage: "Jump to the specified instruction (absolute IP value)", + UsageText: `jump `, + Description: `jump + is mandatory parameter, example: +> jump 12`, + Action: handleJump, + }, { Name: "estack", Usage: "Show evaluation stack contents", @@ -559,21 +568,44 @@ func handleBreak(c *cli.Context) error { if !checkVMIsReady(c.App) { return nil } - v := getVMFromContext(c.App) - args := c.Args() - if len(args) != 1 { - return fmt.Errorf("%w: ", ErrMissingParameter) - } - n, err := strconv.Atoi(args[0]) + n, err := getInstructionParameter(c) if err != nil { - return fmt.Errorf("%w: %s", ErrInvalidParameter, err) + return err } + v := getVMFromContext(c.App) v.AddBreakPoint(n) fmt.Fprintf(c.App.Writer, "breakpoint added at instruction %d\n", n) return nil } +func handleJump(c *cli.Context) error { + if !checkVMIsReady(c.App) { + return nil + } + n, err := getInstructionParameter(c) + if err != nil { + return err + } + + v := getVMFromContext(c.App) + v.Context().Jump(n) + fmt.Fprintf(c.App.Writer, "jumped to instruction %d\n", n) + return nil +} + +func getInstructionParameter(c *cli.Context) (int, error) { + args := c.Args() + if len(args) != 1 { + return 0, fmt.Errorf("%w: ", ErrMissingParameter) + } + n, err := strconv.Atoi(args[0]) + if err != nil { + return 0, fmt.Errorf("%w: %s", ErrInvalidParameter, err) + } + return n, nil +} + func handleXStack(c *cli.Context) error { v := getVMFromContext(c.App) var stackDump string diff --git a/cli/vm/cli_test.go b/cli/vm/cli_test.go index af1e3efcd..4552f9253 100644 --- a/cli/vm/cli_test.go +++ b/cli/vm/cli_test.go @@ -11,6 +11,7 @@ import ( "math/big" "os" "path/filepath" + "strconv" "strings" "sync" "testing" @@ -1181,3 +1182,20 @@ func TestLoaddeployed(t *testing.T) { e.checkStack(t, false) e.checkError(t, errors.New("contract hash, address or ID is mandatory argument")) } + +func TestJump(t *testing.T) { + buf := io.NewBufBinWriter() + emit.Opcodes(buf.BinWriter, opcode.PUSH1, opcode.PUSH2, opcode.ABORT) // some garbage + jmpTo := buf.Len() + emit.Opcodes(buf.BinWriter, opcode.PUSH4, opcode.PUSH5, opcode.ADD) // useful script + e := newTestVMCLI(t) + e.runProg(t, + "loadhex "+hex.EncodeToString(buf.Bytes()), + "jump "+strconv.Itoa(jmpTo), + "run", + ) + + e.checkNextLine(t, "READY: loaded 6 instructions") + e.checkNextLine(t, fmt.Sprintf("jumped to instruction %d", jmpTo)) + e.checkStack(t, 9) +}