public void LogEcmaError(EcmaScriptException ecmaScriptException)
 {
     this.LogError("An error occurred in parsing the Javascript file.");
     if (ecmaScriptException.LineNumber == -1)
     {
         this.LogError("[ERROR] {0} ********", ecmaScriptException.Message);
     }
     else
     {
         this.LogError(
             "[ERROR] {0} ******** Line: {2}. LineOffset: {3}. LineSource: \"{4}\"",
             ecmaScriptException.Message,
             string.IsNullOrEmpty(ecmaScriptException.SourceName)
                 ? string.Empty
                 : "Source: {1}. " + ecmaScriptException.SourceName,
             ecmaScriptException.LineNumber,
             ecmaScriptException.ColumnNumber,
             ecmaScriptException.LineSource);
     }
 }
        internal static string getPatchedStack (EcmaScriptException ex, string nativeStackTrace)
        {
            string tag = "EcmaScript.NET.Interpreter.interpretLoop";
            System.Text.StringBuilder sb = new System.Text.StringBuilder (nativeStackTrace.Length + 1000);
            string lineSeparator = System.Environment.NewLine;

            CallFrame [] array = (CallFrame [])ex.m_InterpreterStackInfo;
            if (array == null) // TODO: when does this happen?
                return sb.ToString ();

            int [] linePC = ex.m_InterpreterLineData;
            int arrayIndex = array.Length;
            int linePCIndex = linePC.Length;
            int offset = 0;
            while (arrayIndex != 0) {
                --arrayIndex;
                int pos = nativeStackTrace.IndexOf (tag, offset);
                if (pos < 0) {
                    break;
                }

                // Skip tag length
                pos += tag.Length;
                // Skip until the end of line
                for (; pos != nativeStackTrace.Length; ++pos) {
                    char c = nativeStackTrace [pos];
                    if (c == '\n' || c == '\r') {
                        break;
                    }
                }
                sb.Append (nativeStackTrace.Substring (offset, (pos) - (offset)));
                offset = pos;

                CallFrame frame = array [arrayIndex];
                while (frame != null) {
                    if (linePCIndex == 0)
                        Context.CodeBug ();
                    --linePCIndex;
                    InterpreterData idata = frame.idata;
                    sb.Append (lineSeparator);
                    sb.Append ("\tat script");
                    if (idata.itsName != null && idata.itsName.Length != 0) {
                        sb.Append ('.');
                        sb.Append (idata.itsName);
                    }
                    sb.Append ('(');
                    sb.Append (idata.itsSourceFile);
                    int pc = linePC [linePCIndex];
                    if (pc >= 0) {
                        // Include line info only if available
                        sb.Append (':');
                        sb.Append (GetIndex (idata.itsICode, pc));
                    }
                    sb.Append (')');
                    frame = frame.parentFrame;
                }
            }
            sb.Append (nativeStackTrace.Substring (offset));

            return sb.ToString ();
        }
        internal static string GetStack (EcmaScriptException ex)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder ();

            CallFrame [] array = (CallFrame [])ex.m_InterpreterStackInfo;
            if (array == null) // TODO: When does this happen?
                return sb.ToString ();

            int [] linePC = ex.m_InterpreterLineData;
            int arrayIndex = array.Length;
            int linePCIndex = linePC.Length;

            while (arrayIndex != 0) {
                --arrayIndex;

                CallFrame frame = array [arrayIndex];
                while (frame != null) {
                    if (linePCIndex == 0)
                        Context.CodeBug ();
                    --linePCIndex;
                    InterpreterData idata = frame.idata;

                    if (sb.Length > 0)
                        sb.Append (Environment.NewLine);
                    sb.Append ("\tat script");
                    if (idata.itsName != null && idata.itsName.Length != 0) {
                        sb.Append ('.');
                        sb.Append (idata.itsName);
                    }
                    sb.Append ('(');
                    sb.Append (idata.itsSourceFile);
                    int pc = linePC [linePCIndex];
                    if (pc >= 0) {
                        // Include line info only if available
                        sb.Append (':');
                        sb.Append (GetIndex (idata.itsICode, pc));
                    }
                    sb.Append (')');


                    frame = frame.parentFrame;


                }
            }

            return sb.ToString ();
        }
        internal static void captureInterpreterStackInfo (EcmaScriptException ex)
        {
            Context cx = Context.CurrentContext;
            if (cx == null || cx.lastInterpreterFrame == null) {
                // No interpreter invocations
                ex.m_InterpreterStackInfo = null;
                ex.m_InterpreterLineData = null;
                return;
            }
            // has interpreter frame on the stack
            CallFrame [] array;
            if (cx.previousInterpreterInvocations == null || cx.previousInterpreterInvocations.size () == 0) {
                array = new CallFrame [1];
            }
            else {
                int previousCount = cx.previousInterpreterInvocations.size ();
                if (cx.previousInterpreterInvocations.peek () == cx.lastInterpreterFrame) {
                    // It can happen if exception was generated after
                    // frame was pushed to cx.previousInterpreterInvocations
                    // but before assignment to cx.lastInterpreterFrame.
                    // In this case frames has to be ignored.
                    --previousCount;
                }
                array = new CallFrame [previousCount + 1];
                cx.previousInterpreterInvocations.ToArray (array);
            }
            array [array.Length - 1] = (CallFrame)cx.lastInterpreterFrame;

            int interpreterFrameCount = 0;
            for (int i = 0; i != array.Length; ++i) {
                interpreterFrameCount += 1 + array [i].frameIndex;
            }

            int [] linePC = new int [interpreterFrameCount];
            // Fill linePC with pc positions from all interpreter frames.
            // Start from the most nested frame
            int linePCIndex = interpreterFrameCount;
            for (int i = array.Length; i != 0; ) {
                --i;
                CallFrame frame = array [i];
                while (frame != null) {
                    --linePCIndex;
                    linePC [linePCIndex] = frame.pcSourceLineStart;
                    frame = frame.parentFrame;
                }
            }
            if (linePCIndex != 0)
                Context.CodeBug ();

            ex.m_InterpreterStackInfo = array;
            ex.m_InterpreterLineData = linePC;
        }