diff options
Diffstat (limited to 'vm/vm_debug.go')
-rw-r--r-- | vm/vm_debug.go | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/vm/vm_debug.go b/vm/vm_debug.go index 05ae347f6..ae5a20175 100644 --- a/vm/vm_debug.go +++ b/vm/vm_debug.go @@ -41,54 +41,61 @@ func NewDebugVm(env Environment) *DebugVm { func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.depth++ + if self.Recoverable { + // Recover from any require exception + defer func() { + if r := recover(); r != nil { + self.Endl() + + closure.UseGas(closure.Gas) + + ret = closure.Return(nil) + + err = fmt.Errorf("%v", r) + + } + }() + } + var ( op OpCode - mem = &Memory{} - stack = NewStack() - pc = big.NewInt(0) - step = 0 - prevStep = 0 - statedb = self.env.State() - require = func(m int) { + destinations = analyseJumpDests(closure.Code) + mem = NewMemory() + stack = NewStack() + pc = big.NewInt(0) + step = 0 + prevStep = 0 + statedb = self.env.State() + require = func(m int) { if stack.Len() < m { panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m)) } } - jump = func(pos *big.Int) { - p := int(pos.Int64()) + jump = func(from, to *big.Int) { + p := int(to.Int64()) - self.Printf(" ~> %v", pos) + self.Printf(" ~> %v", to) // Return to start if p == 0 { pc = big.NewInt(0) } else { - nop := OpCode(closure.GetOp(p - 1)) - if nop != JUMPDEST { + nop := OpCode(closure.GetOp(p)) + if !(nop == JUMPDEST || destinations[from.Int64()] != nil) { panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p)) + } else if nop == JUMP || nop == JUMPI { + panic(fmt.Sprintf("not allowed to JUMP(I) in to JUMP")) } - pc = pos + pc = to + } self.Endl() } ) - if self.Recoverable { - // Recover from any require exception - defer func() { - if r := recover(); r != nil { - self.Endl() - - ret = closure.Return(nil) - // No error should be set. Recover is used with require - // Is this too error prone? - } - }() - } - // Debug hook if self.Dbg != nil { self.Dbg.SetCode(closure.Code) @@ -254,11 +261,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { memGasUsage.Div(memGasUsage, u256(32)) addStepGasUsage(memGasUsage) + + mem.Resize(newMemSize.Uint64()) } + } self.Printf("(pc) %-3d -o- %-14s", pc, op.String()) - self.Printf(" (g) %-3v (%v)", gas, closure.Gas) + self.Printf(" (m) %-4d (s) %-4d (g) %-3v (%v)", mem.Len(), stack.Len(), gas, closure.Gas) if !closure.UseGas(gas) { self.Endl() @@ -270,8 +280,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { return closure.Return(nil), OOG(gas, tmp) } - mem.Resize(newMemSize.Uint64()) - switch op { // 0x20 range case ADD: @@ -404,6 +412,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { } else { num.And(num, mask) } + + num = U256(num) + + self.Printf(" = %v", num) + stack.Push(num) } case NOT: @@ -608,6 +621,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { code := closure.Args[cOff : cOff+l] mem.Set(mOff, l, code) + + self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l]) case CODESIZE, EXTCODESIZE: var code []byte if op == EXTCODESIZE { @@ -649,6 +664,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { codeCopy := code[cOff : cOff+l] mem.Set(mOff, l, codeCopy) + + self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l]) case GASPRICE: stack.Push(closure.Price) @@ -720,12 +737,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { case LOG0, LOG1, LOG2, LOG3, LOG4: n := int(op - LOG0) topics := make([][]byte, n) - mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64() + mStart, mSize := stack.Pop().Int64(), stack.Pop().Int64() data := mem.Geti(mStart, mSize) for i := 0; i < n; i++ { topics[i] = stack.Pop().Bytes() } - self.env.AddLog(state.Log{closure.Address(), topics, data}) + + log := &state.Log{closure.Address(), topics, data} + self.env.AddLog(log) + + self.Printf(" => %v", log) case MLOAD: offset := stack.Pop() val := ethutil.BigD(mem.Get(offset.Int64(), 32)) @@ -763,14 +784,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) case JUMP: - jump(stack.Pop()) + jump(pc, stack.Pop()) continue case JUMPI: cond, pos := stack.Popn() if cond.Cmp(ethutil.BigTrue) >= 0 { - jump(pos) + jump(pc, pos) continue } |