Inheritance: System.Compiler.Statement
Beispiel #1
0
        private ZTry VisitZTry(ZTry Try)
        {
            WriteStart("try");
            this.VisitBlock(Try.Body);

            WriteLine("with");
            WriteLine("{");
            In();
            for (int i = 0, n = Try.Catchers.Length; i < n; i++)
                this.VisitWith(Try.Catchers[i]);
            Out();
            WriteLine("}");
            return Try;
        }
Beispiel #2
0
        private ZTry VisitZTry(ZTry Try)
        {
            Try.Body = this.VisitBlock(Try.Body);

            WithList newCatchers = new WithList();

            for (int i = 0, n = Try.Catchers.Length; i < n; i++)
                newCatchers.Add(this.VisitWith(Try.Catchers[i]));

            Try.Catchers = newCatchers;

            return Try;
        }
Beispiel #3
0
        private ZTry VisitZTry(ZTry Try)
        {
            BasicBlock testerChain = null;

            //
            // Build a sequence of basic blocks to test the thrown exception type
            // and dispatch it to the appropriate handler. Check first to see if
            // a default handler is provided. If not, we need to create one here
            // and fall through to it if no matching handler is found.
            //
            if (Try.Catchers.Length > 0 && Try.Catchers[Try.Catchers.Length - 1].Name != null)
            {
                // No default handler, so we need to put a default of our
                // own in place to rethrow the exception. If we have an
                // outer exception context in this method, then we can
                // simply transfer control there. Otherwise, we need to
                // emit a block to make the runtime pass it up the stack.
                BasicBlock defaultHandler = null;
                if (this.CurrentHandlerBlock != null)
                {
                    // Empty block just transfers control to the outer handler
                    defaultHandler = new BasicBlock(null, this.CurrentHandlerBlock);
                }
                else
                {
                    defaultHandler = new BasicBlock(Templates.GetStatementTemplate("PropagateException"));
                    defaultHandler.PropagatesException = true;
                }
                defaultHandler.MiddleOfTransition = true;
                defaultHandler.SkipNormalizer = true;
                AddBlock(defaultHandler);
                testerChain = defaultHandler;
            }

            //
            // We traverse the list of catchers in reverse order to make
            // sure the default "with" (if any) is handled first, as it's
            // guaranteed (by the parser) to be the last one in the list.
            //
            for (int i = Try.Catchers.Length - 1; i >= 0; i--)
            {
                With with = Try.Catchers[i];

                this.PushContinuationStack();
                this.Visit(with.Block);
                BasicBlock catchBody = this.PopContinuationStack();

                if (!this.insideAtomicBlock)
                {
                    // If we aren't inside an atomic block, then we need an extra block
                    // between the tester and the body of the specific handler. All of
                    // the blocks involved in testing the exception are connected in
                    // an atomic way. If the handler isn't also going to be reached
                    // atomically, then we need an extra block with a non-atomic link
                    // to the body.
                    BasicBlock bodyConnector = new BasicBlock(null, catchBody);
                    AddBlock(bodyConnector);
                    catchBody = bodyConnector;
                }

                BasicBlock catchTester = new BasicBlock(null);

                if (with.Name != null)
                {
                    Expression catchTestExpr = Templates.GetExpressionTemplate("CatchTest");
                    Replacer.Replace(catchTestExpr, "_exception", (Expression)with.Name);
                    catchTester.ConditionalExpression = catchTestExpr;
                    catchTester.ConditionalTarget = catchBody;
                    catchTester.UnconditionalTarget = testerChain;
                }
                else
                {
                    // We're the default catch clause, so no test is necessary.
                    catchTester.UnconditionalTarget = catchBody;
                }
                catchTester.SkipNormalizer = true;
                catchTester.MiddleOfTransition = true;
                AddBlock(catchTester);

                // We just linked the new tester to the front of the tester chain.
                // This tester becomes the new head.
                testerChain = catchTester;
            }

            // All of the catch handlers are in place. Add a statement to the first handler
            // to reset the current handler block. If there's an outer scope, we point there.
            // If not, we point to "None".
            if (testerChain == null)        // could be null if all handlers had syntax errors
                return Try;

            testerChain.Statement = Templates.GetStatementTemplate("SetHandler");
            if (CurrentHandlerBlock != null)
            {
                Replacer.Replace(testerChain.Statement, "_blockName", new Identifier(CurrentHandlerBlock.Name));
                testerChain.handlerTarget = CurrentHandlerBlock;
            }
            else
                Replacer.Replace(testerChain.Statement, "_blockName", new Identifier("None"));

            // Now begin processing the body of the try block. Push the exception context
            // before starting.
            this.PushExceptionContext(testerChain);

            this.Visit(Try.Body);

            // Now create a basic block to establish the current handler as we enter the
            // body of the "try".
            Statement setHandlerStmt = Templates.GetStatementTemplate("SetHandler");
            Replacer.Replace(setHandlerStmt, "_blockName",
                             new Identifier(CurrentHandlerBlock.Name));
            BasicBlock setHandler = new BasicBlock(setHandlerStmt, CurrentContinuation);
            setHandler.MiddleOfTransition = true;
            setHandler.SkipNormalizer = true;
            setHandler.handlerTarget = CurrentHandlerBlock;
            AddBlock(setHandler);
            CurrentContinuation = setHandler;

            this.PopExceptionContext();

            return Try;
        }
Beispiel #4
0
        private ZTry VisitZTry(ZTry Try)
        {
            if (Try == null) return null;
            ZTry result = (ZTry)Try.Clone();

            result.Body = this.VisitBlock(Try.Body);
            result.Catchers = new WithList();

            for (int i = 0, n = Try.Catchers.Length; i < n; i++)
                result.Catchers.Add(this.VisitWith(Try.Catchers[i]));

            return result;
        }
Beispiel #5
0
        private ZTry VisitZTry(ZTry Try)
        {
            if (Try == null) return null;

            Try.Body = this.VisitBlock(Try.Body);

            for (int i = 0, n = Try.Catchers.Length; i < n; i++)
                Try.Catchers[i] = this.VisitWith(Try.Catchers[i]);

            return Try;
        }