diff --git a/common/math/integer.go b/common/math/integer.go index 93b1d036d..0e3ad57a7 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -18,6 +18,7 @@ package math import ( "fmt" + "math/bits" "strconv" ) @@ -78,22 +79,20 @@ func MustParseUint64(s string) uint64 { return v } -// NOTE: The following methods need to be optimised using either bit checking or asm - // SafeSub returns subtraction result and whether overflow occurred. func SafeSub(x, y uint64) (uint64, bool) { - return x - y, x < y + diff, borrowOut := bits.Sub64(x, y, 0) + return diff, borrowOut != 0 } // SafeAdd returns the result and whether overflow occurred. func SafeAdd(x, y uint64) (uint64, bool) { - return x + y, y > MaxUint64-x + sum, carryOut := bits.Add64(x, y, 0) + return sum, carryOut != 0 } // SafeMul returns multiplication result and whether overflow occurred. func SafeMul(x, y uint64) (uint64, bool) { - if x == 0 || y == 0 { - return 0, false - } - return x * y, y > MaxUint64/x + hi, lo := bits.Mul64(x, y) + return lo, hi != 0 } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index ad954c6d6..b8f73763c 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -69,20 +69,20 @@ func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { base, exponent := callContext.stack.pop(), callContext.stack.peek() - // some shortcuts - if exponent.IsZero() { + switch { + case exponent.IsZero(): // x ^ 0 == 1 exponent.SetOne() - } else if base.IsZero() { + case base.IsZero(): // 0 ^ y, if y != 0, == 0 exponent.Clear() - } else if exponent.LtUint64(2) { // exponent == 1 + case exponent.LtUint64(2): // exponent == 1 // x ^ 1 == x exponent.Set(&base) - } else if base.LtUint64(2) { // base == 1 + case base.LtUint64(2): // base == 1 // 1 ^ y == 1 exponent.SetOne() - } else if base.LtUint64(3) { // base == 2 + case base.LtUint64(3): // base == 2 if exponent.LtUint64(256) { n := uint(exponent.Uint64()) exponent.SetOne() @@ -90,7 +90,7 @@ func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt } else { exponent.Clear() } - } else { + default: exponent.Exp(&base, exponent) } return nil, nil