aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/instructions.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/instructions.go')
-rw-r--r--core/vm/instructions.go30
1 files changed, 17 insertions, 13 deletions
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index de0fcaeb6..499e066f7 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -32,13 +32,24 @@ import (
var (
bigZero = new(big.Int)
+ big2 = big.NewInt(2)
+ big256 = big.NewInt(256)
tt255 = math.BigPow(2, 255)
errWriteProtection = errors.New("evm: write protection")
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
errExecutionReverted = errors.New("evm: execution reverted")
errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
+ power2 = make([]*big.Int, 256)
)
+func init() {
+ cur := int64(1)
+ for i := 0; i < 256; i++ {
+ power2[i] = big.NewInt(cur)
+ cur <<= 1
+ }
+}
+
func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.peek()
math.U256(y.Add(x, y))
@@ -126,22 +137,15 @@ func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory
func opExp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
base, exponent := stack.pop(), stack.pop()
- // some shortcuts
- cmpToOne := exponent.Cmp(big1)
- if cmpToOne < 0 { // Exponent is zero
- // x ^ 0 == 1
- stack.push(base.SetUint64(1))
- } else if base.Sign() == 0 {
- // 0 ^ y, if y != 0, == 0
- stack.push(base.SetUint64(0))
- } else if cmpToOne == 0 { // Exponent is one
- // x ^ 1 == x
- stack.push(base)
+ if base.Cmp(big2) == 0 && exponent.Cmp(big256) == -1 {
+ exp := exponent.Int64()
+ stack.push(interpreter.intPool.get().Set(power2[exp]))
} else {
stack.push(math.Exp(base, exponent))
- interpreter.intPool.put(base)
}
- interpreter.intPool.put(exponent)
+
+ interpreter.intPool.put(base, exponent)
+
return nil, nil
}