// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package vm
import (
"errors"
"math/big"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/go-ethereum/common"
"github.com/ava-labs/go-ethereum/common/math"
"golang.org/x/crypto/sha3"
)
var (
bigZero = new(big.Int)
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")
errInvalidJump = errors.New("evm: invalid jump destination")
)
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))
interpreter.intPool.put(x)
return nil, nil
}
func opSub(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.peek()
math.U256(y.Sub(x, y))
interpreter.intPool.put(x)
return nil, nil
}
func opMul(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop()
stack.push(math.U256(x.Mul(x, y)))
interpreter.intPool.put(y)
return nil, nil
}
func opDiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.peek()
if y.Sign() != 0 {
math.U256(y.Div(x, y))
} else {
y.SetUint64(0)
}
interpreter.intPool.put(x)
return nil, nil
}
func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := math.S256(stack.pop()), math.S256(stack.pop())
res := interpreter.intPool.getZero()
if y.Sign() == 0 || x.Sign() == 0 {
stack.push(res)
} else {
if x.Sign() != y.Sign() {
res.Div(x.Abs(x), y.Abs(y))
res.Neg(res)
} else {
res.Div(x.Abs(x), y.Abs(y))
}
stack.push(math.U256(res))
}
interpreter.intPool.put(x, y)
return nil, nil
}
func opMod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop()
if y.Sign() == 0 {
stack.push(x.SetUint64(0))
} else {
stack.push(math.U256(x.Mod(x, y)))
}
interpreter.intPool.put(y)
return nil, nil
}
func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := math.S256(stack.pop()), math.S256(stack.pop())
res := interpreter.intPool.getZero()
if y.Sign() == 0 {