示例#1
0
        // this method creates a new class for the given namespace
        public NamespaceTypeDefinition createNewClass(String className, IUnitNamespace containingUnitNamespace, bool isPublic,
                                                      bool isStatic)
        {
            // create a new class object
            NamespaceTypeDefinition newClass = new NamespaceTypeDefinition();

            newClass.ContainingUnitNamespace = containingUnitNamespace;
            newClass.InternFactory           = this.host.InternFactory;
            newClass.IsClass         = true;
            newClass.IsForeignObject = false;
            newClass.IsInterface     = false;
            newClass.IsPublic        = isPublic;
            newClass.IsStatic        = isStatic;
            newClass.Methods         = new List <IMethodDefinition>();
            newClass.Name            = this.host.NameTable.GetNameFor(className);

            // create list of base classes (only base class is System.Object)
            newClass.BaseClasses = new List <ITypeReference>();
            newClass.BaseClasses.Add(this.host.PlatformType.SystemObject);

            // add new class to module assembly
            Assembly tempAssembly = (Assembly)this.module;

            tempAssembly.AllTypes.Add(newClass);

            return(newClass);
        }
示例#2
0
        public NodeObject(int dimension, int validPathCount, NamespaceTypeDefinition thisClass, MethodDefinition constructorToUse, PathElement pathElement, List <int> positionInGraph)
        {
            // a list of possible objects in the graph that fulfill the needed attributes like this object
            this.possibleExchangeObjects = new List <NodeObject>();

            // a list of possible classes this object could made of
            this.possibleClasses = new List <NamespaceTypeDefinition>();

            // set the amount of child nodes this node object has
            this.dimension   = dimension;
            this.nodeObjects = new NodeObject[this.dimension];

            // class to use for this node object
            this.thisClass = thisClass;

            // constructor to use when a node for the graph is created
            this.constructorToUse = constructorToUse;

            // interfaces that this object represents (or not represents)
            this.pathElements.Add(pathElement);

            // set the maximum amount of valid paths that this node can be an element of
            // (in the list elementOfValidPath is the id of the valid path stored this element is a part of)
            this.validPathCount     = validPathCount;
            this.elementOfValidPath = new List <int>(this.validPathCount);

            // set the position of this node in the graph
            this.positionInGraph = positionInGraph;

            // null every object in the array
            for (int i = 0; i < this.dimension; i++)
            {
                this.nodeObjects[i] = null;
            }
        }
示例#3
0
        public NodeObject(int dimension, int validPathCount, NamespaceTypeDefinition thisClass, MethodDefinition constructorToUse, PathElement pathElement, List<int> positionInGraph) {

            // a list of possible objects in the graph that fulfill the needed attributes like this object
            this.possibleExchangeObjects = new List<NodeObject>();

            // a list of possible classes this object could made of
            this.possibleClasses = new List<NamespaceTypeDefinition>();

            // set the amount of child nodes this node object has
            this.dimension = dimension;
            this.nodeObjects = new NodeObject[this.dimension];

            // class to use for this node object
            this.thisClass = thisClass;

            // constructor to use when a node for the graph is created
            this.constructorToUse = constructorToUse;

            // interfaces that this object represents (or not represents)
            this.pathElements.Add(pathElement);

            // set the maximum amount of valid paths that this node can be an element of
            // (in the list elementOfValidPath is the id of the valid path stored this element is a part of)
            this.validPathCount = validPathCount;
            this.elementOfValidPath = new List<int>(this.validPathCount);

            // set the position of this node in the graph
            this.positionInGraph = positionInGraph;

            // null every object in the array
            for (int i = 0; i < this.dimension; i++) {
                this.nodeObjects[i] = null;
            }
        }
示例#4
0
        public override void RewriteChildren(NamespaceTypeDefinition namespaceTypeDefinition)
        {
            string  typeName       = Util.FullyQualifiedTypeNameFromType(namespaceTypeDefinition);
            Element currentElement = null;

            // Unlike all other types that visited from either a namespace or a parent,
            // the module type is visited from the containing module
            if (_systemTypes.Contains(typeName))
            {
                currentElement = new SpecialTrimType(typeName);
                _trimElements.Push(currentElement);
            }

            this.RewriteChildren((NamedTypeDefinition)namespaceTypeDefinition);
            //namespaceTypeDefinition.ContainingUnitNamespace = this.GetCurrentNamespace();

            if (!_systemTypes.Contains(typeName))
            {
                TypeElement type = _currentTrimAssembly.GetTypeElement(typeName);
                MutateType(namespaceTypeDefinition, type);
            }
            if (currentElement != null)
            {
                _trimElements.Pop();
            }
        }
示例#5
0
        public NodeObject(int dimension, int validPathCount, NamespaceTypeDefinition thisClass, MethodDefinition constructorToUse, PathElement pathElement, List<int> positionInGraph, int validPathId)
            : this(dimension, validPathCount, thisClass, constructorToUse, pathElement, positionInGraph) {

            // add the id of the valid path to the list
            this.elementOfValidPath.Add(validPathId);

        }
示例#6
0
        // this method creates a new method for the given class
        public MethodDefinition createNewMethod(String methodName, NamespaceTypeDefinition methodClass, ITypeReference methodType,
                                                TypeMemberVisibility methodVisibility, List <IParameterDefinition> methodParameters,
                                                CallingConvention methodCallingConvention, bool isStatic, bool isAbstract, bool isVirtual)
        {
            // create a new method
            MethodDefinition newMethod = new MethodDefinition();

            newMethod.ContainingTypeDefinition = methodClass;
            newMethod.InternFactory            = this.host.InternFactory;
            newMethod.IsCil             = true;
            newMethod.IsStatic          = isStatic;
            newMethod.Name              = this.host.NameTable.GetNameFor(methodName);
            newMethod.Type              = methodType;
            newMethod.Visibility        = methodVisibility;
            newMethod.IsAbstract        = isAbstract;
            newMethod.IsVirtual         = isVirtual;
            newMethod.Parameters        = methodParameters;
            newMethod.CallingConvention = methodCallingConvention;

            // add method to class
            if (methodClass.Methods == null)
            {
                methodClass.Methods = new List <IMethodDefinition>();
                methodClass.Methods.Add(newMethod);
            }
            else
            {
                methodClass.Methods.Add(newMethod);
            }

            return(newMethod);
        }
示例#7
0
        // TODO can we avoid visiting every type? Are there only a few, identifiable, types that may perform navigation?
        public override void TraverseChildren(ITypeDefinition typeDefinition)
        {
            typeBeingTraversed = typeDefinition;
            if (typeDefinition.isPhoneApplicationClass(host))
            {
                NamespaceTypeDefinition mutableTypeDef = typeDefinition as NamespaceTypeDefinition;
                if (mutableTypeDef != null)
                {
                    // TODO unify code for current uri fieldreference
                    FieldDefinition fieldDef = new FieldDefinition()
                    {
                        ContainingTypeDefinition = mutableTypeDef,
                        InternFactory            = host.InternFactory,
                        IsStatic   = true,
                        Name       = host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
                        Type       = host.PlatformType.SystemString,
                        Visibility = TypeMemberVisibility.Public,
                    };
                    PhoneCodeHelper.CurrentURIFieldDefinition = fieldDef;
                    mutableTypeDef.Fields.Add(fieldDef);
                }
            }

            codeTraverser.Traverse(typeDefinition);
            base.TraverseChildren(typeDefinition);
        }
示例#8
0
 /// <summary>
 /// Do not deeper if type is not allowed - (as requested on mutation testing start)
 /// </summary>
 /// <param name="namespaceTypeDefinition"></param>
 public override void RewriteChildren(NamespaceTypeDefinition namespaceTypeDefinition)
 {
     if (_filter.Matches(namespaceTypeDefinition))
     {
         base.RewriteChildren(namespaceTypeDefinition);
     }
 }
示例#9
0
        private INamedTypeDefinition GenerateTypeA(IUnitNamespace rootNamespace)
        {
            var nt    = Host.NameTable;
            var typeA = new NamespaceTypeDefinition
            {
                ContainingUnitNamespace = rootNamespace,
                Name          = nt.GetNameFor("A"),
                InternFactory = Host.InternFactory,
                IsClass       = true
            };
            var typeParameter = new GenericTypeParameter
            {
                Name          = nt.GetNameFor("T"),
                InternFactory = Host.InternFactory,
                DefiningType  = typeA,
            };

            typeA.GenericParameters.Add(typeParameter);

            var baseGetMethod = new MethodDefinition
            {
                Name       = nt.GetNameFor("Get"),
                IsCil      = true,
                IsVirtual  = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = typeParameter,
                ContainingTypeDefinition = typeA,
                InternFactory            = Host.InternFactory,
                IsNewSlot = true
            };

            typeA.Methods.Add(baseGetMethod);

            var il       = new ILGenerator(Host);
            var localVar = new LocalDefinition
            {
                Type = typeParameter,
                Name = nt.GetNameFor("local1"),
            };

            // tricky moment, ILGeneratorMethodBody fills internal collection of local vars only in constructor.
            // lines below should not be swapped

            il.AddVariableToCurrentScope(localVar);
            var body = new ILGeneratorMethodBody(il, true, 1)
            {
                MethodDefinition = baseGetMethod
            };

            baseGetMethod.Body = body;


            il.Emit(OperationCode.Ldloca, localVar);
            il.Emit(OperationCode.Initobj, typeParameter);
            il.Emit(OperationCode.Ldloc_0);
            il.Emit(OperationCode.Ret);

            return(typeA);
        }
        /// <summary>
        /// Create private GraphInstance __graphInstance backing field.
        /// </summary>
        /// <param name="namespaceTypeDefinition"></param>
        /// <returns></returns>
        public override NamespaceTypeDefinition Mutate(NamespaceTypeDefinition namespaceTypeDefinition)
        {
            // Only inject types marked with GraphTypeAttribute
            if (namespaceTypeDefinition.Attributes.Where(a => a.Type.ToString() == "ExoGraph.GraphTypeAttribute").Any())
            {
                // Add __graphInstance private field
                //var graphInstanceField = new FieldDefinition()
                //{
                //    Name = host.NameTable.GetNameFor("__graphInstance"),
                //    Type = graphInstance,
                //    InternFactory = host.InternFactory,

                //};
                //namespaceTypeDefinition.Fields.Add(graphInstanceField);

                //// Add IGraphInstance interface to type definition
                //namespaceTypeDefinition.Interfaces.Add(UnitHelper.FindType(host.NameTable, exoGraphAssembly, "ExoGraph.IGraphInstance"));

                //// Add ExoGraph.IGraphInstance.get_Instance getter
                //var get_Instance = new MethodDefinition
                //{
                //    ContainingTypeDefinition = namespaceTypeDefinition,
                //    Type = graphInstance,
                //    Name = host.NameTable.GetNameFor("ExoGraph.IGraphInstance.get_Instance"),
                //    IsSpecialName = true,
                //    IsHiddenBySignature = true,
                //    InternFactory = host.InternFactory,
                //    Body = new MethodBody()
                //    {
                //        Operations = new List<IOperation>()
                //        {
                //            // Load this pointer onto stack
                //            new Operation() { OperationCode = OperationCode.Ldarg_0	},

                //            // Load graph instance from local field
                //            new Operation()	{ OperationCode = OperationCode.Ldfld, Value = graphInstanceField },

                //            // return the graph instance
                //            new Operation()	{ OperationCode = OperationCode.Ret },
                //        }
                //    }
                //};
                //namespaceTypeDefinition.Methods.Add(get_Instance);

                //// Add IGraphInstance.Instance property
                //namespaceTypeDefinition.Properties.Add(new PropertyDefinition()
                //{
                //    Accessors = new List<IMethodReference>() { get_Instance },
                //    ContainingTypeDefinition = namespaceTypeDefinition,
                //    Visibility = TypeMemberVisibility.Public,
                //    Name = host.NameTable.GetNameFor("ExoGraph.IGraphInstance.Instance"),
                //    Type = graphInstance,
                //    Getter = get_Instance
                //});
            }
            return base.Mutate(namespaceTypeDefinition);
        }
示例#11
0
        /// <summary>
        /// Create private GraphInstance __graphInstance backing field.
        /// </summary>
        /// <param name="namespaceTypeDefinition"></param>
        /// <returns></returns>
        public override NamespaceTypeDefinition Mutate(NamespaceTypeDefinition namespaceTypeDefinition)
        {
            // Only inject types marked with GraphTypeAttribute
            if (namespaceTypeDefinition.Attributes.Where(a => a.Type.ToString() == "ExoGraph.GraphTypeAttribute").Any())
            {
                // Add __graphInstance private field
                //var graphInstanceField = new FieldDefinition()
                //{
                //    Name = host.NameTable.GetNameFor("__graphInstance"),
                //    Type = graphInstance,
                //    InternFactory = host.InternFactory,

                //};
                //namespaceTypeDefinition.Fields.Add(graphInstanceField);

                //// Add IGraphInstance interface to type definition
                //namespaceTypeDefinition.Interfaces.Add(UnitHelper.FindType(host.NameTable, exoGraphAssembly, "ExoGraph.IGraphInstance"));

                //// Add ExoGraph.IGraphInstance.get_Instance getter
                //var get_Instance = new MethodDefinition
                //{
                //    ContainingTypeDefinition = namespaceTypeDefinition,
                //    Type = graphInstance,
                //    Name = host.NameTable.GetNameFor("ExoGraph.IGraphInstance.get_Instance"),
                //    IsSpecialName = true,
                //    IsHiddenBySignature = true,
                //    InternFactory = host.InternFactory,
                //    Body = new MethodBody()
                //    {
                //        Operations = new List<IOperation>()
                //        {
                //            // Load this pointer onto stack
                //            new Operation() { OperationCode = OperationCode.Ldarg_0	},

                //            // Load graph instance from local field
                //            new Operation()	{ OperationCode = OperationCode.Ldfld, Value = graphInstanceField },

                //            // return the graph instance
                //            new Operation()	{ OperationCode = OperationCode.Ret },
                //        }
                //    }
                //};
                //namespaceTypeDefinition.Methods.Add(get_Instance);

                //// Add IGraphInstance.Instance property
                //namespaceTypeDefinition.Properties.Add(new PropertyDefinition()
                //{
                //    Accessors = new List<IMethodReference>() { get_Instance },
                //    ContainingTypeDefinition = namespaceTypeDefinition,
                //    Visibility = TypeMemberVisibility.Public,
                //    Name = host.NameTable.GetNameFor("ExoGraph.IGraphInstance.Instance"),
                //    Type = graphInstance,
                //    Getter = get_Instance
                //});
            }
            return(base.Mutate(namespaceTypeDefinition));
        }
示例#12
0
        // this method creates an new interface for the given namespace
        public NamespaceTypeDefinition createNewInterface(String className, IUnitNamespace containingUnitNamespace)
        {
            // create a new class object and modify it to be an interface
            NamespaceTypeDefinition newInterface = this.createNewClass(className, containingUnitNamespace, false, false);

            newInterface.IsAbstract  = true;
            newInterface.IsInterface = true;
            newInterface.BaseClasses = null;

            return(newInterface);
        }
示例#13
0
 private void ReportNameCollisionAndRename(NamespaceTypeDefinition nsType, NamespaceTypeDefinition laterNsType, int position)
 {
     Contract.Requires(nsType != null);
     Contract.Requires(laterNsType != null);
     laterNsType.Name = this.host.NameTable.GetNameFor(laterNsType.Name.Value + "``" + position);
     this.host.ReportError(new ErrorMessage()
     {
         Code             = 4, ErrorReporter = this, Error = MergeError.DuplicateGlobalField,
         MessageParameter = TypeHelper.GetTypeName(nsType),
     });
 }
