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.go134
1 files changed, 63 insertions, 71 deletions
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 8829a9de0..6ad385fd0 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
@@ -83,31 +83,23 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
jump = func(from uint64, to *big.Int) {
p := to.Uint64()
- self.Printf(" ~> %v", to)
- // Return to start
- if p == 0 {
- pc = 0
- } else {
- nop := OpCode(closure.GetOp(p))
- if !(nop == JUMPDEST || destinations[from] != nil) {
- panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
- } else if nop == JUMP || nop == JUMPI {
- panic(fmt.Sprintf("not allowed to JUMP(I) in to JUMP"))
- }
-
- pc = to.Uint64()
-
+ nop := OpCode(context.GetOp(p))
+ if !destinations.Has(p) {
+ panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
}
+ self.Printf(" ~> %v", to)
+ pc = to.Uint64()
+
self.Endl()
}
)
- 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 +109,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 +402,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 +420,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 +477,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 +489,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 +511,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 +552,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 +581,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 +606,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 +636,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 +645,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 +653,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 +670,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 +682,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 +703,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 +718,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 +731,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 +763,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 +777,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 +836,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 +932,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)
}
}