mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-27 15:42:54 +00:00
Merge pull request #1789 from nspcc-dev/vm/pow
vm: implement POW and SQRT opcodes
This commit is contained in:
commit
dbc86b4ecc
6 changed files with 83 additions and 39 deletions
|
@ -162,6 +162,8 @@ var coefficients = map[opcode.Opcode]int64{
|
|||
opcode.MUL: 1 << 3,
|
||||
opcode.DIV: 1 << 3,
|
||||
opcode.MOD: 1 << 3,
|
||||
opcode.POW: 1 << 6,
|
||||
opcode.SQRT: 1 << 11,
|
||||
opcode.SHL: 1 << 3,
|
||||
opcode.SHR: 1 << 3,
|
||||
opcode.NOT: 1 << 2,
|
||||
|
|
|
@ -177,6 +177,8 @@ const (
|
|||
MUL Opcode = 0xA0
|
||||
DIV Opcode = 0xA1
|
||||
MOD Opcode = 0xA2
|
||||
POW Opcode = 0xA3
|
||||
SQRT Opcode = 0xA4
|
||||
SHL Opcode = 0xA8
|
||||
SHR Opcode = 0xA9
|
||||
NOT Opcode = 0xAA
|
||||
|
|
|
@ -159,6 +159,8 @@ func _() {
|
|||
_ = x[MUL-160]
|
||||
_ = x[DIV-161]
|
||||
_ = x[MOD-162]
|
||||
_ = x[POW-163]
|
||||
_ = x[SQRT-164]
|
||||
_ = x[SHL-168]
|
||||
_ = x[SHR-169]
|
||||
_ = x[NOT-170]
|
||||
|
@ -198,7 +200,7 @@ func _() {
|
|||
_ = x[CONVERT-219]
|
||||
}
|
||||
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT"
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT"
|
||||
|
||||
var _Opcode_map = map[Opcode]string{
|
||||
0: _Opcode_name[0:8],
|
||||
|
@ -350,43 +352,45 @@ var _Opcode_map = map[Opcode]string{
|
|||
160: _Opcode_name[856:859],
|
||||
161: _Opcode_name[859:862],
|
||||
162: _Opcode_name[862:865],
|
||||
168: _Opcode_name[865:868],
|
||||
169: _Opcode_name[868:871],
|
||||
170: _Opcode_name[871:874],
|
||||
171: _Opcode_name[874:881],
|
||||
172: _Opcode_name[881:887],
|
||||
177: _Opcode_name[887:889],
|
||||
179: _Opcode_name[889:897],
|
||||
180: _Opcode_name[897:908],
|
||||
181: _Opcode_name[908:910],
|
||||
182: _Opcode_name[910:913],
|
||||
183: _Opcode_name[913:915],
|
||||
184: _Opcode_name[915:918],
|
||||
185: _Opcode_name[918:921],
|
||||
186: _Opcode_name[921:924],
|
||||
187: _Opcode_name[924:930],
|
||||
192: _Opcode_name[930:934],
|
||||
193: _Opcode_name[934:940],
|
||||
194: _Opcode_name[940:949],
|
||||
195: _Opcode_name[949:957],
|
||||
196: _Opcode_name[957:967],
|
||||
197: _Opcode_name[967:977],
|
||||
198: _Opcode_name[977:986],
|
||||
200: _Opcode_name[986:992],
|
||||
202: _Opcode_name[992:996],
|
||||
203: _Opcode_name[996:1002],
|
||||
204: _Opcode_name[1002:1006],
|
||||
205: _Opcode_name[1006:1012],
|
||||
206: _Opcode_name[1012:1020],
|
||||
207: _Opcode_name[1020:1026],
|
||||
208: _Opcode_name[1026:1033],
|
||||
209: _Opcode_name[1033:1045],
|
||||
210: _Opcode_name[1045:1051],
|
||||
211: _Opcode_name[1051:1061],
|
||||
212: _Opcode_name[1061:1068],
|
||||
216: _Opcode_name[1068:1074],
|
||||
217: _Opcode_name[1074:1080],
|
||||
219: _Opcode_name[1080:1087],
|
||||
163: _Opcode_name[865:868],
|
||||
164: _Opcode_name[868:872],
|
||||
168: _Opcode_name[872:875],
|
||||
169: _Opcode_name[875:878],
|
||||
170: _Opcode_name[878:881],
|
||||
171: _Opcode_name[881:888],
|
||||
172: _Opcode_name[888:894],
|
||||
177: _Opcode_name[894:896],
|
||||
179: _Opcode_name[896:904],
|
||||
180: _Opcode_name[904:915],
|
||||
181: _Opcode_name[915:917],
|
||||
182: _Opcode_name[917:920],
|
||||
183: _Opcode_name[920:922],
|
||||
184: _Opcode_name[922:925],
|
||||
185: _Opcode_name[925:928],
|
||||
186: _Opcode_name[928:931],
|
||||
187: _Opcode_name[931:937],
|
||||
192: _Opcode_name[937:941],
|
||||
193: _Opcode_name[941:947],
|
||||
194: _Opcode_name[947:956],
|
||||
195: _Opcode_name[956:964],
|
||||
196: _Opcode_name[964:974],
|
||||
197: _Opcode_name[974:984],
|
||||
198: _Opcode_name[984:993],
|
||||
200: _Opcode_name[993:999],
|
||||
202: _Opcode_name[999:1003],
|
||||
203: _Opcode_name[1003:1009],
|
||||
204: _Opcode_name[1009:1013],
|
||||
205: _Opcode_name[1013:1019],
|
||||
206: _Opcode_name[1019:1027],
|
||||
207: _Opcode_name[1027:1033],
|
||||
208: _Opcode_name[1033:1040],
|
||||
209: _Opcode_name[1040:1052],
|
||||
210: _Opcode_name[1052:1058],
|
||||
211: _Opcode_name[1058:1068],
|
||||
212: _Opcode_name[1068:1075],
|
||||
216: _Opcode_name[1075:1081],
|
||||
217: _Opcode_name[1081:1087],
|
||||
219: _Opcode_name[1087:1094],
|
||||
}
|
||||
|
||||
func (i Opcode) String() string {
|
||||
|
|
2
pkg/vm/testdata/neo-vm
vendored
2
pkg/vm/testdata/neo-vm
vendored
|
@ -1 +1 @@
|
|||
Subproject commit e3f1584b1953dcc13075a57803240858c8a480de
|
||||
Subproject commit 3fb22406ba72a86fb251c763aea72677f9f9baa2
|
16
pkg/vm/vm.go
16
pkg/vm/vm.go
|
@ -910,6 +910,22 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
|
||||
v.estack.PushVal(new(big.Int).Rem(a, b))
|
||||
|
||||
case opcode.POW:
|
||||
exp := v.estack.Pop().BigInt()
|
||||
a := v.estack.Pop().BigInt()
|
||||
if ei := exp.Int64(); !exp.IsInt64() || ei > math.MaxInt32 || ei < 0 {
|
||||
panic("invalid exponent")
|
||||
}
|
||||
v.estack.PushVal(new(big.Int).Exp(a, exp, nil))
|
||||
|
||||
case opcode.SQRT:
|
||||
a := v.estack.Pop().BigInt()
|
||||
if a.Sign() == -1 {
|
||||
panic("negative value")
|
||||
}
|
||||
|
||||
v.estack.PushVal(new(big.Int).Sqrt(a))
|
||||
|
||||
case opcode.SHL, opcode.SHR:
|
||||
b := v.estack.Pop().BigInt().Int64()
|
||||
if b == 0 {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
@ -935,6 +936,25 @@ func TestSUBBigResult(t *testing.T) {
|
|||
runWithArgs(t, prog, nil, -2, bi)
|
||||
}
|
||||
|
||||
func TestPOW(t *testing.T) {
|
||||
prog := makeProgram(opcode.POW)
|
||||
t.Run("good, positive", getTestFuncForVM(prog, 9, 3, 2))
|
||||
t.Run("good, negative, even", getTestFuncForVM(prog, 4, -2, 2))
|
||||
t.Run("good, negative, odd", getTestFuncForVM(prog, -8, -2, 3))
|
||||
t.Run("zero", getTestFuncForVM(prog, 1, 3, 0))
|
||||
t.Run("negative exponent", getTestFuncForVM(prog, nil, 3, -1))
|
||||
t.Run("too big exponent", getTestFuncForVM(prog, nil, 1, math.MaxInt32+1))
|
||||
}
|
||||
|
||||
func TestSQRT(t *testing.T) {
|
||||
prog := makeProgram(opcode.SQRT)
|
||||
t.Run("good, positive", getTestFuncForVM(prog, 3, 9))
|
||||
t.Run("good, round down", getTestFuncForVM(prog, 2, 8))
|
||||
t.Run("one", getTestFuncForVM(prog, 1, 1))
|
||||
t.Run("zero", getTestFuncForVM(prog, 0, 0))
|
||||
t.Run("negative value", getTestFuncForVM(prog, nil, -1))
|
||||
}
|
||||
|
||||
func TestSHR(t *testing.T) {
|
||||
prog := makeProgram(opcode.SHR)
|
||||
t.Run("Good", getTestFuncForVM(prog, 1, 4, 2))
|
||||
|
|
Loading…
Reference in a new issue