public FlowBranchingTryFinally StartFlowBranching(TryFinallyBlock stmt) { FlowBranchingTryFinally branching = new FlowBranchingTryFinally(CurrentBranching, stmt); current_flow_branching = branching; return(branching); }
public Method CreateFinallyHost(TryFinallyBlock block) { var method = new Method(storey, new TypeExpression(storey.Compiler.BuiltinTypes.Void, loc), Modifiers.COMPILER_GENERATED, new MemberName(CompilerGeneratedContainer.MakeName(null, null, "Finally", finally_hosts_counter++), loc), ParametersCompiled.EmptyReadOnlyParameters, null); method.Block = new ToplevelBlock(method.Compiler, method.ParameterInfo, loc); method.Block.IsCompilerGenerated = true; method.Block.AddStatement(new TryFinallyBlockProxyStatement(this, block)); storey.AddMember(method); return(method); }
public override bool Walk(TryFinallyStmt node) { TryFinallyBlock tfb = new TryFinallyBlock(node); tryBlocks.Push(tfb); node.body.Walk(this); tfb.state = ExceptionBlock.State.Finally; node.finallyStmt.Walk(this); ExceptionBlock eb = tryBlocks.Pop(); Debug.Assert((object)eb == (object)tfb); return(false); }
public Method CreateFinallyHost(TryFinallyBlock block) { var method = new Method(storey, new TypeExpression(storey.Compiler.BuiltinTypes.Void, loc), Modifiers.COMPILER_GENERATED, new MemberName(CompilerGeneratedContainer.MakeName(null, null, "Finally", finally_hosts_counter++), loc), ParametersCompiled.EmptyReadOnlyParameters, null); method.Block = new ToplevelBlock(method.Compiler, method.ParameterInfo, loc); method.Block.IsCompilerGenerated = true; method.Block.AddStatement(new TryFinallyBlockProxyStatement(this, block)); // Cannot it add to storey because it'd be emitted before nested // anonoymous methods which could capture shared variable return(method); }
public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt) { FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt); current_flow_branching = branching; return branching; }
public TryFinallyBlockProxyStatement(Iterator iterator, TryFinallyBlock block) { this.iterator = iterator; this.block = block; }
public void Preprocess(ILConversion conversion, ConvertedRoutine routine) { if (routine.IsExceptionHandlingInfoPreprocessed) { return; } routine.IsExceptionHandlingInfoPreprocessed = true; routine.ExceptionHandlingInfo = new ExceptionHandlingInfo(); var handlingInfo = routine.ExceptionHandlingInfo; var methodDefinition = (MethodDefinition)routine.MethodReference; var methodDefinitionBody = methodDefinition.Body; if (!methodDefinitionBody.HasExceptionHandlers) { return; } foreach (var exceptionBlock in methodDefinitionBody.ExceptionHandlers) { switch (exceptionBlock.HandlerType) { case ExceptionHandlerType.Filter: { var filterBlock = new FilterBlock() { TryStartOffset = exceptionBlock.TryStart.Offset, TryEndOffset = exceptionBlock.TryEnd.Offset, HandlerEndOffset = exceptionBlock.HandlerEnd.Offset, FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1, ExceptionHandler = exceptionBlock }; handlingInfo.ExceptionBlocks.Add(filterBlock); AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, filterBlock); AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, filterBlock); AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, filterBlock); break; } case ExceptionHandlerType.Fault: { var faultBlock = new FaultBlock() { TryStartOffset = exceptionBlock.TryStart.Offset, TryEndOffset = exceptionBlock.TryEnd.Offset, HandlerEndOffset = exceptionBlock.HandlerEnd.Offset, FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1, ExceptionHandler = exceptionBlock }; handlingInfo.ExceptionBlocks.Add(faultBlock); AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, faultBlock); AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, faultBlock); AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, faultBlock); break; } case ExceptionHandlerType.Finally: { var finallyBlock = new TryFinallyBlock() { TryStartOffset = exceptionBlock.TryStart.Offset, TryEndOffset = exceptionBlock.TryEnd.Offset, HandlerEndOffset = exceptionBlock.HandlerEnd.Offset, FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1, ExceptionHandler = exceptionBlock }; handlingInfo.ExceptionBlocks.Add(finallyBlock); AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, finallyBlock); AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, finallyBlock); AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, finallyBlock); break; } case ExceptionHandlerType.Catch: { TryCatchBlock tryCatchBlock = null; for (int i = 0; i < handlingInfo.TryCatchEntries.Count; i++) { var x = handlingInfo.TryCatchEntries[i]; if (x.TryStartOffset == exceptionBlock.TryStart.Offset && x.TryEndOffset == exceptionBlock.TryEnd.Offset) { tryCatchBlock = x; } } if (tryCatchBlock == null) { tryCatchBlock = new TryCatchBlock() { // The first instruction that is included in the try catch block TryStartOffset = exceptionBlock.TryStart.Offset, // Gets the first instruction of the catch statement TryEndOffset = exceptionBlock.TryEnd.Offset, // Gets the first instruction that is outside of the catch statement HandlerEndOffset = exceptionBlock.HandlerEnd.Offset, FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1, HandlerEntries = new Dictionary <int, List <ExceptionHandler> >() }; handlingInfo.TryCatchEntries.Add(tryCatchBlock); handlingInfo.ExceptionBlocks.Add(tryCatchBlock); System.Diagnostics.Debug.WriteLine($"Try-Catch: BEGIN @ {exceptionBlock.TryStart.Offset.ToString("X2")}"); AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, tryCatchBlock); } if (!tryCatchBlock.HandlerEntries.TryGetValue(exceptionBlock.HandlerStart.Offset, out List <ExceptionHandler> list)) { list = new List <ExceptionHandler>(); tryCatchBlock.HandlerEntries.Add(exceptionBlock.HandlerStart.Offset, list); } list.Add(exceptionBlock); System.Diagnostics.Debug.WriteLine($"Try-Catch: CATCH @ {exceptionBlock.HandlerStart.Offset.ToString("X2")}"); AddEvent(conversion, ExceptionBlockEventKind.Catch, handlingInfo, exceptionBlock.HandlerStart.Offset, tryCatchBlock, exceptionBlock); break; } default: { throw new NotSupportedException(); } } } for (int i = 0; i < handlingInfo.TryCatchEntries.Count; i++) { var tryCatchBlock = handlingInfo.TryCatchEntries[i]; ExceptionHandler lastHandlerEntry = null; var handlerEntriesListList = tryCatchBlock.HandlerEntries.Values.ToList(); for (int j = 0; j < handlerEntriesListList.Count; j++) { var currentHandlerEntryList = handlerEntriesListList[j]; for (int k = 0; k < currentHandlerEntryList.Count; k++) { var currentHandlerEntry = currentHandlerEntryList[k]; if (lastHandlerEntry == null) { lastHandlerEntry = currentHandlerEntry; } else if (currentHandlerEntry.HandlerEnd.Offset > lastHandlerEntry.HandlerEnd.Offset) { lastHandlerEntry = currentHandlerEntry; } } } if (lastHandlerEntry == null) { continue; } System.Diagnostics.Debug.WriteLine($"Try-Catch: END CATCH @ {lastHandlerEntry.HandlerEnd.Offset.ToString("X2")}"); AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, lastHandlerEntry.HandlerEnd.Offset, tryCatchBlock); } }