using Jint.Native; using Jint.Runtime.Interpreter; namespace Jint.Runtime.Debugger; public enum PauseType { Skip, Step, Break, DebuggerStatement } public class DebugHandler { public delegate void BeforeEvaluateEventHandler(object sender, Program ast); public delegate StepMode DebugEventHandler(object sender, DebugInformation e); private readonly Engine _engine; private bool _paused; private int _steppingDepth; /// /// Triggered before the engine executes/evaluates the parsed AST of a script or module. /// public event BeforeEvaluateEventHandler? BeforeEvaluate; /// /// The Step event is triggered before the engine executes a step-eligible execution point. /// /// /// If the current step mode is , this event is never triggered. The script may /// still be paused by a debugger statement or breakpoint, but these will trigger the /// event. /// public event DebugEventHandler? Step; /// /// The Break event is triggered when a breakpoint or debugger statement is hit. /// /// /// This is event is not triggered if the current script location was reached by stepping. In that case, only /// the event is triggered. /// public event DebugEventHandler? Break; /// /// The Skip event is triggered for each execution point, when the point doesn't trigger a /// or event. /// public event DebugEventHandler? Skip; internal DebugHandler(Engine engine, StepMode initialStepMode) { _engine = engine; HandleNewStepMode(initialStepMode); } private bool IsStepping => _engine.CallStack.Count <= _steppingDepth; /// /// The location of the current (step-eligible) AST node being executed. /// /// /// The location is available as long as DebugMode is enabled - i.e. even when not stepping /// or hitting a breakpoint. /// public SourceLocation? CurrentLocation { get; private set; } /// /// Collection of active breakpoints for the engine. /// public BreakPointCollection BreakPoints { get; } = new BreakPointCollection(); /// /// Evaluates a script (expression) within the current execution context. /// /// /// Internally, this is used for evaluating breakpoint conditions, but may also be used for e.g. watch lists /// in a debugger. /// public JsValue Evaluate(in Prepared