示例#14
0
 protected void DefineModule(Assembly assembly, RootUnitNamespace rootNamespace)
 {
     var nt = Host.NameTable;
     var module = new NamespaceTypeDefinition
                      {
                          ContainingUnitNamespace = rootNamespace,
                          Name = nt.GetNameFor("<Module>"),
                          InternFactory = Host.InternFactory,
                          IsClass = true
                      };
     assembly.AllTypes.Add(module);
 }
            public override IRootUnitNamespace Rewrite(IRootUnitNamespace root)
            {
                var testClass = new NamespaceTypeDefinition
                {
                    BaseClasses = new List <ITypeReference>(1)
                    {
                        Host.PlatformType.SystemObject
                    },
                    ContainingUnitNamespace = root,
                    InternFactory           = Host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = NameTable.GetNameFor("VisualMutatorGeneratedClass"),
                };

                ((RootUnitNamespace)root).Members.Add(testClass);
                ((Assembly)Module).AllTypes.Add(testClass);


                var mainMethod = new MethodDefinition
                {
                    ContainingTypeDefinition = testClass,
                    InternFactory            = Host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = NameTable.GetNameFor("FailOnZero"),
                    Type       = Host.PlatformType.SystemInt32,
                    Visibility = TypeMemberVisibility.Public,
                };

                mainMethod.Parameters = new List <IParameterDefinition>()
                {
                    new ParameterDefinition()
                    {
                        Type = Host.PlatformType.SystemInt32,
                        Name = NameTable.GetNameFor("x"),
                    }
                };
                testClass.Methods.Add(mainMethod);

                var body = new SourceMethodBody(Host)
                {
                    MethodDefinition = mainMethod,
                    LocalsAreZeroed  = true
                };

                mainMethod.Body = body;


                body.Block = GeneratedBlock;
                return(root);
            }
        private INamedTypeDefinition GenerateTypeA(IUnitNamespace rootNamespace)
        {
            var nt = Host.NameTable;
            var typeA = new NamespaceTypeDefinition
                            {
                                ContainingUnitNamespace = rootNamespace,
                                Name = nt.GetNameFor("A"),
                                InternFactory = Host.InternFactory,
                                IsClass = true
                            };
            var typeParameter = new GenericTypeParameter
                                    {
                                        Name = nt.GetNameFor("T"),
                                        InternFactory = Host.InternFactory,
                                        DefiningType = typeA,
                                    };
            typeA.GenericParameters.Add(typeParameter);

            var baseGetMethod = new MethodDefinition
                                    {
                                        Name = nt.GetNameFor("Get"),
                                        IsCil = true,
                                        IsVirtual = true,
                                        Visibility = TypeMemberVisibility.Assembly,
                                        Type = typeParameter,
                                        ContainingTypeDefinition = typeA,
                                        InternFactory = Host.InternFactory,
                                        IsNewSlot = true
                                    };
            typeA.Methods.Add(baseGetMethod);

            var il = new ILGenerator(Host);
            var localVar = new LocalDefinition
            {
                Type = typeParameter,
                Name = nt.GetNameFor("local1"),
            };

            // tricky moment, ILGeneratorMethodBody fills internal collection of local vars only in constructor.
            // lines below should not be swapped

            il.AddVariableToCurrentScope(localVar);
            var body = new ILGeneratorMethodBody(il, true, 1) {MethodDefinition = baseGetMethod};
            baseGetMethod.Body = body;

            il.Emit(OperationCode.Ldloca, localVar);
            il.Emit(OperationCode.Initobj, typeParameter);
            il.Emit(OperationCode.Ldloc_0);
            il.Emit(OperationCode.Ret);

            return typeA;
        }
示例#17
0
        // this function fills the rest of the graph with random nodes
        private void fillNodesRecursively(NodeObject currentNode, List <int> currentPosition, int currentDepth, int maxDepth, List <PossibleNode> allPossibleNodes, ValidGraphPath[] validPaths)
        {
            // check if the maximal depth is reached
            if (currentDepth >= maxDepth)
            {
                return;
            }

            // fill all missing nodes of the current object with new random nodes
            for (int idx = 0; idx < currentNode.dimension; idx++)
            {
                // copy position list and add path index to the position
                List <int> tempCurrentPosition = new List <int>(currentPosition);
                tempCurrentPosition.Add(idx);

                if (currentNode.nodeObjects[idx] == null)
                {
                    // get random possible node from list of all possible nodes
                    int                     randElement     = this.prng.Next(allPossibleNodes.Count);
                    PossibleNode            possibleNode    = allPossibleNodes.ElementAt(randElement);
                    NamespaceTypeDefinition classToUse      = possibleNode.givenClass;
                    MethodDefinition        nodeConstructor = possibleNode.nodeConstructor;

                    // generate path element from chosen interface
                    PathElement pathElement = new PathElement();

                    // create new node object
                    currentNode.nodeObjects[idx] = new NodeObject(this.graphDimension, this.graphValidPathCount, classToUse, nodeConstructor, pathElement, tempCurrentPosition);


                    // search through every valid path if the new created filler node has the same attributes as the valid path node
                    // => add it to the list of possible nodes that can be used for an exchange between valid node and filler node
                    for (int validPathId = 0; validPathId < validPaths.Count(); validPathId++)
                    {
                        for (int depth = 0; depth < validPaths[validPathId].pathElements.Count(); depth++)
                        {
                            // check if the used class of the current filler node is in the list of possible classes of the valid path node
                            if (validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleClasses.Contains(classToUse))
                            {
                                // add current filler node to the list of possible exchange nodes
                                if (!validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleExchangeObjects.Contains(currentNode.nodeObjects[idx]))
                                {
                                    validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleExchangeObjects.Add(currentNode.nodeObjects[idx]);
                                }
                            }
                        }
                    }
                }

                this.fillNodesRecursively(currentNode.nodeObjects[idx], tempCurrentPosition, currentDepth + 1, maxDepth, allPossibleNodes, validPaths);
            }
        }
示例#18
0
        protected void DefineModule(Assembly assembly, RootUnitNamespace rootNamespace)
        {
            var nt     = Host.NameTable;
            var module = new NamespaceTypeDefinition
            {
                ContainingUnitNamespace = rootNamespace,
                Name          = nt.GetNameFor("<Module>"),
                InternFactory = Host.InternFactory,
                IsClass       = true
            };

            assembly.AllTypes.Add(module);
        }
示例#19
0
            public override void RewriteChildren(Assembly assembly)
            {
                // Clear all win32 resources. The version resource will get repopulated.
                assembly.Win32Resources = new List <IWin32Resource>();

                // Remove all the references they will get repopulated while outputing.
                assembly.AssemblyReferences.Clear();

                // Remove all the module references (aka native references)
                assembly.ModuleReferences = new List <IModuleReference>();

                // Remove all file references (ex: *.nlp files in mscorlib)
                assembly.Files = new List <IFileReference>();

                // Remove all security attributes (ex: permissionset in IL)
                assembly.SecurityAttributes = new List <ISecurityAttribute>();

                // Reset the core assembly symbolic identity to the seed core assembly (e.g. mscorlib, corefx)
                // and not the contract core (e.g. System.Runtime).
                assembly.CoreAssemblySymbolicIdentity = _seedCoreAssemblyReference.AssemblyIdentity;

                // Add reference to seed core assembly up-front so that we keep the same order as the C# compiler.
                assembly.AssemblyReferences.Add(_seedCoreAssemblyReference);

                // Remove all type definitions except for the "<Module>" type. Remove all fields and methods from it.
                NamespaceTypeDefinition moduleType = assembly.AllTypes.SingleOrDefault(t => t.Name.Value == "<Module>") as NamespaceTypeDefinition;

                assembly.AllTypes.Clear();
                if (moduleType != null)
                {
                    moduleType.Fields?.Clear();
                    moduleType.Methods?.Clear();
                    assembly.AllTypes.Add(moduleType);
                }

                // Remove any preexisting typeforwards.
                assembly.ExportedTypes = new List <IAliasForType>();

                // Remove any preexisting resources.
                assembly.Resources = new List <IResourceReference>();

                // Clear the reference assembly flag from the contract.
                // For design-time facades, it will be added back later.
                assembly.Flags &= ~ReferenceAssemblyFlag;

                // This flag should not be set until the delay-signed assembly we emit is actually signed.
                assembly.StrongNameSigned = false;

                base.RewriteChildren(assembly);
            }
示例#20
0
        private void MakeInternal(NamedTypeDefinition nsType)
        {
            NestedTypeDefinition    nestedTypeDef    = nsType as NestedTypeDefinition;
            NamespaceTypeDefinition namespaceTypeDef = nsType as NamespaceTypeDefinition;

            if (namespaceTypeDef != null)
            {
                namespaceTypeDef.IsPublic = false;
            }
            else if (nestedTypeDef != null)
            {
                nestedTypeDef.Visibility = GetInternalVisibility(nestedTypeDef.Visibility);
            }
        }
示例#21
0
        public override void Mutate(Assembly assembly)
        {
            Logger.LogInfo("Adding processed flag.");

            var processedInterface = new NamespaceTypeDefinition()
            {
                InternFactory = Host.InternFactory,
                ContainingUnitNamespace = assembly.UnitNamespaceRoot,
                Name = Host.NameTable.GetNameFor("ProcessedByWeavR"),
                IsAbstract = true,
                IsInterface = true,
                MangleName = false
            };
            assembly.AllTypes.Add(processedInterface);
            ((RootUnitNamespace)assembly.UnitNamespaceRoot).Members.Add(processedInterface);
        }
示例#22
0
        public override void RewriteChildren(RootUnitNamespace rootUnitNamespace)
        {
            this.classHoldingThreeArgVersions = this.GetContractClass(rootUnitNamespace);

            base.RewriteChildren(rootUnitNamespace);

            #region Possibly add class for any contract methods that were defined.
            if (0 < this.threeArgumentVersionofContractMethod.Count)
            {
                // Only add class to assembly if any 3 arg versions were actually created
                rootUnitNamespace.Members.Add(classHoldingThreeArgVersions);
                this.allTypes.Add(classHoldingThreeArgVersions);
            }
            #endregion Possibly add class for any contract methods that were defined.

            #region Create a reference to [ContractReferenceAssembly] to mark the assembly with
            INamespaceTypeDefinition contractReferenceAssemblyAttribute = null;
            #region First see if we can find it in the same assembly as the one we are rewriting
            var unit = rootUnitNamespace.Unit;
            contractReferenceAssemblyAttribute = UnitHelper.FindType(this.host.NameTable, unit, "System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute")
                                                 as INamespaceTypeDefinition;
            #endregion First see if we can find it in the same assembly as the one we are rewriting
            #region If it doesn't exist there, then define it in the same place that the three-argument versions are defined
            if (contractReferenceAssemblyAttribute is Dummy)
            {
                contractReferenceAssemblyAttribute = CreateContractReferenceAssemblyAttribute(rootUnitNamespace);
            }
            #endregion If it doesn't exist there, then define it in the same place that the three-argument versions are defined
            #region Create a reference to the ctor
            var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference()
            {
                CallingConvention = CallingConvention.HasThis,
                ContainingType    = contractReferenceAssemblyAttribute,
                InternFactory     = this.host.InternFactory,
                Name = host.NameTable.Ctor,
                Type = systemVoidType,
            };
            var rm = ctorRef.ResolvedMethod;
            this.ContractReferenceAssemblyAttributeInstance = new CustomAttribute()
            {
                Constructor = ctorRef,
            };
            #endregion Create a reference to the ctor
            #endregion Create a reference to [ContractReferenceAssembly] to mark the assembly with

            return;
        }
示例#23
0
        static void mergeClassWithAllAncestors(NamespaceTypeDefinition mergeTargetClass, PeReader.DefaultHost host)
        {
            List <NamespaceTypeDefinition> ancestorClasses = new List <NamespaceTypeDefinition>();

            ancestorClasses.Add(mergeTargetClass);

            NamespaceTypeDefinition currentClass  = mergeTargetClass;
            NamespaceTypeDefinition ancestorClass = null;


            while (true)
            {
                // get class from which was inherited
                if (currentClass.BaseClasses.Count() == 1)
                {
                    // only add base classes of type NamespaceTypeDefinition
                    if (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition != null)
                    {
                        ancestorClass = (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition);
                    }
                    // ignore ancestor that are not of type NamespaceTypeDefinition
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new ArgumentException("Do not know how to handle multiple inheritance.");
                }

                // add ancestor class to list of ancestor classes
                globalLog.writeLine("Found ancestor: " + ancestorClass.ToString());
                ancestorClasses.Add(ancestorClass);

                currentClass = ancestorClass;
            }

            // mrge class with ancenstor (start with the "highest" ancestor)
            for (int i = (ancestorClasses.Count - 1); i >= 0; i--)
            {
                globalLog.writeLine("Merge class \"" + ancestorClasses[i].ToString() + "\" with ancestor");
                mergeClassWithAncestor(ancestorClasses[i], host);
                globalLog.writeLine("");
            }
        }
示例#24
0
        /// <summary>
        /// Creates the appropriate kind of type definition (nested or not) and
        /// adds it to the type symbol cache.
        /// </summary>
        private NamedTypeDefinition CreateTypeDefinition(INamedTypeSymbol typeSymbol)
        {
            Contract.Requires(typeSymbol != null);

            NamedTypeDefinition cciType;

            if (typeSymbol.ContainingType == null)
            {
                cciType = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = (IUnitNamespace)this.namespaceSymbolCache[typeSymbol.ContainingNamespace],
                    IsPublic = typeSymbol.DeclaredAccessibility == Accessibility.Public,
                };
            }
            else
            {
                cciType = new NestedTypeDefinition()
                {
                    ContainingTypeDefinition = (ITypeDefinition)this.typeSymbolCache[typeSymbol.ContainingType],
                    Visibility = TypeMemberVisibility.Private,
                };
            }
            if (typeSymbol.TypeKind == TypeKind.Interface)
            {
                cciType.IsAbstract  = true;
                cciType.IsInterface = true;
            }
            else
            {
                cciType.BaseClasses = new List <ITypeReference> {
                    this.Map(typeSymbol.BaseType)
                };
                cciType.IsBeforeFieldInit = true; // REVIEW: How to determine from typeSymbol?
            }
            cciType.IsClass       = typeSymbol.IsReferenceType;
            cciType.IsValueType   = typeSymbol.IsValueType;
            cciType.IsSealed      = typeSymbol.IsSealed;
            cciType.InternFactory = this.host.InternFactory;
            cciType.Locations     = Helper.WrapLocations(typeSymbol.Locations);
            cciType.Name          = this.host.NameTable.GetNameFor(typeSymbol.Name);

            this.typeSymbolCache.Add(typeSymbol, cciType);
            return(cciType);
        }
示例#25
0
        private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace)
        {
            var contractTypeName      = this.host.NameTable.GetNameFor("Contract");
            var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts");

            Microsoft.Cci.MethodReference compilerGeneratedCtor =
                new Microsoft.Cci.MethodReference(
                    this.host,
                    this.compilerGeneratedAttributeType,
                    CallingConvention.HasThis,
                    this.systemVoidType,
                    this.host.NameTable.Ctor,
                    0);
            CustomAttribute compilerGeneratedAttribute = new CustomAttribute();

            compilerGeneratedAttribute.Constructor = compilerGeneratedCtor;

            var contractsNs = new NestedUnitNamespace()
            {
                ContainingUnitNamespace = unitNamespace,
                Name = contractNamespaceName,
            };
            NamespaceTypeDefinition result = new NamespaceTypeDefinition()
            {
                // NB: The string name must be kept in sync with the code that recognizes contract
                // methods!!
                Name       = contractTypeName,
                Attributes = new List <ICustomAttribute> {
                    compilerGeneratedAttribute
                },
                BaseClasses = new List <ITypeReference> {
                    this.systemObjectType
                },
                ContainingUnitNamespace = contractsNs,
                InternFactory           = this.host.InternFactory,
                IsBeforeFieldInit       = true,
                IsClass      = true,
                IsSealed     = true,
                Layout       = LayoutKind.Auto,
                StringFormat = StringFormatKind.Ansi,
            };

            return(result);
        }
