aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-01-02 23:14:12 +0800
committerobscuren <geffobscura@gmail.com>2015-01-02 23:14:12 +0800
commit4dc7ee90879d7146c9e5004c04992c90ad78f632 (patch)
tree7521046c38bb2e7c69b9813b669c87a8a55d4641 /vm
parente2d1d832efe0623539c9d37ca8aee17d44e47067 (diff)
downloaddexon-4dc7ee90879d7146c9e5004c04992c90ad78f632.tar.gz
dexon-4dc7ee90879d7146c9e5004c04992c90ad78f632.tar.zst
dexon-4dc7ee90879d7146c9e5004c04992c90ad78f632.zip
Closure => Context
Diffstat (limited to 'vm')
-rw-r--r--vm/context.go (renamed from vm/closure.go)34
-rw-r--r--vm/environment.go6
-rw-r--r--vm/virtual_machine.go2
-rw-r--r--vm/vm.go2
-rw-r--r--vm/vm_debug.go124
5 files changed, 88 insertions, 80 deletions
diff --git a/vm/closure.go b/vm/context.go
index df216f2ae..ccbadabda 100644
--- a/vm/closure.go
+++ b/vm/context.go
@@ -8,15 +8,15 @@ import (
"github.com/ethereum/go-ethereum/state"
)
-type ClosureRef interface {
+type ContextRef interface {
ReturnGas(*big.Int, *big.Int)
Address() []byte
SetCode([]byte)
}
-type Closure struct {
- caller ClosureRef
- object ClosureRef
+type Context struct {
+ caller ContextRef
+ object ContextRef
Code []byte
message *state.Message
@@ -25,9 +25,9 @@ type Closure struct {
Args []byte
}
-// Create a new closure for the given data items
-func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure {
- c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil}
+// Create a new context for the given data items
+func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
+ c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil}
// Gas should be a pointer so it can safely be reduced through the run
// This pointer will be off the state transition
@@ -40,11 +40,11 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [
return c
}
-func (c *Closure) GetOp(x uint64) OpCode {
+func (c *Context) GetOp(x uint64) OpCode {
return OpCode(c.GetByte(x))
}
-func (c *Closure) GetByte(x uint64) byte {
+func (c *Context) GetByte(x uint64) byte {
if x < uint64(len(c.Code)) {
return c.Code[x]
}
@@ -52,18 +52,18 @@ func (c *Closure) GetByte(x uint64) byte {
return 0
}
-func (c *Closure) GetBytes(x, y int) []byte {
+func (c *Context) GetBytes(x, y int) []byte {
return c.GetRangeValue(uint64(x), uint64(y))
}
-func (c *Closure) GetRangeValue(x, size uint64) []byte {
+func (c *Context) GetRangeValue(x, size uint64) []byte {
x = uint64(math.Min(float64(x), float64(len(c.Code))))
y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
return ethutil.LeftPadBytes(c.Code[x:y], int(size))
}
-func (c *Closure) Return(ret []byte) []byte {
+func (c *Context) Return(ret []byte) []byte {
// Return the remaining gas to the caller
c.caller.ReturnGas(c.Gas, c.Price)
@@ -73,7 +73,7 @@ func (c *Closure) Return(ret []byte) []byte {
/*
* Gas functions
*/
-func (c *Closure) UseGas(gas *big.Int) bool {
+func (c *Context) UseGas(gas *big.Int) bool {
if c.Gas.Cmp(gas) < 0 {
return false
}
@@ -86,8 +86,8 @@ func (c *Closure) UseGas(gas *big.Int) bool {
}
// Implement the caller interface
-func (c *Closure) ReturnGas(gas, price *big.Int) {
- // Return the gas to the closure
+func (c *Context) ReturnGas(gas, price *big.Int) {
+ // Return the gas to the context
c.Gas.Add(c.Gas, gas)
c.UsedGas.Sub(c.UsedGas, gas)
}
@@ -95,10 +95,10 @@ func (c *Closure) ReturnGas(gas, price *big.Int) {
/*
* Set / Get
*/
-func (c *Closure) Address() []byte {
+func (c *Context) Address() []byte {
return c.object.Address()
}
-func (self *Closure) SetCode(code []byte) {
+func (self *Context) SetCode(code []byte) {
self.Code = code
}
diff --git a/vm/environment.go b/vm/environment.go
index 969bc5e43..01bbd56ce 100644
--- a/vm/environment.go
+++ b/vm/environment.go
@@ -26,9 +26,9 @@ type Environment interface {
Depth() int
SetDepth(i int)
- Call(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
- CallCode(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
- Create(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ClosureRef)
+ Call(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
+ CallCode(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
+ Create(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ContextRef)
}
type Object interface {
diff --git a/vm/virtual_machine.go b/vm/virtual_machine.go
index 3b6f98ab2..23ac4878f 100644
--- a/vm/virtual_machine.go
+++ b/vm/virtual_machine.go
@@ -4,7 +4,7 @@ import "math/big"
type VirtualMachine interface {
Env() Environment
- Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
+ Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
Printf(string, ...interface{}) VirtualMachine
Endl() VirtualMachine
}
diff --git a/vm/vm.go b/vm/vm.go
index 22172cb3a..a5ea297b3 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -20,7 +20,7 @@ func New(env Environment, typ Type) VirtualMachine {
}
}
-func (self *Vm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
+func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
panic("not implemented")
}
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 8829a9de0..1b9c480f8 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -37,7 +37,7 @@ func NewDebugVm(env Environment) *DebugVm {
return &DebugVm{env: env, logTy: lt, Recoverable: true}
}
-func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
+func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
self.env.SetDepth(self.env.Depth() + 1)
msg := self.env.State().Manifest().AddMessage(&state.Message{
@@ -47,7 +47,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value,
})
- closure := NewClosure(msg, caller, me, code, gas, price)
+ context := NewContext(msg, caller, me, code, gas, price)
if self.Recoverable {
// Recover from any require exception
@@ -55,9 +55,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if r := recover(); r != nil {
self.Printf(" %v", r).Endl()
- closure.UseGas(closure.Gas)
+ context.UseGas(context.Gas)
- ret = closure.Return(nil)
+ ret = context.Return(nil)
err = fmt.Errorf("%v", r)
@@ -66,13 +66,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
}
if p := Precompiled[string(me.Address())]; p != nil {
- return self.RunPrecompiled(p, callData, closure)
+ return self.RunPrecompiled(p, callData, context)
}
var (
op OpCode
- destinations = analyseJumpDests(closure.Code)
+ destinations = analyseJumpDests(context.Code)
mem = NewMemory()
stack = NewStack()
pc uint64 = 0
@@ -84,11 +84,19 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
p := to.Uint64()
self.Printf(" ~> %v", to)
+ /* NOTE: new model. Will change soon
+ nop := OpCode(context.GetOp(p))
+ if nop != JUMPDEST {
+ panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
+ }
+
+ pc = to.Uint64()
+ */
// Return to start
if p == 0 {
pc = 0
} else {
- nop := OpCode(closure.GetOp(p))
+ nop := OpCode(context.GetOp(p))
if !(nop == JUMPDEST || destinations[from] != nil) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI {
@@ -103,11 +111,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
}
)
- vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), len(code), closure.Gas, callData)
+ vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
// Don't bother with the execution if there's no code.
if len(code) == 0 {
- return closure.Return(nil), nil
+ return context.Return(nil), nil
}
for {
@@ -117,22 +125,22 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
step++
// Get the memory location of pc
- op = closure.GetOp(pc)
+ op = context.GetOp(pc)
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len())
- newMemSize, gas := self.calculateGasAndSize(closure, caller, op, statedb, mem, stack)
+ newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack)
- self.Printf("(g) %-3v (%v)", gas, closure.Gas)
+ self.Printf("(g) %-3v (%v)", gas, context.Gas)
- if !closure.UseGas(gas) {
+ if !context.UseGas(gas) {
self.Endl()
- tmp := new(big.Int).Set(closure.Gas)
+ tmp := new(big.Int).Set(context.Gas)
- closure.UseGas(closure.Gas)
+ context.UseGas(context.Gas)
- return closure.Return(nil), OOG(gas, tmp)
+ return context.Return(nil), OOG(gas, tmp)
}
mem.Resize(newMemSize.Uint64())
@@ -410,9 +418,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => %x", data)
// 0x30 range
case ADDRESS:
- stack.Push(ethutil.BigD(closure.Address()))
+ stack.Push(ethutil.BigD(context.Address()))
- self.Printf(" => %x", closure.Address())
+ self.Printf(" => %x", context.Address())
case BALANCE:
addr := stack.Pop().Bytes()
@@ -428,7 +436,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => %x", origin)
case CALLER:
- caller := closure.caller.Address()
+ caller := context.caller.Address()
stack.Push(ethutil.BigD(caller))
self.Printf(" => %x", caller)
@@ -485,7 +493,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
code = statedb.GetCode(addr)
} else {
- code = closure.Code
+ code = context.Code
}
l := big.NewInt(int64(len(code)))
@@ -497,7 +505,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if op == EXTCODECOPY {
code = statedb.GetCode(stack.Pop().Bytes())
} else {
- code = closure.Code
+ code = context.Code
}
var (
@@ -519,9 +527,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
case GASPRICE:
- stack.Push(closure.Price)
+ stack.Push(context.Price)
- self.Printf(" => %v", closure.Price)
+ self.Printf(" => %v", context.Price)
// 0x40 range
case PREVHASH:
@@ -560,7 +568,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// 0x50 range
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
a := uint64(op - PUSH1 + 1)
- byts := closure.GetRangeValue(pc+1, a)
+ byts := context.GetRangeValue(pc+1, a)
// Push value to stack
stack.Push(ethutil.BigD(byts))
pc += a
@@ -589,7 +597,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
}
data := mem.Geti(mStart.Int64(), mSize.Int64())
- log := &Log{closure.Address(), topics, data}
+ log := &Log{context.Address(), topics, data}
self.env.AddLog(log)
self.Printf(" => %v", log)
@@ -614,15 +622,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v] 0x%x", off, val)
case SLOAD:
loc := stack.Pop()
- val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes()))
+ val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes()))
stack.Push(val)
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case SSTORE:
val, loc := stack.Popn()
- statedb.SetState(closure.Address(), loc.Bytes(), val)
+ statedb.SetState(context.Address(), loc.Bytes(), val)
- closure.message.AddStorageChange(loc.Bytes())
+ context.message.AddStorageChange(loc.Bytes())
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP:
@@ -644,7 +652,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
case MSIZE:
stack.Push(big.NewInt(int64(mem.Len())))
case GAS:
- stack.Push(closure.Gas)
+ stack.Push(context.Gas)
// 0x60 range
case CREATE:
@@ -653,7 +661,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
value = stack.Pop()
size, offset = stack.Popn()
input = mem.Get(offset.Int64(), size.Int64())
- gas = new(big.Int).Set(closure.Gas)
+ gas = new(big.Int).Set(context.Gas)
// Snapshot the current stack so we are able to
// revert back to it later.
@@ -661,15 +669,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
)
// Generate a new address
- n := statedb.GetNonce(closure.Address())
- addr := crypto.CreateAddress(closure.Address(), n)
- statedb.SetNonce(closure.Address(), n+1)
+ n := statedb.GetNonce(context.Address())
+ addr := crypto.CreateAddress(context.Address(), n)
+ statedb.SetNonce(context.Address(), n+1)
self.Printf(" (*) %x", addr).Endl()
- closure.UseGas(closure.Gas)
+ context.UseGas(context.Gas)
- ret, err, ref := self.env.Create(closure, addr, input, gas, price, value)
+ ret, err, ref := self.env.Create(context, addr, input, gas, price, value)
if err != nil {
stack.Push(ethutil.BigFalse)
@@ -678,7 +686,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// gas < len(ret) * CreateDataGas == NO_CODE
dataGas := big.NewInt(int64(len(ret)))
dataGas.Mul(dataGas, GasCreateByte)
- if closure.UseGas(dataGas) {
+ if context.UseGas(dataGas) {
ref.SetCode(ret)
msg.Output = ret
}
@@ -690,7 +698,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// Debug hook
if self.Dbg != nil {
- self.Dbg.SetCode(closure.Code)
+ self.Dbg.SetCode(context.Code)
}
case CALL, CALLCODE:
self.Endl()
@@ -711,9 +719,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
err error
)
if op == CALLCODE {
- ret, err = self.env.CallCode(closure, addr.Bytes(), args, gas, price, value)
+ ret, err = self.env.CallCode(context, addr.Bytes(), args, gas, price, value)
} else {
- ret, err = self.env.Call(closure, addr.Bytes(), args, gas, price, value)
+ ret, err = self.env.Call(context, addr.Bytes(), args, gas, price, value)
}
if err != nil {
@@ -726,11 +734,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
- self.Printf("resume %x (%v)", closure.Address(), closure.Gas)
+ self.Printf("resume %x (%v)", context.Address(), context.Gas)
// Debug hook
if self.Dbg != nil {
- self.Dbg.SetCode(closure.Code)
+ self.Dbg.SetCode(context.Code)
}
case RETURN:
@@ -739,27 +747,27 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
- return closure.Return(ret), nil
+ return context.Return(ret), nil
case SUICIDE:
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
- balance := statedb.GetBalance(closure.Address())
+ balance := statedb.GetBalance(context.Address())
self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
receiver.AddAmount(balance)
- statedb.Delete(closure.Address())
+ statedb.Delete(context.Address())
fallthrough
- case STOP: // Stop the closure
+ case STOP: // Stop the context
self.Endl()
- return closure.Return(nil), nil
+ return context.Return(nil), nil
default:
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
- closure.ReturnGas(big.NewInt(1), nil)
+ context.ReturnGas(big.NewInt(1), nil)
- return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
+ return context.Return(nil), fmt.Errorf("Invalid opcode %x", op)
}
pc++
@@ -771,11 +779,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if pc == uint64(instrNo) {
self.Stepping = true
- if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
+ if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
return nil, nil
}
} else if self.Stepping {
- if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
+ if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
return nil, nil
}
}
@@ -785,7 +793,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
}
}
-func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
+func (self *DebugVm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
gas := new(big.Int)
addStepGasUsage := func(amount *big.Int) {
if amount.Cmp(ethutil.Big0) >= 0 {
@@ -844,7 +852,7 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
var mult *big.Int
y, x := stack.Peekn()
- val := statedb.GetState(closure.Address(), x.Bytes())
+ val := statedb.GetState(context.Address(), x.Bytes())
if len(val) == 0 && len(y.Bytes()) > 0 {
// 0 => non 0
mult = ethutil.Big3
@@ -940,22 +948,22 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
return newMemSize, gas
}
-func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) {
+func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) {
gas := p.Gas(len(callData))
- if closure.UseGas(gas) {
+ if context.UseGas(gas) {
ret = p.Call(callData)
self.Printf("NATIVE_FUNC => %x", ret)
self.Endl()
- return closure.Return(ret), nil
+ return context.Return(ret), nil
} else {
self.Endl()
- tmp := new(big.Int).Set(closure.Gas)
+ tmp := new(big.Int).Set(context.Gas)
- closure.UseGas(closure.Gas)
+ context.UseGas(context.Gas)
- return closure.Return(nil), OOG(gas, tmp)
+ return context.Return(nil), OOG(gas, tmp)
}
}