Exemple #1
0
        public override int Run(InterpretedFrame frame)
        {
            Debug.Assert(!frame.IsJumpHappened());

            frame.SetStackDepth(GetLabel(frame).StackDepth);
            frame.PushPendingContinuation();
            frame.RemoveContinuation();
            return(1);
        }
Exemple #2
0
        public override int Run(InterpretedFrame frame)
        {
            // Push fault.
            frame.PushContinuation(LabelIndex);

            var prevInstrIndex = frame.InstructionIndex;

            frame.InstructionIndex++;

            // Start to run the try/fault blocks
            var 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.
            var ranWithoutFault = false;

            try
            {
                // run the try block
                var index = frame.InstructionIndex;
                while (index >= Handler !.TryStartIndex && index < Handler.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
                    var index = frame.InstructionIndex = Handler !.FinallyStartIndex;
                    while (index >= Handler.FinallyStartIndex && index < Handler.FinallyEndIndex)
                    {
                        index += instructions[index].Run(frame);
                        frame.InstructionIndex = index;
                    }
                }
            }

            return(frame.InstructionIndex - prevInstrIndex);
        }
Exemple #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);
        }