示例#26
0
        public virtual void VisitNamespace(UnitNamespace unitNamespace)
        {
            if (unitNamespace.Members == null)
            {
                return;
            }

            for (int i = 0; i < unitNamespace.Members.Count; i++)
            {
                INamespaceMember member = unitNamespace.Members[i];

                MethodDefinition methodDef = member as MethodDefinition;

                if (methodDef != null)
                {
                    VisitMethod(methodDef, null);
                    continue;
                }

                NamespaceTypeDefinition typeDef = member as NamespaceTypeDefinition;

                if (typeDef != null)
                {
                    VisitType(typeDef);
                    continue;
                }

                UnitNamespace ns = member as UnitNamespace;

                if (ns != null)
                {
                    VisitNamespace(ns);
                }
                else
                {
                    throw new InvalidOperationException("INamespaceMember");
                }
            }
        }
示例#27
0
    public void AddGenericParamInPlace(NamespaceTypeDefinition namespaceTypeDefinition)
    {
        var oneMoreGP = new List <IGenericTypeParameter>();
        var gp1       = new GenericTypeParameter()
        {
            InternFactory = this.host.InternFactory,
            PlatformType  = this.host.PlatformType,
            Name          = this.host.NameTable.GetNameFor("_SX_"),
            DefiningType  = namespaceTypeDefinition,
            Index         = 0
        };

        oneMoreGP.Add(gp1);
        if (namespaceTypeDefinition.GenericParameters != null)
        {
            foreach (GenericTypeParameter gp in namespaceTypeDefinition.GenericParameters)
            {
                gp.Index++;
                oneMoreGP.Add(gp);
            }
        }
        namespaceTypeDefinition.GenericParameters = oneMoreGP;
    }
示例#28
0
        private NamespaceTypeDefinition GenerateTypeB(IUnitNamespace rootNamespace, ITypeReference baseType)
        {
            var nt    = Host.NameTable;
            var typeB = new NamespaceTypeDefinition
            {
                ContainingUnitNamespace = rootNamespace,
                Name          = nt.GetNameFor("B"),
                InternFactory = Host.InternFactory,
                IsClass       = true,
                BaseClasses   = { baseType }
            };

            var overrideGetMethod = new MethodDefinition
            {
                Name       = nt.GetNameFor("Get"),
                IsCil      = true,
                IsVirtual  = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = Host.PlatformType.SystemString,
                ContainingTypeDefinition = typeB,
                InternFactory            = Host.InternFactory
            };

            typeB.Methods.Add(overrideGetMethod);
            var il   = new ILGenerator(Host);
            var body = new ILGeneratorMethodBody(il, true, 1)
            {
                MethodDefinition = overrideGetMethod
            };

            overrideGetMethod.Body = body;

            il.Emit(OperationCode.Ldstr, "1");
            il.Emit(OperationCode.Ret);
            return(typeB);
        }
示例#29
0
 public override void RewriteChildren(NamespaceTypeDefinition namespaceTypeDefinition) {
   this.PruneInterfacesAndExplicitImplementationOverrides(namespaceTypeDefinition);
   base.RewriteChildren(namespaceTypeDefinition);
 }
    static void Main(string[] args) {
      var nameTable = new NameTable();
      using (var host = new PeReader.DefaultHost(nameTable)) {
        var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

        var assembly = new Assembly() {
          Name = nameTable.GetNameFor("hello"),
          ModuleName = nameTable.GetNameFor("hello.exe"),
          PlatformType = host.PlatformType,
          Kind = ModuleKind.ConsoleApplication,
          RequiresStartupStub = host.PointerSize == 4,
          TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
        };
        assembly.AssemblyReferences.Add(coreAssembly);

        var rootUnitNamespace = new RootUnitNamespace();
        assembly.UnitNamespaceRoot = rootUnitNamespace;
        rootUnitNamespace.Unit = assembly;

        var moduleClass = new NamespaceTypeDefinition() {
          ContainingUnitNamespace = rootUnitNamespace,
          InternFactory = host.InternFactory,
          IsClass = true,
          Name = nameTable.GetNameFor("<Module>"),
        };
        assembly.AllTypes.Add(moduleClass);

        var testClass = new NamespaceTypeDefinition() {
          ContainingUnitNamespace = rootUnitNamespace,
          InternFactory = host.InternFactory,
          IsClass = true,
          IsPublic = true,
          Methods = new List<IMethodDefinition>(1),
          Name = nameTable.GetNameFor("Test"),
        };
        rootUnitNamespace.Members.Add(testClass);
        assembly.AllTypes.Add(testClass);
        testClass.BaseClasses = new List<ITypeReference>() { host.PlatformType.SystemObject };

        var mainMethod = new MethodDefinition() {
          ContainingTypeDefinition = testClass,
          InternFactory = host.InternFactory,
          IsCil = true,
          IsStatic = true,
          Name = nameTable.GetNameFor("Main"),
          Type = host.PlatformType.SystemVoid,
          Visibility = TypeMemberVisibility.Public,
        };
        assembly.EntryPoint = mainMethod;
        testClass.Methods.Add(mainMethod);

        var ilGenerator = new ILGenerator(host, mainMethod);

        var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");
        var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);

        ilGenerator.Emit(OperationCode.Ldstr, "hello");
        ilGenerator.Emit(OperationCode.Call, writeLine);
        ilGenerator.Emit(OperationCode.Ret);

        var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
        mainMethod.Body = body;

        using (var peStream = File.Create("hello.exe")) {
          PeWriter.WritePeToStream(assembly, host, peStream);
        }
      }
    }
        // adds the given interface to the given class
        public void addInterface(NamespaceTypeDefinition addTargetClass, ITypeDefinition interfaceToAdd) {
       

            // add interface to target class
            if (addTargetClass.Interfaces != null) {

                // check if interface is already implemented by class
                if (addTargetClass.Interfaces.Contains(interfaceToAdd)) {
                    this.logger.writeLine("Class \"" + addTargetClass.ToString() + "\" already implements interface \"" + interfaceToAdd.ToString() + "\"");
                    return;
                }
                else {
                    this.logger.writeLine("Add interface \"" + interfaceToAdd.ToString() + "\" to class \"" + addTargetClass.ToString() + "\"");
                    addTargetClass.Interfaces.Add(interfaceToAdd);
                }
            }      
            else {
                List<ITypeReference> interfaceList = new List<ITypeReference>();
                interfaceList.Add(interfaceToAdd);
                addTargetClass.Interfaces = interfaceList;
            }

            // copy all attributes from the interface to the target class
            if (interfaceToAdd.Fields != null) {
                foreach (FieldDefinition field in interfaceToAdd.Fields) {
                    FieldDefinition copy = new FieldDefinition();
                    this.helperClass.copyField(copy, field);
                    copy.ContainingTypeDefinition = addTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = addTargetClass.InternFactory;

                    addTargetClass.Fields.Add(copy);
                }
            }

            // copy all methods from the interface to the target class
            if (interfaceToAdd.Methods != null) {
                foreach (IMethodDefinition method in interfaceToAdd.Methods) {

                    // search through all methods in the target class
                    // to see if this method was already added
                    bool foundMethod = false;
                    foreach (IMethodDefinition tempMethod in addTargetClass.Methods) {

                        // skip constructors
                        if (tempMethod.IsConstructor) {
                            continue;
                        }

                        // check if the number of parameters are the same
                        if (tempMethod.ParameterCount == method.ParameterCount) {

                            // check if the parameters have the same type in the same order
                            bool parameterCorrect = true;
                            for (int i = 0; i < method.ParameterCount; i++) {
                                if (method.Parameters.ElementAt(i).Type != tempMethod.Parameters.ElementAt(i).Type) {
                                    parameterCorrect = false;
                                    break;
                                }
                            }

                            // check if the return type is the same
                            bool returnTypeCorrect = false;
                            if (method.Type.Equals(tempMethod.Type)) {
                                returnTypeCorrect = true;
                            }

                            // check if both methods are static
                            // (c# compiler does not allow static + non-static function with
                            // same signature in same class, but CIL does)
                            bool bothStatic = false;
                            if (method.IsStatic == tempMethod.IsStatic) {
                                bothStatic = true;
                            }

                            // if the parameters and return type are correct => check the name
                            if (parameterCorrect && returnTypeCorrect && bothStatic) {
                                if (method.Name.Equals(tempMethod.Name)) {

                                    // if name is the same => method already added
                                    foundMethod = true;
                                    break;
                                }
                            }
                        }
                    }
                    // skip if method was already added
                    if (foundMethod) {
                        this.logger.writeLine("Method \"" + method.Name.ToString() + "\" already exists");
                        continue;
                    }

                    this.logger.writeLine("Add method: " + method.Name.ToString());

                    // copy method
                    MethodDefinition copy = new MethodDefinition();
                    this.helperClass.copyMethod(copy, method);
                    copy.ContainingTypeDefinition = addTargetClass;


                    // generate random dead code for newly created method
                    ILGenerator ilGenerator = new ILGenerator(host, method);
                    foreach (IOperation tempOperation in CodeGenerator.generateDeadCode(true)) {
                        ilGenerator.Emit(tempOperation.OperationCode, tempOperation.Value);
                    }
                    IMethodBody newBody = new ILGeneratorMethodBody(ilGenerator, true, 8, method, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                    copy.Body = newBody;



                    // set intern factory of the copied method to the one of the class
                    // (without it, the generated binary file will have strange results like call always the same method)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // set method to not abstract
                    copy.IsAbstract = false;

                    // set method to not external
                    copy.IsExternal = false;

                    // set intern factory of the copied method to the one of the class
                    // (without it, the generating of the binary file will have strange results)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // add method to the class
                    addTargetClass.Methods.Add(copy);
                }
            }
        }
示例#32
0
        private void createNodeInterface(IUnitNamespace targetNamespace) {

            this.nodeInterface = this.helperClass.createNewInterface("iNode", targetNamespace); // TODO: interface name

            // create getter and setter for the startPointer variable
            this.interfaceStartPointerGet = this.helperClass.createNewMethod("startPointer_get", this.nodeInterface, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, true, true); // TODO: method name

            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            this.interfaceStartPointerSet = this.helperClass.createNewMethod("startPointer_set", this.nodeInterface, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, true, true); // TODO: method name

            // create getter and setter for the childNodes array variable
            parameters = new List<IParameterDefinition>();
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            this.interfaceChildNodesGet = this.helperClass.createNewMethod("childNodes_get", this.nodeInterface, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, true, true); // TODO: method name

            parameters = new List<IParameterDefinition>();
            // iNode parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            this.interfaceChildNodesSet = this.helperClass.createNewMethod("childNodes_set", this.nodeInterface, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, true, true); // TODO: method name

            // when debugging is activated
            // => create getter for the id variable that distinct identifies the object
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding getter for unique object id to node interface");

                this.debuggingInterfaceIdGet = this.helperClass.createNewMethod("DEBUG_objectId_get", this.nodeInterface, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, true, true); // TODO: method name
            }

        }
