mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/vm: after merge
This commit is contained in:
parent
e27c5ef401
commit
284c0138fb
2 changed files with 30 additions and 32 deletions
|
|
@ -74,7 +74,7 @@ type EVM struct {
|
||||||
vmConfig Config
|
vmConfig Config
|
||||||
// global (to this context) ethereum virtual machine
|
// global (to this context) ethereum virtual machine
|
||||||
// used throughout the execution of the tx.
|
// used throughout the execution of the tx.
|
||||||
interpreter *Interpreter
|
interpreter *EVMJIT
|
||||||
// abort is used to abort the EVM calling operations
|
// abort is used to abort the EVM calling operations
|
||||||
// NOTE: must be set atomically
|
// NOTE: must be set atomically
|
||||||
abort int32
|
abort int32
|
||||||
|
|
@ -89,7 +89,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.interpreter = NewInterpreter(evm, vmConfig)
|
evm.interpreter = NewJit(evm, vmConfig)
|
||||||
return evm
|
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 }
|
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||||
|
|
||||||
// Interpreter returns the EVM interpreter
|
// Interpreter returns the EVM interpreter
|
||||||
func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter }
|
func (evm *EVM) Interpreter() *EVMJIT { return evm.interpreter }
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package vm
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include <evmjit.h>
|
#include <evmjit.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
static struct evm_instance* new_evmjit()
|
static struct evm_instance* new_evmjit()
|
||||||
|
|
@ -63,6 +62,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -70,15 +70,15 @@ import (
|
||||||
|
|
||||||
type EVMJIT struct {
|
type EVMJIT struct {
|
||||||
jit *C.struct_evm_instance
|
jit *C.struct_evm_instance
|
||||||
env *Environment
|
env *EVM
|
||||||
}
|
}
|
||||||
|
|
||||||
type EVMCContext struct {
|
type EVMCContext struct {
|
||||||
contract *Contract
|
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.
|
// FIXME: Destroy the jit later.
|
||||||
return &EVMJIT{C.new_evmjit(), env}
|
return &EVMJIT{C.new_evmjit(), env}
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +226,7 @@ func query(pResult unsafe.Pointer, ctxIdx uintptr, key int32, pArg unsafe.Pointe
|
||||||
*pInt64Result = exist
|
*pInt64Result = exist
|
||||||
// fmt.Printf("EXISTS? %x : %v\n", addr, exist)
|
// fmt.Printf("EXISTS? %x : %v\n", addr, exist)
|
||||||
case C.EVM_CALL_DEPTH:
|
case C.EVM_CALL_DEPTH:
|
||||||
*pInt64Result = int64(ctx.env.Depth - 1)
|
*pInt64Result = int64(ctx.env.depth - 1)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Unhandled EVM-C query %d\n", key))
|
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++ {
|
for i := 0; i < nTopics; i++ {
|
||||||
copy(topics[i][:], tData[i*32:(i+1)*32])
|
copy(topics[i][:], tData[i*32:(i+1)*32])
|
||||||
}
|
}
|
||||||
log := NewLog(ctx.contract.Address(), topics, data, ctx.env.BlockNumber.Uint64())
|
ctx.env.StateDB.AddLog(&types.Log{
|
||||||
ctx.env.StateDB.AddLog(log)
|
Address: ctx.contract.Address(),
|
||||||
|
Topics: topics,
|
||||||
|
Data: data,
|
||||||
|
BlockNumber: ctx.env.BlockNumber.Uint64(),
|
||||||
|
})
|
||||||
case C.EVM_SELFDESTRUCT:
|
case C.EVM_SELFDESTRUCT:
|
||||||
arg := GoByteSlice(pArg1, 32)
|
arg := GoByteSlice(pArg1, 32)
|
||||||
db := ctx.env.StateDB
|
db := ctx.env.StateDB
|
||||||
|
|
@ -293,6 +297,10 @@ func call(
|
||||||
output := GoByteSlice(pOutput, outputSize)
|
output := GoByteSlice(pOutput, outputSize)
|
||||||
bigGas := new(big.Int).SetInt64(gas)
|
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 {
|
switch kind {
|
||||||
case C.EVM_CALL:
|
case C.EVM_CALL:
|
||||||
// fmt.Printf("CALL(gas %d, %x)\n", bigGas, address)
|
// fmt.Printf("CALL(gas %d, %x)\n", bigGas, address)
|
||||||
|
|
@ -306,7 +314,7 @@ func call(
|
||||||
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
|
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
|
||||||
return gasLeft
|
return gasLeft
|
||||||
}
|
}
|
||||||
return gasLeft | C.EVM_CALL_FAILURE
|
return gasLeft | callFailureFlag
|
||||||
case C.EVM_CALLCODE:
|
case C.EVM_CALLCODE:
|
||||||
// fmt.Printf("CALLCODE(gas %d, %x, value %d)\n", bigGas, address, value)
|
// fmt.Printf("CALLCODE(gas %d, %x, value %d)\n", bigGas, address, value)
|
||||||
ctx.contract.Gas.SetInt64(0)
|
ctx.contract.Gas.SetInt64(0)
|
||||||
|
|
@ -320,7 +328,7 @@ func call(
|
||||||
} else {
|
} else {
|
||||||
// fmt.Printf("Error: %v\n", err)
|
// fmt.Printf("Error: %v\n", err)
|
||||||
}
|
}
|
||||||
return gasLeft | C.EVM_CALL_FAILURE
|
return gasLeft | callFailureFlag
|
||||||
case C.EVM_DELEGATECALL:
|
case C.EVM_DELEGATECALL:
|
||||||
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
|
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
|
||||||
ctx.contract.Gas.SetInt64(0)
|
ctx.contract.Gas.SetInt64(0)
|
||||||
|
|
@ -332,16 +340,16 @@ func call(
|
||||||
copy(output, ret)
|
copy(output, ret)
|
||||||
return gasLeft
|
return gasLeft
|
||||||
}
|
}
|
||||||
return gasLeft | C.EVM_CALL_FAILURE
|
return gasLeft | callFailureFlag
|
||||||
case C.EVM_CREATE:
|
case C.EVM_CREATE:
|
||||||
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
|
// fmt.Printf("DELEGATECALL(gas %d, %x)\n", bigGas, address)
|
||||||
ctx.contract.Gas.SetInt64(0)
|
ctx.contract.Gas.SetInt64(0)
|
||||||
_, addr, err := ctx.env.Create(ctx.contract, input, bigGas, value)
|
_, addr, err := ctx.env.Create(ctx.contract, input, bigGas, value)
|
||||||
gasLeft := ctx.contract.Gas.Int64()
|
gasLeft := ctx.contract.Gas.Int64()
|
||||||
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
|
assert(gasLeft <= gas, fmt.Sprintf("%d <= %d", gasLeft, gas))
|
||||||
if (ctx.env.ChainConfig().IsHomestead(ctx.env.BlockNumber) && err == CodeStoreOutOfGasError) ||
|
if (ctx.env.ChainConfig().IsHomestead(ctx.env.BlockNumber) && err == ErrCodeStoreOutOfGas) ||
|
||||||
(err != nil && err != CodeStoreOutOfGasError) {
|
(err != nil && err != ErrCodeStoreOutOfGas) {
|
||||||
return C.EVM_CALL_FAILURE
|
return callFailureFlag
|
||||||
} else {
|
} else {
|
||||||
copy(output, addr[:])
|
copy(output, addr[:])
|
||||||
return gasLeft
|
return gasLeft
|
||||||
|
|
@ -355,7 +363,7 @@ func ptr(bytes []byte) *C.uint8_t {
|
||||||
return (*C.uint8_t)(unsafe.Pointer(header.Data))
|
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
|
n := env.BlockNumber
|
||||||
if env.ChainConfig().IsEIP158(n) {
|
if env.ChainConfig().IsEIP158(n) {
|
||||||
return C.EVM_CLEARING
|
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) {
|
func (evm *EVMJIT) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
||||||
evm.env.Depth++
|
evm.env.depth++
|
||||||
defer func() { evm.env.Depth-- }()
|
defer func() { evm.env.depth-- }()
|
||||||
|
|
||||||
if contract.CodeAddr != nil {
|
if contract.CodeAddr != nil {
|
||||||
if p := Precompiled[contract.CodeAddr.Str()]; p != nil {
|
if p := PrecompiledContracts[*contract.CodeAddr]; p != nil {
|
||||||
return evm.RunPrecompiled(p, input, contract)
|
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 {
|
if r.code != 0 {
|
||||||
// EVMJIT does not informs about the kind of the EVM expection.
|
// EVMJIT does not informs about the kind of the EVM expection.
|
||||||
err = OutOfGasError
|
err = ErrOutOfGas
|
||||||
}
|
}
|
||||||
|
|
||||||
C.evm_release_result(&r)
|
C.evm_release_result(&r)
|
||||||
return output, err
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue