aboutsummaryrefslogtreecommitdiffstats
path: root/vm/vm_debug.go
diff options
context:
space:
mode:
Diffstat (limited to 'vm/vm_debug.go')
-rw-r--r--vm/vm_debug.go124
1 files changed, 66 insertions, 58 deletions
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)
}
}