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
            DefineModule(assembly, rootNamespace);

            var typeA = GenerateTypeA(rootNamespace);
            assembly.AllTypes.Add(typeA);

            var baseType = GenericTypeInstance.GetGenericTypeInstance(typeA, new[] { Host.PlatformType.SystemString }, Host.InternFactory);
            var typeB = GenerateTypeB(rootNamespace, baseType);
            assembly.AllTypes.Add(typeB);

            return assembly;
        }
示例#2
0
        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
            DefineModule(assembly, rootNamespace);

            var typeA = GenerateTypeA(rootNamespace);

            assembly.AllTypes.Add(typeA);

            var baseType = GenericTypeInstance.GetGenericTypeInstance(typeA, new[] { Host.PlatformType.SystemString }, Host.InternFactory);
            var typeB    = GenerateTypeB(rootNamespace, baseType);

            assembly.AllTypes.Add(typeB);

            return(assembly);
        }
示例#3
0
 public override void RewriteChildren(RootUnitNamespace rootUnitNamespace)
 {
     if (rootUnitNamespace.Unit.UnitIdentity.Equals(this.sourceUnit.UnitIdentity))
     {
         rootUnitNamespace.Unit = this.targetUnit;
     }
     base.RewriteChildren(rootUnitNamespace);
 }
示例#4
0
            public override void RewriteChildren(RootUnitNamespace rootUnitNamespace)
            {
                var assemblyReference = rootUnitNamespace.Unit as IAssemblyReference;

                if (assemblyReference != null)
                {
                    rootUnitNamespace.Unit = Rewrite(assemblyReference).ResolvedUnit;
                }

                base.RewriteChildren(rootUnitNamespace);
            }
示例#5
0
        private NamespaceTypeDefinition GetContractClass(RootUnitNamespace unitNamespace)
        {
            var contractClass = UnitHelper.FindType(this.host.NameTable, (IModule)unitNamespace.Unit, "System.Diagnostics.Contracts.Contract")
                                as NamespaceTypeDefinition;

            if (contractClass != null)
            {
                return(contractClass);
            }
            return(CreateContractClass(unitNamespace));
        }
示例#6
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);
 }
示例#7
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);
        }
示例#8
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;
        }
示例#9
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);
                }
            }
        }
示例#10
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;
    }
示例#11
0
文件: Rewriter.cs 项目: xornand/cci
    private NamespaceTypeDefinition GetContractClass(RootUnitNamespace unitNamespace) {
      var contractClass = UnitHelper.FindType(this.host.NameTable, (IModule)unitNamespace.Unit, "System.Diagnostics.Contracts.Contract")
                          as NamespaceTypeDefinition;

      if (contractClass != null) return contractClass;
      return CreateContractClass(unitNamespace);
    }
示例#12
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;
        }
    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;
    }
示例#14
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;

    }
示例#15
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);
        }
