|
|
@@ -27,56 +27,42 @@ import (
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
)
|
|
|
|
|
|
-var bigZero = new(big.Int)
|
|
|
-
|
|
|
-func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(U256(x.Add(x, y)))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(U256(x.Sub(x, y)))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(U256(x.Mul(x, y)))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
if y.Cmp(common.Big0) != 0 {
|
|
|
stack.push(U256(x.Div(x, y)))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := S256(stack.pop()), S256(stack.pop())
|
|
|
if y.Cmp(common.Big0) == 0 {
|
|
|
stack.push(new(big.Int))
|
|
|
return nil, nil
|
|
|
} else {
|
|
|
n := new(big.Int)
|
|
|
- if evm.interpreter.intPool.get().Mul(x, y).Cmp(common.Big0) < 0 {
|
|
|
+ if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 {
|
|
|
n.SetInt64(-1)
|
|
|
} else {
|
|
|
n.SetInt64(1)
|
|
|
@@ -87,22 +73,20 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
|
|
|
|
|
|
stack.push(U256(res))
|
|
|
}
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
if y.Cmp(common.Big0) == 0 {
|
|
|
stack.push(new(big.Int))
|
|
|
} else {
|
|
|
stack.push(U256(x.Mod(x, y)))
|
|
|
}
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := S256(stack.pop()), S256(stack.pop())
|
|
|
|
|
|
if y.Cmp(common.Big0) == 0 {
|
|
|
@@ -120,20 +104,16 @@ func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
|
|
|
|
|
|
stack.push(U256(res))
|
|
|
}
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
base, exponent := stack.pop(), stack.pop()
|
|
|
stack.push(math.Exp(base, exponent))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(base, exponent)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
back := stack.pop()
|
|
|
if back.Cmp(big.NewInt(31)) < 0 {
|
|
|
bit := uint(back.Uint64()*8 + 7)
|
|
|
@@ -148,231 +128,198 @@ func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac
|
|
|
|
|
|
stack.push(U256(num))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(back)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x := stack.pop()
|
|
|
stack.push(U256(x.Not(x)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
if x.Cmp(y) < 0 {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x, y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
if x.Cmp(y) > 0 {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x, y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := S256(stack.pop()), S256(stack.pop())
|
|
|
if x.Cmp(S256(y)) < 0 {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x, y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := S256(stack.pop()), S256(stack.pop())
|
|
|
if x.Cmp(y) > 0 {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x, y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
if x.Cmp(y) == 0 {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x, y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x := stack.pop()
|
|
|
if x.Cmp(common.Big0) > 0 {
|
|
|
stack.push(new(big.Int))
|
|
|
} else {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
|
+ stack.push(big.NewInt(1))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(x)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(x.And(x, y))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(x.Or(x, y))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y := stack.pop(), stack.pop()
|
|
|
stack.push(x.Xor(x, y))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
th, val := stack.pop(), stack.pop()
|
|
|
if th.Cmp(big.NewInt(32)) < 0 {
|
|
|
- byte := evm.interpreter.intPool.get().SetInt64(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
|
|
|
+ byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
|
|
|
stack.push(byte)
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(th, val)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
|
|
- if z.Cmp(bigZero) > 0 {
|
|
|
+ if z.Cmp(Zero) > 0 {
|
|
|
add := x.Add(x, y)
|
|
|
add.Mod(add, z)
|
|
|
stack.push(U256(add))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y, z)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
|
|
- if z.Cmp(bigZero) > 0 {
|
|
|
+ if z.Cmp(Zero) > 0 {
|
|
|
mul := x.Mul(x, y)
|
|
|
mul.Mod(mul, z)
|
|
|
stack.push(U256(mul))
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(y, z)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
offset, size := stack.pop(), stack.pop()
|
|
|
data := memory.Get(offset.Int64(), size.Int64())
|
|
|
hash := crypto.Keccak256(data)
|
|
|
|
|
|
- if evm.vmConfig.EnablePreimageRecording {
|
|
|
- evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
|
|
|
+ if env.vmConfig.EnablePreimageRecording {
|
|
|
+ env.StateDB.AddPreimage(common.BytesToHash(hash), data)
|
|
|
}
|
|
|
|
|
|
stack.push(common.BytesToBig(hash))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(offset, size)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.push(common.Bytes2Big(contract.Address().Bytes()))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
addr := common.BigToAddress(stack.pop())
|
|
|
- balance := evm.StateDB.GetBalance(addr)
|
|
|
+ balance := env.StateDB.GetBalance(addr)
|
|
|
|
|
|
stack.push(new(big.Int).Set(balance))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.Origin.Big())
|
|
|
+func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(env.Origin.Big())
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.push(contract.Caller().Big())
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().Set(contract.value))
|
|
|
+func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(new(big.Int).Set(contract.value))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
|
|
|
+func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(big.NewInt(int64(len(contract.Input))))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
var (
|
|
|
mOff = stack.pop()
|
|
|
cOff = stack.pop()
|
|
|
l = stack.pop()
|
|
|
)
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(mOff, cOff, l)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- a := stack.pop()
|
|
|
-
|
|
|
- addr := common.BigToAddress(a)
|
|
|
- a.SetInt64(int64(evm.StateDB.GetCodeSize(addr)))
|
|
|
- stack.push(a)
|
|
|
-
|
|
|
+func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ addr := common.BigToAddress(stack.pop())
|
|
|
+ l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
|
|
|
+ stack.push(l)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
|
|
|
+func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ l := big.NewInt(int64(len(contract.Code)))
|
|
|
stack.push(l)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
var (
|
|
|
mOff = stack.pop()
|
|
|
cOff = stack.pop()
|
|
|
@@ -381,129 +328,113 @@ func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
|
|
|
codeCopy := getData(contract.Code, cOff, l)
|
|
|
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(mOff, cOff, l)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
var (
|
|
|
addr = common.BigToAddress(stack.pop())
|
|
|
mOff = stack.pop()
|
|
|
cOff = stack.pop()
|
|
|
l = stack.pop()
|
|
|
)
|
|
|
- codeCopy := getData(evm.StateDB.GetCode(addr), cOff, l)
|
|
|
+ codeCopy := getData(env.StateDB.GetCode(addr), cOff, l)
|
|
|
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(mOff, cOff, l)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
|
|
|
+func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(new(big.Int).Set(env.GasPrice))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
num := stack.pop()
|
|
|
|
|
|
- n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
|
|
|
- if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
|
|
|
- stack.push(evm.GetHash(num.Uint64()).Big())
|
|
|
+ n := new(big.Int).Sub(env.BlockNumber, common.Big257)
|
|
|
+ if num.Cmp(n) > 0 && num.Cmp(env.BlockNumber) < 0 {
|
|
|
+ stack.push(env.GetHash(num.Uint64()).Big())
|
|
|
} else {
|
|
|
stack.push(new(big.Int))
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(num, n)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.Coinbase.Big())
|
|
|
+func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(env.Coinbase.Big())
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(U256(new(big.Int).Set(evm.Time)))
|
|
|
+func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(U256(new(big.Int).Set(env.Time)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(U256(new(big.Int).Set(evm.BlockNumber)))
|
|
|
+func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(U256(new(big.Int).Set(env.BlockNumber)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(U256(new(big.Int).Set(evm.Difficulty)))
|
|
|
+func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(U256(new(big.Int).Set(env.Difficulty)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(U256(new(big.Int).Set(evm.GasLimit)))
|
|
|
+func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(U256(new(big.Int).Set(env.GasLimit)))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- evm.interpreter.intPool.put(stack.pop())
|
|
|
+func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.pop()
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
offset := stack.pop()
|
|
|
val := common.BigD(memory.Get(offset.Int64(), 32))
|
|
|
stack.push(val)
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(offset)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
// pop value of the stack
|
|
|
mStart, val := stack.pop(), stack.pop()
|
|
|
memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(mStart, val)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
off, val := stack.pop().Int64(), stack.pop().Int64()
|
|
|
memory.store[off] = byte(val & 0xff)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
loc := common.BigToHash(stack.pop())
|
|
|
- val := evm.StateDB.GetState(contract.Address(), loc).Big()
|
|
|
+ val := env.StateDB.GetState(contract.Address(), loc).Big()
|
|
|
stack.push(val)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
loc := common.BigToHash(stack.pop())
|
|
|
val := stack.pop()
|
|
|
- evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(val)
|
|
|
+ env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
pos := stack.pop()
|
|
|
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
|
|
nop := contract.GetOp(pos.Uint64())
|
|
|
return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
|
|
|
}
|
|
|
*pc = pos.Uint64()
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(pos)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
pos, cond := stack.pop(), stack.pop()
|
|
|
if cond.Cmp(common.BigTrue) >= 0 {
|
|
|
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
|
|
@@ -514,62 +445,57 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St
|
|
|
} else {
|
|
|
*pc++
|
|
|
}
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(pos, cond)
|
|
|
return nil, nil
|
|
|
}
|
|
|
-func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
|
|
|
+func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(new(big.Int).SetUint64(*pc))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
|
|
|
+func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(big.NewInt(int64(memory.Len())))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
|
|
|
+func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ stack.push(new(big.Int).Set(contract.Gas))
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
var (
|
|
|
value = stack.pop()
|
|
|
offset, size = stack.pop(), stack.pop()
|
|
|
input = memory.Get(offset.Int64(), size.Int64())
|
|
|
- gas = contract.Gas
|
|
|
+ gas = new(big.Int).Set(contract.Gas)
|
|
|
)
|
|
|
- if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
|
|
|
- gas -= gas / 64
|
|
|
+ if env.ChainConfig().IsEIP150(env.BlockNumber) {
|
|
|
+ gas.Div(gas, n64)
|
|
|
+ gas = gas.Sub(contract.Gas, gas)
|
|
|
}
|
|
|
|
|
|
contract.UseGas(gas)
|
|
|
- _, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
|
|
|
+ _, addr, suberr := env.Create(contract, input, gas, value)
|
|
|
// Push item on the stack based on the returned error. If the ruleset is
|
|
|
// homestead we must check for CodeStoreOutOfGasError (homestead only
|
|
|
// rule) and treat as an error, if the ruleset is frontier we must
|
|
|
// ignore this error and pretend the operation was successful.
|
|
|
- if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
|
|
|
+ if env.ChainConfig().IsHomestead(env.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
|
|
|
stack.push(new(big.Int))
|
|
|
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
|
|
|
stack.push(new(big.Int))
|
|
|
} else {
|
|
|
stack.push(addr.Big())
|
|
|
}
|
|
|
- contract.Gas += returnGas
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(value, offset, size)
|
|
|
-
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- gas := stack.pop().Uint64()
|
|
|
+func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ gas := stack.pop()
|
|
|
// pop gas and value of the stack.
|
|
|
addr, value := stack.pop(), stack.pop()
|
|
|
value = U256(value)
|
|
|
@@ -583,26 +509,25 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
|
|
|
// Get the arguments from the memory
|
|
|
args := memory.Get(inOffset.Int64(), inSize.Int64())
|
|
|
|
|
|
- if value.BitLen() > 0 {
|
|
|
- gas += params.CallStipend
|
|
|
+ if len(value.Bytes()) > 0 {
|
|
|
+ gas.Add(gas, params.CallStipend)
|
|
|
}
|
|
|
|
|
|
- ret, returnGas, err := evm.Call(contract, address, args, gas, value)
|
|
|
+ ret, err := env.Call(contract, address, args, gas, value)
|
|
|
+
|
|
|
if err != nil {
|
|
|
stack.push(new(big.Int))
|
|
|
+
|
|
|
} else {
|
|
|
stack.push(big.NewInt(1))
|
|
|
|
|
|
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
|
|
}
|
|
|
- contract.Gas += returnGas
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- gas := stack.pop().Uint64()
|
|
|
+func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ gas := stack.pop()
|
|
|
// pop gas and value of the stack.
|
|
|
addr, value := stack.pop(), stack.pop()
|
|
|
value = U256(value)
|
|
|
@@ -616,11 +541,12 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
|
|
|
// Get the arguments from the memory
|
|
|
args := memory.Get(inOffset.Int64(), inSize.Int64())
|
|
|
|
|
|
- if value.BitLen() > 0 {
|
|
|
- gas += params.CallStipend
|
|
|
+ if len(value.Bytes()) > 0 {
|
|
|
+ gas.Add(gas, params.CallStipend)
|
|
|
}
|
|
|
|
|
|
- ret, returnGas, err := evm.CallCode(contract, address, args, gas, value)
|
|
|
+ ret, err := env.CallCode(contract, address, args, gas, value)
|
|
|
+
|
|
|
if err != nil {
|
|
|
stack.push(new(big.Int))
|
|
|
|
|
|
@@ -629,54 +555,46 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
|
|
|
|
|
|
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
|
|
}
|
|
|
- contract.Gas += returnGas
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
// if not homestead return an error. DELEGATECALL is not supported
|
|
|
// during pre-homestead.
|
|
|
- if !evm.ChainConfig().IsHomestead(evm.BlockNumber) {
|
|
|
+ if !env.ChainConfig().IsHomestead(env.BlockNumber) {
|
|
|
return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
|
|
|
}
|
|
|
|
|
|
- gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
|
|
+ gas, to, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
|
|
|
|
|
toAddr := common.BigToAddress(to)
|
|
|
args := memory.Get(inOffset.Int64(), inSize.Int64())
|
|
|
-
|
|
|
- ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
|
|
|
+ ret, err := env.DelegateCall(contract, toAddr, args, gas)
|
|
|
if err != nil {
|
|
|
stack.push(new(big.Int))
|
|
|
} else {
|
|
|
stack.push(big.NewInt(1))
|
|
|
memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
|
|
|
}
|
|
|
- contract.Gas += returnGas
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
offset, size := stack.pop(), stack.pop()
|
|
|
ret := memory.GetPtr(offset.Int64(), size.Int64())
|
|
|
|
|
|
- evm.interpreter.intPool.put(offset, size)
|
|
|
return ret, nil
|
|
|
}
|
|
|
|
|
|
-func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
-func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- balance := evm.StateDB.GetBalance(contract.Address())
|
|
|
- evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
|
|
|
+func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ balance := env.StateDB.GetBalance(contract.Address())
|
|
|
+ env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
|
|
|
|
|
|
- evm.StateDB.Suicide(contract.Address())
|
|
|
+ env.StateDB.Suicide(contract.Address())
|
|
|
|
|
|
return nil, nil
|
|
|
}
|
|
|
@@ -685,7 +603,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *
|
|
|
|
|
|
// make log instruction function
|
|
|
func makeLog(size int) executionFunc {
|
|
|
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
topics := make([]common.Hash, size)
|
|
|
mStart, mSize := stack.pop(), stack.pop()
|
|
|
for i := 0; i < size; i++ {
|
|
|
@@ -693,24 +611,22 @@ func makeLog(size int) executionFunc {
|
|
|
}
|
|
|
|
|
|
d := memory.Get(mStart.Int64(), mSize.Int64())
|
|
|
- evm.StateDB.AddLog(&types.Log{
|
|
|
+ env.StateDB.AddLog(&types.Log{
|
|
|
Address: contract.Address(),
|
|
|
Topics: topics,
|
|
|
Data: d,
|
|
|
// This is a non-consensus field, but assigned here because
|
|
|
// core/state doesn't know the current block number.
|
|
|
- BlockNumber: evm.BlockNumber.Uint64(),
|
|
|
+ BlockNumber: env.BlockNumber.Uint64(),
|
|
|
})
|
|
|
-
|
|
|
- evm.interpreter.intPool.put(mStart, mSize)
|
|
|
return nil, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// make push instruction function
|
|
|
func makePush(size uint64, bsize *big.Int) executionFunc {
|
|
|
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
- byts := getData(contract.Code, evm.interpreter.intPool.get().SetUint64(*pc+1), bsize)
|
|
|
+ return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
|
|
|
stack.push(common.Bytes2Big(byts))
|
|
|
*pc += size
|
|
|
return nil, nil
|
|
|
@@ -719,7 +635,7 @@ func makePush(size uint64, bsize *big.Int) executionFunc {
|
|
|
|
|
|
// make push instruction function
|
|
|
func makeDup(size int64) executionFunc {
|
|
|
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.dup(int(size))
|
|
|
return nil, nil
|
|
|
}
|
|
|
@@ -729,7 +645,7 @@ func makeDup(size int64) executionFunc {
|
|
|
func makeSwap(size int64) executionFunc {
|
|
|
// switch n + 1 otherwise n would be swapped with n
|
|
|
size += 1
|
|
|
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.swap(int(size))
|
|
|
return nil, nil
|
|
|
}
|