Exemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: For use by InteractiveOps.Commands._break() and
        //       Engine.CheckBreakpoints() only.
        //
        internal InteractiveLoopData(
            ReturnCode code,
            BreakpointType breakpointType,
            string breakpointName,
            IToken token,
            ITraceInfo traceInfo,
            EngineFlags engineFlags,
            SubstitutionFlags substitutionFlags,
            EventFlags eventFlags,
            ExpressionFlags expressionFlags,
            HeaderFlags headerFlags,
            IClientData clientData,
            ArgumentList arguments
            )
            : this()
        {
            this.code              = code;
            this.breakpointType    = breakpointType;
            this.breakpointName    = breakpointName;
            this.token             = token;
            this.traceInfo         = traceInfo;
            this.engineFlags       = engineFlags;
            this.substitutionFlags = substitutionFlags;
            this.eventFlags        = eventFlags;
            this.expressionFlags   = expressionFlags;
            this.headerFlags       = headerFlags;
            this.clientData        = clientData;
            this.arguments         = arguments;
        }
Exemplo n.º 2
0
        ////////////////////////////////////////////////////////////////////////

        #region IExecuteTrace Members
        public virtual ReturnCode Execute(
            BreakpointType breakpointType,
            Interpreter interpreter,
            ITraceInfo traceInfo,
            ref Result result
            )
        {
            return(ReturnCode.Ok);
        }
Exemplo n.º 3
0
 public void TraceState(ITraceInfo traceInfo)
 {
     _ = traceInfo ?? throw new ArgumentNullException(nameof(traceInfo));
     logger.LogInformation("{0:HH:mm:ss} {1}{2} [{3}] {4}",
                           DateTime.Now,
                           new string(' ', (traceInfo.ExecuteContext.ExecutePath.Depth - 1) * 4),
                           traceInfo.ExecuteContext.ExecutePath.ExecuteId,
                           traceInfo.ExecuteContext.ActionFullName,
                           traceInfo.State);
 }
Exemplo n.º 4
0
        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: For Interpreter class use only.
        //
        internal InteractiveLoopData(
            InteractiveLoopData loopData,
            IToken token,
            ITraceInfo traceInfo,
            HeaderFlags headerFlags
            )
            : this(loopData)
        {
            this.token       = token;
            this.traceInfo   = traceInfo;
            this.headerFlags = headerFlags;
        }
Exemplo n.º 5
0
        private ReturnCode PluginTraceCallback(
            BreakpointType breakpointType, /* in */
            Interpreter interpreter,       /* in */
            ITraceInfo traceInfo,          /* in */
            ref Result result              /* out */
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (traceInfo == null)
            {
                result = "invalid trace";
                return(ReturnCode.Error);
            }

            //
            // NOTE: Intercept attempted get operations on variables
            //       that we are monitoring.
            //
            if (breakpointType == BreakpointType.BeforeVariableGet)
            {
                //
                // NOTE: Demonstrate that we can return a value that is
                //       totally dynamic and totally unrelated to the
                //       actual variable itself.
                //
                result = Utility.GetUtcNow();

                traceInfo.Cancel     = true;
                traceInfo.ReturnCode = ReturnCode.Ok;
            }
            else if (breakpointType == BreakpointType.BeforeVariableUnset)
            {
                //
                // NOTE: Demonstrate that we can forbid operations from
                //       taking place.
                //
                result = String.Format(
                    "cannot unset \"{0}\", it is logically read-only",
                    traceInfo.Name);

                traceInfo.Cancel     = true;
                traceInfo.ReturnCode = ReturnCode.Error;
            }

            return(traceInfo.ReturnCode);
        }
Exemplo n.º 6
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecuteTrace Members
        public ReturnCode Execute(
            BreakpointType breakpointType,
            Interpreter interpreter,
            ITraceInfo traceInfo,
            ref Result result
            )
        {
            if (trace != null)
            {
                return(trace.Execute(
                           breakpointType, interpreter, traceInfo, ref result));
            }
            else
            {
                return(ReturnCode.Error);
            }
        }
Exemplo n.º 7
0
        ////////////////////////////////////////////////////////////////////////

        #region IExecuteTrace Members
        public override ReturnCode Execute(
            BreakpointType breakpointType,
            Interpreter interpreter,
            ITraceInfo traceInfo,
            ref Result result
            )
        {
            TraceCallback callback = this.Callback;

            if (callback != null)
            {
                return(callback(breakpointType, interpreter, traceInfo, ref result));
            }
            else
            {
                return(ReturnCode.Error);
            }
        }
