From a54e3516d160c9b7292b23b907215ec69198f299 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Sun, 18 Jul 2021 16:08:23 +0300 Subject: [PATCH] slice: add Reverse function, deduplicate code a bit --- pkg/core/native/std.go | 12 +++--------- pkg/util/slice/array.go | 15 ++++++++++++--- pkg/util/slice/array_test.go | 3 +++ pkg/vm/vm.go | 7 +++---- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/pkg/core/native/std.go b/pkg/core/native/std.go index f2e614b0a..2155883b5 100644 --- a/pkg/core/native/std.go +++ b/pkg/core/native/std.go @@ -16,6 +16,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" + "github.com/nspcc-dev/neo-go/pkg/util/slice" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -232,7 +233,7 @@ func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item { break } bs := bigint.ToBytes(num) - reverse(bs) + slice.Reverse(bs) str = hex.EncodeToString(bs) if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 { str = str[1:] @@ -280,7 +281,7 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item { if changed && bs[0]&0x8 != 0 { bs[0] |= 0xF0 } - reverse(bs) + slice.Reverse(bs) bi = bigint.FromBytes(bs) default: panic(ErrInvalidBase) @@ -289,13 +290,6 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item { return stackitem.NewBigInteger(bi) } -func reverse(b []byte) { - l := len(b) - for i := 0; i < l/2; i++ { - b[i], b[l-i-1] = b[l-i-1], b[i] - } -} - func (s *Std) base64Encode(_ *interop.Context, args []stackitem.Item) stackitem.Item { src := s.toLimitedBytes(args[0]) result := base64.StdEncoding.EncodeToString(src) diff --git a/pkg/util/slice/array.go b/pkg/util/slice/array.go index 50e3f5d6c..3ade1a37f 100644 --- a/pkg/util/slice/array.go +++ b/pkg/util/slice/array.go @@ -7,8 +7,17 @@ package slice // original. func CopyReverse(b []byte) []byte { dest := make([]byte, len(b)) - for i, j := 0, len(b)-1; i <= j; i, j = i+1, j-1 { - dest[i], dest[j] = b[j], b[i] - } + reverse(dest, b) return dest } + +// Reverse does in-place reversing of byte slice. +func Reverse(b []byte) { + reverse(b, b) +} + +func reverse(dst []byte, src []byte) { + for i, j := 0, len(src)-1; i <= j; i, j = i+1, j-1 { + dst[i], dst[j] = src[j], src[i] + } +} diff --git a/pkg/util/slice/array_test.go b/pkg/util/slice/array_test.go index 7ba88dec9..5106b6f2f 100644 --- a/pkg/util/slice/array_test.go +++ b/pkg/util/slice/array_test.go @@ -41,5 +41,8 @@ func TestCopyReverse(t *testing.T) { have[i] = ^have[i] } require.Equal(t, tc.arr, arg) + + Reverse(arg) + require.Equal(t, tc.rev, arg) } } diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 9d996d7f8..106d5fb90 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -21,6 +21,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/util/slice" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -1167,10 +1168,8 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro a[i], a[j] = a[j], a[i] } case *stackitem.Buffer: - slice := t.Value().([]byte) - for i, j := 0, t.Len()-1; i < j; i, j = i+1, j-1 { - slice[i], slice[j] = slice[j], slice[i] - } + b := t.Value().([]byte) + slice.Reverse(b) default: panic(fmt.Sprintf("invalid item type %s", t)) }