core/vm: after merge

This commit is contained in:
Paweł Bylica 2017-01-20 22:14:10 +01:00
parent e27c5ef401
commit 284c0138fb
No known key found for this signature in database
GPG key ID: 7A0C037434FE77EF
2 changed files with 30 additions and 32 deletions

View file

@ -74,7 +74,7 @@ type EVM struct {
vmConfig Config
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
interpreter *Interpreter
interpreter *EVMJIT
// abort is used to abort the EVM calling operations
// NOTE: must be set atomically
abort int32
@ -89,7 +89,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
chainConfig: chainConfig,
}
evm.interpreter = NewInterpreter(evm, vmConfig)
evm.interpreter = NewJit(evm, vmConfig)
return evm
}
@ -325,4 +325,4 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (re
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
// Interpreter returns the EVM interpreter
func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter }
func (evm *EVM) Interpreter() *EVMJIT { return evm.interpreter }

View file

@ -19,7 +19,6 @@ package vm
/*
#include <evmjit.h>
#include <stdlib.h>
static struct evm_instance* new_evmjit()
@ -63,6 +62,7 @@ import (
"sync"
"unsafe"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
@ -70,15 +70,15 @@ import (
type EVMJIT struct {
jit *C.struct_evm_instance
env *Environment
env *EVM
}
type EVMCContext struct {
contract *Contract
env *Environment
env *EVM
}
func NewJit(env *Environment, cfg Config) *EVMJIT {
func NewJit(env *EVM, cfg Config) *EVMJIT {
// FIXME: Destroy the jit later.
return &EVMJIT{C.new_evmjit(), env}
}
@ -226,7 +226,7 @@ func query(pResult unsafe.Pointer, ctxIdx uintptr, key int32, pArg unsafe.Pointe
*pInt64Result = exist
// fmt.Printf("EXISTS? %x : %v\n", addr, exist)
case C.EVM_CALL_DEPTH:
*pInt64Result = int64(ctx.env.Depth - 1)
*pInt64Result = int64(ctx.env.depth - 1)
default:
panic(fmt.Sprintf("Unhandled EVM-C query %d\n", key))
@ -258,8 +258,12 @@ func update(ctxIdx uintptr, key int32, pArg1 unsafe.Pointer, pArg2 unsafe.Pointe
for i := 0; i < nTopics; i++ {
copy(topics[i][:], tData[i*32:(i+1)*32])
}
log := NewLog(ctx.contract.Address(), topics, data, ctx.env.BlockNumber.Uint64())
ctx.env.StateDB.AddLog(log)
ctx.env.StateDB.AddLog(&types.Log{
Address: ctx.contract.Address(),
Topics: topics,
Data: data,
BlockNumber: ctx.env.BlockNumber.Uint64(),
})
case C.EVM_SELFDESTRUCT:
arg := GoByteSlice(pArg1, 32)
db := ctx.env.StateDB
@ -293,6 +297,10 @@ func call(
output := GoByteSlice(pOutput, outputSize)
bigGas := new(big.Int).SetInt64(gas)
// TODO: For some reason C.EVM_CALL_FAILURE "constant" is not visible
// by go linker. This probably should be reported as cgo bug.
const callFailureFlag int64 = -(1 << 63);
switch kind {
case C.EVM_CALL:
// fmt.Printf("CALL(gas %d, %x)\n", bigGas, address)
@ -306,7 +314,7 @@ func call(
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
return gasLeft
}
return gasLeft | C.EVM_CALL_FAILURE
return gasLeft | callFailureFlag
case C.EVM_CALLCODE:
// fmt.Printf("CALLCODE(gas %d, %x, value %d)\n", bigGas, address, value)
ctx.contract.Gas.SetInt64(0)
@ -320,7 +328,7 @@ func call(
} else {
// fmt.Printf("Error: %v\n", err)
}
return gasLeft | C.EVM_CALL_FAILURE
return gasLeft | callFailureFlag
case C.EVM_DELEGATECALL:
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
ctx.contract.Gas.SetInt64(0)
@ -332,16 +340,16 @@ func call(
copy(output, ret)
return gasLeft
}
return gasLeft | C.EVM_CALL_FAILURE
return gasLeft | callFailureFlag
case C.EVM_CREATE:
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
ctx.contract.Gas.SetInt64(0)
_, addr, err := ctx.env.Create(ctx.contract, input, bigGas, value)
gasLeft := ctx.contract.Gas.Int64()
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
if (ctx.env.ChainConfig().IsHomestead(ctx.env.BlockNumber) && err == CodeStoreOutOfGasError) ||
(err != nil && err != CodeStoreOutOfGasError) {
return C.EVM_CALL_FAILURE
if (ctx.env.ChainConfig().IsHomestead(ctx.env.BlockNumber) && err == ErrCodeStoreOutOfGas) ||
(err != nil && err != ErrCodeStoreOutOfGas) {
return callFailureFlag
} else {
copy(output, addr[:])
return gasLeft
@ -355,7 +363,7 @@ func ptr(bytes []byte) *C.uint8_t {
return (*C.uint8_t)(unsafe.Pointer(header.Data))
}
func getMode(env *Environment) C.enum_evm_mode {
func getMode(env *EVM) C.enum_evm_mode {
n := env.BlockNumber
if env.ChainConfig().IsEIP158(n) {
return C.EVM_CLEARING
@ -370,12 +378,12 @@ func getMode(env *Environment) C.enum_evm_mode {
}
func (evm *EVMJIT) Run(contract *Contract, input []byte) (ret []byte, err error) {
evm.env.Depth++
defer func() { evm.env.Depth-- }()
evm.env.depth++
defer func() { evm.env.depth-- }()
if contract.CodeAddr != nil {
if p := Precompiled[contract.CodeAddr.Str()]; p != nil {
return evm.RunPrecompiled(p, input, contract)
if p := PrecompiledContracts[*contract.CodeAddr]; p != nil {
return RunPrecompiledContract(p, input, contract)
}
}
@ -412,19 +420,9 @@ func (evm *EVMJIT) Run(contract *Contract, input []byte) (ret []byte, err error)
if r.code != 0 {
// EVMJIT does not informs about the kind of the EVM expection.
err = OutOfGasError
err = ErrOutOfGas
}
C.evm_release_result(&r)
return output, err
}
func (evm *EVMJIT) RunPrecompiled(p *PrecompiledAccount, input []byte, contract *Contract) (ret []byte, err error) {
gas := p.Gas(len(input))
if contract.UseGas(gas) {
ret = p.Call(input)
return ret, nil
} else {
return nil, OutOfGasError
}
}