@ -18,7 +18,6 @@ package vm
import (
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
@ -35,6 +34,7 @@ var (
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 ) {
@ -405,7 +405,7 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory
}
func opAddress ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
stack . push ( contract . Address ( ) . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( contract . Address ( ) . Bytes ( ) ) )
return nil , nil
}
@ -416,12 +416,12 @@ func opBalance(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memo
}
func opOrigin ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
stack . push ( interpreter . evm . Origin . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( interpreter . evm . Origin . Bytes ( ) ) )
return nil , nil
}
func opCaller ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
stack . push ( contract . Caller ( ) . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( contract . Caller ( ) . Bytes ( ) ) )
return nil , nil
}
@ -467,7 +467,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contrac
)
defer interpreter . intPool . put ( memOffset , dataOffset , length , end )
if end . BitLen ( ) > 64 || uint64 ( len ( interpreter . returnData ) ) < end . Uint64 ( ) {
if ! end . IsUint64 ( ) || uint64 ( len ( interpreter . returnData ) ) < end . Uint64 ( ) {
return nil , errReturnDataOutOfBounds
}
memory . Set ( memOffset . Uint64 ( ) , length . Uint64 ( ) , interpreter . returnData [ dataOffset . Uint64 ( ) : end . Uint64 ( ) ] )
@ -572,7 +572,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, me
}
func opCoinbase ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
stack . push ( interpreter . evm . Coinbase . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( interpreter . evm . Coinbase . Bytes ( ) ) )
return nil , nil
}
@ -645,8 +645,7 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memor
func opJump ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
pos := stack . pop ( )
if ! contract . validJumpdest ( pos ) {
nop := contract . GetOp ( pos . Uint64 ( ) )
return nil , fmt . Errorf ( "invalid jump destination (%v) %v" , nop , pos )
return nil , errInvalidJump
}
* pc = pos . Uint64 ( )
@ -658,8 +657,7 @@ func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory
pos , cond := stack . pop ( ) , stack . pop ( )
if cond . Sign ( ) != 0 {
if ! contract . validJumpdest ( pos ) {
nop := contract . GetOp ( pos . Uint64 ( ) )
return nil , fmt . Errorf ( "invalid jump destination (%v) %v" , nop , pos )
return nil , errInvalidJump
}
* pc = pos . Uint64 ( )
} else {
@ -711,7 +709,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memor
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
stack . push ( interpreter . intPool . getZero ( ) )
} else {
stack . push ( addr . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( addr . Bytes ( ) ) )
}
contract . Gas += returnGas
interpreter . intPool . put ( value , offset , size )
@ -739,7 +737,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memo
if suberr != nil {
stack . push ( interpreter . intPool . getZero ( ) )
} else {
stack . push ( addr . Big ( ) )
stack . push ( interpreter . intPool . get ( ) . SetBytes ( addr . Bytes ( ) ) )
}
contract . Gas += returnGas
interpreter . intPool . put ( endowment , offset , size , salt )
@ -912,6 +910,21 @@ func makeLog(size int) executionFunc {
}
}
// opPush1 is a specialized version of pushN
func opPush1 ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {
var (
codeLen = uint64 ( len ( contract . Code ) )
integer = interpreter . intPool . get ( )
)
* pc += 1
if * pc < codeLen {
stack . push ( integer . SetUint64 ( uint64 ( contract . Code [ * pc ] ) ) )
} else {
stack . push ( integer . SetUint64 ( 0 ) )
}
return nil , nil
}
// make push instruction function
func makePush ( size uint64 , pushByteSize int ) executionFunc {
return func ( pc * uint64 , interpreter * EVMInterpreter , contract * Contract , memory * Memory , stack * Stack ) ( [ ] byte , error ) {