vm: implement PICK instruction

This commit is contained in:
Roman Khimov 2019-09-05 15:18:04 +03:00
parent b34a1b6c25
commit 5f0f9e1638
2 changed files with 41 additions and 0 deletions

View file

@ -337,6 +337,14 @@ func (v *VM) execute(ctx *Context, op Instruction) {
v.estack.Push(b)
v.estack.Push(a)
case PICK:
n := int(v.estack.Pop().BigInt().Int64())
if n < 0 {
panic("negative stack item returned")
}
a := v.estack.Peek(n)
v.estack.Push(a)
case ROLL:
n := int(v.estack.Pop().BigInt().Int64())
if n < 0 {

View file

@ -264,6 +264,39 @@ func TestNZfalse(t *testing.T) {
assert.Equal(t, false, vm.estack.Pop().Bool())
}
func TestPICKbadNoitem(t *testing.T) {
prog := makeProgram(PICK)
vm := load(prog)
vm.estack.PushVal(1)
vm.Run()
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestPICKbadNegative(t *testing.T) {
prog := makeProgram(PICK)
vm := load(prog)
vm.estack.PushVal(-1)
vm.Run()
assert.Equal(t, true, vm.state.HasFlag(faultState))
}
func TestPICKgood(t *testing.T) {
prog := makeProgram(PICK)
result := 2
vm := load(prog)
vm.estack.PushVal(0)
vm.estack.PushVal(1)
vm.estack.PushVal(result)
vm.estack.PushVal(3)
vm.estack.PushVal(4)
vm.estack.PushVal(5)
vm.estack.PushVal(3)
vm.Run()
assert.Equal(t, false, vm.state.HasFlag(faultState))
assert.Equal(t, int64(result), vm.estack.Pop().BigInt().Int64())
}
func makeProgram(opcodes ...Instruction) []byte {
prog := make([]byte, len(opcodes)+1) // RET
for i := 0; i < len(opcodes); i++ {