RemoveContinuation() public method

public RemoveContinuation ( ) : void
return void
示例#1
0
        public override int Run(InterpretedFrame frame)
        {
            Debug.Assert(_tryHandler != null, "the tryHandler must be set already");

            // Push fault.
            frame.PushContinuation(_labelIndex);

            int prevInstrIndex = frame.InstructionIndex;

            frame.InstructionIndex++;

            // Start to run the try/fault blocks
            Instruction[] instructions = frame.Interpreter.Instructions.Instructions;

            // C# 6 has no direct support for fault blocks, but they can be faked or coerced out of the compiler
            // in several ways. Catch-and-rethrow can work in specific cases, but not generally as the double-pass
            // will not work correctly with filters higher up the call stack. Iterators can be used to produce real
            // fault blocks, but it depends on an implementation detail rather than a guarantee, and is rather
            // indirect. This leaves using a finally block and not doing anything in it if the body ran to
            // completion, which is the approach used here.
            bool ranWithoutFault = false;

            try
            {
                // run the try block
                int index = frame.InstructionIndex;
                while (index >= _tryHandler.TryStartIndex && index < _tryHandler.TryEndIndex)
                {
                    index += instructions[index].Run(frame);
                    frame.InstructionIndex = index;
                }

                // run the 'Goto' that jumps out of the try/fault blocks
                Debug.Assert(instructions[index] is GotoInstruction, "should be the 'Goto' instruction that jumps out the try/fault");

                // if we've arrived here there was no exception thrown. As the fault block won't run, we need to
                // pop the continuation for it here, before Gotoing the end of the try/fault.
                ranWithoutFault = true;
                frame.RemoveContinuation();
                frame.InstructionIndex += instructions[index].Run(frame);
            }
            finally
            {
                if (!ranWithoutFault)
                {
                    // run the fault block
                    // we cannot jump out of the finally block, and we cannot have an immediate rethrow in it
                    int index = frame.InstructionIndex = _tryHandler.FinallyStartIndex;
                    while (index >= _tryHandler.FinallyStartIndex && index < _tryHandler.FinallyEndIndex)
                    {
                        index += instructions[index].Run(frame);
                        frame.InstructionIndex = index;
                    }
                }
            }

            return(frame.InstructionIndex - prevInstrIndex);
        }
示例#2
0
        public override int Run(InterpretedFrame frame)
        {
            Debug.Assert(!frame.IsJumpHappened());

            frame.SetStackDepth(GetLabel(frame).StackDepth);
            frame.PushPendingContinuation();
            frame.RemoveContinuation();
            return(1);
        }
示例#3
0
        public override int Run(InterpretedFrame frame)
        {
            // If _pendingContinuation == -1 then we were getting into the finally block because an exception was thrown
            //      in this case we need to set the stack depth
            // Else we were getting into this finally block from a 'Goto' jump, and the stack depth is already set properly
            if (!frame.IsJumpHappened())
            {
                frame.SetStackDepth(GetLabel(frame).StackDepth);
            }

            frame.PushPendingContinuation();
            frame.RemoveContinuation();
            return(1);
        }