vm: allow Null arguments for LT,LE,GT,GE opcodes
This commit is contained in:
parent
dc393642a2
commit
8fa4a576f4
2 changed files with 32 additions and 18 deletions
38
pkg/vm/vm.go
38
pkg/vm/vm.go
|
@ -972,25 +972,27 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
a := v.estack.Pop().BigInt()
|
a := v.estack.Pop().BigInt()
|
||||||
v.estack.PushVal(a.Cmp(b) != 0)
|
v.estack.PushVal(a.Cmp(b) != 0)
|
||||||
|
|
||||||
case opcode.LT:
|
case opcode.LT, opcode.LE, opcode.GT, opcode.GE:
|
||||||
b := v.estack.Pop().BigInt()
|
eb := v.estack.Pop()
|
||||||
a := v.estack.Pop().BigInt()
|
ea := v.estack.Pop()
|
||||||
v.estack.PushVal(a.Cmp(b) == -1)
|
_, aNil := ea.Item().(stackitem.Null)
|
||||||
|
_, bNil := eb.Item().(stackitem.Null)
|
||||||
|
|
||||||
case opcode.LE:
|
res := !aNil && !bNil
|
||||||
b := v.estack.Pop().BigInt()
|
if res {
|
||||||
a := v.estack.Pop().BigInt()
|
cmp := ea.BigInt().Cmp(eb.BigInt())
|
||||||
v.estack.PushVal(a.Cmp(b) <= 0)
|
switch op {
|
||||||
|
case opcode.LT:
|
||||||
case opcode.GT:
|
res = cmp == -1
|
||||||
b := v.estack.Pop().BigInt()
|
case opcode.LE:
|
||||||
a := v.estack.Pop().BigInt()
|
res = cmp <= 0
|
||||||
v.estack.PushVal(a.Cmp(b) == 1)
|
case opcode.GT:
|
||||||
|
res = cmp == 1
|
||||||
case opcode.GE:
|
case opcode.GE:
|
||||||
b := v.estack.Pop().BigInt()
|
res = cmp >= 0
|
||||||
a := v.estack.Pop().BigInt()
|
}
|
||||||
v.estack.PushVal(a.Cmp(b) >= 0)
|
}
|
||||||
|
v.estack.PushVal(res)
|
||||||
|
|
||||||
case opcode.MIN:
|
case opcode.MIN:
|
||||||
b := v.estack.Pop().BigInt()
|
b := v.estack.Pop().BigInt()
|
||||||
|
|
|
@ -807,6 +807,18 @@ func TestSHL(t *testing.T) {
|
||||||
t.Run("BigResult", getTestFuncForVM(prog, nil, getBigInt(stackitem.MaxBigIntegerSizeBits/2, 0), stackitem.MaxBigIntegerSizeBits/2))
|
t.Run("BigResult", getTestFuncForVM(prog, nil, getBigInt(stackitem.MaxBigIntegerSizeBits/2, 0), stackitem.MaxBigIntegerSizeBits/2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArithNullArg(t *testing.T) {
|
||||||
|
for _, op := range []opcode.Opcode{opcode.LT, opcode.LE, opcode.GT, opcode.GE} {
|
||||||
|
prog := makeProgram(op)
|
||||||
|
t.Run(op.String(), func(t *testing.T) {
|
||||||
|
runWithArgs(t, prog, false, stackitem.Null{}, 0)
|
||||||
|
runWithArgs(t, prog, false, 0, stackitem.Null{})
|
||||||
|
runWithArgs(t, prog, nil, stackitem.NewInterop(nil), 1) // also has `.Value() == nil`
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLT(t *testing.T) {
|
func TestLT(t *testing.T) {
|
||||||
prog := makeProgram(opcode.LT)
|
prog := makeProgram(opcode.LT)
|
||||||
runWithArgs(t, prog, false, 4, 3)
|
runWithArgs(t, prog, false, 4, 3)
|
||||||
|
|
Loading…
Reference in a new issue