示例#33
0
        // this function adds the created iNode interface to the class and also implements all neded functions
        public void addNodeInterfaceToTargetClass(NamespaceTypeDefinition givenClass) {

            this.logger.writeLine("");
            this.logger.writeLine("Add node interface \"" + this.nodeInterface.ToString() + "\" to class \"" + givenClass.ToString() + "\"");

            // check if generated interface was already added to target class
            if (givenClass.Interfaces != null
                && givenClass.Interfaces.Contains(this.nodeInterface)) {
                this.logger.writeLine("Class \"" + givenClass.ToString() + "\" already contains node interface \"" + this.nodeInterface.ToString() + "\"");
                return;
            }

            // add nodes interface to class
            if (givenClass.Interfaces != null) {
                givenClass.Interfaces.Add(this.nodeInterface);
            }
            else {
                givenClass.Interfaces = new List<ITypeReference>();
                givenClass.Interfaces.Add(this.nodeInterface);
            }

            // add start pointer field
            FieldDefinition startPointerField = new FieldDefinition();
            startPointerField.IsCompileTimeConstant = false;
            startPointerField.IsNotSerialized = false;
            startPointerField.IsReadOnly = false;
            startPointerField.IsRuntimeSpecial = false;
            startPointerField.IsSpecialName = false;
            startPointerField.Type = this.nodeInterface;
            startPointerField.IsStatic = false;
            startPointerField.Visibility = TypeMemberVisibility.Public;
            startPointerField.Name = host.NameTable.GetNameFor("startPointer");
            startPointerField.InternFactory = host.InternFactory;
            startPointerField.ContainingTypeDefinition = givenClass;
            if (givenClass.Fields != null) {
                givenClass.Fields.Add(startPointerField);
            }
            else {
                givenClass.Fields = new List<IFieldDefinition>();
                givenClass.Fields.Add(startPointerField);
            }

            // create getter for the startPointer variable
            MethodDefinition startPointerGetMethod = this.helperClass.createNewMethod("startPointer_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ILGenerator ilGenerator = new ILGenerator(host, startPointerGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerGetMethod.Body = body;

            // create setter for the startPointer variable
            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition startPointerSetMethod = this.helperClass.createNewMethod("startPointer_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, startPointerSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerSetMethod.Body = body;

            // add childNodes array field
            FieldDefinition childNodesField = new FieldDefinition();
            childNodesField.IsCompileTimeConstant = false;
            childNodesField.IsNotSerialized = false;
            childNodesField.IsReadOnly = false;
            childNodesField.IsRuntimeSpecial = false;
            childNodesField.IsSpecialName = false;
            // create array of node interface type
            VectorTypeReference nodeInterfaceArrayType = new VectorTypeReference();
            nodeInterfaceArrayType.ElementType = this.nodeInterface;
            nodeInterfaceArrayType.Rank = 1;
            nodeInterfaceArrayType.IsFrozen = true;
            nodeInterfaceArrayType.IsValueType = false;
            nodeInterfaceArrayType.InternFactory = host.InternFactory;
            childNodesField.Type = nodeInterfaceArrayType;

            childNodesField.IsStatic = false;
            childNodesField.Visibility = TypeMemberVisibility.Public;
            childNodesField.Name = host.NameTable.GetNameFor("childNodes");
            childNodesField.InternFactory = host.InternFactory;
            childNodesField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(childNodesField);

            // create getter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesGetMethod = this.helperClass.createNewMethod("childNodes_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, childNodesGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesGetMethod.Body = body;

            // create setter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // iNode parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesSetMethod = this.helperClass.createNewMethod("childNodes_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, childNodesSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesSetMethod.Body = body;

            // add current node field
            FieldDefinition currentNodeField = new FieldDefinition();
            currentNodeField.IsCompileTimeConstant = false;
            currentNodeField.IsNotSerialized = false;
            currentNodeField.IsReadOnly = false;
            currentNodeField.IsRuntimeSpecial = false;
            currentNodeField.IsSpecialName = false;
            currentNodeField.Type = this.nodeInterface;
            currentNodeField.IsStatic = false;
            currentNodeField.Visibility = TypeMemberVisibility.Public;
            currentNodeField.Name = host.NameTable.GetNameFor("currentNode");
            currentNodeField.InternFactory = host.InternFactory;
            currentNodeField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(currentNodeField);

            // create getter for the currentNode variable
            MethodDefinition currentNodeGetMethod = this.helperClass.createNewMethod("currentNode_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, currentNodeGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeGetMethod.Body = body;

            // create setter for the currentNode variable
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition currentNodeSetMethod = this.helperClass.createNewMethod("currentNode_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeSetMethod.Body = body;

            // check if debugging is activated
            // => add graph debugging attributes and methods
            MethodDefinition objectIdGetMethod = null;
            FieldDefinition objectIdField = null;
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding field for unique object id and getter method");

                // add objectId field
                objectIdField = new FieldDefinition();
                objectIdField.IsCompileTimeConstant = false;
                objectIdField.IsNotSerialized = false;
                objectIdField.IsReadOnly = false;
                objectIdField.IsRuntimeSpecial = false;
                objectIdField.IsSpecialName = false;
                objectIdField.Type = this.host.PlatformType.SystemString;
                objectIdField.IsStatic = false;
                objectIdField.Name = host.NameTable.GetNameFor("DEBUG_objectId");
                objectIdField.Visibility = TypeMemberVisibility.Public;
                objectIdField.InternFactory = host.InternFactory;
                objectIdField.ContainingTypeDefinition = givenClass;
                givenClass.Fields.Add(objectIdField);

                // create getter for the objectId variable
                objectIdGetMethod = this.helperClass.createNewMethod("DEBUG_objectId_get", givenClass, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

                // create a body for the getter method
                ilGenerator = new ILGenerator(host, objectIdGetMethod);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldfld, objectIdField);
                ilGenerator.Emit(OperationCode.Ret);
                body = new ILGeneratorMethodBody(ilGenerator, true, 1, objectIdGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                objectIdGetMethod.Body = body;

            }

            // add .ctor(iNode) to target class
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);

            MethodDefinition nodeConstructor = this.helperClass.createNewMethod(".ctor", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, false);
            nodeConstructor.IsSpecialName = true;
            nodeConstructor.IsHiddenBySignature = true;
            nodeConstructor.IsRuntimeSpecial = true;

            // generate node constructor body
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);

            // create local variable list
            List<ILocalDefinition> localVariables = new List<ILocalDefinition>();

            // call system.object constructor
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, this.helperClass.objectCtor);

            // initialize childNodes array
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
            ilGenerator.Emit(OperationCode.Newarr, nodeInterfaceArrayType);
            ilGenerator.Emit(OperationCode.Stfld, childNodesField);

            // check if debugging is activated
            // => add code to constructor that generates a unique id for this object
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding code to generate unique id to node constructor");

                // create local integer variable needed for debugging code
                LocalDefinition intLocal = new LocalDefinition();
                intLocal.IsReference = false;
                intLocal.IsPinned = false;
                intLocal.IsModified = false;
                intLocal.Type = this.host.PlatformType.SystemInt32;
                intLocal.MethodDefinition = nodeConstructor;
                localVariables.Add(intLocal);

                // use the hash code of this instance as unique object id
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.objectGetHashCode);
                ilGenerator.Emit(OperationCode.Stloc, intLocal);

                // cast random integer to string and store in object id
                ilGenerator.Emit(OperationCode.Ldloca, intLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Stfld, objectIdField);

            }

            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 8, nodeConstructor, localVariables, Enumerable<ITypeDefinition>.Empty);
            nodeConstructor.Body = body;


            // add class to the list of possible nodes for the graph
            PossibleNode tempStruct = new PossibleNode();
            tempStruct.nodeConstructor = nodeConstructor;
            tempStruct.givenClass = givenClass;

            // for each interface the class implements add it to the according list
            foreach (ITypeReference interfaceRef in givenClass.Interfaces) {

                this.logger.writeLine("Add class \"" + givenClass.ToString() + "\" to graph interface list \"" + interfaceRef.ToString() + "\"");

                // check if a list with this interface already exists
                // => if it does just add current class to list
                if (this.graphInterfaces.ContainsKey(interfaceRef)) {
                    List<PossibleNode> tempList = (List<PossibleNode>)this.graphInterfaces[interfaceRef];
                    tempList.Add(tempStruct);
                }
                // if not => add new list for this interface
                else {
                    List<PossibleNode> tempList = new List<PossibleNode>();
                    tempList.Add(tempStruct);
                    this.graphInterfaces.Add(interfaceRef, tempList);
                }
            }

            this.logger.writeLine("");

        }
        // adds the given interface to the given class
        public void addInterface(NamespaceTypeDefinition addTargetClass, ITypeDefinition interfaceToAdd)
        {
            // add interface to target class
            if (addTargetClass.Interfaces != null)
            {
                // check if interface is already implemented by class
                if (addTargetClass.Interfaces.Contains(interfaceToAdd))
                {
                    this.logger.writeLine("Class \"" + addTargetClass.ToString() + "\" already implements interface \"" + interfaceToAdd.ToString() + "\"");
                    return;
                }
                else
                {
                    this.logger.writeLine("Add interface \"" + interfaceToAdd.ToString() + "\" to class \"" + addTargetClass.ToString() + "\"");
                    addTargetClass.Interfaces.Add(interfaceToAdd);
                }
            }
            else
            {
                List <ITypeReference> interfaceList = new List <ITypeReference>();
                interfaceList.Add(interfaceToAdd);
                addTargetClass.Interfaces = interfaceList;
            }

            // copy all attributes from the interface to the target class
            if (interfaceToAdd.Fields != null)
            {
                foreach (FieldDefinition field in interfaceToAdd.Fields)
                {
                    FieldDefinition copy = new FieldDefinition();
                    this.helperClass.copyField(copy, field);
                    copy.ContainingTypeDefinition = addTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = addTargetClass.InternFactory;

                    addTargetClass.Fields.Add(copy);
                }
            }

            // copy all methods from the interface to the target class
            if (interfaceToAdd.Methods != null)
            {
                foreach (IMethodDefinition method in interfaceToAdd.Methods)
                {
                    // search through all methods in the target class
                    // to see if this method was already added
                    bool foundMethod = false;
                    foreach (IMethodDefinition tempMethod in addTargetClass.Methods)
                    {
                        // skip constructors
                        if (tempMethod.IsConstructor)
                        {
                            continue;
                        }

                        // check if the number of parameters are the same
                        if (tempMethod.ParameterCount == method.ParameterCount)
                        {
                            // check if the parameters have the same type in the same order
                            bool parameterCorrect = true;
                            for (int i = 0; i < method.ParameterCount; i++)
                            {
                                if (method.Parameters.ElementAt(i).Type != tempMethod.Parameters.ElementAt(i).Type)
                                {
                                    parameterCorrect = false;
                                    break;
                                }
                            }

                            // check if the return type is the same
                            bool returnTypeCorrect = false;
                            if (method.Type.Equals(tempMethod.Type))
                            {
                                returnTypeCorrect = true;
                            }

                            // check if both methods are static
                            // (c# compiler does not allow static + non-static function with
                            // same signature in same class, but CIL does)
                            bool bothStatic = false;
                            if (method.IsStatic == tempMethod.IsStatic)
                            {
                                bothStatic = true;
                            }

                            // if the parameters and return type are correct => check the name
                            if (parameterCorrect && returnTypeCorrect && bothStatic)
                            {
                                if (method.Name.Equals(tempMethod.Name))
                                {
                                    // if name is the same => method already added
                                    foundMethod = true;
                                    break;
                                }
                            }
                        }
                    }
                    // skip if method was already added
                    if (foundMethod)
                    {
                        this.logger.writeLine("Method \"" + method.Name.ToString() + "\" already exists");
                        continue;
                    }

                    this.logger.writeLine("Add method: " + method.Name.ToString());

                    // copy method
                    MethodDefinition copy = new MethodDefinition();
                    this.helperClass.copyMethod(copy, method);
                    copy.ContainingTypeDefinition = addTargetClass;


                    // generate random dead code for newly created method
                    ILGenerator ilGenerator = new ILGenerator(host, method);
                    foreach (IOperation tempOperation in CodeGenerator.generateDeadCode(true))
                    {
                        ilGenerator.Emit(tempOperation.OperationCode, tempOperation.Value);
                    }
                    IMethodBody newBody = new ILGeneratorMethodBody(ilGenerator, true, 8, method, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);
                    copy.Body = newBody;



                    // set intern factory of the copied method to the one of the class
                    // (without it, the generated binary file will have strange results like call always the same method)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // set method to not abstract
                    copy.IsAbstract = false;

                    // set method to not external
                    copy.IsExternal = false;

                    // set intern factory of the copied method to the one of the class
                    // (without it, the generating of the binary file will have strange results)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // add method to the class
                    addTargetClass.Methods.Add(copy);
                }
            }
        }
示例#35
0
        static void mergeClassWithAllAncestors(NamespaceTypeDefinition mergeTargetClass, PeReader.DefaultHost host) {

            List<NamespaceTypeDefinition> ancestorClasses = new List<NamespaceTypeDefinition>();
            ancestorClasses.Add(mergeTargetClass);

            NamespaceTypeDefinition currentClass = mergeTargetClass;
            NamespaceTypeDefinition ancestorClass = null;


            while (true) {

                // get class from which was inherited
                if (currentClass.BaseClasses.Count() == 1) {                    
                    // only add base classes of type NamespaceTypeDefinition
                    if (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition != null) {
                        ancestorClass = (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition);
                    }
                    // ignore ancestor that are not of type NamespaceTypeDefinition
                    else {
                        break;
                    }
                }
                else {
                    throw new ArgumentException("Do not know how to handle multiple inheritance.");
                }

                // add ancestor class to list of ancestor classes
                globalLog.writeLine("Found ancestor: " + ancestorClass.ToString());
                ancestorClasses.Add(ancestorClass);

                currentClass = ancestorClass;
            }

            // mrge class with ancenstor (start with the "highest" ancestor)
            for (int i = (ancestorClasses.Count - 1); i >= 0; i--) {
                globalLog.writeLine("Merge class \"" + ancestorClasses[i].ToString() + "\" with ancestor");
                mergeClassWithAncestor(ancestorClasses[i], host);
                globalLog.writeLine("");
            }


        }
示例#36
0
文件: Rewriter.cs 项目: xornand/cci
    private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) {

      var contractTypeName = this.host.NameTable.GetNameFor("Contract");
      var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts");

      Microsoft.Cci.MethodReference compilerGeneratedCtor =
        new Microsoft.Cci.MethodReference(
          this.host,
          this.compilerGeneratedAttributeType,
          CallingConvention.HasThis,
          this.systemVoidType,
          this.host.NameTable.Ctor,
          0);
      CustomAttribute compilerGeneratedAttribute = new CustomAttribute();
      compilerGeneratedAttribute.Constructor = compilerGeneratedCtor;

      var contractsNs = new NestedUnitNamespace() {
        ContainingUnitNamespace = unitNamespace,
        Name = contractNamespaceName,
      };
      NamespaceTypeDefinition result = new NamespaceTypeDefinition() {
        // NB: The string name must be kept in sync with the code that recognizes contract
        // methods!!
        Name = contractTypeName,
        Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute },
        BaseClasses = new List<ITypeReference>{ this.systemObjectType },
        ContainingUnitNamespace = contractsNs,
        InternFactory = this.host.InternFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        Layout = LayoutKind.Auto,
        StringFormat = StringFormatKind.Ansi,
      };
      return result;
    }
示例#37
0
        private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs)
        {
            var internFactory = this.host.InternFactory;
            var nameTable     = this.host.NameTable;

            var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute");
            var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts");

            #region Define type
            CustomAttribute compilerGeneratedAttribute = new CustomAttribute()
            {
                Constructor = new Microsoft.Cci.MethodReference(
                    this.host,
                    this.compilerGeneratedAttributeType,
                    CallingConvention.HasThis,
                    this.systemVoidType,
                    this.host.NameTable.Ctor,
                    0)
            };

            var contractsNs = new NestedUnitNamespace()
            {
                ContainingUnitNamespace = rootNs,
                Name = contractNamespaceName,
            };
            NamespaceTypeDefinition result = new NamespaceTypeDefinition()
            {
                Name       = contractReferenceAssemblyAttributeName,
                Attributes = new List <ICustomAttribute> {
                    compilerGeneratedAttribute
                },
                BaseClasses = new List <ITypeReference> {
                    this.systemAttributeType
                },
                ContainingUnitNamespace = contractsNs, //unitNamespace,
                InternFactory           = internFactory,
                IsBeforeFieldInit       = true,
                IsClass      = true,
                IsSealed     = true,
                Methods      = new List <IMethodDefinition>(),
                Layout       = LayoutKind.Auto,
                StringFormat = StringFormatKind.Ansi,
            };
            contractsNs.Members.Add(result);
            this.allTypes.Add(result);
            #endregion Define type
            #region Define the ctor
            List <IStatement> statements = new List <IStatement>();
            SourceMethodBody  body       = new SourceMethodBody(this.host)
            {
                LocalsAreZeroed = true,
                Block           = new BlockStatement()
                {
                    Statements = statements
                },
            };
            MethodDefinition ctor = new MethodDefinition()
            {
                Body = body,
                CallingConvention        = CallingConvention.HasThis,
                ContainingTypeDefinition = result,
                InternFactory            = internFactory,
                IsRuntimeSpecial         = true,
                IsStatic      = false,
                IsSpecialName = true,
                Name          = nameTable.Ctor,
                Type          = this.systemVoidType,
                Visibility    = TypeMemberVisibility.Public,
            };
            body.MethodDefinition = ctor;
            var thisRef = new ThisReference()
            {
                Type = result,
            };
            // base();
            foreach (var baseClass in result.BaseClasses)
            {
                var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference()
                {
                    CallingConvention     = CallingConvention.HasThis,
                    ContainingType        = baseClass,
                    GenericParameterCount = 0,
                    InternFactory         = this.host.InternFactory,
                    Name = nameTable.Ctor,
                    Type = this.systemVoidType,
                };
                statements.Add(
                    new ExpressionStatement()
                {
                    Expression = new MethodCall()
                    {
                        MethodToCall = baseCtor,
                        IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
                        ThisArgument = new ThisReference()
                        {
                            Type = result,
                        },
                        Type      = this.systemVoidType, // REVIEW: Is this the right way to do this?
                        Arguments = new List <IExpression>(),
                    }
                }
                    );
                break;
            }

            // return;
            statements.Add(new ReturnStatement());
            result.Methods.Add(ctor);
            #endregion Define the ctor
            return(result);
        }
示例#38
0
 public override void RewriteChildren(NamespaceTypeDefinition namespaceTypeDefinition)
 {
     this.PruneInterfacesAndExplicitImplementationOverrides(namespaceTypeDefinition);
     base.RewriteChildren(namespaceTypeDefinition);
 }
示例#39
0
        private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace)
        {
            Contract.Requires(host != null);
            var internFactory = host.InternFactory;

            #region Define the type
            var methodHashAttributeType = new NamespaceTypeDefinition()
            {
                BaseClasses = new List <ITypeReference> {
                    host.PlatformType.SystemAttribute,
                },
                ContainingUnitNamespace = rootUnitNamespace,
                InternFactory           = internFactory,
                //IsBeforeFieldInit = true,
                IsClass  = true,
                IsPublic = true,
                //IsSealed = true,
                Methods = new List <IMethodDefinition>(1),
                Name    = host.NameTable.GetNameFor("MethodHashAttribute"),
                //Layout = LayoutKind.Auto,
                //StringFormat = StringFormatKind.Ansi,
            };
            #endregion

            #region Define the ctor
            var systemVoidType           = host.PlatformType.SystemVoid;
            List <IStatement> statements = new List <IStatement>();
            SourceMethodBody  body       = new SourceMethodBody(host)
            {
                LocalsAreZeroed = true,
                Block           = new BlockStatement()
                {
                    Statements = statements
                },
            };

            var ctor = new MethodDefinition()
            {
                Body = body,
                CallingConvention        = CallingConvention.HasThis,
                ContainingTypeDefinition = methodHashAttributeType,
                InternFactory            = internFactory,
                IsRuntimeSpecial         = true,
                IsStatic      = false,
                IsSpecialName = true,
                Name          = host.NameTable.Ctor,
                Type          = systemVoidType,
                Visibility    = TypeMemberVisibility.Public,
            };
            var systemStringType = host.PlatformType.SystemString;
            var systemIntType    = host.PlatformType.SystemInt32;
            ctor.Parameters = new List <IParameterDefinition>()
            {
                new ParameterDefinition()
                {
                    ContainingSignature = ctor,
                    Name  = host.NameTable.GetNameFor("a"),
                    Type  = systemStringType,
                    Index = 0,
                },
                new ParameterDefinition()
                {
                    ContainingSignature = ctor,
                    Name  = host.NameTable.GetNameFor("b"),
                    Type  = systemIntType,
                    Index = 1,
                }
            };

            body.MethodDefinition = ctor;
            var thisRef = new ThisReference()
            {
                Type = methodHashAttributeType,
            };
            // base();
            foreach (var baseClass in methodHashAttributeType.BaseClasses)
            {
                var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference()
                {
                    CallingConvention     = CallingConvention.HasThis,
                    ContainingType        = baseClass,
                    GenericParameterCount = 0,
                    InternFactory         = internFactory,
                    Name = host.NameTable.Ctor,
                    Type = systemVoidType,
                };
                statements.Add(
                    new ExpressionStatement()
                {
                    Expression = new MethodCall()
                    {
                        MethodToCall = baseCtor,
                        IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
                        ThisArgument = new ThisReference()
                        {
                            Type = methodHashAttributeType,
                        },
                        Type      = systemVoidType, // REVIEW: Is this the right way to do this?
                        Arguments = new List <IExpression>(),
                    }
                }
                    );
                break;
            }

            // return;
            statements.Add(new ReturnStatement());
            methodHashAttributeType.Methods.Add(ctor);
            #endregion Define the ctor
            return(methodHashAttributeType);
        }
示例#40
0
        private Assembly TranslateMetadata(IAssemblySymbol assemblySymbol)
        {
            Contract.Requires(assemblySymbol != null);
            Contract.Ensures(Contract.Result <Assembly>() != null);

            IAssemblyReference cciAssemblyReference = null;
            Assembly           cciAssembly          = null;

            if (assemblySymbolCache.TryGetValue(assemblySymbol, out cciAssemblyReference))
            {
                cciAssembly = cciAssemblyReference as Assembly;
                System.Diagnostics.Debug.Assert(cciAssembly != null);
                return(cciAssembly);
            }

            var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
            var name         = assemblySymbol.Identity.Name;
            var iname        = nameTable.GetNameFor(name);

            cciAssembly = new Assembly()
            {
                Attributes           = this.TranslateMetadata(assemblySymbol.GetAttributes()),
                Name                 = iname,
                Locations            = Helper.WrapLocations(assemblySymbol.Locations),
                ModuleName           = iname,
                Kind                 = ModuleKind.DynamicallyLinkedLibrary,
                RequiresStartupStub  = this.host.PointerSize == 4,
                TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                Version              = assemblySymbol.Identity.Version,
            };
            cciAssembly.AssemblyReferences.Add(coreAssembly);
            this.assemblySymbolCache.Add(assemblySymbol, cciAssembly);
            this.module = cciAssembly;

            var rootUnitNamespace = new RootUnitNamespace();

            cciAssembly.UnitNamespaceRoot = rootUnitNamespace;
            rootUnitNamespace.Unit        = cciAssembly;
            this.namespaceSymbolCache.Add(assemblySymbol.GlobalNamespace, rootUnitNamespace);

            var moduleClass = new NamespaceTypeDefinition()
            {
                ContainingUnitNamespace = rootUnitNamespace,
                InternFactory           = host.InternFactory,
                IsClass = true,
                Name    = nameTable.GetNameFor("<Module>"),
            };

            cciAssembly.AllTypes.Add(moduleClass);


            foreach (var m in assemblySymbol.GlobalNamespace.GetMembers())
            {
                var namespaceSymbol = m as INamespaceSymbol;
                if (namespaceSymbol != null)
                {
                    var cciNtd = TranslateMetadata(namespaceSymbol);
                    rootUnitNamespace.Members.Add(cciNtd);
                    continue;
                }

                var typeSymbol = m as ITypeSymbol;
                if (typeSymbol != null)
                {
                    var namedType = TranslateMetadata((INamedTypeSymbol)typeSymbol);
                    // TODO: fix
                    //namedType.Attributes = TranslateMetadata(typeSymbol.GetAttributes());
                    var cciType = (INamespaceTypeDefinition)namedType;
                    rootUnitNamespace.Members.Add(cciType);
                    //cciAssembly.AllTypes.Add(cciType);
                    continue;
                }
            }

            //if (this.entryPoint != null) {
            //  cciAssembly.Kind = ModuleKind.ConsoleApplication;
            //  cciAssembly.EntryPoint = this.entryPoint;
            //}

            return(cciAssembly);
        }
示例#41
0
        public GraphTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, IUnitNamespace targetNamespace, NamespaceTypeDefinition targetClass, int depth, int dimension, bool debugging = false) {
            this.host = host;
            this.logger = logger;
            this.module = module;
            this.prng = prng;
            this.helperClass = new Helper(module, host, logger);
            this.cfgBuilder = new Cfg.CfgBuilder(module, host, logger);

            this.targetClass = targetClass;

            this.graphDepth = depth;
            this.graphDimension = dimension;

            this.debugging = debugging;
            this.debuggingNumber = 0;

            // create iNode interface
            this.createNodeInterface(targetNamespace);

            // add created iNode interface to the given target class
            this.addNodeInterfaceToTargetClass(this.targetClass);
        }
示例#42
0
        private IModule CreateNewDll(string assemblyName)
        {
            var host = new PeReader.DefaultHost();
            var core = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

            var assembly = new Assembly();
            assembly.Name = host.NameTable.GetNameFor(assemblyName);
            assembly.ModuleName = host.NameTable.GetNameFor(assemblyName + ".dll");
            assembly.Kind = ModuleKind.DynamicallyLinkedLibrary;
            assembly.PlatformType = host.PlatformType;
            assembly.TargetRuntimeVersion = core.TargetRuntimeVersion;
            assembly.AssemblyReferences.Add(core);

            foreach (var referencePath in model.ReferencePaths)
            {
                assembly.AssemblyReferences.Add(host.LoadUnitFrom(referencePath) as IAssembly);
            }

            var root = new RootUnitNamespace();
            root.Unit = assembly;
            assembly.UnitNamespaceRoot = root;

            var module = new NamespaceTypeDefinition();
            module.Name = host.NameTable.GetNameFor("<Module>");
            module.IsClass = true;
            module.InternFactory = host.InternFactory;
            module.ContainingUnitNamespace = root;

            assembly.AllTypes.Add(module);

            var rootTypeNamespace = new NestedUnitNamespace();
            rootTypeNamespace.Name = host.NameTable.GetNameFor(assembly.Name.Value);

            root.Members.Add(rootTypeNamespace);

            foreach (var classConfiguration in model.Classes)
            {
                var newClass = new NamespaceTypeDefinition();
                newClass.IsAbstract = classConfiguration.IsAbstract;
                newClass.IsClass = true;
                newClass.BaseClasses = new List<ITypeReference>{ host.PlatformType.SystemObject };
                newClass.IsPublic = true;

                if (classConfiguration.IsStatic)
                {
                    newClass.IsStatic = true;
                    newClass.IsAbstract = true;
                    newClass.IsSealed = true;
                }

                if (!String.IsNullOrEmpty(classConfiguration.Namespace))
                {
                    NestedUnitNamespace classContainer = rootTypeNamespace;
                    var namespaceNames = classConfiguration.Namespace.Split('.');
                    foreach (var namespaceName in namespaceNames)
                    {
                        var existingMembers = classContainer.GetMembersNamed(host.NameTable.GetNameFor(namespaceName), false);
                        var nestedNamespace = new NestedUnitNamespace();
                        foreach (var existing in existingMembers)
                        {
                            if (existing as NestedUnitNamespace != null)
                            {
                                nestedNamespace = existing as NestedUnitNamespace;
                                break;
                            }
                        }

                        nestedNamespace.Name = host.NameTable.GetNameFor(namespaceName);
                        nestedNamespace.ContainingUnitNamespace = classContainer;
                        classContainer.Members.Add(nestedNamespace);
                        classContainer = nestedNamespace;
                    }

                    newClass.ContainingUnitNamespace = classContainer;
                }
                else
                {
                    newClass.ContainingUnitNamespace = rootTypeNamespace;
                }

                newClass.InternFactory = host.InternFactory;
                newClass.Name = host.NameTable.GetNameFor(classConfiguration.Name);
                newClass.Methods = new List<IMethodDefinition>(classConfiguration.Methods.Count);
                newClass.Fields = new List<IFieldDefinition>(classConfiguration.Fields.Count);

                foreach (var methodConfiguration in classConfiguration.Methods)
                {
                    var newMethod = new MethodDefinition();
                    newMethod.Name = host.NameTable.GetNameFor(methodConfiguration.Name);
                    newMethod.IsStatic = methodConfiguration.IsStatic;
                    newMethod.ContainingTypeDefinition = newClass;
                    newMethod.IsCil = true;
                    newMethod.IsHiddenBySignature = true;
                    newMethod.InternFactory = host.InternFactory;
                    newMethod.Visibility = TypeMemberVisibility.Public;
                    newMethod.Type = host.PlatformType.SystemVoid;

                    var newMethodParameters = new List<IParameterDefinition>();
                    foreach (var param in methodConfiguration.Parameters)
                    {
                        var newMethodParameter = new ParameterDefinition();
                        newMethodParameter.ContainingSignature = newMethod;
                        newMethodParameter.Index = (ushort)methodConfiguration.Parameters.IndexOf(param);
                        newMethodParameter.Name = host.NameTable.GetNameFor(param.Key);
                        newMethodParameter.Type = new UnitReflector(host).Get(param.Value);

                        newMethodParameters.Add(newMethodParameter);
                    }

                    newMethod.Parameters = newMethodParameters;

                    var methodBody = new SourceMethodBody(host, null);
                    methodBody.MethodDefinition = newMethod;
                    methodBody.LocalsAreZeroed = true;

                    var block = new BlockStatement();
                    var returnStatement = new ReturnStatement();

                    if (methodConfiguration.ReturnType != null)
                    {
                        newMethod.Type = new UnitReflector(host).Get(methodConfiguration.ReturnType);
                        returnStatement.Expression = new CompileTimeConstant();
                    }

                    if (methodConfiguration.MethodBody != null)
                    {
                        var codeBuilder = new CodeBuilder(host, newMethod.Parameters);
                        methodConfiguration.MethodBody(codeBuilder);

                        foreach (var statement in codeBuilder.Statements)
                        {
                            block.Statements.Add(statement);
                        }
                    }

                    // "Stack must be empty on return from a void method"
                    //returnStatement.Expression = new CompileTimeConstant();
                    //block.Statements.Add(returnStatement);

                    methodBody.Block = block;

                    newMethod.Body = methodBody;

                    newClass.Methods.Add(newMethod);
                }

                foreach (var field in classConfiguration.Fields)
                {
                    var fieldDefinition = new FieldDefinition();
                    fieldDefinition.ContainingTypeDefinition = newClass;
                    fieldDefinition.InternFactory = host.InternFactory;
                    fieldDefinition.IsReadOnly = field.IsReadonly;
                    fieldDefinition.IsStatic = field.IsStatic;
                    fieldDefinition.Name = host.NameTable.GetNameFor(field.Name);
                    fieldDefinition.Type = new UnitReflector(host).Get(field.FieldType);
                    fieldDefinition.Visibility = field.Accessibility.ToTypeMemberVisibility();

                    newClass.Fields.Add(fieldDefinition);
                }

                assembly.AllTypes.Add(newClass);
            }

            using (var dll = File.Create(assemblyName + ".dll"))
            {
                PeWriter.WritePeToStream(assembly, host, dll);
                dll.Close();
            }

            return assembly;
        }
示例#43
0
    private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) {
      Contract.Requires(host != null);
      var internFactory = host.InternFactory;

      #region Define the type
      var methodHashAttributeType = new NamespaceTypeDefinition() {
        BaseClasses = new List<ITypeReference> { host.PlatformType.SystemAttribute, },
        ContainingUnitNamespace = rootUnitNamespace,
        InternFactory = internFactory,
        //IsBeforeFieldInit = true,
        IsClass = true,
        IsPublic = true,
        //IsSealed = true,
        Methods = new List<IMethodDefinition>(1),
        Name = host.NameTable.GetNameFor("MethodHashAttribute"),
        //Layout = LayoutKind.Auto,
        //StringFormat = StringFormatKind.Ansi,
      };
      #endregion

      #region Define the ctor
      var systemVoidType = host.PlatformType.SystemVoid;
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };

      var ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = methodHashAttributeType,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = host.NameTable.Ctor,
        Type = systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      var systemStringType = host.PlatformType.SystemString;
      var systemIntType = host.PlatformType.SystemInt32;
      ctor.Parameters = new List<IParameterDefinition>(){
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("a"),
          Type = systemStringType,
          Index = 0,
        },
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("b"),
          Type = systemIntType,
          Index = 1,
        }
      };

      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = methodHashAttributeType, };
      // base();
      foreach (var baseClass in methodHashAttributeType.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = internFactory,
          Name = host.NameTable.Ctor,
          Type = systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = methodHashAttributeType, },
              Type = systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      methodHashAttributeType.Methods.Add(ctor);
      #endregion Define the ctor
      return methodHashAttributeType;

    }
示例#44
0
文件: Rewriter.cs 项目: xornand/cci
    public override void RewriteChildren(RootUnitNamespace rootUnitNamespace) {
      this.classHoldingThreeArgVersions = this.GetContractClass(rootUnitNamespace);

      base.RewriteChildren(rootUnitNamespace);

      #region Possibly add class for any contract methods that were defined.
      if (0 < this.threeArgumentVersionofContractMethod.Count) {
        // Only add class to assembly if any 3 arg versions were actually created
        rootUnitNamespace.Members.Add(classHoldingThreeArgVersions);
        this.allTypes.Add(classHoldingThreeArgVersions);
      }
      #endregion Possibly add class for any contract methods that were defined.

      #region Create a reference to [ContractReferenceAssembly] to mark the assembly with
      INamespaceTypeDefinition contractReferenceAssemblyAttribute = null;
      #region First see if we can find it in the same assembly as the one we are rewriting
      var unit = rootUnitNamespace.Unit;
      contractReferenceAssemblyAttribute = UnitHelper.FindType(this.host.NameTable, unit, "System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute")
                          as INamespaceTypeDefinition;
      #endregion First see if we can find it in the same assembly as the one we are rewriting
      #region If it doesn't exist there, then define it in the same place that the three-argument versions are defined
      if (contractReferenceAssemblyAttribute is Dummy) {
        contractReferenceAssemblyAttribute = CreateContractReferenceAssemblyAttribute(rootUnitNamespace);
      }
      #endregion If it doesn't exist there, then define it in the same place that the three-argument versions are defined
      #region Create a reference to the ctor
      var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() {
        CallingConvention = CallingConvention.HasThis,
        ContainingType = contractReferenceAssemblyAttribute,
        InternFactory = this.host.InternFactory,
        Name = host.NameTable.Ctor,
        Type = systemVoidType,
      };
      var rm = ctorRef.ResolvedMethod;
      this.ContractReferenceAssemblyAttributeInstance = new CustomAttribute() {
        Constructor = ctorRef,
      };
      #endregion Create a reference to the ctor
      #endregion Create a reference to [ContractReferenceAssembly] to mark the assembly with

      return;
    }
示例#45
0
        // this method creates a new class for the given namespace
        public NamespaceTypeDefinition createNewClass(String className, IUnitNamespace containingUnitNamespace, bool isPublic,
            bool isStatic)
        {
            // create a new class object
            NamespaceTypeDefinition newClass = new NamespaceTypeDefinition();
            newClass.ContainingUnitNamespace = containingUnitNamespace;
            newClass.InternFactory = this.host.InternFactory;
            newClass.IsClass = true;
            newClass.IsForeignObject = false;
            newClass.IsInterface = false;
            newClass.IsPublic = isPublic;
            newClass.IsStatic = isStatic;
            newClass.Methods = new List<IMethodDefinition>();
            newClass.Name = this.host.NameTable.GetNameFor(className);

            // create list of base classes (only base class is System.Object)
            newClass.BaseClasses = new List<ITypeReference>();
            newClass.BaseClasses.Add(this.host.PlatformType.SystemObject);

            // add new class to module assembly
            Assembly tempAssembly = (Assembly)this.module;
            tempAssembly.AllTypes.Add(newClass);

            return newClass;
        }
示例#46
0
        // builds a CFG for the given class (means a CFG for all methods of this class) and returns it
        public ClassCfg buildCfgForClass(NamespaceTypeDefinition targetClass) {

            ClassCfg classCfg = new ClassCfg();
            classCfg.classObj = targetClass;

            if (targetClass.Methods != null) {
                foreach (MethodDefinition method in targetClass.Methods) {

                    // ignore method if it is external
                    if (method.IsExternal) {
                        continue;
                    }

                    logger.writeLine("Create CFG for method \"" + method.ToString() + "\"");
                    classCfg.methodCfgs.Add(buildCfgForMethod(method));
                    logger.writeLine("");
                }
            }

            return classCfg;
        }
示例#47
0
文件: Rewriter.cs 项目: xornand/cci
    private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) {

      var internFactory = this.host.InternFactory;
      var nameTable = this.host.NameTable;

      var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute");
      var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts");

      #region Define type
      CustomAttribute compilerGeneratedAttribute = new CustomAttribute() {
        Constructor = new Microsoft.Cci.MethodReference(
          this.host,
          this.compilerGeneratedAttributeType,
          CallingConvention.HasThis,
          this.systemVoidType,
          this.host.NameTable.Ctor,
          0)
      };

      var contractsNs = new NestedUnitNamespace() {
        ContainingUnitNamespace = rootNs,
        Name = contractNamespaceName,
      };
      NamespaceTypeDefinition result = new NamespaceTypeDefinition() {
        Name = contractReferenceAssemblyAttributeName,
        Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute },
        BaseClasses = new List<ITypeReference>{ this.systemAttributeType },
        ContainingUnitNamespace = contractsNs, //unitNamespace,
        InternFactory = internFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        Methods = new List<IMethodDefinition>(),
        Layout = LayoutKind.Auto,
        StringFormat = StringFormatKind.Ansi,
      };
      contractsNs.Members.Add(result);
      this.allTypes.Add(result);
      #endregion Define type
      #region Define the ctor
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(this.host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };
      MethodDefinition ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = result,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = nameTable.Ctor,
        Type = this.systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = result, };
      // base();
      foreach (var baseClass in result.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = this.host.InternFactory,
          Name = nameTable.Ctor,
          Type = this.systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = result, },
              Type = this.systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      result.Methods.Add(ctor);
      #endregion Define the ctor
      return result;
    }
