Ejemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////

        internal StringList GetLocals(
            Interpreter interpreter,
            string pattern
            )
        {
            if (pattern != null)
            {
                pattern = ScriptOps.MakeVariableName(pattern);
            }

            StringList result = new StringList();

            foreach (KeyValuePair <string, IVariable> pair in this)
            {
                IVariable variable = pair.Value;

                if (variable == null)
                {
                    continue;
                }

                if (EntityOps.IsUndefined(variable) ||
                    EntityOps.IsLink(variable))
                {
                    continue;
                }

                ICallFrame frame = CallFrameOps.FollowNext(variable.Frame);

                if (interpreter != null)
                {
                    if (interpreter.IsGlobalCallFrame(frame))
                    {
                        continue;
                    }

                    if (Interpreter.IsNamespaceCallFrame(frame))
                    {
                        continue;
                    }
                }

                string name = variable.Name;

                if ((pattern == null) || StringOps.Match(
                        interpreter, StringOps.DefaultMatchMode,
                        name, pattern, false))
                {
                    result.Add(name);
                }
            }

            return(result);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\"";
                return(ReturnCode.Error);
            }

            ReturnCode code;
            int        currentLevel = 0;

            code = interpreter.GetInfoLevel(
                CallFrameOps.InfoLevelSubCommand, ref currentLevel,
                ref result);

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

            bool       mark         = false;
            bool       absolute     = false;
            bool       super        = false;
            int        level        = 0;
            ICallFrame currentFrame = null;
            ICallFrame otherFrame   = null;

            FrameResult frameResult = interpreter.GetCallFrame(
                arguments[1], ref mark, ref absolute, ref super,
                ref level, ref currentFrame, ref otherFrame,
                ref result);

            if (frameResult == FrameResult.Invalid)
            {
                return(ReturnCode.Error);
            }

            int argumentIndex = ((int)frameResult + 1);

            //
            // BUGFIX: The argument count needs to be checked again here.
            //
            if (argumentIndex >= arguments.Count)
            {
                result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\"";
                return(ReturnCode.Error);
            }

            if (mark)
            {
                code = CallFrameOps.MarkMatching(
                    interpreter.CallStack, interpreter.CurrentFrame,
                    absolute, level, CallFrameFlags.Variables,
                    CallFrameFlags.Invisible | CallFrameFlags.NoVariables,
                    CallFrameFlags.Invisible, false, false, true,
                    ref result);
            }

            if (code == ReturnCode.Ok)
            {
                try
                {
                    string name = StringList.MakeList("uplevel", arguments[1]);

                    ICallFrame newFrame = interpreter.NewUplevelCallFrame(
                        name, currentLevel, CallFrameFlags.None, mark,
                        currentFrame, otherFrame);

                    ICallFrame savedFrame = null;

                    interpreter.PushUplevelCallFrame(
                        currentFrame, newFrame, true, ref savedFrame);

                    if ((argumentIndex + 1) >= arguments.Count)
                    {
                        code = interpreter.EvaluateScript(
                            arguments[argumentIndex], ref result);
                    }
                    else
                    {
                        code = interpreter.EvaluateScript(
                            arguments, argumentIndex, ref result);
                    }

                    if (code == ReturnCode.Error)
                    {
                        Engine.AddErrorInformation(interpreter, result,
                                                   String.Format("{0}    (\"uplevel\" body line {1})",
                                                                 Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                    }

                    //
                    // NOTE: Pop the original call frame that we pushed above and
                    //       any intervening scope call frames that may be leftover
                    //       (i.e. they were not explicitly closed).
                    //
                    /* IGNORED */
                    interpreter.PopUplevelCallFrame(
                        currentFrame, newFrame, ref savedFrame);
                }
                finally
                {
                    if (mark)
                    {
                        //
                        // NOTE: We should not get an error at this point from
                        //       unmarking the call frames; however, if we do get
                        //       one, we need to complain loudly about it because
                        //       that means the interpreter state has probably been
                        //       corrupted somehow.
                        //
                        ReturnCode markCode;
                        Result     markResult = null;

                        markCode = CallFrameOps.MarkMatching(
                            interpreter.CallStack, interpreter.CurrentFrame,
                            absolute, level, CallFrameFlags.Variables,
                            CallFrameFlags.NoVariables, CallFrameFlags.Invisible,
                            false, false, false, ref markResult);

                        if (markCode != ReturnCode.Ok)
                        {
                            DebugOps.Complain(interpreter, markCode, markResult);
                        }
                    }
                }
            }

            return(code);
        }
Ejemplo n.º 4
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"variable ?name value...? name ?value?\"";
                return(ReturnCode.Error);
            }

            ICallFrame localFrame = null;

            if (interpreter.GetVariableFrameViaResolvers(
                    LookupFlags.Default, ref localFrame,
                    ref result) != ReturnCode.Ok)
            {
                return(ReturnCode.Error);
            }

            if (localFrame == null)
            {
                result = "local call frame is invalid";
                return(ReturnCode.Error);
            }

            if (!localFrame.IsVariable)
            {
                result = "local call frame does not support variables";
                return(ReturnCode.Error);
            }

            bool       useNamespaces    = interpreter.AreNamespacesEnabled();
            INamespace currentNamespace = null;

            if (useNamespaces &&
                interpreter.GetCurrentNamespaceViaResolvers(
                    null, LookupFlags.Default, ref currentNamespace,
                    ref result) != ReturnCode.Ok)
            {
                return(ReturnCode.Error);
            }

            ICallFrame otherFrame = null;

            if ((currentNamespace != null) &&
                !interpreter.IsGlobalNamespace(currentNamespace))
            {
                otherFrame = currentNamespace.VariableFrame;
            }
            else
            {
                otherFrame = interpreter.CurrentGlobalFrame;
            }

            for (int argumentIndex = 1;
                 argumentIndex < arguments.Count;
                 argumentIndex += 2)
            {
                string varName = arguments[argumentIndex];

                lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                {
                    VariableFlags flags = VariableFlags.NoElement;

                    if (!useNamespaces)
                    {
                        flags |= VariableFlags.GlobalOnly;
                    }

                    IVariable otherVariable = null;
                    Result    error         = null;

                    if (interpreter.GetVariableViaResolversWithSplit(
                            varName, ref flags, ref otherVariable,
                            ref error) != ReturnCode.Ok)
                    {
                        if (FlagOps.HasFlags(
                                flags, VariableFlags.NotFound, true))
                        {
                            error = null;

                            if (interpreter.AddVariable2(
                                    VariableFlags.Undefined | flags,
                                    varName, null, true, ref otherVariable,
                                    ref error) != ReturnCode.Ok)
                            {
                                result = error;
                                return(ReturnCode.Error);
                            }
                        }
                        else
                        {
                            //
                            // NOTE: We did not search for the variable, let
                            //       the caller know why.
                            //
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }

                    //
                    // NOTE: Create the variable link between the local frame
                    //       (i.e. a procedure, etc) and the other frame (i.e.
                    //       namespace or global).
                    //
                    if (CallFrameOps.IsLocal(localFrame))
                    {
                        error = null;

                        if (ScriptOps.LinkVariable(
                                interpreter, localFrame, varName, otherFrame,
                                varName, ref error) != ReturnCode.Ok)
                        {
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }

                    //
                    // NOTE: If they provided a value, set it now.
                    //
                    // BUGFIX: This must be done after setting up the link
                    //         and not before; otherwise, the LinkVariable
                    //         method will detect a defined variable with
                    //         the same name in the local call frame and
                    //         refuse to overwrite it (by design).
                    //
                    if ((argumentIndex + 1) < arguments.Count)
                    {
                        error = null;

                        if (interpreter.SetVariableValue2(
                                VariableFlags.None, otherFrame, varName,
                                null, arguments[argumentIndex + 1].Value, null,
                                ref otherVariable, ref error) != ReturnCode.Ok)
                        {
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }
                }
            }

            result = String.Empty;
            return(ReturnCode.Ok);
        }