Exemplo n.º 1
0
        /// <summary>
        /// Rewrites Try/Catch part of the Try/Catch/Finally
        /// </summary>
        private Statement RewriteFinalizedRegion(TryStatement node)
        {
            var rewrittenTry = (Block)Visit(node.ProtectedBlock);

            var catches = node.ExceptionHandlers;

            if (catches.IsEmpty)
            {
                return(rewrittenTry);
            }

            var origAwaitCatchFrame = _currentAwaitCatchFrame;

            _currentAwaitCatchFrame = null;

            Visit(node.ExceptionHandlers);
            Statement tryWithCatches = new TryStatement {
                EnsureBlock = rewrittenTry
            };

            ((TryStatement)tryWithCatches).ExceptionHandlers = node.ExceptionHandlers;

            var currentAwaitCatchFrame = _currentAwaitCatchFrame;

            if (currentAwaitCatchFrame != null)
            {
                var handledLabel = _F.CreateLabel(tryWithCatches, CompilerContext.Current.GetUniqueName("handled"), _tryDepth);
                var handlersList = currentAwaitCatchFrame.handlers;
                _tryDepth = node.GetAncestors <TryStatement>().Count() + 1;
                var handlers = new List <Statement> {
                    _F.CreateGoto(handledLabel, _tryDepth)
                };
                for (int i = 0, l = handlersList.Count; i < l; i++)
                {
                    handlers.Add(
                        new Block(
                            handlersList[i],
                            _F.CreateGoto(handledLabel, _tryDepth)));
                }

                _containingMethod.Locals.Add(currentAwaitCatchFrame.pendingCaughtException.Local);
                _containingMethod.Locals.Add(currentAwaitCatchFrame.pendingCatch.Local);
                _containingMethod.Locals.AddRange(currentAwaitCatchFrame.GetHoistedLocals().Select(l => l.Local));

                tryWithCatches = new Block(
                    new ExpressionStatement(
                        _F.CreateAssignment(
                            _F.CreateLocalReference(currentAwaitCatchFrame.pendingCatch),
                            _F.CreateDefaultInvocation(LexicalInfo.Empty, currentAwaitCatchFrame.pendingCatch.Type))),
                    tryWithCatches,
                    CreateSwitch(handlers, handledLabel, currentAwaitCatchFrame.pendingCatch));
            }

            _currentAwaitCatchFrame = origAwaitCatchFrame;

            return(tryWithCatches);
        }