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()
|
||||
v.estack.PushVal(a.Cmp(b) != 0)
|
||||
|
||||
case opcode.LT:
|
||||
b := v.estack.Pop().BigInt()
|
||||
a := v.estack.Pop().BigInt()
|
||||
v.estack.PushVal(a.Cmp(b) == -1)
|
||||
case opcode.LT, opcode.LE, opcode.GT, opcode.GE:
|
||||
eb := v.estack.Pop()
|
||||
ea := v.estack.Pop()
|
||||
_, aNil := ea.Item().(stackitem.Null)
|
||||
_, bNil := eb.Item().(stackitem.Null)
|
||||
|
||||
case opcode.LE:
|
||||
b := v.estack.Pop().BigInt()
|
||||
a := v.estack.Pop().BigInt()
|
||||
v.estack.PushVal(a.Cmp(b) <= 0)
|
||||
|
||||
case opcode.GT:
|
||||
b := v.estack.Pop().BigInt()
|
||||
a := v.estack.Pop().BigInt()
|
||||
v.estack.PushVal(a.Cmp(b) == 1)
|
||||
|
||||
case opcode.GE:
|
||||
b := v.estack.Pop().BigInt()
|
||||
a := v.estack.Pop().BigInt()
|
||||
v.estack.PushVal(a.Cmp(b) >= 0)
|
||||
res := !aNil && !bNil
|
||||
if res {
|
||||
cmp := ea.BigInt().Cmp(eb.BigInt())
|
||||
switch op {
|
||||
case opcode.LT:
|
||||
res = cmp == -1
|
||||
case opcode.LE:
|
||||
res = cmp <= 0
|
||||
case opcode.GT:
|
||||
res = cmp == 1
|
||||
case opcode.GE:
|
||||
res = cmp >= 0
|
||||
}
|
||||
}
|
||||
v.estack.PushVal(res)
|
||||
|
||||
case opcode.MIN:
|
||||
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))
|
||||
}
|
||||
|
||||
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) {
|
||||
prog := makeProgram(opcode.LT)
|
||||
runWithArgs(t, prog, false, 4, 3)
|
||||
|
|
Loading…
Reference in a new issue