Exemplo n.º 8
0
        ///////////////////////////////////////////////////////////////////////

        public ITraceInfo Update(
            ITraceInfo traceInfo
            )
        {
            if (traceInfo != null)
            {
                Update(
                    traceInfo.Trace, traceInfo.BreakpointType,
                    traceInfo.Frame, traceInfo.Variable,
                    traceInfo.Name, traceInfo.Index,
                    traceInfo.Flags, traceInfo.OldValue,
                    traceInfo.NewValue, traceInfo.OldValues,
                    traceInfo.NewValues, traceInfo.List,
                    traceInfo.Cancel, traceInfo.PostProcess,
                    traceInfo.ReturnCode);
            }

            return(traceInfo);
        }
Exemplo n.º 9
0
 public VariableContext(
     Interpreter interpreter,
     int threadId,
     CallStack callStack,
     ICallFrame globalFrame,
     ICallFrame globalScopeFrame,
     ICallFrame currentFrame,
     ICallFrame procedureFrame,
     ICallFrame uplevelFrame,
     ITraceInfo traceInfo
     )
 {
     this.interpreter      = interpreter;
     this.threadId         = threadId;
     this.callStack        = callStack;
     this.globalFrame      = globalFrame;
     this.globalScopeFrame = globalScopeFrame;
     this.currentFrame     = currentFrame;
     this.procedureFrame   = procedureFrame;
     this.uplevelFrame     = uplevelFrame;
     this.traceInfo        = traceInfo;
 }
Exemplo n.º 10
0
 private InteractiveLoopData(
     bool debug,
     IEnumerable <string> args,
     ReturnCode code,
     BreakpointType breakpointType,
     string breakpointName,
     IToken token,
     ITraceInfo traceInfo,
     EngineFlags engineFlags,
     SubstitutionFlags substitutionFlags,
     EventFlags eventFlags,
     ExpressionFlags expressionFlags,
     HeaderFlags headerFlags,
     IClientData clientData,
     ArgumentList arguments,
     bool exit
     )
 {
     this.kind              = IdentifierKind.InteractiveLoopData;
     this.id                = AttributeOps.GetObjectId(this);
     this.debug             = debug;
     this.args              = args;
     this.code              = code;
     this.breakpointType    = breakpointType;
     this.breakpointName    = breakpointName;
     this.token             = token;
     this.traceInfo         = traceInfo;
     this.engineFlags       = engineFlags;
     this.substitutionFlags = substitutionFlags;
     this.eventFlags        = eventFlags;
     this.expressionFlags   = expressionFlags;
     this.headerFlags       = headerFlags;
     this.clientData        = clientData;
     this.arguments         = arguments;
     this.exit              = exit;
 }