示例#16
0
        public InteropHelperReferences(IMetadataHost host, Assembly assembly)
        {
            ITypeReference systemEnvironment = null;

            foreach (var typeRef in assembly.ResolvedAssembly.GetTypeReferences())
            {
                var name = TypeHelper.GetTypeName(typeRef);

                if (string.Equals(name, "System.Environment", StringComparison.Ordinal))
                {
                    systemEnvironment = typeRef;
                    continue;
                }

                if (string.Equals(name, "System.Runtime.InteropServices.Marshal", StringComparison.Ordinal))
                {
                    this.SystemRuntimeInteropServicesMarshal = typeRef;
                }

                if (string.Equals(name, "System.Runtime.CompilerServices.RuntimeHelpers", StringComparison.Ordinal))
                {
                    this.SystemRuntimeCompilerServicesRuntimeHelpers = typeRef;
                }
            }

            var mscorlibAsmRef = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("mscorlib"));

            if (mscorlibAsmRef == null)
            {
                var tempRef = new AssemblyReference
                {
                    Name           = host.NameTable.GetNameFor("mscorlib"),
                    Version        = new Version(4, 0, 0, 0),
                    PublicKeyToken = new List <byte> {
                        0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89
                    }
                };

                mscorlibAsmRef = tempRef;
                assembly.AssemblyReferences.Add(mscorlibAsmRef);
            }

            if (systemEnvironment == null)
            {
                systemEnvironment = CreateTypeReference(host, mscorlibAsmRef, "System.Environment");
            }

            if (this.SystemRuntimeInteropServicesMarshal == null)
            {
                var interopServicesAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime.InteropServices")) ?? mscorlibAsmRef;
                this.SystemRuntimeInteropServicesMarshal = CreateTypeReference(host, interopServicesAssembly, "System.Runtime.InteropServices.Marshal");
            }

            if (this.SystemRuntimeCompilerServicesRuntimeHelpers == null)
            {
                var runtimeAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime")) ?? mscorlibAsmRef;
                this.SystemRuntimeCompilerServicesRuntimeHelpers = CreateTypeReference(host, runtimeAssembly, "System.Runtime.CompilerServices.RuntimeHelpers");
            }

            var getNewLine = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("get_NewLine"),
                ContainingType = systemEnvironment,
                Type           = host.PlatformType.SystemString
            };

            var stringOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpEquality,
                ContainingType = host.PlatformType.SystemString,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                }
            };

            var rootUnitNamespace = new RootUnitNamespace();

            rootUnitNamespace.Members.AddRange(assembly.UnitNamespaceRoot.Members);
            assembly.UnitNamespaceRoot = rootUnitNamespace;
            rootUnitNamespace.Unit     = assembly;

            var typeDef = CreatePInvokeHelpers(rootUnitNamespace, host);

            this.PInvokeHelpers = typeDef;
            rootUnitNamespace.Members.Add(typeDef);
            assembly.AllTypes.Add(typeDef);

            var platformSpecificHelpers = new PlatformSpecificHelpersTypeAdder(host, typeDef, this.SystemRuntimeInteropServicesMarshal);

            var windowsLoaderMethods = platformSpecificHelpers.WindowsLoaderMethods;
            var unixLoaderMethods    = platformSpecificHelpers.UnixLoaderMethods;

            var isUnix = CreateIsUnixField(host, typeDef);

            var isUnixStaticFunction = CreateIsUnixStaticFunction(host, typeDef, getNewLine, stringOpEquality);
            var cctor = CreateCCtor(host, typeDef, isUnix, isUnixStaticFunction);

            var intPtrZero = new FieldReference
            {
                Name           = host.NameTable.GetNameFor("Zero"),
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemIntPtr
            };

            var getLength = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor("get_Length"),
                ContainingType    = host.PlatformType.SystemString,
                Type              = host.PlatformType.SystemInt32,
                CallingConvention = CallingConvention.HasThis
            };

            var getChars = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor("get_Chars"),
                ContainingType    = host.PlatformType.SystemString,
                Type              = host.PlatformType.SystemChar,
                CallingConvention = CallingConvention.HasThis,
                Parameters        = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemInt32
                    }
                }
            };

            var stringToGlobalAnsi = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("StringToHGlobalAnsi"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemIntPtr,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemString
                    }
                }
            };

            var stringToGlobalUni = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("StringToHGlobalUni"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemIntPtr,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemString
                    }
                }
            };

            var intPtrOpInequality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpInequality,
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            var freeHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("FreeHGlobal"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemVoid,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            this.LoadLibrary                         = CreateLoadLibrary(host, typeDef, windowsLoaderMethods.LoadLibrary, unixLoaderMethods.LoadLibrary, isUnix, intPtrZero);
            this.FreeLibrary                         = CreateFreeLibrary(host, typeDef, windowsLoaderMethods.FreeLibrary, unixLoaderMethods.FreeLibrary, isUnix);
            this.GetProcAddress                      = CreateGetProcAddress(host, typeDef, windowsLoaderMethods.GetProcAddress, unixLoaderMethods.GetProcAddress, isUnix, intPtrZero);
            this.StringToAnsiByteArray               = CreateStringToAnsi(host, typeDef, getLength, getChars);
            this.StringArrayAnsiMarshallingProlog    = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalAnsi, "StringArrayAnsiMarshallingProlog");
            this.StringArrayUnicodeMarshallingProlog = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalUni, "StringArrayUnicodeMarshallingProlog");
            this.StringArrayMarshallingEpilog        = CreateStringArrayMarshallingEpilog(host, typeDef, intPtrZero, intPtrOpInequality, freeHGlobal);
            this.IsLibraryInitialized                = CreateIsLibraryInitialized(host, typeDef, intPtrZero);

            typeDef.Methods = new List <IMethodDefinition> {
                isUnixStaticFunction, cctor, this.LoadLibrary, this.FreeLibrary, this.GetProcAddress, this.StringToAnsiByteArray, this.StringArrayAnsiMarshallingProlog, this.StringArrayUnicodeMarshallingProlog, this.StringArrayMarshallingEpilog, this.IsLibraryInitialized
            };
            typeDef.Fields = new List <IFieldDefinition> {
                isUnix
            };

            typeDef.Methods.AddRange(platformSpecificHelpers.Methods);
        }
示例#17
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);
        }
    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);
        }
      }
    }
        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);
        }
        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;
        }
示例#21
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);
                }
            }
        }
示例#22
0
            public override void RewriteChildren(RootUnitNamespace rootUnitNamespace)
            {
                var assemblyReference = rootUnitNamespace.Unit as IAssemblyReference;
                if (assemblyReference != null)
                    rootUnitNamespace.Unit = Rewrite(assemblyReference).ResolvedUnit;

                base.RewriteChildren(rootUnitNamespace);
            }
示例#23
0
 public override void RewriteChildren(RootUnitNamespace rootUnitNamespace) {
   if (rootUnitNamespace.Unit.UnitIdentity.Equals(this.sourceUnit.UnitIdentity))
     rootUnitNamespace.Unit = this.targetUnit;
   base.RewriteChildren(rootUnitNamespace);
 }
示例#24
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);
                }
            }
        }
示例#25
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);
                }
            }
        }