void ExecuteScript(State runstate, SmartContract.Debug.LogScript script) { runstate.PushExe(script.hash); foreach (var op in script.ops) { if (op.op == VM.OpCode.APPCALL)//不造成栈影响,由目标script影响 { ExecuteScript(runstate, op.subScript); mapState[op] = runstate.StateID; } else if (op.op == VM.OpCode.CALL)//不造成栈影响 就是个jmp { runstate.PushExe(script.hash); mapState[op] = runstate.StateID; } else if (op.op == VM.OpCode.RET) { mapState[op] = runstate.StateID; } else { if (op.op == VM.OpCode.SYSCALL)//syscall比较独特,有些syscall 可以产生独立的log { var name = System.Text.Encoding.ASCII.GetString(op.param); careinfo.Add(new CareItem(name, runstate)); //runstate.DoSysCall(op.op); } if (runstate.CalcCalcStack(op.op) == false) { if (op.stack != null) { for (var i = 0; i < op.stack.Length; i++) { if (i == op.stack.Length - 1) { runstate.CalcCalcStack(op.stack[i], op.opresult); } else { runstate.CalcCalcStack(op.stack[i], null); } } } } if (stateClone.ContainsKey(runstate.StateID) == false) { stateClone[runstate.StateID] = (Debug.State)runstate.Clone(); } mapState[op] = runstate.StateID; } } }
public void Execute(SmartContract.Debug.FullLog FullLog) { State runstate = new State(); runstate.SetId(0); stateClone = new Dictionary <int, State>(); mapState = new Dictionary <SmartContract.Debug.LogOp, int>(); careinfo = new List <CareItem>(); regenScript = new SmartContract.Debug.LogScript(FullLog.script.hash); lastScript = regenScript; ExecuteScript(runstate, FullLog.script); }
//加入outputscript,做一個補救,以前導出的log樹層次可能是錯的 void ExecuteScript(State runstate, SmartContract.Debug.LogScript script) { try { runstate.PushExe(script.hash); foreach (var op in script.ops) { var _nop = op.Clone(); lastScript.ops.Add(_nop); try { if (op.op == VM.OpCode.APPCALL)//不造成栈影响,由目标script影响 { var _script = op.subScript; var outscript = new SmartContract.Debug.LogScript(op.subScript.hash); outscript.parent = lastScript; _nop.subScript = outscript; lastScript = outscript; //有可能造成影响 if (op.stack != null) { for (var i = 0; i < op.stack.Length; i++) { if (i == op.stack.Length - 1) { runstate.CalcCalcStack(op.stack[i], op.opresult); } else { runstate.CalcCalcStack(op.stack[i], null); } } } runstate.PushExe(script.hash); if (stateClone.ContainsKey(runstate.StateID) == false) { stateClone[runstate.StateID] = (Debug.State)runstate.Clone(); } ExecuteScript(runstate, _script); mapState[_nop] = runstate.StateID; } else if (op.op == VM.OpCode.CALL)//造成栈影响 就是个jmp { var _lastScript = new SmartContract.Debug.LogScript(lastScript.hash); _lastScript.parent = lastScript; _nop.subScript = _lastScript; lastScript = _lastScript; runstate.PushExe(lastScript.hash); mapState[_nop] = runstate.StateID; //runstate.callcount++; } else if (op.op == VM.OpCode.RET) { runstate.PopExe(); //mapState[op] = runstate.StateID; //if (runstate.callcount > 0) //{ // runstate.callcount--; //} //if (runstate.callcount == 0) { lastScript = lastScript.parent; } if (stateClone.ContainsKey(runstate.StateID) == false) { stateClone[runstate.StateID] = (Debug.State)runstate.Clone(); } mapState[_nop] = runstate.StateID; } else { if (op.op == VM.OpCode.SYSCALL)//syscall比较独特,有些syscall 可以产生独立的log { var name = System.Text.Encoding.ASCII.GetString(op.param); careinfo.Add(new CareItem(name, runstate)); //runstate.DoSysCall(op.op); } if (runstate.CalcCalcStack(op.op) == false) { if (op.stack != null) { for (var i = 0; i < op.stack.Length; i++) { if (i == op.stack.Length - 1) { runstate.CalcCalcStack(op.stack[i], op.opresult); } else { runstate.CalcCalcStack(op.stack[i], null); } } } } if (stateClone.ContainsKey(runstate.StateID) == false) { stateClone[runstate.StateID] = (Debug.State)runstate.Clone(); } mapState[_nop] = runstate.StateID; } } catch (Exception err1) { _nop.error = true; } } } catch (Exception err) { throw new Exception("error in:" + err.Message); } }