Exemplo n.º 11
0
        ///////////////////////////////////////////////////////////////////////

        public void Free(
            bool global
            )
        {
            TraceOps.DebugTrace(String.Format(
                                    "Free: called, global = {0}, interpreter = {1}, disposed = {2}",
                                    global, FormatOps.InterpreterNoThrow(interpreter), disposed),
                                typeof(VariableContext).Name, TracePriority.CleanupDebug);

            ///////////////////////////////////////////////////////////////////

            interpreter = null; /* NOT OWNED: Do not dispose. */
            threadId    = 0;

            ///////////////////////////////////////////////////////////////////

            if (traceInfo != null)
            {
                traceInfo = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the current call stack
            //       unless we are [also] disposing of the interpreter itself;
            //       therefore, use the special Free method here instead of the
            //       Dispose method.  The Free method is guaranteed to do the
            //       right thing with regard to the global call frame (assuming
            //       the "global" paramter is correct).
            //
            if (callStack != null)
            {
                callStack.Free(global);
                callStack = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the uplevel call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (uplevelFrame != null)
            {
                uplevelFrame.Free(global);
                uplevelFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the procedure call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (procedureFrame != null)
            {
                procedureFrame.Free(global);
                procedureFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the current call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (currentFrame != null)
            {
                currentFrame.Free(global);
                currentFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the uplevel call frame
            //       unless we are [also] disposing of the interpreter itself.
            //       If this is really a named scope call frame -AND- we are
            //       being disposed, it should have already been cleaned up by
            //       this point; therefore, this should be a no-op.
            //
            if (globalScopeFrame != null)
            {
                globalScopeFrame.Free(global);
                globalScopeFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the global call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (globalFrame != null)
            {
                globalFrame.Free(global);
                globalFrame = null;
            }
        }
Exemplo n.º 12
0
        ///////////////////////////////////////////////////////////////////////

        #region INotify Members
        public override ReturnCode Notify(
            Interpreter interpreter,
            IScriptEventArgs eventArgs,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (eventArgs == null)
            {
                return(ReturnCode.Ok);
            }

            if (!FlagOps.HasFlags(
                    eventArgs.NotifyTypes, NotifyType.CallFrame, false))
            {
                return(ReturnCode.Ok);
            }

            NotifyFlags notifyFlags = eventArgs.NotifyFlags;

            if (!FlagOps.HasFlags(notifyFlags,
                                  NotifyFlags.Popped | NotifyFlags.Deleted, false))
            {
                return(ReturnCode.Ok);
            }

            IClientData eventClientData = eventArgs.ClientData;

            if (eventClientData == null)
            {
                return(ReturnCode.Ok);
            }

            ICallFrame newFrame = eventClientData.Data as ICallFrame;

            if (newFrame == null)
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Make sure the variables in this frame actually BELONG
            //       to this frame.  Also, we do not handle the global call
            //       frame.
            //
            if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Force, true) &&
                !CallFrameOps.IsNonGlobalVariable(newFrame))
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: If this is a [scope] created call frame, we do NOT want
            //       to change any reference counts unless the call frame is
            //       being deleted, not simply popped.
            //
            if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Deleted, true) &&
                CallFrameOps.IsScope(newFrame))
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Grab the variables for this call frame.  If there are
            //       none, we are done.
            //
            VariableDictionary variables = newFrame.Variables;

            if (variables == null)
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Process each variable in the call frame to adjust all
            //       all the reference counts.  After this point, we need
            //       the interpreter context for the event.
            //
            Interpreter eventInterpreter = eventArgs.Interpreter;

            if (eventInterpreter == null)
            {
                return(ReturnCode.Ok);
            }

            foreach (KeyValuePair <string, IVariable> pair in variables)
            {
                //
                // NOTE: Grab the variable and make sure the variable it is
                //       valid.
                //
                IVariable variable = pair.Value;

                if (variable == null)
                {
                    continue;
                }

                //
                // NOTE: For unset operations, ObjectTraceCallback uses only
                //       the "traceInfo.Variable" and "traceInfo.oldValue"
                //       members of the ITraceInfo object instance.  If the
                //       number of trace and/or watch levels exceeds one,
                //       force creation of a new TraceInfo object here;
                //       otherwise, we may interfere with the setting of an
                //       unrelated variable value.
                //
                ITraceInfo traceInfo = ScriptOps.NewTraceInfo(
                    interpreter, null, BreakpointType.BeforeVariableUnset,
                    newFrame, variable, pair.Key, null, VariableFlags.None,
                    variable.Value, null, null, null, null,
                    interpreter.NeedNewTraceInfo(VariableFlags.None),
                    false, !EntityOps.IsNoPostProcess(variable),
                    ReturnCode.Ok);

                //
                // HACK: Manually invoke the Interpreter.ObjectTraceCallback
                //       static (trace callback) method, in order to handle
                //       contained object reference(s), if any.  After this
                //       method returns, the entire call frame will be going
                //       away, along with any object references contained
                //       within it.
                //
                ReturnCode code = Interpreter.ObjectTraceCallback(
                    traceInfo.BreakpointType, eventInterpreter, traceInfo,
                    ref result);

                if (code != ReturnCode.Ok)
                {
                    return(code);
                }
            }

            return(ReturnCode.Ok);
        }
Exemplo n.º 13
0
        private static ReturnCode TraceCallback(
            BreakpointType breakpointType, /* in */
            Interpreter interpreter,       /* in */
            ITraceInfo traceInfo,          /* in */
            ref Result result              /* out */
            )
        {
            if (interpreter == null)
            {
                //
                // NOTE: We require a valid interpreter context.  Most custom
                //       variable trace methods will want to do this because it
                //       is a fairly standard safety check (HIGHLY RECOMMENDED).
                //
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (traceInfo == null)
            {
                //
                // NOTE: This parameter should contain the information about
                //       the current variable access being processed.  If it
                //       is null, we cannot continue (HIGHLY RECOMMENDED).
                //
                result = "invalid trace";
                return(ReturnCode.Error);
            }

            //
            // NOTE: This trace method intercepts and show all variable access
            //       for the interpreter.  We could do practically anything
            //       inside this method, including monitoring and/or modifying
            //       the values to be fetched and/or set, changing the state of
            //       the interpreter, or aborting the operation altogether.
            //
            ///////////////////////////////////////////////////////////////////
            // ******************* BEGIN CUSTOM TRACE CODE ********************
            ///////////////////////////////////////////////////////////////////

            //
            // NOTE: This particular variable trace method requires a valid
            //       interpreter host; however, in practice, such a requirement
            //       would be very rare.
            //
            IHost host = interpreter.Host;

            if (host == null)
            {
                result = "interpreter host not available";
                return(ReturnCode.Error);
            }

            //
            // NOTE: The try block here is optional; however, custom variable
            //       trace methods are "officially" discouraged from raising
            //       exceptions.
            //
            ReturnCode code = ReturnCode.Ok;

            switch (traceInfo.BreakpointType)
            {
            case BreakpointType.BeforeVariableUnset:
            {
                try
                {
                    //
                    // NOTE: Query the configured foreground and
                    //       background colors used by the host
                    //       to display variable trace information.
                    //
                    ConsoleColor foregroundColor = _ConsoleColor.None;
                    ConsoleColor backgroundColor = _ConsoleColor.None;

                    code = host.GetColors(null,
                                          "TraceInfo", true, true, ref foregroundColor,
                                          ref backgroundColor, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        //
                        // NOTE: Clear the interpreter host and reset
                        //       its output position as well.
                        //
                        host.Clear();
                        host.ResetPosition();

                        //
                        // NOTE: Write the variable trace information
                        //       received by this method to the
                        //       interpreter host.
                        //
                        host.WriteTraceInfo(
                            interpreter, traceInfo,
                            DetailFlags.EmptyContent, true,
                            foregroundColor, backgroundColor);

                        host.RestorePosition(false);

                        int left = 0;
                        int top  = 0;

                        host.GetPosition(ref left, ref top);

                        left = 0;         /* NOTE: Left aligned. */
                        top++;            /* NOTE: On next line. */

                        host.WriteBox(null,
                                      "Press any key to continue...", null,
                                      false, false, ref left, ref top);

                        host.Pause();
                    }
                }
                catch (Exception e)
                {
                    result = e;
                    code   = ReturnCode.Error;
                }

                unsetTraces++;
                break;
            }

            case BreakpointType.BeforeVariableGet:
            {
                getTraces++;
                break;
            }

            case BreakpointType.BeforeVariableSet:
            {
                setTraces++;
                break;
            }
            }

            //
            // NOTE: Finally, return one of the standard status codes that
            //       indicate success / failure of this variable access.
            //
            return(code);

            ///////////////////////////////////////////////////////////////////
            // ******************** END CUSTOM TRACE CODE *********************
            ///////////////////////////////////////////////////////////////////
        }
Exemplo n.º 14
0
 public static bool Validate(this ITraceInfo traceInfo, Type ownerType, MethodBase methodBase)
 {
     return(ownerType == traceInfo.Info.Key && methodBase.Name == traceInfo.Info.Value);
 }
Exemplo n.º 15
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode FireTraces(
            BreakpointType breakpointType,
            Interpreter interpreter,
            ITraceInfo traceInfo,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (traces != null)
            {
                //
                // NOTE: Save the current variable flags.
                //
                VariableFlags savedFlags = flags;

                //
                // NOTE: Prevent endless trace recursion.
                //
                flags |= VariableFlags.NoTrace;

                try
                {
                    //
                    // NOTE: Process each trace (as long as they all continue
                    //       to succeed).
                    //
                    foreach (ITrace trace in traces)
                    {
                        if ((trace != null) && !EntityOps.IsDisabled(trace))
                        {
                            //
                            // NOTE: If possible, set the Trace property of the
                            //       TraceInfo to the one we are about to execute.
                            //
                            if (traceInfo != null)
                            {
                                traceInfo.Trace = trace;
                            }

                            //
                            // NOTE: Since variable traces can basically do anything
                            //       they want, we wrap them in a try block to prevent
                            //       exceptions from escaping.
                            //
                            interpreter.EnterTraceLevel();

                            try
                            {
                                code = trace.Execute(
                                    breakpointType, interpreter, traceInfo, ref result);
                            }
                            catch (Exception e)
                            {
                                //
                                // NOTE: Translate exceptions to a failure return.
                                //
                                result = String.Format(
                                    "caught exception while firing variable trace: {0}",
                                    e);

                                code = ReturnCode.Error;
                            }
                            finally
                            {
                                interpreter.ExitTraceLevel();
                            }

                            //
                            // NOTE: Check for exception results specially because we
                            //       treat "Break" different from other return codes.
                            //
                            if (code == ReturnCode.Break)
                            {
                                //
                                // NOTE: Success; however, skip processing further
                                //       traces for this variable operation.
                                //
                                code = ReturnCode.Ok;
                                break;
                            }
                            else if (code != ReturnCode.Ok)
                            {
                                //
                                // NOTE: Some type of failure (or exception), stop
                                //       processing for this variable operation.
                                //
                                break;
                            }
                        }
                    }
                }
                finally
                {
                    //
                    // NOTE: Restore the saved variable flags.
                    //
                    flags = savedFlags;
                }
            }

            return(code);
        }
Exemplo n.º 16
0
 internal TraceInfo(
     ITraceInfo traceInfo
     )
 {
     Update(traceInfo);
 }