parent
811e09675f
commit
884428ab93
2 changed files with 57 additions and 7 deletions
|
@ -92,6 +92,15 @@ var commands = []cli.Command{
|
||||||
> break 12`,
|
> break 12`,
|
||||||
Action: handleBreak,
|
Action: handleBreak,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "jump",
|
||||||
|
Usage: "Jump to the specified instruction (absolute IP value)",
|
||||||
|
UsageText: `jump <ip>`,
|
||||||
|
Description: `jump <ip>
|
||||||
|
<ip> is mandatory parameter, example:
|
||||||
|
> jump 12`,
|
||||||
|
Action: handleJump,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "estack",
|
Name: "estack",
|
||||||
Usage: "Show evaluation stack contents",
|
Usage: "Show evaluation stack contents",
|
||||||
|
@ -559,21 +568,44 @@ func handleBreak(c *cli.Context) error {
|
||||||
if !checkVMIsReady(c.App) {
|
if !checkVMIsReady(c.App) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
v := getVMFromContext(c.App)
|
n, err := getInstructionParameter(c)
|
||||||
args := c.Args()
|
|
||||||
if len(args) != 1 {
|
|
||||||
return fmt.Errorf("%w: <ip>", ErrMissingParameter)
|
|
||||||
}
|
|
||||||
n, err := strconv.Atoi(args[0])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %s", ErrInvalidParameter, err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := getVMFromContext(c.App)
|
||||||
v.AddBreakPoint(n)
|
v.AddBreakPoint(n)
|
||||||
fmt.Fprintf(c.App.Writer, "breakpoint added at instruction %d\n", n)
|
fmt.Fprintf(c.App.Writer, "breakpoint added at instruction %d\n", n)
|
||||||
return nil
|
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: <ip>", 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 {
|
func handleXStack(c *cli.Context) error {
|
||||||
v := getVMFromContext(c.App)
|
v := getVMFromContext(c.App)
|
||||||
var stackDump string
|
var stackDump string
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -1181,3 +1182,20 @@ func TestLoaddeployed(t *testing.T) {
|
||||||
e.checkStack(t, false)
|
e.checkStack(t, false)
|
||||||
e.checkError(t, errors.New("contract hash, address or ID is mandatory argument"))
|
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)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue