github.com/pfcoder/quorum@v2.0.3-0.20180501191142-d4a1b0958135+incompatible/core/vm/instructions.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vm
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/math"
    26  	"github.com/ethereum/go-ethereum/core/types"
    27  	"github.com/ethereum/go-ethereum/crypto"
    28  	"github.com/ethereum/go-ethereum/params"
    29  )
    30  
    31  var (
    32  	bigZero                  = new(big.Int)
    33  	errWriteProtection       = errors.New("evm: write protection")
    34  	errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
    35  	errExecutionReverted     = errors.New("evm: execution reverted")
    36  	errMaxCodeSizeExceeded   = errors.New("evm: max code size exceeded")
    37  )
    38  
    39  func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    40  	x, y := stack.pop(), stack.pop()
    41  	stack.push(math.U256(x.Add(x, y)))
    42  
    43  	evm.interpreter.intPool.put(y)
    44  
    45  	return nil, nil
    46  }
    47  
    48  func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    49  	x, y := stack.pop(), stack.pop()
    50  	stack.push(math.U256(x.Sub(x, y)))
    51  
    52  	evm.interpreter.intPool.put(y)
    53  
    54  	return nil, nil
    55  }
    56  
    57  func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    58  	x, y := stack.pop(), stack.pop()
    59  	stack.push(math.U256(x.Mul(x, y)))
    60  
    61  	evm.interpreter.intPool.put(y)
    62  
    63  	return nil, nil
    64  }
    65  
    66  func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    67  	x, y := stack.pop(), stack.pop()
    68  	if y.Sign() != 0 {
    69  		stack.push(math.U256(x.Div(x, y)))
    70  	} else {
    71  		stack.push(new(big.Int))
    72  	}
    73  
    74  	evm.interpreter.intPool.put(y)
    75  
    76  	return nil, nil
    77  }
    78  
    79  func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    80  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
    81  	if y.Sign() == 0 {
    82  		stack.push(new(big.Int))
    83  		return nil, nil
    84  	} else {
    85  		n := new(big.Int)
    86  		if evm.interpreter.intPool.get().Mul(x, y).Sign() < 0 {
    87  			n.SetInt64(-1)
    88  		} else {
    89  			n.SetInt64(1)
    90  		}
    91  
    92  		res := x.Div(x.Abs(x), y.Abs(y))
    93  		res.Mul(res, n)
    94  
    95  		stack.push(math.U256(res))
    96  	}
    97  	evm.interpreter.intPool.put(y)
    98  	return nil, nil
    99  }
   100  
   101  func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   102  	x, y := stack.pop(), stack.pop()
   103  	if y.Sign() == 0 {
   104  		stack.push(new(big.Int))
   105  	} else {
   106  		stack.push(math.U256(x.Mod(x, y)))
   107  	}
   108  	evm.interpreter.intPool.put(y)
   109  	return nil, nil
   110  }
   111  
   112  func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   113  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   114  
   115  	if y.Sign() == 0 {
   116  		stack.push(new(big.Int))
   117  	} else {
   118  		n := new(big.Int)
   119  		if x.Sign() < 0 {
   120  			n.SetInt64(-1)
   121  		} else {
   122  			n.SetInt64(1)
   123  		}
   124  
   125  		res := x.Mod(x.Abs(x), y.Abs(y))
   126  		res.Mul(res, n)
   127  
   128  		stack.push(math.U256(res))
   129  	}
   130  	evm.interpreter.intPool.put(y)
   131  	return nil, nil
   132  }
   133  
   134  func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   135  	base, exponent := stack.pop(), stack.pop()
   136  	stack.push(math.Exp(base, exponent))
   137  
   138  	evm.interpreter.intPool.put(base, exponent)
   139  
   140  	return nil, nil
   141  }
   142  
   143  func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   144  	back := stack.pop()
   145  	if back.Cmp(big.NewInt(31)) < 0 {
   146  		bit := uint(back.Uint64()*8 + 7)
   147  		num := stack.pop()
   148  		mask := back.Lsh(common.Big1, bit)
   149  		mask.Sub(mask, common.Big1)
   150  		if num.Bit(int(bit)) > 0 {
   151  			num.Or(num, mask.Not(mask))
   152  		} else {
   153  			num.And(num, mask)
   154  		}
   155  
   156  		stack.push(math.U256(num))
   157  	}
   158  
   159  	evm.interpreter.intPool.put(back)
   160  	return nil, nil
   161  }
   162  
   163  func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   164  	x := stack.pop()
   165  	stack.push(math.U256(x.Not(x)))
   166  	return nil, nil
   167  }
   168  
   169  func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   170  	x, y := stack.pop(), stack.pop()
   171  	if x.Cmp(y) < 0 {
   172  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   173  	} else {
   174  		stack.push(new(big.Int))
   175  	}
   176  
   177  	evm.interpreter.intPool.put(x, y)
   178  	return nil, nil
   179  }
   180  
   181  func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   182  	x, y := stack.pop(), stack.pop()
   183  	if x.Cmp(y) > 0 {
   184  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   185  	} else {
   186  		stack.push(new(big.Int))
   187  	}
   188  
   189  	evm.interpreter.intPool.put(x, y)
   190  	return nil, nil
   191  }
   192  
   193  func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   194  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   195  	if x.Cmp(math.S256(y)) < 0 {
   196  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   197  	} else {
   198  		stack.push(new(big.Int))
   199  	}
   200  
   201  	evm.interpreter.intPool.put(x, y)
   202  	return nil, nil
   203  }
   204  
   205  func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   206  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   207  	if x.Cmp(y) > 0 {
   208  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   209  	} else {
   210  		stack.push(new(big.Int))
   211  	}
   212  
   213  	evm.interpreter.intPool.put(x, y)
   214  	return nil, nil
   215  }
   216  
   217  func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   218  	x, y := stack.pop(), stack.pop()
   219  	if x.Cmp(y) == 0 {
   220  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   221  	} else {
   222  		stack.push(new(big.Int))
   223  	}
   224  
   225  	evm.interpreter.intPool.put(x, y)
   226  	return nil, nil
   227  }
   228  
   229  func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   230  	x := stack.pop()
   231  	if x.Sign() > 0 {
   232  		stack.push(new(big.Int))
   233  	} else {
   234  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   235  	}
   236  
   237  	evm.interpreter.intPool.put(x)
   238  	return nil, nil
   239  }
   240  
   241  func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   242  	x, y := stack.pop(), stack.pop()
   243  	stack.push(x.And(x, y))
   244  
   245  	evm.interpreter.intPool.put(y)
   246  	return nil, nil
   247  }
   248  
   249  func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   250  	x, y := stack.pop(), stack.pop()
   251  	stack.push(x.Or(x, y))
   252  
   253  	evm.interpreter.intPool.put(y)
   254  	return nil, nil
   255  }
   256  
   257  func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   258  	x, y := stack.pop(), stack.pop()
   259  	stack.push(x.Xor(x, y))
   260  
   261  	evm.interpreter.intPool.put(y)
   262  	return nil, nil
   263  }
   264  
   265  func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   266  	th, val := stack.pop(), stack.peek()
   267  	if th.Cmp(common.Big32) < 0 {
   268  		b := math.Byte(val, 32, int(th.Int64()))
   269  		val.SetUint64(uint64(b))
   270  	} else {
   271  		val.SetUint64(0)
   272  	}
   273  	evm.interpreter.intPool.put(th)
   274  	return nil, nil
   275  }
   276  
   277  func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   278  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   279  	if z.Cmp(bigZero) > 0 {
   280  		add := x.Add(x, y)
   281  		add.Mod(add, z)
   282  		stack.push(math.U256(add))
   283  	} else {
   284  		stack.push(new(big.Int))
   285  	}
   286  
   287  	evm.interpreter.intPool.put(y, z)
   288  	return nil, nil
   289  }
   290  
   291  func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   292  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   293  	if z.Cmp(bigZero) > 0 {
   294  		mul := x.Mul(x, y)
   295  		mul.Mod(mul, z)
   296  		stack.push(math.U256(mul))
   297  	} else {
   298  		stack.push(new(big.Int))
   299  	}
   300  
   301  	evm.interpreter.intPool.put(y, z)
   302  	return nil, nil
   303  }
   304  
   305  func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   306  	offset, size := stack.pop(), stack.pop()
   307  	data := memory.Get(offset.Int64(), size.Int64())
   308  	hash := crypto.Keccak256(data)
   309  
   310  	if evm.vmConfig.EnablePreimageRecording {
   311  		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
   312  	}
   313  
   314  	stack.push(new(big.Int).SetBytes(hash))
   315  
   316  	evm.interpreter.intPool.put(offset, size)
   317  	return nil, nil
   318  }
   319  
   320  func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   321  	stack.push(contract.Address().Big())
   322  	return nil, nil
   323  }
   324  
   325  func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   326  	addr := common.BigToAddress(stack.pop())
   327  	balance := getDualState(evm, addr).GetBalance(addr)
   328  
   329  	stack.push(new(big.Int).Set(balance))
   330  	return nil, nil
   331  }
   332  
   333  func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   334  	stack.push(evm.Origin.Big())
   335  	return nil, nil
   336  }
   337  
   338  func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   339  	stack.push(contract.Caller().Big())
   340  	return nil, nil
   341  }
   342  
   343  func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   344  	stack.push(evm.interpreter.intPool.get().Set(contract.value))
   345  	return nil, nil
   346  }
   347  
   348  func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   349  	stack.push(new(big.Int).SetBytes(getDataBig(contract.Input, stack.pop(), big32)))
   350  	return nil, nil
   351  }
   352  
   353  func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   354  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
   355  	return nil, nil
   356  }
   357  
   358  func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   359  	var (
   360  		memOffset  = stack.pop()
   361  		dataOffset = stack.pop()
   362  		length     = stack.pop()
   363  	)
   364  	memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length))
   365  
   366  	evm.interpreter.intPool.put(memOffset, dataOffset, length)
   367  	return nil, nil
   368  }
   369  
   370  func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   371  	stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData))))
   372  	return nil, nil
   373  }
   374  
   375  func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   376  	var (
   377  		memOffset  = stack.pop()
   378  		dataOffset = stack.pop()
   379  		length     = stack.pop()
   380  	)
   381  	defer evm.interpreter.intPool.put(memOffset, dataOffset, length)
   382  
   383  	end := new(big.Int).Add(dataOffset, length)
   384  	if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() {
   385  		return nil, errReturnDataOutOfBounds
   386  	}
   387  	memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()])
   388  
   389  	return nil, nil
   390  }
   391  
   392  func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   393  	a := stack.pop()
   394  
   395  	addr := common.BigToAddress(a)
   396  	a.SetInt64(int64(getDualState(evm, addr).GetCodeSize(addr)))
   397  	stack.push(a)
   398  
   399  	return nil, nil
   400  }
   401  
   402  func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   403  	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
   404  	stack.push(l)
   405  	return nil, nil
   406  }
   407  
   408  func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   409  	var (
   410  		memOffset  = stack.pop()
   411  		codeOffset = stack.pop()
   412  		length     = stack.pop()
   413  	)
   414  	codeCopy := getDataBig(contract.Code, codeOffset, length)
   415  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   416  
   417  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   418  	return nil, nil
   419  }
   420  
   421  func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   422  	var (
   423  		addr       = common.BigToAddress(stack.pop())
   424  		memOffset  = stack.pop()
   425  		codeOffset = stack.pop()
   426  		length     = stack.pop()
   427  	)
   428  	codeCopy := getDataBig(getDualState(evm, addr).GetCode(addr), codeOffset, length)
   429  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   430  
   431  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   432  	return nil, nil
   433  }
   434  
   435  func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   436  	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
   437  	return nil, nil
   438  }
   439  
   440  func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   441  	num := stack.pop()
   442  
   443  	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
   444  	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
   445  		stack.push(evm.GetHash(num.Uint64()).Big())
   446  	} else {
   447  		stack.push(new(big.Int))
   448  	}
   449  
   450  	evm.interpreter.intPool.put(num, n)
   451  	return nil, nil
   452  }
   453  
   454  func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   455  	stack.push(evm.Coinbase.Big())
   456  	return nil, nil
   457  }
   458  
   459  func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   460  	stack.push(math.U256(new(big.Int).Set(evm.Time)))
   461  	return nil, nil
   462  }
   463  
   464  func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   465  	stack.push(math.U256(new(big.Int).Set(evm.BlockNumber)))
   466  	return nil, nil
   467  }
   468  
   469  func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   470  	stack.push(math.U256(new(big.Int).Set(evm.Difficulty)))
   471  	return nil, nil
   472  }
   473  
   474  func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   475  	stack.push(math.U256(new(big.Int).Set(evm.GasLimit)))
   476  	return nil, nil
   477  }
   478  
   479  func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   480  	evm.interpreter.intPool.put(stack.pop())
   481  	return nil, nil
   482  }
   483  
   484  func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   485  	offset := stack.pop()
   486  	val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32))
   487  	stack.push(val)
   488  
   489  	evm.interpreter.intPool.put(offset)
   490  	return nil, nil
   491  }
   492  
   493  func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   494  	// pop value of the stack
   495  	mStart, val := stack.pop(), stack.pop()
   496  	memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
   497  
   498  	evm.interpreter.intPool.put(mStart, val)
   499  	return nil, nil
   500  }
   501  
   502  func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   503  	off, val := stack.pop().Int64(), stack.pop().Int64()
   504  	memory.store[off] = byte(val & 0xff)
   505  
   506  	return nil, nil
   507  }
   508  
   509  func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   510  	loc := common.BigToHash(stack.pop())
   511  	val := getDualState(evm, contract.Address()).GetState(contract.Address(), loc).Big()
   512  	stack.push(val)
   513  	return nil, nil
   514  }
   515  
   516  func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   517  	loc := common.BigToHash(stack.pop())
   518  	val := stack.pop()
   519  	getDualState(evm, contract.Address()).SetState(contract.Address(), loc, common.BigToHash(val))
   520  
   521  	evm.interpreter.intPool.put(val)
   522  	return nil, nil
   523  }
   524  
   525  func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   526  	pos := stack.pop()
   527  	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   528  		nop := contract.GetOp(pos.Uint64())
   529  		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   530  	}
   531  	*pc = pos.Uint64()
   532  
   533  	evm.interpreter.intPool.put(pos)
   534  	return nil, nil
   535  }
   536  
   537  func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   538  	pos, cond := stack.pop(), stack.pop()
   539  	if cond.Sign() != 0 {
   540  		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   541  			nop := contract.GetOp(pos.Uint64())
   542  			return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   543  		}
   544  		*pc = pos.Uint64()
   545  	} else {
   546  		*pc++
   547  	}
   548  
   549  	evm.interpreter.intPool.put(pos, cond)
   550  	return nil, nil
   551  }
   552  
   553  func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   554  	return nil, nil
   555  }
   556  
   557  func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   558  	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
   559  	return nil, nil
   560  }
   561  
   562  func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   563  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
   564  	return nil, nil
   565  }
   566  
   567  func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   568  	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
   569  	return nil, nil
   570  }
   571  
   572  func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   573  	var (
   574  		value        = stack.pop()
   575  		offset, size = stack.pop(), stack.pop()
   576  		input        = memory.Get(offset.Int64(), size.Int64())
   577  		gas          = contract.Gas
   578  	)
   579  	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
   580  		gas -= gas / 64
   581  	}
   582  
   583  	contract.UseGas(gas)
   584  	res, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
   585  	// Push item on the stack based on the returned error. If the ruleset is
   586  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   587  	// rule) and treat as an error, if the ruleset is frontier we must
   588  	// ignore this error and pretend the operation was successful.
   589  	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
   590  		stack.push(new(big.Int))
   591  	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
   592  		stack.push(new(big.Int))
   593  	} else {
   594  		stack.push(addr.Big())
   595  	}
   596  	contract.Gas += returnGas
   597  	evm.interpreter.intPool.put(value, offset, size)
   598  
   599  	if suberr == errExecutionReverted {
   600  		return res, nil
   601  	}
   602  	return nil, nil
   603  }
   604  
   605  func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   606  	gas := stack.pop().Uint64()
   607  	// pop gas and value of the stack.
   608  	addr, value := stack.pop(), stack.pop()
   609  	value = math.U256(value)
   610  	// pop input size and offset
   611  	inOffset, inSize := stack.pop(), stack.pop()
   612  	// pop return size and offset
   613  	retOffset, retSize := stack.pop(), stack.pop()
   614  
   615  	address := common.BigToAddress(addr)
   616  
   617  	// Get the arguments from the memory
   618  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   619  
   620  	if value.Sign() != 0 {
   621  		gas += params.CallStipend
   622  	}
   623  	ret, returnGas, err := evm.Call(contract, address, args, gas, value)
   624  	if err != nil {
   625  		stack.push(new(big.Int))
   626  	} else {
   627  		stack.push(big.NewInt(1))
   628  	}
   629  	if err == nil || err == errExecutionReverted {
   630  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   631  	}
   632  	contract.Gas += returnGas
   633  
   634  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   635  	return ret, nil
   636  }
   637  
   638  func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   639  	gas := stack.pop().Uint64()
   640  	// pop gas and value of the stack.
   641  	addr, value := stack.pop(), stack.pop()
   642  	value = math.U256(value)
   643  	// pop input size and offset
   644  	inOffset, inSize := stack.pop(), stack.pop()
   645  	// pop return size and offset
   646  	retOffset, retSize := stack.pop(), stack.pop()
   647  
   648  	address := common.BigToAddress(addr)
   649  
   650  	// Get the arguments from the memory
   651  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   652  
   653  	if value.Sign() != 0 {
   654  		gas += params.CallStipend
   655  	}
   656  
   657  	ret, returnGas, err := evm.CallCode(contract, address, args, gas, value)
   658  	if err != nil {
   659  		stack.push(new(big.Int))
   660  	} else {
   661  		stack.push(big.NewInt(1))
   662  	}
   663  	if err == nil || err == errExecutionReverted {
   664  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   665  	}
   666  	contract.Gas += returnGas
   667  
   668  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   669  	return ret, nil
   670  }
   671  
   672  func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   673  	gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   674  
   675  	toAddr := common.BigToAddress(to)
   676  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   677  
   678  	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
   679  	if err != nil {
   680  		stack.push(new(big.Int))
   681  	} else {
   682  		stack.push(big.NewInt(1))
   683  	}
   684  	if err == nil || err == errExecutionReverted {
   685  		memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
   686  	}
   687  	contract.Gas += returnGas
   688  
   689  	evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize)
   690  	return ret, nil
   691  }
   692  
   693  func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   694  	// pop gas
   695  	gas := stack.pop().Uint64()
   696  	// pop address
   697  	addr := stack.pop()
   698  	// pop input size and offset
   699  	inOffset, inSize := stack.pop(), stack.pop()
   700  	// pop return size and offset
   701  	retOffset, retSize := stack.pop(), stack.pop()
   702  
   703  	address := common.BigToAddress(addr)
   704  
   705  	// Get the arguments from the memory
   706  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   707  
   708  	ret, returnGas, err := evm.StaticCall(contract, address, args, gas)
   709  	if err != nil {
   710  		stack.push(new(big.Int))
   711  	} else {
   712  		stack.push(big.NewInt(1))
   713  	}
   714  	if err == nil || err == errExecutionReverted {
   715  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   716  	}
   717  	contract.Gas += returnGas
   718  
   719  	evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
   720  	return ret, nil
   721  }
   722  
   723  func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   724  	offset, size := stack.pop(), stack.pop()
   725  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   726  
   727  	evm.interpreter.intPool.put(offset, size)
   728  	return ret, nil
   729  }
   730  
   731  func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   732  	offset, size := stack.pop(), stack.pop()
   733  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   734  
   735  	evm.interpreter.intPool.put(offset, size)
   736  	return ret, nil
   737  }
   738  
   739  func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   740  	return nil, nil
   741  }
   742  
   743  func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   744  	db := getDualState(evm, contract.Address())
   745  	balance := db.GetBalance(contract.Address())
   746  	db.AddBalance(common.BigToAddress(stack.pop()), balance)
   747  
   748  	db.Suicide(contract.Address())
   749  	return nil, nil
   750  }
   751  
   752  // following functions are used by the instruction jump  table
   753  
   754  // make log instruction function
   755  func makeLog(size int) executionFunc {
   756  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   757  		topics := make([]common.Hash, size)
   758  		mStart, mSize := stack.pop(), stack.pop()
   759  		for i := 0; i < size; i++ {
   760  			topics[i] = common.BigToHash(stack.pop())
   761  		}
   762  
   763  		d := memory.Get(mStart.Int64(), mSize.Int64())
   764  		evm.StateDB.AddLog(&types.Log{
   765  			Address: contract.Address(),
   766  			Topics:  topics,
   767  			Data:    d,
   768  			// This is a non-consensus field, but assigned here because
   769  			// core/state doesn't know the current block number.
   770  			BlockNumber: evm.BlockNumber.Uint64(),
   771  		})
   772  
   773  		evm.interpreter.intPool.put(mStart, mSize)
   774  		return nil, nil
   775  	}
   776  }
   777  
   778  // make push instruction function
   779  func makePush(size uint64, pushByteSize int) executionFunc {
   780  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   781  		codeLen := len(contract.Code)
   782  
   783  		startMin := codeLen
   784  		if int(*pc+1) < startMin {
   785  			startMin = int(*pc + 1)
   786  		}
   787  
   788  		endMin := codeLen
   789  		if startMin+pushByteSize < endMin {
   790  			endMin = startMin + pushByteSize
   791  		}
   792  
   793  		integer := evm.interpreter.intPool.get()
   794  		stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
   795  
   796  		*pc += size
   797  		return nil, nil
   798  	}
   799  }
   800  
   801  // make push instruction function
   802  func makeDup(size int64) executionFunc {
   803  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   804  		stack.dup(evm.interpreter.intPool, int(size))
   805  		return nil, nil
   806  	}
   807  }
   808  
   809  // make swap instruction function
   810  func makeSwap(size int64) executionFunc {
   811  	// switch n + 1 otherwise n would be swapped with n
   812  	size += 1
   813  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   814  		stack.swap(int(size))
   815  		return nil, nil
   816  	}
   817  }