/// <summary>Called when a script exception has been thrown.</summary> /// <remarks>Called when a script exception has been thrown.</remarks> private void HandleExceptionThrown(Context cx, Exception ex, Dim.StackFrame frame) { if (breakOnExceptions) { Dim.ContextData cd = frame.ContextData(); if (cd.lastProcessedException != ex) { Interrupted(cx, frame, ex); cd.lastProcessedException = ex; } } }
/// <summary>Interrupts script execution.</summary> /// <remarks>Interrupts script execution.</remarks> private void Interrupted(Context cx, Dim.StackFrame frame, Exception scriptException) { Dim.ContextData contextData = frame.ContextData(); bool eventThreadFlag = callback.IsGuiEventThread(); contextData.eventThreadFlag = eventThreadFlag; bool recursiveEventThreadCall = false; lock (eventThreadMonitor) { if (eventThreadFlag) { if (interruptedContextData != null) { recursiveEventThreadCall = true; goto interruptedCheck_break; } } else { while (interruptedContextData != null) { try { System.Threading.Monitor.Wait(eventThreadMonitor); } catch (Exception) { return; } } } interruptedContextData = contextData; } interruptedCheck_break: ; if (recursiveEventThreadCall) { // XXX: For now the following is commented out as on Linux // too deep recursion of dispatchNextGuiEvent causes GUI lockout. // Note: it can make GUI unresponsive if long-running script // will be called on GUI thread while processing another interrupt if (false) { // Run event dispatch until gui sets a flag to exit the initial // call to interrupted. while (this.returnValue == -1) { try { callback.DispatchNextGuiEvent(); } catch (Exception) { } } } return; } if (interruptedContextData == null) { Kit.CodeBug(); } try { do { int frameCount = contextData.FrameCount(); this.frameIndex = frameCount - 1; string threadTitle = Sharpen.Thread.CurrentThread().ToString(); string alertMessage; if (scriptException == null) { alertMessage = null; } else { alertMessage = scriptException.ToString(); } int returnValue = -1; if (!eventThreadFlag) { lock (monitor) { if (insideInterruptLoop) { Kit.CodeBug(); } this.insideInterruptLoop = true; this.evalRequest = null; this.returnValue = -1; callback.EnterInterrupt(frame, threadTitle, alertMessage); try { for (; ; ) { try { System.Threading.Monitor.Wait(monitor); } catch (Exception) { Sharpen.Thread.CurrentThread().Interrupt(); break; } if (evalRequest != null) { this.evalResult = null; try { evalResult = Do_eval(cx, evalFrame, evalRequest); } finally { evalRequest = null; evalFrame = null; System.Threading.Monitor.Pulse(monitor); } continue; } if (this.returnValue != -1) { returnValue = this.returnValue; break; } } } finally { insideInterruptLoop = false; } } } else { this.returnValue = -1; callback.EnterInterrupt(frame, threadTitle, alertMessage); while (this.returnValue == -1) { try { callback.DispatchNextGuiEvent(); } catch (Exception) { } } returnValue = this.returnValue; } switch (returnValue) { case STEP_OVER: { contextData.breakNextLine = true; contextData.stopAtFrameDepth = contextData.FrameCount(); break; } case STEP_INTO: { contextData.breakNextLine = true; contextData.stopAtFrameDepth = -1; break; } case STEP_OUT: { if (contextData.FrameCount() > 1) { contextData.breakNextLine = true; contextData.stopAtFrameDepth = contextData.FrameCount() - 1; } break; } } } while (false); } finally { lock (eventThreadMonitor) { interruptedContextData = null; System.Threading.Monitor.PulseAll(eventThreadMonitor); } } }
/// <summary> /// Copies the breakpoints from the given SourceInfo object into this /// one. /// </summary> /// <remarks> /// Copies the breakpoints from the given SourceInfo object into this /// one. /// </remarks> private void CopyBreakpointsFrom(Dim.SourceInfo old) { int end = old.breakpoints.Length; if (end > this.breakpoints.Length) { end = this.breakpoints.Length; } for (int line = 0; line != end; ++line) { if (old.breakpoints[line]) { this.breakpoints[line] = true; } } }
/// <summary>Called when a breakpoint has been hit.</summary> /// <remarks>Called when a breakpoint has been hit.</remarks> private void HandleBreakpointHit(Dim.StackFrame frame, Context cx) { breakFlag = false; Interrupted(cx, frame, null); }
/// <summary>Creates a new StackFrame.</summary> /// <remarks>Creates a new StackFrame.</remarks> private StackFrame(Context cx, Dim dim, Dim.FunctionSource fsource) { this.dim = dim; this.contextData = Dim.ContextData.Get(cx); this.fsource = fsource; this.breakpoints = fsource.SourceInfo().breakpoints; this.lineNumber = fsource.FirstLine(); }
/// <summary>Creates a new FunctionSource.</summary> /// <remarks>Creates a new FunctionSource.</remarks> private FunctionSource(Dim.SourceInfo sourceInfo, int firstLine, string name) { if (name == null) { throw new ArgumentException(); } this.sourceInfo = sourceInfo; this.firstLine = firstLine; this.name = name; }
/// <summary>Pushes a stack frame on to the stack.</summary> /// <remarks>Pushes a stack frame on to the stack.</remarks> private void PushFrame(Dim.StackFrame frame) { frameStack.Push(frame); }
/// <summary>Creates a new DimIProxy.</summary> /// <remarks>Creates a new DimIProxy.</remarks> private DimIProxy(Dim dim, int type) { this.dim = dim; this.type = type; }
/// <summary>Evaluates script in the given stack frame.</summary> /// <remarks>Evaluates script in the given stack frame.</remarks> private static string Do_eval(Context cx, Dim.StackFrame frame, string expr) { string resultString; Rhino.Debug.Debugger saved_debugger = cx.GetDebugger(); object saved_data = cx.GetDebuggerContextData(); int saved_level = cx.GetOptimizationLevel(); cx.SetDebugger(null, null); cx.SetOptimizationLevel(-1); cx.SetGeneratingDebug(false); try { Callable script = (Callable)cx.CompileString(expr, string.Empty, 0, null); object result = script.Call(cx, frame.scope, frame.thisObj, ScriptRuntime.emptyArgs); if (result == Undefined.instance) { resultString = string.Empty; } else { resultString = ScriptRuntime.ToString(result); } } catch (Exception exc) { resultString = exc.Message; } finally { cx.SetGeneratingDebug(true); cx.SetOptimizationLevel(saved_level); cx.SetDebugger(saved_debugger, saved_data); } if (resultString == null) { resultString = "null"; } return resultString; }
/// <summary>Creates a new Main.</summary> /// <remarks>Creates a new Main.</remarks> public Program(string title) { dim = new Dim(); debugGui = new SwingGui(dim, title); }
/// <summary>Frees any resources held by the debugger.</summary> /// <remarks>Frees any resources held by the debugger.</remarks> public virtual void Dispose() { ClearAllBreakpoints(); dim.Go(); debugGui.Dispose(); dim = null; }