aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/evm/main.go9
-rw-r--r--core/execution.go4
-rw-r--r--core/vm/common.go14
-rw-r--r--core/vm/environment.go4
-rw-r--r--core/vm/instructions.go1
-rw-r--r--core/vm/jit_test.go8
-rw-r--r--core/vm/jump_table.go12
-rw-r--r--core/vm/jump_table_test.go4
-rw-r--r--core/vm/runtime/env.go8
-rw-r--r--core/vm/vm.go13
-rw-r--r--core/vm/vm_jit_fake.go2
-rw-r--r--core/vm_env.go6
-rw-r--r--tests/util.go8
13 files changed, 49 insertions, 44 deletions
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index ef679e373..0ba6820e0 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger/glog"
+ "github.com/ethereum/go-ethereum/params"
)
var (
@@ -174,17 +175,23 @@ type VMEnv struct {
Gas *big.Int
time *big.Int
logs []vm.StructLog
+
+ evm *vm.Vm
}
func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int) *VMEnv {
- return &VMEnv{
+ params.HomesteadBlock = new(big.Int)
+ env := &VMEnv{
state: state,
transactor: &transactor,
value: value,
time: big.NewInt(time.Now().Unix()),
}
+ env.evm = vm.EVM(env)
+ return env
}
+func (self *VMEnv) Vm() *vm.Vm { return self.evm }
func (self *VMEnv) Db() vm.Database { return self.state }
func (self *VMEnv) MakeSnapshot() vm.Database { return self.state.Copy() }
func (self *VMEnv) SetSnapshot(db vm.Database) { self.state.Set(db.(*state.StateDB)) }
diff --git a/core/execution.go b/core/execution.go
index 24c0c93ae..d90dceafc 100644
--- a/core/execution.go
+++ b/core/execution.go
@@ -60,7 +60,7 @@ func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPric
}
func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.Address, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
- evm := vm.NewVm(env)
+ evm := env.Vm()
// Depth check execution. Fail if we're trying to execute above the
// limit.
if env.Depth() > int(params.CallCreateDepth.Int64()) {
@@ -136,7 +136,7 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
}
func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toAddr, codeAddr *common.Address, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
- evm := vm.NewVm(env)
+ evm := env.Vm()
// Depth check execution. Fail if we're trying to execute above the
// limit.
if env.Depth() > int(params.CallCreateDepth.Int64()) {
diff --git a/core/vm/common.go b/core/vm/common.go
index 395ed0471..f73bc1527 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -21,7 +21,6 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
)
@@ -51,19 +50,6 @@ var (
max = big.NewInt(math.MaxInt64) // Maximum 64 bit integer
)
-// NewVm returns a new VM based on the Environment
-func NewVm(env Environment) VirtualMachine {
- switch env.VmType() {
- case JitVmTy:
- return NewJitVm(env)
- default:
- glog.V(0).Infoln("unsupported vm type %d", env.VmType())
- fallthrough
- case StdVmTy:
- return New(env)
- }
-}
-
// calculates the memory size required for a step
func calcMemSize(off, l *big.Int) *big.Int {
if l.Cmp(common.Big0) == 0 {
diff --git a/core/vm/environment.go b/core/vm/environment.go
index d5d21a45b..3c530962b 100644
--- a/core/vm/environment.go
+++ b/core/vm/environment.go
@@ -58,10 +58,8 @@ type Environment interface {
AddStructLog(StructLog)
// Returns all coalesced structured logs
StructLogs() []StructLog
-
// Type of the VM
- VmType() Type
-
+ Vm() *Vm
// Current calling depth
Depth() int
SetDepth(i int)
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 1e1086b13..c4b4339a2 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -597,7 +597,6 @@ func opDelegateCall(instr instruction, pc *uint64, env Environment, contract *Co
toAddr := common.BigToAddress(to)
args := memory.Get(inOffset.Int64(), inSize.Int64())
ret, err := env.DelegateCall(contract, toAddr, args, gas, contract.Price)
-
if err != nil {
stack.push(new(big.Int))
} else {
diff --git a/core/vm/jit_test.go b/core/vm/jit_test.go
index 19261827b..5fac0156f 100644
--- a/core/vm/jit_test.go
+++ b/core/vm/jit_test.go
@@ -154,7 +154,7 @@ func runVmBench(test vmBench, b *testing.B) {
context := NewContract(sender, sender, big.NewInt(100), big.NewInt(10000), big.NewInt(0))
context.Code = test.code
context.CodeAddr = &common.Address{}
- _, err := New(env).Run(context, test.input)
+ _, err := env.Vm().Run(context, test.input)
if err != nil {
b.Error(err)
b.FailNow()
@@ -165,12 +165,16 @@ func runVmBench(test vmBench, b *testing.B) {
type Env struct {
gasLimit *big.Int
depth int
+ evm *Vm
}
func NewEnv() *Env {
- return &Env{big.NewInt(10000), 0}
+ env := &Env{gasLimit: big.NewInt(10000), depth: 0}
+ env.evm = EVM(env)
+ return env
}
+func (self *Env) Vm() *Vm { return self.evm }
func (self *Env) Origin() common.Address { return common.Address{} }
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
func (self *Env) AddStructLog(log StructLog) {
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index 37d7bb160..8297d3e1d 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -13,19 +13,15 @@ type jumpPtr struct {
type vmJumpTable [256]jumpPtr
-func (jt vmJumpTable) init(blockNumber *big.Int) {
+func newJumpTable(blockNumber *big.Int) vmJumpTable {
+ var jumpTable vmJumpTable
+
// when initialising a new VM execution we must first check the homestead
// changes.
if params.IsHomestead(blockNumber) {
jumpTable[DELEGATECALL] = jumpPtr{opDelegateCall, true}
- } else {
- jumpTable[DELEGATECALL] = jumpPtr{nil, false}
}
-}
-var jumpTable vmJumpTable
-
-func init() {
jumpTable[ADD] = jumpPtr{opAdd, true}
jumpTable[SUB] = jumpPtr{opSub, true}
jumpTable[MUL] = jumpPtr{opMul, true}
@@ -156,4 +152,6 @@ func init() {
jumpTable[JUMP] = jumpPtr{nil, true}
jumpTable[JUMPI] = jumpPtr{nil, true}
jumpTable[STOP] = jumpPtr{nil, true}
+
+ return jumpTable
}
diff --git a/core/vm/jump_table_test.go b/core/vm/jump_table_test.go
index 98d34bef2..2ed1b26fc 100644
--- a/core/vm/jump_table_test.go
+++ b/core/vm/jump_table_test.go
@@ -10,13 +10,13 @@ import (
func TestInit(t *testing.T) {
params.HomesteadBlock = big.NewInt(1)
- jumpTable.init(big.NewInt(0))
+ jumpTable := newJumpTable(big.NewInt(0))
if jumpTable[DELEGATECALL].valid {
t.Error("Expected DELEGATECALL not to be present")
}
for _, n := range []int64{1, 2, 100} {
- jumpTable.init(big.NewInt(n))
+ jumpTable := newJumpTable(big.NewInt(n))
if !jumpTable[DELEGATECALL].valid {
t.Error("Expected DELEGATECALL to be present for block", n)
}
diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go
index 77519df81..e9bf828ea 100644
--- a/core/vm/runtime/env.go
+++ b/core/vm/runtime/env.go
@@ -41,11 +41,13 @@ type Env struct {
logs []vm.StructLog
getHashFn func(uint64) common.Hash
+
+ evm *vm.Vm
}
// NewEnv returns a new vm.Environment
func NewEnv(cfg *Config, state *state.StateDB) vm.Environment {
- return &Env{
+ env := &Env{
state: state,
origin: cfg.Origin,
coinbase: cfg.Coinbase,
@@ -54,6 +56,9 @@ func NewEnv(cfg *Config, state *state.StateDB) vm.Environment {
difficulty: cfg.Difficulty,
gasLimit: cfg.GasLimit,
}
+ env.evm = vm.EVM(env)
+
+ return env
}
func (self *Env) StructLogs() []vm.StructLog {
@@ -64,6 +69,7 @@ func (self *Env) AddStructLog(log vm.StructLog) {
self.logs = append(self.logs, log)
}
+func (self *Env) Vm() *vm.Vm { return self.evm }
func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int { return self.number }
func (self *Env) Coinbase() common.Address { return self.coinbase }
diff --git a/core/vm/vm.go b/core/vm/vm.go
index 95d27c64c..26df8aef4 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -30,15 +30,12 @@ import (
// Vm is an EVM and implements VirtualMachine
type Vm struct {
- env Environment
+ env Environment
+ jumpTable vmJumpTable
}
-// New returns a new Vm
-func New(env Environment) *Vm {
- // init the jump table. Also prepares the homestead changes
- jumpTable.init(env.BlockNumber())
-
- return &Vm{env: env}
+func EVM(env Environment) *Vm {
+ return &Vm{env: env, jumpTable: newJumpTable(env.BlockNumber())}
}
// Run loops and evaluates the contract's code with the given input data
@@ -169,7 +166,7 @@ func (self *Vm) Run(contract *Contract, input []byte) (ret []byte, err error) {
mem.Resize(newMemSize.Uint64())
// Add a log message
self.log(pc, op, contract.Gas, cost, mem, stack, contract, nil)
- if opPtr := jumpTable[op]; opPtr.valid {
+ if opPtr := self.jumpTable[op]; opPtr.valid {
if opPtr.fn != nil {
opPtr.fn(instruction{}, &pc, self.env, contract, mem, stack)
} else {
diff --git a/core/vm/vm_jit_fake.go b/core/vm/vm_jit_fake.go
index 456fcb8d4..192f3615d 100644
--- a/core/vm/vm_jit_fake.go
+++ b/core/vm/vm_jit_fake.go
@@ -22,5 +22,5 @@ import "fmt"
func NewJitVm(env Environment) VirtualMachine {
fmt.Printf("Warning! EVM JIT not enabled.\n")
- return New(env)
+ return EVM(env)
}
diff --git a/core/vm_env.go b/core/vm_env.go
index 7b9a1a0f9..0fab4a090 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -51,10 +51,11 @@ type VMEnv struct {
getHashFn func(uint64) common.Hash
// structured logging
logs []vm.StructLog
+ evm *vm.Vm
}
func NewEnv(state *state.StateDB, chain *BlockChain, msg Message, header *types.Header) *VMEnv {
- return &VMEnv{
+ env := &VMEnv{
chain: chain,
state: state,
header: header,
@@ -62,8 +63,11 @@ func NewEnv(state *state.StateDB, chain *BlockChain, msg Message, header *types.
typ: vm.StdVmTy,
getHashFn: GetHashFn(header.ParentHash, chain),
}
+ env.evm = vm.EVM(env)
+ return env
}
+func (self *VMEnv) Vm() *vm.Vm { return self.evm }
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase }
diff --git a/tests/util.go b/tests/util.go
index 29f4c9b72..2c749edba 100644
--- a/tests/util.go
+++ b/tests/util.go
@@ -143,12 +143,15 @@ type Env struct {
logs []vm.StructLog
vmTest bool
+
+ evm *vm.Vm
}
func NewEnv(state *state.StateDB) *Env {
- return &Env{
+ env := &Env{
state: state,
}
+ return env
}
func (self *Env) StructLogs() []vm.StructLog {
@@ -171,9 +174,12 @@ func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues
env.gasLimit = common.Big(envValues["currentGasLimit"])
env.Gas = new(big.Int)
+ env.evm = vm.EVM(env)
+
return env
}
+func (self *Env) Vm() *vm.Vm { return self.evm }
func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int { return self.number }
func (self *Env) Coinbase() common.Address { return self.coinbase }