Inheritance: System.Compiler.Method
Example #1
0
        private Class GenerateClassMethod(ZMethod zMethod, Interface x)
        {
            this.currentMethod = zMethod;
            Class newClass = (Class)Templates.GetTypeTemplateByName("ClassMethod");
            QualifiedIdentifier qi = (x == null)
                                     ? new QualifiedIdentifier(new Identifier("Z"), new Identifier("ZingMethod"))
                                     : new QualifiedIdentifier(x.Name, zMethod.Name);
            Replacer.Replace(newClass, new Identifier("__Method"), qi);

            if (x == null)
            {
                if (!zMethod.IsStatic)
                    GenerateThisParameter(newClass);
                Class interfaceClass = (Class)Templates.GetTypeTemplateByName("InterfaceMethod");
                for (int i = 0, n = interfaceClass.Members.Count; i < n; i++)
                {
                    newClass.Members.Add(interfaceClass.Members[i]);
                    interfaceClass.Members[i].DeclaringType = newClass;
                }

                Class inputsClass = (Class)Templates.GetMemberByName(newClass.Members, "InputVars");
                GenerateInputs(zMethod, inputsClass);

                Class outputsClass = (Class)Templates.GetMemberByName(newClass.Members, "OutputVars");
                GenerateOutputs(zMethod, outputsClass);
            }

            Class localsClass = (Class)Templates.GetMemberByName(newClass.Members, "LocalVars");
            GenerateLocals(zMethod, localsClass);

            Class extras = (Class)Templates.GetTypeTemplateByName(zMethod.IsStatic
                                         ? "StaticMethodExtras"
                                         : "InstanceMethodExtras");
            for (int i = 0, n = extras.Members.Count; i < n; i++)
            {
                newClass.Members.Add(extras.Members[i]);
                extras.Members[i].DeclaringType = newClass;
                Property p = extras.Members[i] as Property;

                if (p != null)
                {
                    if (p.Getter != null)
                        p.Getter.DeclaringType = newClass;
                    if (p.Setter != null)
                        p.Setter.DeclaringType = newClass;
                }
            }

            Replacer.Replace(newClass, newClass.Name, zMethod.Name);
            SetTypeId(newClass);

            ExtendMethodConstructor(newClass, zMethod);

            // If this method doesn't return concrete bool, then remove the helper
            // property for accessing bool return values.
            if (zMethod.ReturnType == SystemTypes.Boolean)
            {
                Property boolRetValProp = (Property)Templates.GetTypeTemplateByName("BooleanReturnValueProperty").Members[0];
                newClass.Members.Add(boolRetValProp);
                boolRetValProp.DeclaringType = newClass;
                newClass.Members.Add(boolRetValProp.Getter);
                boolRetValProp.Getter.DeclaringType = newClass;
            }

            // Clear the "Activated" attribute if we aren't...
            if (!zMethod.Activated)
                newClass.Attributes = new AttributeList(0);

            GenerateBasicBlocks(newClass, zMethod);
            this.currentMethod = null;

            return newClass;
        }
