vm CLI: allow to dump slots
This commit is contained in:
parent
b502c5f148
commit
6da458365d
5 changed files with 166 additions and 0 deletions
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
@ -129,6 +130,37 @@ func (e *executor) checkStack(t *testing.T, items ...interface{}) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func (e *executor) checkSlot(t *testing.T, items ...interface{}) {
|
||||
d := json.NewDecoder(e.out)
|
||||
var actual interface{}
|
||||
require.NoError(t, d.Decode(&actual))
|
||||
rawActual, err := json.Marshal(actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := make([]json.RawMessage, len(items))
|
||||
for i := range items {
|
||||
if items[i] == nil {
|
||||
expected[i] = []byte("null")
|
||||
continue
|
||||
}
|
||||
data, err := stackitem.ToJSONWithTypes(stackitem.Make(items[i]))
|
||||
require.NoError(t, err)
|
||||
expected[i] = data
|
||||
}
|
||||
rawExpected, err := json.MarshalIndent(expected, "", " ")
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, string(rawExpected), string(rawActual))
|
||||
|
||||
// Decoder has it's own buffer, we need to return unread part to the output.
|
||||
outRemain := e.out.String()
|
||||
e.out.Reset()
|
||||
_, err = gio.Copy(e.out, d.Buffered())
|
||||
require.NoError(t, err)
|
||||
e.out.WriteString(outRemain)
|
||||
_, err = e.out.ReadString('\n')
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
script := []byte{byte(opcode.PUSH3), byte(opcode.PUSH4), byte(opcode.ADD)}
|
||||
t.Run("loadhex", func(t *testing.T) {
|
||||
|
@ -376,6 +408,55 @@ func TestBreakpoint(t *testing.T) {
|
|||
e.checkStack(t, 9)
|
||||
}
|
||||
|
||||
func TestDumpSSlot(t *testing.T) {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.Opcodes(w.BinWriter, opcode.INITSSLOT, 2, // init static slot with size=2
|
||||
opcode.PUSH5, opcode.STSFLD, 1, // put `int(5)` to sslot[1]; sslot[0] is nil
|
||||
opcode.LDSFLD1) // put sslot[1] to the top of estack
|
||||
e := newTestVMCLI(t)
|
||||
e.runProg(t,
|
||||
"loadhex "+hex.EncodeToString(w.Bytes()),
|
||||
"break 5",
|
||||
"step", "sslot",
|
||||
"cont", "estack",
|
||||
)
|
||||
e.checkNextLine(t, "READY: loaded 6 instructions")
|
||||
e.checkNextLine(t, "breakpoint added at instruction 5")
|
||||
|
||||
e.checkNextLine(t, "at breakpoint 5.*LDSFLD1")
|
||||
e.checkSlot(t, nil, 5)
|
||||
|
||||
e.checkStack(t, 5)
|
||||
}
|
||||
|
||||
func TestDumpLSlot_DumpASlot(t *testing.T) {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.Opcodes(w.BinWriter, opcode.PUSH4, opcode.PUSH5, opcode.PUSH6, // items for args slot
|
||||
opcode.INITSLOT, 2, 3, // init local slot with size=2 and args slot with size 3
|
||||
opcode.PUSH7, opcode.STLOC1, // put `int(7)` to lslot[1]; lslot[0] is nil
|
||||
opcode.LDLOC, 1) // put lslot[1] to the top of estack
|
||||
e := newTestVMCLI(t)
|
||||
e.runProg(t,
|
||||
"loadhex "+hex.EncodeToString(w.Bytes()),
|
||||
"break 6",
|
||||
"break 8",
|
||||
"cont", "aslot",
|
||||
"cont", "lslot",
|
||||
"cont", "estack",
|
||||
)
|
||||
e.checkNextLine(t, "READY: loaded 10 instructions")
|
||||
e.checkNextLine(t, "breakpoint added at instruction 6")
|
||||
e.checkNextLine(t, "breakpoint added at instruction 8")
|
||||
|
||||
e.checkNextLine(t, "at breakpoint 6.*PUSH7")
|
||||
e.checkSlot(t, 6, 5, 4) // args slot
|
||||
|
||||
e.checkNextLine(t, "at breakpoint 8.*LDLOC")
|
||||
e.checkSlot(t, nil, 7) // local slot
|
||||
|
||||
e.checkStack(t, 7)
|
||||
}
|
||||
|
||||
func TestStep(t *testing.T) {
|
||||
script := hex.EncodeToString([]byte{
|
||||
byte(opcode.PUSH0), byte(opcode.PUSH1), byte(opcode.PUSH2), byte(opcode.PUSH3),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue