From 6aa7ed253e21ba71e09dc60a53a31703f963d929 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sat, 30 Mar 2019 11:25:42 +0100 Subject: [PATCH 1/4] Move breakpoints logic to other class --- src/neo-vm/DebugeableExecutionEngine.cs | 45 +++++++++++++++++++++++++ src/neo-vm/ExecutionEngine.cs | 31 ++--------------- 2 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 src/neo-vm/DebugeableExecutionEngine.cs diff --git a/src/neo-vm/DebugeableExecutionEngine.cs b/src/neo-vm/DebugeableExecutionEngine.cs new file mode 100644 index 00000000..6eb5e1e9 --- /dev/null +++ b/src/neo-vm/DebugeableExecutionEngine.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; + +namespace Neo.VM +{ + public class DebugeableExecutionEngine : ExecutionEngine + { + private readonly Dictionary> break_points = new Dictionary>(new HashComparer()); + + public DebugeableExecutionEngine(IScriptContainer container, ICrypto crypto, IScriptTable table = null, IInteropService service = null) : + base(container, crypto, table, service) + { } + + public void AddBreakPoint(byte[] script_hash, uint position) + { + if (!break_points.TryGetValue(script_hash, out HashSet hashset)) + { + hashset = new HashSet(); + break_points.Add(script_hash, hashset); + } + hashset.Add(position); + } + + protected override bool PostExecuteInstruction(Instruction instruction) + { + var ret = base.PostExecuteInstruction(instruction); + + if (State == VMState.NONE && InvocationStack.Count > 0) + { + if (break_points.Count > 0 && break_points.TryGetValue(CurrentContext.ScriptHash, out HashSet hashset) && hashset.Contains((uint)CurrentContext.InstructionPointer)) + State = VMState.BREAK; + } + + return ret; + } + + public bool RemoveBreakPoint(byte[] script_hash, uint position) + { + if (!break_points.TryGetValue(script_hash, out HashSet hashset)) return false; + if (!hashset.Remove(position)) return false; + if (hashset.Count == 0) break_points.Remove(script_hash); + + return true; + } + } +} \ No newline at end of file diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 940320dc..65751a6d 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -1,11 +1,11 @@ -using Neo.VM.Types; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Security.Cryptography; +using Neo.VM.Types; using VMArray = Neo.VM.Types.Array; namespace Neo.VM @@ -57,7 +57,6 @@ public class ExecutionEngine : IDisposable private bool is_stackitem_count_strict = true; private readonly IScriptTable table; - private readonly Dictionary> break_points = new Dictionary>(new HashComparer()); public IScriptContainer ScriptContainer { get; } public ICrypto Crypto { get; } @@ -77,16 +76,6 @@ public ExecutionEngine(IScriptContainer container, ICrypto crypto, IScriptTable this.Service = service; } - public void AddBreakPoint(byte[] script_hash, uint position) - { - if (!break_points.TryGetValue(script_hash, out HashSet hashset)) - { - hashset = new HashSet(); - break_points.Add(script_hash, hashset); - } - hashset.Add(position); - } - #region Limits /// @@ -225,11 +214,6 @@ protected void ExecuteNext() { State = VMState.FAULT; } - if (State == VMState.NONE && InvocationStack.Count > 0) - { - if (break_points.Count > 0 && break_points.TryGetValue(CurrentContext.ScriptHash, out HashSet hashset) && hashset.Contains((uint)CurrentContext.InstructionPointer)) - State = VMState.BREAK; - } } } @@ -1308,17 +1292,6 @@ protected virtual bool PreExecuteInstruction() return true; } - public bool RemoveBreakPoint(byte[] script_hash, uint position) - { - if (!break_points.TryGetValue(script_hash, out HashSet hashset)) - return false; - if (!hashset.Remove(position)) - return false; - if (hashset.Count == 0) - break_points.Remove(script_hash); - return true; - } - public void StepInto() { if (State.HasFlag(VMState.HALT) || State.HasFlag(VMState.FAULT)) return; From 71b9acde1df6047ed33b034ddd5bed913a97c483 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Sat, 30 Mar 2019 20:30:39 +0800 Subject: [PATCH 2/4] Add `Debugger` --- src/neo-vm/DebugeableExecutionEngine.cs | 45 -------------- src/neo-vm/Debugger.cs | 78 +++++++++++++++++++++++++ src/neo-vm/ExecutionEngine.cs | 35 +---------- 3 files changed, 80 insertions(+), 78 deletions(-) delete mode 100644 src/neo-vm/DebugeableExecutionEngine.cs create mode 100644 src/neo-vm/Debugger.cs diff --git a/src/neo-vm/DebugeableExecutionEngine.cs b/src/neo-vm/DebugeableExecutionEngine.cs deleted file mode 100644 index 6eb5e1e9..00000000 --- a/src/neo-vm/DebugeableExecutionEngine.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; - -namespace Neo.VM -{ - public class DebugeableExecutionEngine : ExecutionEngine - { - private readonly Dictionary> break_points = new Dictionary>(new HashComparer()); - - public DebugeableExecutionEngine(IScriptContainer container, ICrypto crypto, IScriptTable table = null, IInteropService service = null) : - base(container, crypto, table, service) - { } - - public void AddBreakPoint(byte[] script_hash, uint position) - { - if (!break_points.TryGetValue(script_hash, out HashSet hashset)) - { - hashset = new HashSet(); - break_points.Add(script_hash, hashset); - } - hashset.Add(position); - } - - protected override bool PostExecuteInstruction(Instruction instruction) - { - var ret = base.PostExecuteInstruction(instruction); - - if (State == VMState.NONE && InvocationStack.Count > 0) - { - if (break_points.Count > 0 && break_points.TryGetValue(CurrentContext.ScriptHash, out HashSet hashset) && hashset.Contains((uint)CurrentContext.InstructionPointer)) - State = VMState.BREAK; - } - - return ret; - } - - public bool RemoveBreakPoint(byte[] script_hash, uint position) - { - if (!break_points.TryGetValue(script_hash, out HashSet hashset)) return false; - if (!hashset.Remove(position)) return false; - if (hashset.Count == 0) break_points.Remove(script_hash); - - return true; - } - } -} \ No newline at end of file diff --git a/src/neo-vm/Debugger.cs b/src/neo-vm/Debugger.cs new file mode 100644 index 00000000..8518e3ef --- /dev/null +++ b/src/neo-vm/Debugger.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; + +namespace Neo.VM +{ + public class Debugger + { + private readonly ExecutionEngine engine; + private readonly Dictionary> break_points = new Dictionary>(new HashComparer()); + + public Debugger(ExecutionEngine engine) + { + this.engine = engine; + } + + public void AddBreakPoint(byte[] script_hash, uint position) + { + if (!break_points.TryGetValue(script_hash, out HashSet hashset)) + { + hashset = new HashSet(); + break_points.Add(script_hash, hashset); + } + hashset.Add(position); + } + + public void Execute() + { + engine.State &= ~VMState.BREAK; + while (!engine.State.HasFlag(VMState.HALT) && !engine.State.HasFlag(VMState.FAULT) && !engine.State.HasFlag(VMState.BREAK)) + { + engine.ExecuteNext(); + if (engine.State == VMState.NONE && engine.InvocationStack.Count > 0 && break_points.Count > 0) + { + if (break_points.TryGetValue(engine.CurrentContext.ScriptHash, out HashSet hashset) && hashset.Contains((uint)engine.CurrentContext.InstructionPointer)) + engine.State = VMState.BREAK; + } + } + } + + public bool RemoveBreakPoint(byte[] script_hash, uint position) + { + if (!break_points.TryGetValue(script_hash, out HashSet hashset)) return false; + if (!hashset.Remove(position)) return false; + if (hashset.Count == 0) break_points.Remove(script_hash); + return true; + } + + public void StepInto() + { + if (engine.State.HasFlag(VMState.HALT) || engine.State.HasFlag(VMState.FAULT)) return; + engine.ExecuteNext(); + if (engine.State == VMState.NONE) + engine.State = VMState.BREAK; + } + + public void StepOut() + { + engine.State &= ~VMState.BREAK; + int c = engine.InvocationStack.Count; + while (!engine.State.HasFlag(VMState.HALT) && !engine.State.HasFlag(VMState.FAULT) && !engine.State.HasFlag(VMState.BREAK) && engine.InvocationStack.Count >= c) + engine.ExecuteNext(); + if (engine.State == VMState.NONE) + engine.State = VMState.BREAK; + } + + public void StepOver() + { + if (engine.State.HasFlag(VMState.HALT) || engine.State.HasFlag(VMState.FAULT)) return; + engine.State &= ~VMState.BREAK; + int c = engine.InvocationStack.Count; + do + { + engine.ExecuteNext(); + } while (!engine.State.HasFlag(VMState.HALT) && !engine.State.HasFlag(VMState.FAULT) && !engine.State.HasFlag(VMState.BREAK) && engine.InvocationStack.Count > c); + if (engine.State == VMState.NONE) + engine.State = VMState.BREAK; + } + } +} diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 65751a6d..330e71c3 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -66,7 +66,7 @@ public class ExecutionEngine : IDisposable public ExecutionContext CurrentContext => InvocationStack.Peek(); public ExecutionContext CallingContext => InvocationStack.Count > 1 ? InvocationStack.Peek(1) : null; public ExecutionContext EntryContext => InvocationStack.Peek(InvocationStack.Count - 1); - public VMState State { get; protected set; } = VMState.BREAK; + public VMState State { get; internal protected set; } = VMState.BREAK; public ExecutionEngine(IScriptContainer container, ICrypto crypto, IScriptTable table = null, IInteropService service = null) { @@ -196,7 +196,7 @@ public void Execute() ExecuteNext(); } - protected void ExecuteNext() + internal protected void ExecuteNext() { if (InvocationStack.Count == 0) { @@ -1291,36 +1291,5 @@ protected virtual bool PreExecuteInstruction() { return true; } - - public void StepInto() - { - if (State.HasFlag(VMState.HALT) || State.HasFlag(VMState.FAULT)) return; - ExecuteNext(); - if (State == VMState.NONE) - State = VMState.BREAK; - } - - public void StepOut() - { - State &= ~VMState.BREAK; - int c = InvocationStack.Count; - while (!State.HasFlag(VMState.HALT) && !State.HasFlag(VMState.FAULT) && !State.HasFlag(VMState.BREAK) && InvocationStack.Count >= c) - ExecuteNext(); - if (State == VMState.NONE) - State = VMState.BREAK; - } - - public void StepOver() - { - if (State.HasFlag(VMState.HALT) || State.HasFlag(VMState.FAULT)) return; - State &= ~VMState.BREAK; - int c = InvocationStack.Count; - do - { - ExecuteNext(); - } while (!State.HasFlag(VMState.HALT) && !State.HasFlag(VMState.FAULT) && !State.HasFlag(VMState.BREAK) && InvocationStack.Count > c); - if (State == VMState.NONE) - State = VMState.BREAK; - } } } From b72e1a7a97f2019318f09c50fc0be3131cb3e0c1 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Sat, 30 Mar 2019 20:33:46 +0800 Subject: [PATCH 3/4] format --- src/neo-vm/ExecutionEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 330e71c3..f529184a 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -1,11 +1,11 @@ -using System; +using Neo.VM.Types; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Security.Cryptography; -using Neo.VM.Types; using VMArray = Neo.VM.Types.Array; namespace Neo.VM From 98612a2629f32fa8e8d86714006459db40e24255 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Sat, 30 Mar 2019 20:35:54 +0800 Subject: [PATCH 4/4] fix tests --- tests/neo-vm.Tests/VMJsonTestBase.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/neo-vm.Tests/VMJsonTestBase.cs b/tests/neo-vm.Tests/VMJsonTestBase.cs index d51d826e..de3fdcf4 100644 --- a/tests/neo-vm.Tests/VMJsonTestBase.cs +++ b/tests/neo-vm.Tests/VMJsonTestBase.cs @@ -50,6 +50,7 @@ public void ExecuteTest(VMUT ut) using (var engine = new ExecutionEngine(scriptContainer, Crypto.Default, scriptTable, service)) { + Debugger debugger = new Debugger(engine); engine.LoadScript(test.Script); // Execute Steps @@ -64,10 +65,10 @@ public void ExecuteTest(VMUT ut) { switch (run) { - case VMUTActionType.Execute: engine.Execute(); break; - case VMUTActionType.StepInto: engine.StepInto(); break; - case VMUTActionType.StepOut: engine.StepOut(); break; - case VMUTActionType.StepOver: engine.StepOver(); break; + case VMUTActionType.Execute: debugger.Execute(); break; + case VMUTActionType.StepInto: debugger.StepInto(); break; + case VMUTActionType.StepOut: debugger.StepOut(); break; + case VMUTActionType.StepOver: debugger.StepOver(); break; } }