Example #2
0
        //
        // This is the primary entry point into BBSplitter. This is called from the
        // Splicer to do basic block analysis before using the Normalizer to do code-gen
        // for each basic block.
        //
        public static List<BasicBlock> SplitMethod(ZMethod method, Splicer splicer)
        {
            BBSplitter splitter = new BBSplitter(splicer);

            splitter.atomicBranches = new List<BasicBlock>();
            splitter.scopeStack.Push(method.Body.Scope);

            BasicBlock finalBlock = splitter.AddBlock(new BasicBlock(null));

            if (method.Atomic)
            {
                //
                // For summarization, we need for atomic methods to have an "extra"
                // terminating block. This corresponds to what happens in VisitAtomic
                // for regular atomic blocks.
                //
                finalBlock = splitter.AddBlock(new BasicBlock(null, finalBlock));
                finalBlock.MiddleOfTransition = true;

                splitter.insideAtomicBlock = true;
            }

            splitter.PushContinuationStack(finalBlock);

            splitter.VisitStatementList(method.Body.Statements);

            // For each branch within the atomic block, we need to look at the target
            // and see if it too is within an atomic block (by definition, the same
            // one). If not, then we need to make the branch's block be the effective
            // end of the atomic execution. We can do this by resetting its atomicity
            // level
            foreach (BasicBlock b in splitter.atomicBranches)
            {
                // The actual branch target is two blocks away because branch targets
                // always introduce an extra block that flow atomically into "real" code.
                BasicBlock branchTarget;
                if (b.UnconditionalTarget.IsReturn)
                    continue;

                Debug.Assert(b.UnconditionalTarget.UnconditionalTarget != null);
                branchTarget = b.UnconditionalTarget.UnconditionalTarget;

                // If the target isn't atomic, then we need to introduce an interleaving
                // just after the branch. We do this by forcing it to be the end of
                // the atomic block.  We must also make sure such a block cannot be the entry
                // point of the atomic block.
                if (branchTarget.RelativeAtomicLevel == 0)
                {
                    b.RelativeAtomicLevel = 0;
                    b.IsAtomicEntry = false;
                }
            }

            BasicBlock firstBlock = splitter.PopContinuationStack();

            firstBlock.IsEntryPoint = true;
            if (firstBlock.RelativeAtomicLevel > 0)
                firstBlock.IsAtomicEntry = true;

            return splitter.blockList;
        }
Example #3
0
 private InterfaceList FindMatchingInterfaces(Class c, ZMethod zMethod)
 {
     InterfaceList matches = new InterfaceList(1);
     if (c.Interfaces != null && c.Interfaces.Count > 0)
     {
         for (int i = 0; i < c.Interfaces.Count; i++)
         {
             Interface x = c.Interfaces[i];
             if (x.GetMatchingMethod(zMethod) != null)
                 matches.Add(x);
         }
     }
     return matches;
 }
Example #4
0
        private void GenerateBasicBlocks(Class newClass, ZMethod zMethod)
        {
            //
            // Split the method into basic blocks, and then do code generation
            // based on this analysis
            //
            if (labelString != null)
                basicBlockToLabel = new Hashtable();
            List<BasicBlock> basicBlocks = BBSplitter.SplitMethod(zMethod, this);
            if (labelString != null)
            {
                string methodName = zMethod.FullName;
                int index = methodName.IndexOf('(');
                if (index < 0)
                    AddToLabelString(methodName);
                else
                {
                    Debug.Assert(index > 0);
                    AddToLabelString(methodName.Substring(0, index));
                }
            }

            //
            // Look for opportunities to combine or remove blocks
            //
            // NOTE: this breaks summarization because it removes "transition" blocks
            // around atomic regions that they rely on.
            //
            //basicBlocks = BBOptimizer.Optimize(basicBlocks);

            EnumNode enumNode = (EnumNode)Templates.GetMemberByName(newClass.Members, "Blocks");
            Field entryPointField = (Field)enumNode.Members[1];
            int nextBlockEnumValue = 2;

            // Accumulate a list of scopes for which we've generated cleanup methods. These are
            // scopes that contain pointers.
            List<Scope> nonTrivialScopes = new List<Scope>();
            foreach (BasicBlock block in basicBlocks)
            {
                if (!nonTrivialScopes.Contains(block.Scope) && ScopeNeedsCleanup(block.Scope))
                {
                    nonTrivialScopes.Add(block.Scope);
                    AddScopeCleanupMethod(newClass, block.Scope);
                }
            }

            foreach (BasicBlock block in basicBlocks)
            {
                // Add the blocks to the Blocks enum
                if (!block.IsEntryPoint)
                {
                    Field f = new Field(enumNode, null, entryPointField.Flags,
                        new Identifier(block.Name), entryPointField.Type, null);
                    f.Initializer = new Literal(nextBlockEnumValue++, SystemTypes.UInt16);
                    enumNode.Members.Add(f);
                }

                // Emit a method for this block
                AddBlockMethod(zMethod, newClass, block, nonTrivialScopes);
            }

            PatchDispatchMethod(newClass, basicBlocks);
            PatchRunnableMethod(newClass, basicBlocks);
            PatchIsAtomicEntryMethod(newClass, basicBlocks);
            PatchValidEndStateProperty(newClass, basicBlocks);
            PatchSourceContextProperty(zMethod, newClass, basicBlocks);
            PatchContextAttributeProperty(zMethod, newClass, basicBlocks);
        }
