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) ) ) ) ); } }
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; }