Esempio n. 1
0
        ///////////////////////////////////////////////////////////////////////

        public static bool HasFlags(
            CancelFlags flags,
            CancelFlags hasFlags,
            bool all
            )
        {
            if (all)
            {
                return((flags & hasFlags) == hasFlags);
            }
            else
            {
                return((flags & hasFlags) != CancelFlags.None);
            }
        }
Esempio n. 2
0
 public void CancelAsyncOperation(CancelFlags flags)
 {
     throw new NotImplementedException();
 }
Esempio n. 3
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    //
                    // try {<tryBody>}
                    // [finally {<finallyBody>}]
                    //
                    if ((arguments.Count == 2) || (arguments.Count == 4))
                    {
                        if ((arguments.Count < 3) || (String.Compare(arguments[2],
                                                                     Try.Finally, StringOps.SystemStringComparisonType) == 0))
                        {
                            string name = StringList.MakeList("try");

                            ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                CallFrameFlags.Try);

                            interpreter.PushAutomaticCallFrame(frame);

                            ReturnCode tryCode;
                            Result     tryResult = null;

                            tryCode = interpreter.EvaluateScript(arguments[1], ref tryResult);

                            if (tryCode == ReturnCode.Error)
                            {
                                Engine.AddErrorInformation(interpreter, tryResult,
                                                           String.Format("{0}    (\"try\" 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.PopScopeCallFramesAndOneMore();

                            Result     finallyResult = null;
                            ReturnCode finallyCode   = ReturnCode.Ok;

                            if (arguments.Count == 4)
                            {
                                name = StringList.MakeList("finally");

                                frame = interpreter.NewTrackingCallFrame(name,
                                                                         CallFrameFlags.Finally);

                                interpreter.PushAutomaticCallFrame(frame);

                                //
                                // BUGFIX: Preserve any and all existing error related
                                //         information during evaluation of the finally
                                //         block.
                                //
                                Engine.SetNoResetError(interpreter, true);

                                //
                                // NOTE: If there was an error during the try block as well,
                                //       keep them somewhat organized in the final error
                                //       information.
                                //
                                if (tryCode == ReturnCode.Error)
                                {
                                    Engine.AddErrorInformation(interpreter, null,
                                                               String.Format("{0}    ... continued ...",
                                                                             Environment.NewLine));
                                }

                                //
                                // NOTE: If the appropriate flag is set, call into the
                                //       Engine.ResetCancel method (with "force" enabled)
                                //       prior to evaluating the finally block script.
                                //       It should be noted here that even though the
                                //       return code of this call is checked by the code,
                                //       it basically cannot fail at this point.
                                //
                                Result canceledResult = null;
                                bool   canceled       = false;
                                bool   unwound        = false;
                                bool   resetCancel    = false;

                                //
                                // NOTE: If the appropriate flag is set, reset the Exit
                                //       property prior to evaluating the finally block
                                //       script.
                                //
                                bool exit      = false;
                                bool resetExit = false;

                                try
                                {
                                    if (ScriptOps.HasFlags(interpreter,
                                                           InterpreterFlags.FinallyResetCancel, true))
                                    {
                                        ReturnCode resetCode;
                                        Result     resetError = null;

                                        resetCode = Engine.ResetCancel(
                                            interpreter, CancelFlags.TryBlock, ref canceledResult,
                                            ref canceled, ref unwound, ref resetCancel,
                                            ref resetError);

                                        if (resetCode != ReturnCode.Ok)
                                        {
                                            DebugOps.Complain(interpreter, resetCode, resetError);
                                        }
                                    }

                                    if (ScriptOps.HasFlags(interpreter,
                                                           InterpreterFlags.FinallyResetExit, true))
                                    {
                                        exit = interpreter.Exit;

                                        if (exit)
                                        {
                                            interpreter.Exit = false;
                                            resetExit        = true;
                                        }
                                    }

                                    ReturnCode timeoutCode;
                                    Result     timeoutResult = null;

                                    timeoutCode = Interpreter.StartFinallyTimeoutThread(
                                        interpreter, false, true, ref timeoutResult);

                                    if (timeoutCode != ReturnCode.Ok)
                                    {
                                        DebugOps.Complain(interpreter, timeoutCode, timeoutResult);
                                    }

                                    try
                                    {
                                        //
                                        // NOTE: Evaluate the finally block.
                                        //
                                        finallyCode = interpreter.EvaluateScript(
                                            arguments[3], ref finallyResult);
                                    }
                                    finally
                                    {
                                        timeoutCode = Interpreter.InterruptFinallyTimeoutThread(
                                            interpreter, false, ref timeoutResult);

                                        if (timeoutCode != ReturnCode.Ok)
                                        {
                                            DebugOps.Complain(interpreter, timeoutCode, timeoutResult);
                                        }
                                    }
                                }
                                finally
                                {
                                    if (exit && resetExit)
                                    {
                                        if (ScriptOps.HasFlags(interpreter,
                                                               InterpreterFlags.FinallyRestoreExit, true))
                                        {
                                            interpreter.Exit = true;
                                        }
                                    }

                                    if ((canceled || unwound) && resetCancel)
                                    {
                                        if (ScriptOps.HasFlags(interpreter,
                                                               InterpreterFlags.FinallyRestoreCancel, true))
                                        {
                                            CancelFlags cancelFlags = CancelFlags.FinallyBlock;

                                            if (unwound)
                                            {
                                                cancelFlags |= CancelFlags.Unwind;
                                            }

                                            ReturnCode cancelCode;
                                            Result     cancelError = null;

                                            cancelCode = Engine.CancelEvaluate(
                                                interpreter, canceledResult, cancelFlags,
                                                ref cancelError);

                                            if (cancelCode != ReturnCode.Ok)
                                            {
                                                DebugOps.Complain(interpreter, cancelCode, cancelError);
                                            }
                                        }
                                    }
                                }

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

                                //
                                // NOTE: Restore normal result reset semantics.
                                //
                                Engine.SetNoResetError(interpreter, false);

                                //
                                // 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.PopScopeCallFramesAndOneMore();
                            }

                            //
                            // NOTE: Initially, the overall command return code and result
                            //       is that of the try block; however, if the finally block
                            //       fails, that will be the return code and result.
                            //
                            if (finallyCode == ReturnCode.Ok)
                            {
                                result = tryResult;
                                code   = tryCode;
                            }
                            else
                            {
                                result = finallyResult;
                                code   = finallyCode;
                            }
                        }
                        else
                        {
                            result = String.Format(
                                "expected \"finally\" but got \"{0}\"",
                                arguments[2]);

                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"try script ?finally script?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    return(ReturnCode.Error);
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }