public override int Run(InterpretedFrame frame) { Debug.Assert(!frame.IsJumpHappened()); frame.SetStackDepth(GetLabel(frame).StackDepth); frame.PushPendingContinuation(); frame.RemoveContinuation(); return(1); }
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); }
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); }