import (
"math"
+ "github.com/holiman/uint256"
+
"github.com/bytom/bytom/math/checked"
)
return err
}
- return vm.pushBigInt(n.Rsh(n,1), true)
+ return vm.pushBigInt(n.Rsh(n, 1), true)
}
func opNegate(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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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)
}