VM: Implement INC, DEC opcode (#231)
[VM] - Implemented INC, DEC opcode
This commit is contained in:
parent
24cd21bd8c
commit
d8e399f67d
3 changed files with 104 additions and 0 deletions
|
@ -5,6 +5,8 @@ import "github.com/CityOfZion/neo-go/pkg/vm/stack"
|
||||||
type stackInfo func(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error)
|
type stackInfo func(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error)
|
||||||
|
|
||||||
var opFunc = map[stack.Instruction]stackInfo{
|
var opFunc = map[stack.Instruction]stackInfo{
|
||||||
|
stack.INC: Inc,
|
||||||
|
stack.DEC: Dec,
|
||||||
stack.ADD: Add,
|
stack.ADD: Add,
|
||||||
stack.SUB: Sub,
|
stack.SUB: Sub,
|
||||||
stack.PUSHBYTES1: PushNBytes,
|
stack.PUSHBYTES1: PushNBytes,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/vm/stack"
|
"github.com/CityOfZion/neo-go/pkg/vm/stack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,6 +44,56 @@ func Sub(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rst
|
||||||
return NONE, nil
|
return NONE, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inc increments the stack Item's value by 1.
|
||||||
|
// Returns an error if the item cannot be casted to an integer
|
||||||
|
// or if 1 cannot be added to the item
|
||||||
|
func Inc(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||||
|
|
||||||
|
i, err := ctx.Estack.PopInt()
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
one, err := stack.NewInt(big.NewInt(1))
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := i.Add(one)
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Estack.Push(res)
|
||||||
|
|
||||||
|
return NONE, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dec decrements the stack Item's value by 1.
|
||||||
|
// Returns an error if the item cannot be casted to an integer
|
||||||
|
// or if 1 cannot be subtracted to the item
|
||||||
|
func Dec(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||||
|
|
||||||
|
i, err := ctx.Estack.PopInt()
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
one, err := stack.NewInt(big.NewInt(1))
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := i.Sub(one)
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Estack.Push(res)
|
||||||
|
|
||||||
|
return NONE, nil
|
||||||
|
}
|
||||||
|
|
||||||
func popTwoIntegers(ctx *stack.Context) (*stack.Int, *stack.Int, error) {
|
func popTwoIntegers(ctx *stack.Context) (*stack.Int, *stack.Int, error) {
|
||||||
operandA, err := ctx.Estack.PopInt()
|
operandA, err := ctx.Estack.PopInt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -8,6 +8,56 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestIncOp(t *testing.T) {
|
||||||
|
|
||||||
|
v := VM{}
|
||||||
|
|
||||||
|
a, err := stack.NewInt(big.NewInt(20))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := stack.NewContext([]byte{})
|
||||||
|
ctx.Estack.Push(a)
|
||||||
|
|
||||||
|
v.executeOp(stack.INC, ctx)
|
||||||
|
|
||||||
|
// Stack should have one item
|
||||||
|
assert.Equal(t, 1, ctx.Estack.Len())
|
||||||
|
|
||||||
|
item, err := ctx.Estack.PopInt()
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, int64(21), item.Value().Int64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecOp(t *testing.T) {
|
||||||
|
|
||||||
|
v := VM{}
|
||||||
|
|
||||||
|
a, err := stack.NewInt(big.NewInt(20))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := stack.NewContext([]byte{})
|
||||||
|
ctx.Estack.Push(a)
|
||||||
|
|
||||||
|
v.executeOp(stack.DEC, ctx)
|
||||||
|
|
||||||
|
// Stack should have one item
|
||||||
|
assert.Equal(t, 1, ctx.Estack.Len())
|
||||||
|
|
||||||
|
item, err := ctx.Estack.PopInt()
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, int64(19), item.Value().Int64())
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddOp(t *testing.T) {
|
func TestAddOp(t *testing.T) {
|
||||||
|
|
||||||
v := VM{}
|
v := VM{}
|
||||||
|
|
Loading…
Reference in a new issue