OSDN Git Service

Feat(BVM): change op cmp (#1873)
[bytom/bytom.git] / protocol / vm / numeric.go
index 976e6ac..392a1b2 100644 (file)
@@ -3,6 +3,8 @@ package vm
 import (
        "math"
 
+       "github.com/holiman/uint256"
+
        "github.com/bytom/bytom/math/checked"
 )
 
@@ -86,7 +88,7 @@ func op2Div(vm *virtualMachine) error {
                return err
        }
 
-       return vm.pushBigInt(n.Rsh(n,1), true)
+       return vm.pushBigInt(n.Rsh(n, 1), true)
 }
 
 func opNegate(vm *virtualMachine) error {
@@ -128,11 +130,13 @@ func opNot(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       n, err := vm.popInt64(true)
+
+       n, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       return vm.pushBool(n == 0, true)
+
+       return vm.pushBool(n.Cmp(uint256.NewInt()) == 0, true)
 }
 
 func op0NotEqual(vm *virtualMachine) error {
@@ -140,11 +144,13 @@ func op0NotEqual(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       n, err := vm.popInt64(true)
+
+       n, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       return vm.pushBool(n != 0, true)
+
+       return vm.pushBool(n.Cmp(uint256.NewInt()) != 0, true)
 }
 
 func opAdd(vm *virtualMachine) error {
@@ -152,19 +158,22 @@ func opAdd(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       res, ok := checked.AddInt64(x, y)
-       if !ok {
+
+       if x.Add(x, y); x.Sign() < 0 {
                return ErrRange
        }
-       return vm.pushInt64(res, true)
+
+       return vm.pushBigInt(x, true)
 }
 
 func opSub(vm *virtualMachine) error {
@@ -172,19 +181,22 @@ func opSub(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       res, ok := checked.SubInt64(x, y)
-       if !ok {
+
+       if x.Sub(x, y); x.Sign() < 0 {
                return ErrRange
        }
-       return vm.pushInt64(res, true)
+
+       return vm.pushBigInt(x, true)
 }
 
 func opMul(vm *virtualMachine) error {
@@ -192,19 +204,22 @@ func opMul(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       res, ok := checked.MulInt64(x, y)
-       if !ok {
+
+       if overflow := x.MulOverflow(x, y); overflow || x.Sign() < 0 {
                return ErrRange
        }
-       return vm.pushInt64(res, true)
+
+       return vm.pushBigInt(x, true)
 }
 
 func opDiv(vm *virtualMachine) error {
@@ -212,22 +227,22 @@ func opDiv(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       if y == 0 {
+
+       if y.IsZero() {
                return ErrDivZero
        }
-       res, ok := checked.DivInt64(x, y)
-       if !ok {
-               return ErrRange
-       }
-       return vm.pushInt64(res, true)
+
+       return vm.pushBigInt(x.Div(x, y), true)
 }
 
 func opMod(vm *virtualMachine) error {
@@ -235,30 +250,22 @@ func opMod(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       if y == 0 {
-               return ErrDivZero
-       }
-
-       res, ok := checked.ModInt64(x, y)
-       if !ok {
-               return ErrRange
-       }
 
-       // Go's modulus operator produces the wrong result for mixed-sign
-       // operands
-       if res != 0 && (x >= 0) != (y >= 0) {
-               res += y
+       if y.IsZero() {
+               return ErrDivZero
        }
 
-       return vm.pushInt64(res, true)
+       return vm.pushBigInt(x.Mod(x, y), true)
 }
 
 func opLshift(vm *virtualMachine) error {
@@ -428,18 +435,21 @@ func opMin(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       if x > y {
-               x = y
+
+       if x.Cmp(y) > 0 {
+               return vm.pushBigInt(y, true)
        }
-       return vm.pushInt64(x, true)
+       return vm.pushBigInt(x, true)
 }
 
 func opMax(vm *virtualMachine) error {
@@ -447,18 +457,21 @@ func opMax(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       y, err := vm.popInt64(true)
+
+       y, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       if x < y {
-               x = y
+
+       if x.Cmp(y) < 0 {
+               return vm.pushBigInt(y, true)
        }
-       return vm.pushInt64(x, true)
+       return vm.pushBigInt(x, true)
 }
 
 func opWithin(vm *virtualMachine) error {
@@ -466,17 +479,20 @@ func opWithin(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       max, err := vm.popInt64(true)
+       max, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       min, err := vm.popInt64(true)
+
+       min, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       x, err := vm.popInt64(true)
+
+       x, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       return vm.pushBool(x >= min && x < max, true)
+
+       return vm.pushBool(x.Cmp(min) >= 0 && x.Cmp(max) < 0, true)
 }