示例#48
0
        static void Main(string[] args)
        {
            var nameTable = new NameTable();

            using (var host = new PeReader.DefaultHost(nameTable)) {
                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

                var assembly = new Assembly()
                {
                    Name                 = nameTable.GetNameFor("hello"),
                    ModuleName           = nameTable.GetNameFor("hello.exe"),
                    Kind                 = ModuleKind.ConsoleApplication,
                    PlatformType         = host.PlatformType,
                    RequiresStartupStub  = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit     = assembly;

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass = true,
                    Name    = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                var testClass = new NamespaceTypeDefinition()
                {
                    BaseClasses = new List <ITypeReference>(1)
                    {
                        host.PlatformType.SystemObject
                    },
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = nameTable.GetNameFor("Test"),
                };
                rootUnitNamespace.Members.Add(testClass);
                assembly.AllTypes.Add(testClass);

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = testClass,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = nameTable.GetNameFor("Main"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                testClass.Methods.Add(mainMethod);

                var body = new SourceMethodBody(host)
                {
                    MethodDefinition = mainMethod,
                    LocalsAreZeroed  = true
                };
                mainMethod.Body = body;

                var block = new BlockStatement();
                body.Block = block;

                var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");
                var writeLine     = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);

                var call = new MethodCall()
                {
                    IsStaticCall = true, MethodToCall = writeLine, Type = host.PlatformType.SystemVoid
                };
                call.Arguments.Add(new CompileTimeConstant()
                {
                    Type = host.PlatformType.SystemString, Value = "hello"
                });
                block.Statements.Add(new ExpressionStatement()
                {
                    Expression = call
                });
                block.Statements.Add(new ReturnStatement());

                using (var peStream = File.Create("hello.exe")) {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
示例#49
0
        public void Compile(string fileName)
        {
            string appName = Path.GetFileNameWithoutExtension(fileName);
            string exeName = appName + ".exe";
            string src = "";
            using (TextReader file = new StreamReader(fileName))
            {
                src = file.ReadToEnd();
            }

            var nameTable = new NameTable();
            using (var host = new PeReader.DefaultHost(nameTable))
            {
                // Load Mirage types

                IModule module = host.LoadUnitFrom("Mirage.dll") as IModule;
                if (module == null || module is Dummy)
                {
                    return;
                }
                var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine");
                var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput");
                var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput");

                // Create assembly

                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
                var assembly = new Assembly()
                {
                    Name = nameTable.GetNameFor(appName),
                    ModuleName = nameTable.GetNameFor(exeName),
                    PlatformType = host.PlatformType,
                    Kind = ModuleKind.ConsoleApplication,
                    RequiresStartupStub = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                // Create namespace

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit = assembly;

                // Create module class

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory = host.InternFactory,
                    IsClass = true,
                    Name = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                // Create program class

                var programClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory = host.InternFactory,
                    IsClass = true,
                    IsPublic = true,
                    Methods = new List<IMethodDefinition>(1),
                    Name = nameTable.GetNameFor("Program"),
                };
                programClass.BaseClasses = new List<ITypeReference>() { host.PlatformType.SystemObject };
                rootUnitNamespace.Members.Add(programClass);

                // Add types to the assembly

                assembly.AllTypes.Add(machineType);
                foreach (var t in machineType.NestedTypes)
                {
                    assembly.AllTypes.Add(t);
                }
                assembly.AllTypes.Add(inputType);
                assembly.AllTypes.Add(outputType);
                assembly.AllTypes.Add(programClass);

                // Create main method

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = programClass,
                    InternFactory = host.InternFactory,
                    IsCil = true,
                    IsStatic = true,
                    Name = nameTable.GetNameFor("Main"),
                    Type = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                programClass.Methods.Add(mainMethod);

                // Create constructors and methods

                IMethodReference machineConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    machineType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );

                IMethodReference inputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    inputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );
                var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType);

                IMethodReference outputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    outputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );
                var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType);

                var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers"));
                var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers"));
                var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer"));
                var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer"));
                var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer"));
                var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer"));
                var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer"));
                var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers"));

                var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear"));
                var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add"));
                var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec"));
                var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not"));
                var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And"));
                var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or"));
                var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor"));
                var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal"));
                var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar"));

                var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString);
                var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type);
                var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type);

                var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz"));

                // Create program code

                var labels = new Stack<ILGeneratorLabel>(100);

                var ilGenerator = new ILGenerator(host, mainMethod);
                ilGenerator.Emit(OperationCode.Newobj, machineConstructor);
                ilGenerator.Emit(OperationCode.Stloc_0);
                ilGenerator.Emit(OperationCode.Newobj, inputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_1);
                ilGenerator.Emit(OperationCode.Newobj, outputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_2);

                int pc = 0;
                while (pc < src.Length)
                {
                    char opcode = src[pc++];

                    switch (opcode)
                    {
                        case '>':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opIncPointers);
                            break;
                        case '<':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDecPointers);
                            break;
                        case ']':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer);
                            break;
                        case '[':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer);
                            break;
                        case '#':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer);
                            break;
                        case '$':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer);
                            break;
                        case '=':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer);
                            break;
                        case '%':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opXchPointers);
                            break;
                        case '_':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opClear);
                            break;
                        case '+':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opAdd);
                            break;
                        case '-':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDec);
                            break;
                        case '~':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opNot);
                            break;
                        case '&':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opAnd);
                            break;
                        case '|':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opOr);
                            break;
                        case '^':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opXor);
                            break;
                        case '*':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opSal);
                            break;
                        case '/':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opSar);
                            break;
                        case '(':
                            int dataStart = pc;
                            int dataEnd = dataStart;
                            while (src[pc++] != ')')
                            {
                                dataEnd = pc;
                            }
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart));
                            ilGenerator.Emit(OperationCode.Callvirt, opLoadData);
                            break;
                        case '?':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldloc_1);
                            ilGenerator.Emit(OperationCode.Call, inputCast);
                            ilGenerator.Emit(OperationCode.Callvirt, opInput);
                            break;
                        case '!':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldloc_2);
                            ilGenerator.Emit(OperationCode.Call, outputCast);
                            ilGenerator.Emit(OperationCode.Callvirt, opOutput);
                            break;
                        case '{':
                            var cycleStart = new ILGeneratorLabel();
                            var cycleEnd = new ILGeneratorLabel();
                            labels.Push(cycleStart);
                            labels.Push(cycleEnd);
                            ilGenerator.Emit(OperationCode.Br, cycleEnd);
                            ilGenerator.MarkLabel(cycleStart);
                            break;
                        case '}':
                            ilGenerator.MarkLabel(labels.Pop());
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opJz);
                            ilGenerator.Emit(OperationCode.Ldc_I4_0);
                            ilGenerator.Emit(OperationCode.Ceq);
                            ilGenerator.Emit(OperationCode.Stloc_3);
                            ilGenerator.Emit(OperationCode.Ldloc_3);
                            ilGenerator.Emit(OperationCode.Brtrue, labels.Pop());
                            break;
                        default:
                            break;
                    }
                }

                ilGenerator.Emit(OperationCode.Ret);

                mainMethod.Body = new ILGeneratorMethodBody(
                    ilGenerator,
                    true,
                    8,
                    mainMethod,
                    new List<ILocalDefinition>() {
                        new LocalDefinition() { Type = machineType },
                        new LocalDefinition() { Type = inputType },
                        new LocalDefinition() { Type = outputType },
                        new LocalDefinition() { Type = host.PlatformType.SystemInt32 },
                    },
                    Enumerable<ITypeDefinition>.Empty
                );

                using (var peStream = File.Create(exeName))
                {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
        private NamespaceTypeDefinition GenerateTypeB(IUnitNamespace rootNamespace, ITypeReference baseType)
        {
            var nt = Host.NameTable;
            var typeB = new NamespaceTypeDefinition
                            {
                                ContainingUnitNamespace = rootNamespace,
                                Name = nt.GetNameFor("B"),
                                InternFactory = Host.InternFactory,
                                IsClass = true,
                                BaseClasses = { baseType }
                            };

            var overrideGetMethod = new MethodDefinition
                                        {
                                            Name = nt.GetNameFor("Get"),
                                            IsCil = true,
                                            IsVirtual = true,
                                            Visibility = TypeMemberVisibility.Assembly,
                                            Type = Host.PlatformType.SystemString,
                                            ContainingTypeDefinition = typeB,
                                            InternFactory = Host.InternFactory
                                        };
            typeB.Methods.Add(overrideGetMethod);
            var il = new ILGenerator(Host);
            var body = new ILGeneratorMethodBody(il, true, 1) {MethodDefinition = overrideGetMethod};
            overrideGetMethod.Body = body;

            il.Emit(OperationCode.Ldstr, "1");
            il.Emit(OperationCode.Ret);
            return typeB;
        }
示例#51
0
        // this method creates a new method for the given class
        public MethodDefinition createNewMethod(String methodName, NamespaceTypeDefinition methodClass, ITypeReference methodType,
            TypeMemberVisibility methodVisibility, List<IParameterDefinition> methodParameters,
            CallingConvention methodCallingConvention, bool isStatic, bool isAbstract, bool isVirtual)
        {
            // create a new method
            MethodDefinition newMethod = new MethodDefinition();
            newMethod.ContainingTypeDefinition = methodClass;
            newMethod.InternFactory = this.host.InternFactory;
            newMethod.IsCil = true;
            newMethod.IsStatic = isStatic;
            newMethod.Name = this.host.NameTable.GetNameFor(methodName);
            newMethod.Type = methodType;
            newMethod.Visibility = methodVisibility;
            newMethod.IsAbstract = isAbstract;
            newMethod.IsVirtual = isVirtual;
            newMethod.Parameters = methodParameters;
            newMethod.CallingConvention = methodCallingConvention;

            // add method to class
            if (methodClass.Methods == null) {
                methodClass.Methods = new List<IMethodDefinition>();
                methodClass.Methods.Add(newMethod);
            }
            else {
                methodClass.Methods.Add(newMethod);
            }

            return newMethod;
        }
    private Assembly TranslateMetadata(R.IAssemblySymbol assemblySymbol) {
      Contract.Requires(assemblySymbol != null);
      Contract.Ensures(Contract.Result<Assembly>() != null);

      IAssemblyReference cciAssemblyReference = null;
      Assembly cciAssembly = null;
      if (assemblySymbolCache.TryGetValue(assemblySymbol, out cciAssemblyReference)) {
        cciAssembly = cciAssemblyReference as Assembly;
        System.Diagnostics.Debug.Assert(cciAssembly != null);
        return cciAssembly;
      }

      var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
      var name = assemblySymbol.Identity.Name;
      var iname = nameTable.GetNameFor(name);
      cciAssembly = new Assembly() {
        Attributes = this.TranslateMetadata(assemblySymbol.GetAttributes()),
        Name = iname,
        Locations = Helper.WrapLocations(assemblySymbol.Locations),
        ModuleName = iname,
        Kind = ModuleKind.DynamicallyLinkedLibrary,
        RequiresStartupStub = this.host.PointerSize == 4,
        TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
        Version = assemblySymbol.Identity.Version,
      };
      cciAssembly.AssemblyReferences.Add(coreAssembly);
      this.assemblySymbolCache.Add(assemblySymbol, cciAssembly);
      this.module = cciAssembly;

      var rootUnitNamespace = new RootUnitNamespace();
      cciAssembly.UnitNamespaceRoot = rootUnitNamespace;
      rootUnitNamespace.Unit = cciAssembly;
      this.namespaceSymbolCache.Add(assemblySymbol.GlobalNamespace, rootUnitNamespace);

      var moduleClass = new NamespaceTypeDefinition() {
        ContainingUnitNamespace = rootUnitNamespace,
        InternFactory = host.InternFactory,
        IsClass = true,
        Name = nameTable.GetNameFor("<Module>"),
      };
      cciAssembly.AllTypes.Add(moduleClass);


      foreach (var m in assemblySymbol.GlobalNamespace.GetMembers()) {

        var namespaceSymbol = m as NamespaceSymbol;
        if (namespaceSymbol != null) {
          var cciNtd = TranslateMetadata(namespaceSymbol);
          rootUnitNamespace.Members.Add(cciNtd);
          continue;
        }

        var typeSymbol = m as TypeSymbol;
        if (typeSymbol != null) {
          var namedType = TranslateMetadata((R.INamedTypeSymbol) typeSymbol);
          // TODO: fix
          //namedType.Attributes = TranslateMetadata(typeSymbol.GetAttributes());
          var cciType = (INamespaceTypeDefinition) namedType;
          rootUnitNamespace.Members.Add(cciType);
          //cciAssembly.AllTypes.Add(cciType);
          continue;
        }

      }

      //if (this.entryPoint != null) {
      //  cciAssembly.Kind = ModuleKind.ConsoleApplication;
      //  cciAssembly.EntryPoint = this.entryPoint;
      //}

      return cciAssembly;
    }
        protected override Assembly Generate()
        {
            var nt = Host.NameTable;
            var mscorlib = Host.LoadAssembly(Host.CoreAssemblySymbolicIdentity);
            var assembly = new Assembly
                               {
                                   Name = nt.GetNameFor(AssemblyName),
                                   ModuleName = nt.GetNameFor(DllName),
                                   Kind = ModuleKind.DynamicallyLinkedLibrary,
                                   TargetRuntimeVersion = mscorlib.TargetRuntimeVersion,
                                   MetadataFormatMajorVersion = 2
                               };
            assembly.AssemblyReferences.Add(mscorlib);

            var rootNamespace = new RootUnitNamespace();
            assembly.UnitNamespaceRoot = rootNamespace;
            rootNamespace.Unit = assembly;

            // define module
            var module = new NamespaceTypeDefinition
                             {
                                 ContainingUnitNamespace = rootNamespace,
                                 Name = nt.GetNameFor("<Module>"),
                                 InternFactory = Host.InternFactory,
                                 IsClass = true
                             };
            assembly.AllTypes.Add(module);

            // define X<T>
            var xType = new NamespaceTypeDefinition
                            {
                                ContainingUnitNamespace = rootNamespace,
                                Name = nt.GetNameFor("X"),
                                InternFactory = Host.InternFactory,
                                IsClass = true
                            };
            var typeParameter = new GenericTypeParameter
                                    {
                                        Name = nt.GetNameFor("T"),
                                        InternFactory = Host.InternFactory,
                                        IsClass = true,
                                        DefiningType = xType
                                    };
            xType.GenericParameters.Add(typeParameter);
            assembly.AllTypes.Add(xType);

            var aType = new NamespaceTypeDefinition
                            {
                                ContainingUnitNamespace = rootNamespace,
                                Name = nt.GetNameFor("A"),
                                InternFactory = Host.InternFactory,
                                IsClass = true
                            };
            assembly.AllTypes.Add(aType);

            var bType = new NamespaceTypeDefinition
                            {
                                ContainingUnitNamespace = rootNamespace,
                                Name = nt.GetNameFor("B"),
                                InternFactory = Host.InternFactory,
                                IsClass = true
                            };
            assembly.AllTypes.Add(bType);

            aType.BaseClasses.Add(new GenericTypeInstanceReference { GenericType = xType, GenericArguments = { bType }, InternFactory = Host.InternFactory });
            bType.BaseClasses.Add(new GenericTypeInstanceReference { GenericType = xType, GenericArguments = { aType }, InternFactory = Host.InternFactory });

            return assembly;
        }
    /// <summary>
    /// Creates the appropriate kind of type definition (nested or not) and
    /// adds it to the type symbol cache.
    /// </summary>
    private NamedTypeDefinition CreateTypeDefinition(R.INamedTypeSymbol typeSymbol) {
      Contract.Requires(typeSymbol != null);

      NamedTypeDefinition cciType;

      if (typeSymbol.ContainingType == null) {
        cciType = new NamespaceTypeDefinition() {
          ContainingUnitNamespace = (IUnitNamespace)this.namespaceSymbolCache[typeSymbol.ContainingNamespace],
          IsPublic = typeSymbol.DeclaredAccessibility == R.CommonAccessibility.Public,
        };
      } else {
        cciType = new NestedTypeDefinition() {
          ContainingTypeDefinition = (ITypeDefinition)this.typeSymbolCache[typeSymbol.ContainingType],
          Visibility = TypeMemberVisibility.Private,
        };
      }
      if (typeSymbol.TypeKind == R.CommonTypeKind.Interface) {
        cciType.IsAbstract = true;
        cciType.IsInterface = true;
      } else {
        cciType.BaseClasses = new List<ITypeReference> { this.Map(typeSymbol.BaseType) };
        cciType.IsBeforeFieldInit = true; // REVIEW: How to determine from typeSymbol?
      }
      cciType.IsClass = typeSymbol.IsReferenceType;
      cciType.IsValueType = typeSymbol.IsValueType;
      cciType.IsSealed = typeSymbol.IsSealed;
      cciType.InternFactory = this.host.InternFactory;
      cciType.Locations = Helper.WrapLocations(typeSymbol.Locations);
      cciType.Name = this.host.NameTable.GetNameFor(typeSymbol.Name);

      this.typeSymbolCache.Add(typeSymbol, cciType);
      return cciType;
    }
示例#55
0
        static void mergeClassWithAncestor(NamespaceTypeDefinition mergeTargetClass, PeReader.DefaultHost host) {

            // get class from which was inherited
            ITypeDefinition ancestorClass = null;
            INamedEntity ancestorClassName = null;
            if (mergeTargetClass.BaseClasses.Count == 1) {

                // TODO
                // entferne wenn Methode umgeschrieben
                /*
                // ignore inheritance from System.Object
                if (mergeTargetClass.BaseClasses[0].ToString() != "System.Object") {
                    ancestorClass = (mergeTargetClass.BaseClasses[0] as NamespaceTypeDefinition);
                }
                // return if ancestor class equals System.Object
                else {
                    return;
                }
                */



                // check base class is of type NamespaceTypeDefinition
                if (mergeTargetClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition != null) {
                    ancestorClass = (mergeTargetClass.BaseClasses.ElementAt(0) as ITypeDefinition);
                    ancestorClassName = (mergeTargetClass.BaseClasses.ElementAt(0) as INamedEntity);
                }                
                // ignore inheritance from System.Object
                else if (mergeTargetClass.BaseClasses[0].ToString() == "System.Object") {                                       
                    return;                 
                }
                // check for needed values in base class and its resolved value (for example when base class of type NamespaceTypeReference)
                else if ((mergeTargetClass.BaseClasses.ElementAt(0).ResolvedType as ITypeDefinition != null)
                    && (mergeTargetClass.BaseClasses.ElementAt(0) as INamedEntity != null)) {
                    // TODO
                    // weiss nicht ob es Sinn macht externe Klassen wie z.B. system.ValueType
                    // in die aktuelle Klasse rein zu mergen => denn Trick mit methoden auf Virtual stellen
                    // damit JIT Compiler unsere Methoden aufruft klappt nicht in dem Fall (da wir die Methoden von System.ValueType nicht umschreiben koennen)
                    //ancestorClass = (mergeTargetClass.BaseClasses[0].ResolvedType as ITypeDefinition);
                    //ancestorClassName = (mergeTargetClass.BaseClasses[0].ResolvedType as INamedEntity);
                    return;
                }
                else {
                    throw new ArgumentException("Do not know how to handle base class.");
                }
            }
            else {
                throw new ArgumentException("Do not know how to handle multiple inheritance.");
            }


            // copy all attributes from the ancestor class to the current class
            if (ancestorClass.Fields != null) {
                globalLog.writeLine("Copying fileds");
                foreach (FieldDefinition field in ancestorClass.Fields) {
                    FieldDefinition copy = new FieldDefinition();
                    globalLog.writeLine("Copying field: " + field.Name.ToString());
                    copyField(copy, field);
                    copy.ContainingTypeDefinition = mergeTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = mergeTargetClass.InternFactory;

                    mergeTargetClass.Fields.Add(copy);
                }
                globalLog.writeLine("");
            }

            // list of all constructors of the ancestor class
            List<MethodDefinition> copiedAncestorConstructors = new List<MethodDefinition>();            

            // copy methods from the ancestor class to the current class
            if (ancestorClass.Methods != null) {
                globalLog.writeLine("Copying methods");
                foreach (IMethodDefinition method in ancestorClass.Methods) {
                    globalLog.writeLine("Copying method: " + method.Name.ToString());

                    // check if the method is a constructor
                    if (method.IsConstructor) {
                        MethodDefinition copiedAncestorConstructor = new MethodDefinition();
                        copyMethod(copiedAncestorConstructor, method, host);

                        // TODO
                        // name muss noch geaendert werden
                        String tempName = "ctor_" + ancestorClassName.Name.ToString();
                        copiedAncestorConstructor.Name = host.NameTable.GetNameFor(tempName);

                        // constructor has the "SpecialName" (the name describes the functionality)
                        // and "RTSpecialName" (runtime should check name encoding) flag set 
                        // runtime will raise an exception if these flags are set for a copied constructor
                        // which is added as a normal function 
                        copiedAncestorConstructor.IsSpecialName = false;
                        copiedAncestorConstructor.IsRuntimeSpecial = false;




                        // TODO:
                        // vielleicht einfach von späterer Schleife machen lassen (sollte jetzt schon gehen, aber noch nicht getestet,
                        // deshalb erst ein mal drin gelassen)
                        // copy constructor and rewrite instructions to use attributes and functions
                        // inside the same class
                        var testIlGenerator = new ILGenerator(host, copiedAncestorConstructor);
                        foreach (var operation in copiedAncestorConstructor.Body.Operations) {
                            switch (operation.OperationCode) {

                                case OperationCode.Call:

                                    // HIER NOCH CHECKEN OB ANDERE FUNKTIONEN INNERHALB DES ANCESTORS AUFGERUFEN WERDEN
                                    // DIESE MUESSEN UMGELEITET WERDEN

                                    /*
                                    Microsoft.Cci.MutableCodeModel.MethodDefinition blah = null;
                                    if (operation.Value is Microsoft.Cci.MutableCodeModel.MethodDefinition) {
                                        blah = (Microsoft.Cci.MutableCodeModel.MethodDefinition)(operation.Value);
                                        NamespaceTypeDefinition test = (NamespaceTypeDefinition)blah.ContainingTypeDefinition;

                                        if (ancestorClass.Name.Equals(test.Name)) {
                                            System.Console.WriteLine("Ja");
                                        }


                                    }
                                    */

                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                    break;

                                case OperationCode.Stfld:

                                    FieldDefinition attribute = (FieldDefinition)operation.Value;

                                    // search for the method attribute that is used in the copied constructor
                                    // and replace it with the method attribute from the current class
                                    FieldDefinition foundField = null;
                                    foreach (FieldDefinition field in mergeTargetClass.Fields) {
                                        if (attribute.Name.Equals(field.Name)
                                            && attribute.Type.Equals(field.Type)) {
                                            foundField = field;
                                            break;
                                        }
                                    }
                                    if (foundField == null) {
                                        System.Console.WriteLine("Attribute not found");
                                        return;
                                    }

                                    testIlGenerator.Emit(operation.OperationCode, foundField);

                                    break;

                                default:
                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                    break;

                            }
                        }

                        // create new body
                        List<ILocalDefinition> variableListCopy = new List<ILocalDefinition>(method.Body.LocalVariables);
                        List<ITypeDefinition> privateHelperTypesListCopy = new List<ITypeDefinition>(method.Body.PrivateHelperTypes);
                        var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, copiedAncestorConstructor, variableListCopy, privateHelperTypesListCopy);
                        copiedAncestorConstructor.Body = newBody;

                        // set intern factory of the copied constructor to the one of the class
                        // (without it, the generated binary file will have strange results like call always the same method)
                        copiedAncestorConstructor.InternFactory = mergeTargetClass.InternFactory;

                        // add copied constructor to the class
                        copiedAncestorConstructor.ContainingTypeDefinition = mergeTargetClass;
                        copiedAncestorConstructor.Visibility = TypeMemberVisibility.Private;
                        mergeTargetClass.Methods.Add(copiedAncestorConstructor);

                        // add copied ancestor constructor to the list of copied ancestor constructors
                        copiedAncestorConstructors.Add(copiedAncestorConstructor);

                        continue;
                    }

                    else {

                        // copy method
                        MethodDefinition copy = new MethodDefinition();
                        copyMethod(copy, method, host);
                        copy.ContainingTypeDefinition = mergeTargetClass;

                        // set intern factory of the copied method to the one of the class
                        // (without it, the generating of the binary file will have strange results)
                        copy.InternFactory = mergeTargetClass.InternFactory;

                        // add method to the class
                        if (mergeTargetClass.Methods == null) {
                            mergeTargetClass.Methods = new List<IMethodDefinition>();
                        }
                        mergeTargetClass.Methods.Add(copy);
                    }
                }
                globalLog.writeLine("");
            }


            // rewrite constructors of the class to call the copied constructor instead of
            // the constructor of the ancestor class
            // (rewriting methods is handled later)
            foreach (MethodDefinition method in mergeTargetClass.Methods) {

                // check if method is a constructor
                if (method.IsConstructor) {

                    var testIlGenerator = new ILGenerator(host, method);
                    foreach (var operation in method.Body.Operations) {

                        switch (operation.OperationCode) {

                            // only call instructions that call a constructor have to be redirected
                            case OperationCode.Call:

                                MethodDefinition calledMethod = (MethodDefinition)operation.Value;
                                if (calledMethod.IsConstructor) {

                                    // TODO hier treten noch Probleme auf, wenn System.Object ist nicht der oberste Ancestor
                                    // sondern z.B. System.ValueType
                                    // check if the called constructor is not the constructor of System.Object
                                    // and if the constructor that is called is not a constructor of THIS class
                                    NamespaceTypeDefinition calledMethodNamespace = (NamespaceTypeDefinition)calledMethod.ContainingTypeDefinition;
                                    if (calledMethodNamespace.ToString() != "System.Object"
                                        && !calledMethodNamespace.Name.Equals(mergeTargetClass.Name)) {

                                        // search for the copied constructor that has to be called
                                        // (it is searched by parameter types because they always are named the same ".ctor")
                                        MethodDefinition copiedConstructorToCall = null;
                                        foreach (MethodDefinition copiedAncestorConstructor in copiedAncestorConstructors) {

                                            // check if the count of the parameters of the called constructor and the copied constructor are the same
                                            if (copiedAncestorConstructor.ParameterCount == calledMethod.ParameterCount) {

                                                // check if the parameters have the same type in the same order
                                                bool found = true;
                                                for (int i = 0; i < calledMethod.ParameterCount; i++) {
                                                    if (calledMethod.Parameters[i].Type != copiedAncestorConstructor.Parameters[i].Type) {
                                                        found = false;
                                                        break;
                                                    }
                                                }
                                                if (found) {
                                                    copiedConstructorToCall = copiedAncestorConstructor;
                                                    break;
                                                }
                                            }
                                        }
                                        if (copiedConstructorToCall == null) {
                                            throw new ArgumentException("No copied constructor with the same parameter types in the same order.");
                                        }

                                        // call copied constructor instead of constructor of the ancestor
                                        testIlGenerator.Emit(operation.OperationCode, copiedConstructorToCall);

                                    }
                                    // just emit if the called constructor is the constructor of System.Object
                                    else {
                                        testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                    }
                                }

                                // just emit operation if no constructor is called
                                // (rewriting methods is handled later)
                                else {
                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                }

                                break;

                            // just emit operation if none of the above cases match
                            default:
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                break;
                        }
                    }

                    // create new body
                    List<ILocalDefinition> variableListCopy = new List<ILocalDefinition>(method.Body.LocalVariables);
                    List<ITypeDefinition> privateHelperTypesListCopy = new List<ITypeDefinition>(method.Body.PrivateHelperTypes);
                    var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, method, variableListCopy, privateHelperTypesListCopy);
                    method.Body = newBody;
                }
            }


            // rewrite all methods to use local attributes/methods instead of the ones of the ancestor
            foreach (MethodDefinition method in mergeTargetClass.Methods) {

                var testIlGenerator = new ILGenerator(host, method);
                foreach (var operation in method.Body.Operations) {
                    switch (operation.OperationCode) {

                        case OperationCode.Stfld:
                        case OperationCode.Ldfld:

                            // get namespace of attribute
                            FieldDefinition attribute = (FieldDefinition)operation.Value;
                            INamedTypeDefinition attributeNamespace = (INamedTypeDefinition)attribute.ContainingTypeDefinition;

                            // check if namespace of attribute equals the namespace of THIS class
                            // => just emit operation
                            if (mergeTargetClass.Name.Equals(attributeNamespace.Name)) {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                continue;
                            }

                            // try the namespace of all ancestors of this class to see if it was copied
                            else {

                                // flag that indicates if the operation was emitted during the search loop
                                bool operationEmitted = false;

                                // search through all ancestors to find the namespace of the used attribute
                                NamespaceTypeDefinition tempAncestorClass = mergeTargetClass;
                                while (true) {

                                    // get class from which was inherited
                                    if (tempAncestorClass.BaseClasses.Count == 1) {
                                        // ignore inheritance from System.Object
                                        if (tempAncestorClass.BaseClasses[0].ToString() != "System.Object") {
                                            tempAncestorClass = (tempAncestorClass.BaseClasses[0] as NamespaceTypeDefinition);
                                        }
                                        // return if ancestor class equals System.Object
                                        else {
                                            break;
                                        }
                                    }
                                    else {
                                        throw new ArgumentException("Do not know how to handle multiple inheritance.");
                                    }

                                    // check namespace of used attribute is equal to namespace of ancestor
                                    // => change target of operation to THIS class                                        
                                    if (tempAncestorClass.Name.Equals(attributeNamespace.Name)) {

                                        // search for the method attribute that is used in the copied method
                                        // and replace it with the method attribute from the current class
                                        FieldDefinition foundField = null;
                                        foreach (FieldDefinition field in mergeTargetClass.Fields) {
                                            if (attribute.Name.Equals(field.Name)
                                                && attribute.Type.Equals(field.Type)) {
                                                foundField = field;
                                                break;
                                            }
                                        }
                                        if (foundField == null) {
                                            throw new ArgumentException("Attribute not found.");
                                        }

                                        // emit operation and set flag that it was emitted
                                        operationEmitted = true;
                                        testIlGenerator.Emit(operation.OperationCode, foundField);
                                        break;
                                    }
                                }

                                // if operation was not emitted yet => emit it
                                if (operationEmitted == false) {
                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                }
                            }
                            break;

                        case OperationCode.Call:

                            // just emit if value is of type method reference
                            if (operation.Value is Microsoft.Cci.MutableCodeModel.MethodReference) {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                continue;
                            }

                            // get namespace of called method
                            MethodDefinition calledMethod = (MethodDefinition)operation.Value;
                            NamespaceTypeDefinition calledMethodNamespace = (NamespaceTypeDefinition)calledMethod.ContainingTypeDefinition;

                            // check if namespace of called method equals the namespace of THIS class
                            // => just emit operation
                            if (mergeTargetClass.Name.Equals(calledMethodNamespace.Name)) {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                continue;
                            }

                            // try the namespace of all ancestors of this class to see if it was copied
                            else {

                                // flag that indicates if the operation was emitted during the search loop
                                bool operationEmitted = false;

                                // search through all ancestors to find the namespace of the called method
                                NamespaceTypeDefinition tempAncestorClass = mergeTargetClass;
                                while (true) {

                                    // get class from which was inherited
                                    if (tempAncestorClass.BaseClasses.Count == 1) {
                                        // ignore inheritance from System.Object
                                        if (tempAncestorClass.BaseClasses[0].ToString() != "System.Object") {
                                            tempAncestorClass = (tempAncestorClass.BaseClasses[0] as NamespaceTypeDefinition);
                                        }
                                        // return if ancestor class equals System.Object
                                        else {
                                            break;
                                        }
                                    }
                                    else {
                                        throw new ArgumentException("Do not know how to handle multiple inheritance.");
                                    }

                                    // check namespace of called method is equal to namespace of ancestor, if the same
                                    // => find copied method in THIS class
                                    // => change target of operation to method in THIS class    
                                    if (tempAncestorClass.Name.Equals(calledMethodNamespace.Name)) {

                                        // search through all methods in THISS class and search for the copied one
                                        MethodDefinition foundMethod = null;
                                        foreach (MethodDefinition newMethod in mergeTargetClass.Methods) {

                                            // skip constructors (can not be called from the ancestor)
                                            if (newMethod.IsConstructor) {
                                                continue;
                                            }

                                            if (newMethod.ParameterCount == calledMethod.ParameterCount) {

                                                // check if the parameters have the same type in the same order
                                                bool parameterCorrect = true;
                                                for (int i = 0; i < calledMethod.ParameterCount; i++) {
                                                    if (calledMethod.Parameters[i].Type != newMethod.Parameters[i].Type) {
                                                        parameterCorrect = false;
                                                        break;
                                                    }
                                                }

                                                // if the parameters are correct => check the name
                                                if (parameterCorrect) {
                                                    if (calledMethod.Name.Equals(newMethod.Name)) {

                                                        // if name is the same => found method to call
                                                        foundMethod = newMethod;
                                                        break;
                                                    }
                                                }
                                            }
                                        }

                                        // check if the method we want to call was found
                                        if (foundMethod == null) {
                                            throw new ArgumentException("Did not find a method to call.");
                                        }

                                        // emit operation and set flag that it was emitted
                                        operationEmitted = true;
                                        testIlGenerator.Emit(operation.OperationCode, foundMethod);
                                        break;

                                    }
                                }

                                // if operation was not emitted yet => emit it
                                if (operationEmitted == false) {
                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                }
                            }
                            break;

                        // just emit operation if none of the above cases match
                        default:
                            testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            break;

                    }
                }

                // create new body
                List<ILocalDefinition> variableListCopy = new List<ILocalDefinition>(method.Body.LocalVariables);
                List<ITypeDefinition> privateHelperTypesListCopy = new List<ITypeDefinition>(method.Body.PrivateHelperTypes);
                var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, method, variableListCopy, privateHelperTypesListCopy);
                method.Body = newBody;
            }
        }
