Example #1
0
        private void AddBlockMethod(ZMethod zMethod, Class methodClass, BasicBlock block, List<Scope> nonTrivialScopes)
        {
            Method blockMethod = (Method)Templates.GetTypeTemplateByName("BlockMethod").Members[0];
            blockMethod.Name = new Identifier(block.Name);
            methodClass.Members.Add(blockMethod);
            blockMethod.DeclaringType = methodClass;

            // Generate the appropriate closing statements for the block. Indicate if the
            // block terminates an atomic region and establish the transfer of control to
            // the next block(s) or out of the method.

            if ((ZingCompilerOptions.IsPreemtive && !block.MiddleOfTransition && !block.IsReturn) || (block.Yields))
            {
                // p.MiddleOfTransition = false;
                blockMethod.Body.Statements.Add(
                    new ExpressionStatement(
                        new AssignmentExpression(
                            new AssignmentStatement(
                                new QualifiedIdentifier(Identifier.For("p"), Identifier.For("MiddleOfTransition")),
                                new Literal(false, SystemTypes.Boolean)
                            )
                        )
                    )
                );
            }

            // p.AtomicityLevel = this.SavedAtomicityLevel + X;
            blockMethod.Body.Statements.Add(
                new ExpressionStatement(
                    new AssignmentExpression(
                        new AssignmentStatement(
                            new QualifiedIdentifier(Identifier.For("p"), Identifier.For("AtomicityLevel")),
                            new BinaryExpression(
                                new QualifiedIdentifier(new This(), Identifier.For("SavedAtomicityLevel")),
                                new Literal(block.RelativeAtomicLevel, SystemTypes.Int32),
                                NodeType.Add
                            )
                        )
                    )
                )
            );

            #if false
            //
            // The following code was added for summarization, but isn't quite right. It
            // updates the nextBlock too early for some blocks. -- Tony
            //
            //
            // when generating summaries of type MaxCall, we need to
            // know the value of nextBlock before we invoke p.Call().
            // the first of the two basic blocks of a Zing method call
            // is guaranteed to fall through, so we only need to lift
            // the assignment of nextBlock for fall-through blocks.
            if (block.ConditionalTarget == null && block.UnconditionalTarget != null)
            {
                stmt = Templates.GetStatementTemplate("UnconditionalBlockTransfer");
                Replacer.Replace(stmt, "_UnconditionalBlock",
                                 new Identifier(block.UnconditionalTarget.Name));
                blockMethod.Body.Statements.Add(stmt);
            }
            #endif

            if (block.Attributes != null)
            {
                Duplicator duplicator = new Duplicator(null, null);

                for (int i = 0, n = block.Attributes.Count; i < n; i++)
                {
                    if (block.Attributes[i] == null)
                        continue;

                    AttributeNode dupAttr = duplicator.VisitAttributeNode(block.Attributes[i]);

                    Normalizer normalizer = new Normalizer(false);
                    ExpressionList attrParams = normalizer.VisitExpressionList(dupAttr.Expressions);

                    // application.Trace(_context, _contextAttr, new Z.Attributes._attrName(...) );
                    ExpressionStatement traceStmt = new ExpressionStatement(
                        new MethodCall(
                            new QualifiedIdentifier(Identifier.For("application"), Identifier.For("Trace")),
                            new ExpressionList(
                                SourceContextConstructor(dupAttr.SourceContext),
                                new Literal(null, SystemTypes.Object),
                                new Construct(
                                    new MemberBinding(
                                        null,
                                        new TypeExpression(
                                            new QualifiedIdentifier(
                                                new QualifiedIdentifier(Identifier.For("Z"), Identifier.For("Attributes")),
                                                dupAttr.Type.Name
                                            )
                                        )
                                    ),
                                    attrParams
                                )
                            )
                        )
                    );
                    blockMethod.Body.Statements.Add(traceStmt);
                }
            }

            if (block.Statement != null)
            {
                if (block.SkipNormalizer)
                    blockMethod.Body.Statements.Add(block.Statement);
                else
                {
                    // Do statement-level code-gen pass on the block's statement
                    Normalizer normalizer = new Normalizer(this, block.Attributes, block.SecondOfTwo);

                    blockMethod.Body.Statements.Add((Statement)normalizer.Visit(block.Statement));
                }
            }

            if (block.ConditionalTarget != null && block.ConditionalExpression != null)
            {
                Block trueBlock, falseBlock;

                // if (_conditionalExpression)
                //     nextBlock = Blocks._conditionalTarget;
                // else
                //     nextBlock = Blocks._unconditionalTarget;
                blockMethod.Body.Statements.Add(
                    new If(
                        block.ConditionalExpression,
                        trueBlock = new Block(new StatementList(
                            new ExpressionStatement(
                                new AssignmentExpression(
                                    new AssignmentStatement(
                                        Identifier.For("nextBlock"),
                                        new QualifiedIdentifier(
                                            Identifier.For("Blocks"),
                                            Identifier.For(block.ConditionalTarget.Name)
                                        )
                                    )
                                )
                            )
                        )),
                        falseBlock = new Block(new StatementList(
                            new ExpressionStatement(
                                new AssignmentExpression(
                                    new AssignmentStatement(
                                        Identifier.For("nextBlock"),
                                        new QualifiedIdentifier(
                                            Identifier.For("Blocks"),
                                            Identifier.For(block.UnconditionalTarget.Name)
                                        )
                                    )
                                )
                            )
                        ))
                    )
                );

                AddScopeCleanupCalls(trueBlock.Statements, block, block.ConditionalTarget, nonTrivialScopes);
                AddScopeCleanupCalls(falseBlock.Statements, block, block.UnconditionalTarget, nonTrivialScopes);
            }
            else if (block.UnconditionalTarget != null)
            {
                // nextBlock = Blocks.X;
                blockMethod.Body.Statements.Add(
                    new ExpressionStatement(
                        new AssignmentExpression(
                            new AssignmentStatement(
                                Identifier.For("nextBlock"),
                                new QualifiedIdentifier(Identifier.For("Blocks"), Identifier.For(block.UnconditionalTarget.Name))
                            )
                        )
                    )
                );
                AddScopeCleanupCalls(blockMethod.Body.Statements, block, block.UnconditionalTarget, nonTrivialScopes);
            }
            else if (block.IsReturn)
            {
                Debug.Assert(block.UnconditionalTarget == null);

                Statement returnCall = Templates.GetStatementTemplate("ReturnBlockTransfer");
                SourceContext context;
                Return ret = block.Statement as Return;
                if (ret != null)
                {
                    context = ret.SourceContext;
                }
                else
                {
                    // If not a return stmt, the context is the closing brace of the method
                    context = zMethod.SourceContext;
                    context.StartPos = context.EndPos - 1;
                }

                Replacer.Replace(returnCall, "_context", SourceContextConstructor(context));
                Replacer.Replace(returnCall, "_contextAttr", ContextAttributeConstructor(block.Attributes));

                blockMethod.Body.Statements.Add(returnCall);

                // StateImpl.IsReturn = true;
                blockMethod.Body.Statements.Add(
                    new ExpressionStatement(
                        new AssignmentExpression(
                            new AssignmentStatement(
                                new QualifiedIdentifier(Identifier.For("StateImpl"), Identifier.For("IsReturn")),
                                new Literal(true, SystemTypes.Boolean)
                            )
                        )
                    )
                );
            }
        }
Example #2
0
        internal Expression ContextAttributeConstructor(AttributeList attrs)
        {
            AttributeNode contextAttr = this.GetContextAttribute(attrs);

            if (contextAttr == null)
                return new Literal(null, SystemTypes.Object);

            Duplicator duplicator = new Duplicator(null, null);
            AttributeNode dupAttr = duplicator.VisitAttributeNode(contextAttr);

            Construct cons = (Construct)Templates.GetExpressionTemplate("ContextAttributeConstructor");

            Replacer.Replace(cons, "_AttributeName", dupAttr.Type.Name);

            Normalizer normalizer = new Normalizer(false);
            cons.Operands = normalizer.VisitExpressionList(dupAttr.Expressions);

            return cons;
        }