Example #5
0
        private void PatchSourceContextProperty(ZMethod zMethod, Class methodClass, List<BasicBlock> basicBlocks)
        {
            Property contextProperty = (Property)Templates.GetMemberByName(methodClass.Members, "Context");
            Method contextMethod = contextProperty.Getter;
            Debug.Assert(contextMethod.Body.Statements[0] is System.Compiler.Switch);
            System.Compiler.Switch switchStmt = (System.Compiler.Switch)contextMethod.Body.Statements[0];

            foreach (BasicBlock block in basicBlocks)
            {
                SourceContext ctxt = new SourceContext(null, 0, 0);

                //ctxt.Document = null;
                //ctxt.StartPos = 0;
                //ctxt.EndPos = 0;

                if (block.SourceContext.StartPos != 0 || block.SourceContext.EndPos != 0)
                {
                    // If the block says something explicit about its context, take that
                    // as final.
                    ctxt = block.SourceContext;
                }
                else
                {
                    // The block doesn't say anything, so figure it out from the statements
                    // inside the block.

                    BasicBlock effectiveBlock = block;
                    //
                    // If we only fall through to another BB without any executable code,
                    // conditional branching, interleaving, or return - then consider our
                    // source context to be the next "real" thing that happens.
                    //
                    while ((effectiveBlock.Statement == null || effectiveBlock.SkipNormalizer) &&
                        effectiveBlock.ConditionalExpression == null &&
                        effectiveBlock.SourceContext.SourceText == null &&
                        effectiveBlock.MiddleOfTransition &&
                        !effectiveBlock.IsReturn && !effectiveBlock.PropagatesException)
                    {
                        effectiveBlock = effectiveBlock.UnconditionalTarget;
                    }

                    // See which source context is the most appropriate for this block.
                    if (effectiveBlock.Statement != null)
                    {
                        if (effectiveBlock.Statement.SourceContext.SourceText != null)
                            ctxt = effectiveBlock.Statement.SourceContext;
                        else
                        {
                            Block b = effectiveBlock.Statement as Block;
                            if (b != null)
                            {
                                for (int i = 0, n = b.Statements.Count; i < n; i++)
                                {
                                    if (b.Statements[i] != null)
                                    {
                                        ctxt = b.Statements[i].SourceContext;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else if (effectiveBlock.ConditionalExpression != null)
                        ctxt = effectiveBlock.ConditionalExpression.SourceContext;
                    else if (effectiveBlock.SourceContext.SourceText != null)
                        ctxt = effectiveBlock.SourceContext;
                    else
                    {
                        // For "return" blocks, show the closing brace as the source context.
                        ctxt.Document = zMethod.SourceContext.Document;
                        ctxt.EndPos = zMethod.SourceContext.EndPos;
                        ctxt.StartPos = ctxt.EndPos - 1;
                    }
                }

                if (ctxt.StartPos < 0)
                    ctxt.StartPos = 0;

                SwitchCase newCase = new SwitchCase(
                    new QualifiedIdentifier(Identifier.For("Blocks"), Identifier.For(block.Name)),
                    new Block(new StatementList(
                        new Return(SourceContextConstructor(ctxt))))
                    );

                switchStmt.Cases.Add(newCase);
            }
        }
Example #6
0
        // Create a secondary constructor that provides for initialization of
        // the "this" pointer as well as the input parameters
        private void ExtendMethodConstructor(Class newClass, ZMethod zMethod)
        {
            int numAddedParams = 0;

            // Duplicate our basic constructor so we can make an extended version
            System.Compiler.Duplicator dup = new System.Compiler.Duplicator(null, null);
            InstanceInitializer ctor = dup.VisitInstanceInitializer((InstanceInitializer)newClass.Members[0]);

            if (!zMethod.IsStatic)
            {
                // For instance methods, add a "This" parameter to the constructor
                ctor.Parameters.Add(new Parameter(Identifier.For("This"), new TypeExpression(Identifier.For("Pointer"))));

                // this.This = This;
                ctor.Body.Statements.Add(
                    new ExpressionStatement(
                        new AssignmentExpression(
                            new AssignmentStatement(
                                new QualifiedIdentifier(new This(), Identifier.For("This")),
                                Identifier.For("This"))))
                );

                numAddedParams++;
            }

            for (int i = 0, n = zMethod.Parameters.Count; i < n; i++)
            {
                TypeNode paramType;
                Parameter param = zMethod.Parameters[i];

                if (param == null || param.Type == null)
                    continue;

                if (param.IsOut)
                    continue;

                if (GetTypeClassification(param.Type) == TypeClassification.Heap)
                    paramType = this.ZingPtrType;
                else if (!IsPredefinedType(param.Type))
                    paramType = new TypeExpression(new QualifiedIdentifier(
                        new Identifier("Application"), param.Type.Name));
                else
                    paramType = param.Type;

                ctor.Parameters.Add(new Parameter(param.Name, paramType));
                // inputs.foo = foo;
                ctor.Body.Statements.Add(
                    new ExpressionStatement(
                        new AssignmentExpression(
                            new AssignmentStatement(
                                new QualifiedIdentifier(Identifier.For("inputs"), param.Name),
                                param.Name)))
                    );

                numAddedParams++;
            }

            // If we didn't actually add any parameters, then the basic constructor is
            // all that we need. Only add the new constructor if it's different.
            if (numAddedParams > 0)
            {
                newClass.Members.Add(ctor);
                ctor.DeclaringType = newClass;
            }
        }
Example #7
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 #8
0
        private void PatchContextAttributeProperty(ZMethod zMethod, Class methodClass, List<BasicBlock> basicBlocks)
        {
            Property contextProperty = (Property)Templates.GetMemberByName(methodClass.Members, "ContextAttribute");
            Method contextMethod = contextProperty.Getter;
            Debug.Assert(contextMethod.Body.Statements[0] is System.Compiler.Switch);
            System.Compiler.Switch switchStmt = (System.Compiler.Switch)contextMethod.Body.Statements[0];

            foreach (BasicBlock block in basicBlocks)
            {
                AttributeNode contextAttr = GetContextAttribute(block.Attributes);

                if (contextAttr == null)
                    continue;               // no context attribute found

                SwitchCase newCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("ContextAttributeSwitch")).Cases[0];
                Replacer.Replace(newCase, "_BlockName", new Identifier(block.Name));

                // TODO: for user-defined attributes, we'll need to construct a qualified identifier here
                Replacer.Replace(newCase, "_AttributeName", contextAttr.Type.Name);

                // Patch the selected context columns into the constructor template
                Return ret = (Return)newCase.Body.Statements[0];
                Construct cons = (Construct)ret.Expression;
                cons.Operands = contextAttr.Expressions;

                switchStmt.Cases.Add(newCase);
            }
        }
Example #9
0
        private void GenerateOutputs(ZMethod zMethod, Class outputsClass)
        {
            List<Field> outputs = new List<Field>(10);

            Method outputsGetValue = (Method)Templates.GetMemberByName(outputsClass.Members, "GetValue");
            Method outputsSetValue = (Method)Templates.GetMemberByName(outputsClass.Members, "SetValue");
            System.Compiler.Switch switchOutputsGetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch");
            outputsGetValue.Body.Statements.Add(switchOutputsGetValue);
            System.Compiler.Switch switchOutputsSetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch");
            outputsSetValue.Body.Statements.Add(switchOutputsSetValue);
            Method copier = (Method)Templates.GetMemberByName(outputsClass.Members, "CopyContents");

            // Create fields in Inputs or Outputs for the parameters
            for (int i = 0, n = zMethod.Parameters.Count; i < n; i++)
            {
                Parameter param = zMethod.Parameters[i];
                if (param == null || param.Type == null || (param.Flags & ParameterFlags.Out) == 0)
                    continue;

                TypeNode zingType = param.Type;

                zingType = ((Reference)zingType).ElementType;

                Field f = new Field(outputsClass, null, FieldFlags.Public,
                    new Identifier("priv_" + param.Name.Name),
                    param.Type, null);

                if (f.Type is Reference)
                    f.Type = ((Reference)f.Type).ElementType;

                if (GetTypeClassification(f.Type) == TypeClassification.Heap)
                {
                    f.Type = this.ZingPtrType;
                }
                else if (!IsPredefinedType(f.Type))
                    f.Type = new TypeExpression(new QualifiedIdentifier(
                        new Identifier("Application"), zingType.Name), zingType.SourceContext);

                Identifier idFieldName = new Identifier("id_" + param.Name.Name);
                Field idf = new Field(outputsClass, null, FieldFlags.Public | FieldFlags.Static,
                    idFieldName,
                    SystemTypes.Int32, null);
                idf.Initializer = new Literal(i, SystemTypes.Int32);

                SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0];
                Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(getCase, "_fieldName", new Identifier(f.Name.Name));
                switchOutputsGetValue.Cases.Add(getCase);

                SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0];
                Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(setCase, "_fieldName", new Identifier(f.Name.Name));
                TypeExpression tn = f.Type as TypeExpression;
                Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name));
                switchOutputsSetValue.Cases.Add(setCase);

                QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Output"));

                Property accessor = GetAccessorProperty("outputAccessor", f.Type, param.Name, f.Name, idf.Name, localInputOrOutput);

                outputsClass.Members.Add(f);
                outputsClass.Members.Add(idf);
                outputsClass.Members.Add(accessor);
                f.DeclaringType = outputsClass;
                idf.DeclaringType = outputsClass;
                accessor.DeclaringType = outputsClass;
                if (accessor.Getter != null)
                {
                    outputsClass.Members.Add(accessor.Getter);
                    accessor.Getter.DeclaringType = outputsClass;
                }
                if (accessor.Setter != null)
                {
                    outputsClass.Members.Add(accessor.Setter);
                    accessor.Setter.DeclaringType = outputsClass;
                }

                //for outputs create an additional lastfunction accessor
                QualifiedIdentifier lfcOutput =
                    new QualifiedIdentifier(new Identifier("LocType"), new Identifier("LastFunctionOutput"));

                Identifier lfcid = new Identifier("_Lfc_" + param.Name.Name);

                Property lfcAccessor = GetAccessorProperty("lastFunctionOutputAccessor", f.Type,
                    lfcid, f.Name, idf.Name, lfcOutput);
                outputsClass.Members.Add(lfcAccessor);
                lfcAccessor.DeclaringType = outputsClass;
                if (lfcAccessor.Getter != null)
                {
                    outputsClass.Members.Add(lfcAccessor.Getter);
                    lfcAccessor.Getter.DeclaringType = outputsClass;
                }

                if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal)
                    collectStructAccessors(false, (Struct)zingType, f.Name,
                        param.Name.Name, outputsClass);

                copier.Body.Statements.Add(GetCopyStatement(f.Name));
                outputs.Add(f);
            }

            if (zMethod.ReturnType.TypeCode != TypeCode.Empty)
            {
                Field f = new Field(outputsClass, null, FieldFlags.Public,
                                    new Identifier("priv_ReturnValue"),
                                    zMethod.ReturnType, null);

                QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Output"));

                TypeNode zingType = zMethod.ReturnType;

                if (GetTypeClassification(f.Type) == TypeClassification.Heap)
                {
                    f.Type = this.ZingPtrType;
                }
                else if (!IsPredefinedType(f.Type))
                {
                    f.Type = new TypeExpression(new QualifiedIdentifier(
                        new Identifier("Application"), zingType.Name), zingType.SourceContext);
                }

                Identifier idFieldName = new Identifier("id_ReturnValue");
                Field idf = new Field(outputsClass, null, FieldFlags.Public | FieldFlags.Static,
                    idFieldName,
                    SystemTypes.Int32, null);
                idf.Initializer = new Literal(zMethod.Parameters.Count, SystemTypes.Int32);

                SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0];
                Replacer.Replace(getCase, "_fieldId", new Literal(zMethod.Parameters.Count, SystemTypes.Int32));
                Replacer.Replace(getCase, "_fieldName", new Identifier("priv_ReturnValue"));
                switchOutputsGetValue.Cases.Add(getCase);

                SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0];
                Replacer.Replace(setCase, "_fieldId", new Literal(zMethod.Parameters.Count, SystemTypes.Int32));
                Replacer.Replace(setCase, "_fieldName", new Identifier("priv_ReturnValue"));
                TypeExpression tn = f.Type as TypeExpression;
                Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name));
                switchOutputsSetValue.Cases.Add(setCase);

                Property accessor = GetAccessorProperty("outputAccessor", f.Type,
                                                        new Identifier("_ReturnValue"),
                                                        f.Name, idf.Name, localInputOrOutput);

                QualifiedIdentifier lfcOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("LastFunctionOutput"));

                Property lfcAccessor = GetAccessorProperty("lastFunctionOutputAccessor", f.Type,
                                                           new Identifier("_Lfc_ReturnValue"),
                                                           f.Name, idf.Name, lfcOutput);

                Identifier qualifier = new Identifier("outputs");

                outputsClass.Members.Add(f);
                outputsClass.Members.Add(idf);
                outputsClass.Members.Add(accessor);
                outputsClass.Members.Add(lfcAccessor);
                f.DeclaringType = outputsClass;
                idf.DeclaringType = outputsClass;
                accessor.DeclaringType = outputsClass;
                lfcAccessor.DeclaringType = outputsClass;

                if (accessor.Getter != null)
                {
                    outputsClass.Members.Add(accessor.Getter);
                    accessor.Getter.DeclaringType = outputsClass;
                }
                if (accessor.Setter != null)
                {
                    outputsClass.Members.Add(accessor.Setter);
                    accessor.Setter.DeclaringType = outputsClass;
                }
                if (lfcAccessor.Getter != null)
                {
                    outputsClass.Members.Add(lfcAccessor.Getter);
                    lfcAccessor.Getter.DeclaringType = outputsClass;
                }

                if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal)
                {
                    collectStructAccessors(false, (Struct)zingType, f.Name,
                        "_ReturnValue", outputsClass);
                    collectStructAccessors(false, (Struct)zingType, f.Name,
                        "_Lfc_ReturnValue", outputsClass);
                }

                copier.Body.Statements.Add(GetCopyStatement(f.Name));
                outputs.Add(f);
            }

            Method writer = (Method)Templates.GetMemberByName(outputsClass.Members, "WriteString");
            Method traverser = (Method)Templates.GetMemberByName(outputsClass.Members, "TraverseFields");

            for (int i = 0, n = outputs.Count; i < n; i++)
            {
                Field f = (Field)outputs[i];
                writer.Body.Statements.Add
                    (GetWriterStatement("this", f.Type, f.Name));
                traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, f.Name));
            }
        }