示例#56
0
        public override void RewriteChildren(NamespaceTypeDefinition namespaceTypeDefinition)
        {
            string typeName = Util.FullyQualifiedTypeNameFromType(namespaceTypeDefinition);
            Element currentElement = null;

            // Unlike all other types that visited from either a namespace or a parent, 
            // the module type is visited from the containing module
            if (_systemTypes.Contains(typeName))
            {
                currentElement = new SpecialTrimType(typeName);
                _trimElements.Push(currentElement);
            }

            this.RewriteChildren((NamedTypeDefinition)namespaceTypeDefinition);
            //namespaceTypeDefinition.ContainingUnitNamespace = this.GetCurrentNamespace();

            if (!_systemTypes.Contains(typeName))
            {
                TypeElement type = _currentTrimAssembly.GetTypeElement(typeName);
                MutateType(namespaceTypeDefinition, type);
            }
            if (currentElement != null)
            {
                _trimElements.Pop();
            }
        }
示例#57
0
        static void Main(string[] args)
        {
            var nameTable = new NameTable();

            using (var host = new PeReader.DefaultHost(nameTable)) {
                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

                var assembly = new Assembly()
                {
                    Name                 = nameTable.GetNameFor("hello"),
                    ModuleName           = nameTable.GetNameFor("hello.exe"),
                    PlatformType         = host.PlatformType,
                    Kind                 = ModuleKind.ConsoleApplication,
                    RequiresStartupStub  = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit     = assembly;

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass = true,
                    Name    = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                var testClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = nameTable.GetNameFor("Test"),
                };
                rootUnitNamespace.Members.Add(testClass);
                assembly.AllTypes.Add(testClass);
                testClass.BaseClasses = new List <ITypeReference>()
                {
                    host.PlatformType.SystemObject
                };

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = testClass,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = nameTable.GetNameFor("Main"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                testClass.Methods.Add(mainMethod);

                var ilGenerator = new ILGenerator(host, mainMethod);

                var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");
                var writeLine     = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);

                ilGenerator.Emit(OperationCode.Ldstr, "hello");
                ilGenerator.Emit(OperationCode.Call, writeLine);
                ilGenerator.Emit(OperationCode.Ret);

                var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);
                mainMethod.Body = body;

                using (var peStream = File.Create("hello.exe")) {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
示例#58
0
        public void Compile(string fileName)
        {
            string appName = Path.GetFileNameWithoutExtension(fileName);
            string exeName = appName + ".exe";
            string src     = "";

            using (TextReader file = new StreamReader(fileName))
            {
                src = file.ReadToEnd();
            }

            var nameTable = new NameTable();

            using (var host = new PeReader.DefaultHost(nameTable))
            {
                // Load Mirage types

                IModule module = host.LoadUnitFrom("Mirage.dll") as IModule;
                if (module == null || module is Dummy)
                {
                    return;
                }
                var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine");
                var inputType   = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput");
                var outputType  = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput");

                // Create assembly

                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
                var assembly     = new Assembly()
                {
                    Name                 = nameTable.GetNameFor(appName),
                    ModuleName           = nameTable.GetNameFor(exeName),
                    PlatformType         = host.PlatformType,
                    Kind                 = ModuleKind.ConsoleApplication,
                    RequiresStartupStub  = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                // Create namespace

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit     = assembly;

                // Create module class

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass = true,
                    Name    = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                // Create program class

                var programClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = nameTable.GetNameFor("Program"),
                };
                programClass.BaseClasses = new List <ITypeReference>()
                {
                    host.PlatformType.SystemObject
                };
                rootUnitNamespace.Members.Add(programClass);

                // Add types to the assembly

                assembly.AllTypes.Add(machineType);
                foreach (var t in machineType.NestedTypes)
                {
                    assembly.AllTypes.Add(t);
                }
                assembly.AllTypes.Add(inputType);
                assembly.AllTypes.Add(outputType);
                assembly.AllTypes.Add(programClass);

                // Create main method

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = programClass,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = nameTable.GetNameFor("Main"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                programClass.Methods.Add(mainMethod);

                // Create constructors and methods

                IMethodReference machineConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    machineType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );

                IMethodReference inputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    inputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );
                var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType);

                IMethodReference outputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    outputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );
                var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType);

                var opIncPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers"));
                var opDecPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers"));
                var opIncHiPointer     = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer"));
                var opDecHiPointer     = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer"));
                var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer"));
                var opLoadHiPointer    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer"));
                var opDragLoPointer    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer"));
                var opXchPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers"));

                var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear"));
                var opAdd   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add"));
                var opDec   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec"));
                var opNot   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not"));
                var opAnd   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And"));
                var opOr    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or"));
                var opXor   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor"));
                var opSal   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal"));
                var opSar   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar"));

                var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString);
                var opInput    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type);
                var opOutput   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type);

                var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz"));

                // Create program code

                var labels = new Stack <ILGeneratorLabel>(100);

                var ilGenerator = new ILGenerator(host, mainMethod);
                ilGenerator.Emit(OperationCode.Newobj, machineConstructor);
                ilGenerator.Emit(OperationCode.Stloc_0);
                ilGenerator.Emit(OperationCode.Newobj, inputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_1);
                ilGenerator.Emit(OperationCode.Newobj, outputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_2);

                int pc = 0;
                while (pc < src.Length)
                {
                    char opcode = src[pc++];

                    switch (opcode)
                    {
                    case '>':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opIncPointers);
                        break;

                    case '<':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDecPointers);
                        break;

                    case ']':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer);
                        break;

                    case '[':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer);
                        break;

                    case '#':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer);
                        break;

                    case '$':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer);
                        break;

                    case '=':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer);
                        break;

                    case '%':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opXchPointers);
                        break;

                    case '_':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opClear);
                        break;

                    case '+':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opAdd);
                        break;

                    case '-':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDec);
                        break;

                    case '~':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opNot);
                        break;

                    case '&':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opAnd);
                        break;

                    case '|':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opOr);
                        break;

                    case '^':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opXor);
                        break;

                    case '*':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opSal);
                        break;

                    case '/':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opSar);
                        break;

                    case '(':
                        int dataStart = pc;
                        int dataEnd   = dataStart;
                        while (src[pc++] != ')')
                        {
                            dataEnd = pc;
                        }
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart));
                        ilGenerator.Emit(OperationCode.Callvirt, opLoadData);
                        break;

                    case '?':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldloc_1);
                        ilGenerator.Emit(OperationCode.Call, inputCast);
                        ilGenerator.Emit(OperationCode.Callvirt, opInput);
                        break;

                    case '!':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldloc_2);
                        ilGenerator.Emit(OperationCode.Call, outputCast);
                        ilGenerator.Emit(OperationCode.Callvirt, opOutput);
                        break;

                    case '{':
                        var cycleStart = new ILGeneratorLabel();
                        var cycleEnd   = new ILGeneratorLabel();
                        labels.Push(cycleStart);
                        labels.Push(cycleEnd);
                        ilGenerator.Emit(OperationCode.Br, cycleEnd);
                        ilGenerator.MarkLabel(cycleStart);
                        break;

                    case '}':
                        ilGenerator.MarkLabel(labels.Pop());
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opJz);
                        ilGenerator.Emit(OperationCode.Ldc_I4_0);
                        ilGenerator.Emit(OperationCode.Ceq);
                        ilGenerator.Emit(OperationCode.Stloc_3);
                        ilGenerator.Emit(OperationCode.Ldloc_3);
                        ilGenerator.Emit(OperationCode.Brtrue, labels.Pop());
                        break;

                    default:
                        break;
                    }
                }

                ilGenerator.Emit(OperationCode.Ret);

                mainMethod.Body = new ILGeneratorMethodBody(
                    ilGenerator,
                    true,
                    8,
                    mainMethod,
                    new List <ILocalDefinition>()
                {
                    new LocalDefinition()
                    {
                        Type = machineType
                    },
                    new LocalDefinition()
                    {
                        Type = inputType
                    },
                    new LocalDefinition()
                    {
                        Type = outputType
                    },
                    new LocalDefinition()
                    {
                        Type = host.PlatformType.SystemInt32
                    },
                },
                    Enumerable <ITypeDefinition> .Empty
                    );

                using (var peStream = File.Create(exeName))
                {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }