Example #1
0
        public FlowBranchingTryFinally StartFlowBranching(TryFinallyBlock stmt)
        {
            FlowBranchingTryFinally branching = new FlowBranchingTryFinally(CurrentBranching, stmt);

            current_flow_branching = branching;
            return(branching);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #5
0
		public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt)
		{
			FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt);
			current_flow_branching = branching;
			return branching;
		}
Example #6
0
 public TryFinallyBlockProxyStatement(Iterator iterator, TryFinallyBlock block)
 {
     this.iterator = iterator;
     this.block    = block;
 }
Example #7
0
        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);
            }
        }