Example #10
0
        private void GenerateLocals(ZMethod zMethod, Class localsClass)
        {
            List<Field> locals = new List<Field>(10);

            Method localsGetValue = (Method)Templates.GetMemberByName(localsClass.Members, "GetValue");
            Method localsSetValue = (Method)Templates.GetMemberByName(localsClass.Members, "SetValue");
            System.Compiler.Switch switchLocalsGetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch");
            localsGetValue.Body.Statements.Add(switchLocalsGetValue);
            System.Compiler.Switch switchLocalsSetValue =
                (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch");
            localsSetValue.Body.Statements.Add(switchLocalsSetValue);
            Method copier = (Method)Templates.GetMemberByName(localsClass.Members, "CopyContents");

            for (int i = 0, n = zMethod.LocalVars.Count; i < n; i++)
            {
                Field localVar = zMethod.LocalVars[i];
                TypeNode zingType = localVar.Type;
                if (localVar.Type == null)
                    continue;

                Field f = new Field(localsClass, null, FieldFlags.Public,
                                    new Identifier("priv_" + localVar.Name.Name),
                                    localVar.Type, null);

                if (GetTypeClassification(f.Type) == TypeClassification.Heap)
                    f.Type = this.ZingPtrType;
                else if (!IsPredefinedType(f.Type))
                    f.Type = new TypeExpression(new QualifiedIdentifier(
                        new Identifier("Application"), zingType.Name), zingType.SourceContext);

                Identifier idFieldName = new Identifier("id_" + localVar.Name.Name);
                Field idf = new Field(localsClass, null, FieldFlags.Public | FieldFlags.Static,
                    idFieldName,
                    SystemTypes.Int32, null);
                idf.Initializer = new Literal(i, SystemTypes.Int32);
                SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0];
                Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(getCase, "_fieldName", new Identifier(f.Name.Name));
                switchLocalsGetValue.Cases.Add(getCase);

                SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0];
                Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32));
                Replacer.Replace(setCase, "_fieldName", new Identifier(f.Name.Name));
                TypeExpression tn = f.Type as TypeExpression;
                Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name));
                switchLocalsSetValue.Cases.Add(setCase);

                QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Local"));

                Property accessor = GetAccessorProperty("localAccessor", f.Type,
                                                        localVar.Name, f.Name, idf.Name, localInputOrOutput);

                Identifier qualifier = new Identifier("locals");

                localsClass.Members.Add(f);
                localsClass.Members.Add(idf);
                localsClass.Members.Add(accessor);
                f.DeclaringType = localsClass;
                idf.DeclaringType = localsClass;
                accessor.DeclaringType = localsClass;
                if (accessor.Getter != null)
                {
                    localsClass.Members.Add(accessor.Getter);
                    accessor.Getter.DeclaringType = localsClass;
                }
                if (accessor.Setter != null)
                {
                    localsClass.Members.Add(accessor.Setter);
                    accessor.Setter.DeclaringType = localsClass;
                }

                if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal)
                    collectStructAccessors(false, (Struct)zingType, f.Name,
                                           localVar.Name.Name, localsClass);

                copier.Body.Statements.Add(GetCopyStatement(f.Name));
                locals.Add(f);
            }

            Method writer = (Method)Templates.GetMemberByName(localsClass.Members, "WriteString");
            Method traverser = (Method)Templates.GetMemberByName(localsClass.Members, "TraverseFields");

            for (int i = 0, n = locals.Count; i < n; i++)
            {
                Field f = (Field)locals[i];
                writer.Body.Statements.Add(GetWriterStatement("this", f.Type, f.Name));
                traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, f.Name));
            }
        }
