From d8e399f67d6188881090620b7507cf8659e8b99d Mon Sep 17 00:00:00 2001 From: dauTT <30392990+dauTT@users.noreply.github.com> Date: Wed, 27 Mar 2019 00:15:13 +0100 Subject: [PATCH] VM: Implement INC, DEC opcode (#231) [VM] - Implemented INC, DEC opcode --- pkg/vm/vm_ops.go | 2 ++ pkg/vm/vm_ops_maths.go | 52 +++++++++++++++++++++++++++++++++++++ pkg/vm/vm_ops_maths_test.go | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/pkg/vm/vm_ops.go b/pkg/vm/vm_ops.go index d8b032ebc..016c96389 100644 --- a/pkg/vm/vm_ops.go +++ b/pkg/vm/vm_ops.go @@ -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) var opFunc = map[stack.Instruction]stackInfo{ + stack.INC: Inc, + stack.DEC: Dec, stack.ADD: Add, stack.SUB: Sub, stack.PUSHBYTES1: PushNBytes, diff --git a/pkg/vm/vm_ops_maths.go b/pkg/vm/vm_ops_maths.go index 612c7630c..77a4c2622 100644 --- a/pkg/vm/vm_ops_maths.go +++ b/pkg/vm/vm_ops_maths.go @@ -1,6 +1,8 @@ package vm import ( + "math/big" + "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 } +// 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) { operandA, err := ctx.Estack.PopInt() if err != nil { diff --git a/pkg/vm/vm_ops_maths_test.go b/pkg/vm/vm_ops_maths_test.go index 4964e6923..f50c27916 100644 --- a/pkg/vm/vm_ops_maths_test.go +++ b/pkg/vm/vm_ops_maths_test.go @@ -8,6 +8,56 @@ import ( "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) { v := VM{}