Example #11
0
        private Class GenerateInterfaceMethod(ZMethod zMethod)
        {
            this.currentMethod = zMethod;

            Class newClass = (Class)Templates.GetTypeTemplateByName("InterfaceMethod");

            Debug.Assert(!zMethod.IsStatic);
            GenerateThisParameter(newClass);

            Class inputsClass = (Class)Templates.GetMemberByName(newClass.Members, "InputVars");
            GenerateInputs(zMethod, inputsClass);

            Class outputsClass = (Class)Templates.GetMemberByName(newClass.Members, "OutputVars");
            GenerateOutputs(zMethod, outputsClass);

            Replacer.Replace(newClass, newClass.Name, zMethod.Name);

            // If this method doesn't return concrete bool, then remove the helper
            // property for accessing bool return values.
            if (zMethod.ReturnType == SystemTypes.Boolean)
            {
                Property boolRetValProp = (Property)Templates.GetTypeTemplateByName("BooleanReturnValueProperty").Members[0];
                newClass.Members.Add(boolRetValProp);
                boolRetValProp.DeclaringType = newClass;
                newClass.Members.Add(boolRetValProp.Getter);
                boolRetValProp.Getter.DeclaringType = newClass;
            }

            // Clear the "Activated" attribute if we aren't...
            if (!zMethod.Activated)
                newClass.Attributes = new AttributeList(0);

            this.currentMethod = null;

            return newClass;
        }