예제 #1
0
 public void Compile()
 {
     foreach (AssemblyDefinition assemblyDefinition in _compiler.LoadedAssemblies)
     {
         _compileInfo = new AssemblyCompileInfo(assemblyDefinition);
         //TestPdb(_compileInfo);
         //TestPdb2(_compileInfo);
         Compile(_compileInfo);
         _compileInfo = null;
     }
 }
예제 #2
0
        private void Compile(AssemblyCompileInfo compileInfo)
        {
            AssemblyDefinition sourceAssemblyDefinition = compileInfo.SourceAssemblyDefinition;

            // TODO: Check that sourceAssemblyDefinition references OSCorlib

            compileInfo.OutputFilePath = GetOutputFilePath(sourceAssemblyDefinition);

            AssemblyDefinition assemblyDefinition =
                compileInfo.OutputAssemblyDefinition =
                AssemblyFactory.DefineAssembly(sourceAssemblyDefinition.Name.Name, sourceAssemblyDefinition.Kind);

            ModuleDefinition moduleDefinition = assemblyDefinition.MainModule;

            Importer importer = new Importer(compileInfo, this);
            moduleDefinition.Importer = importer;

            // add reference to mscorlib
            moduleDefinition.AssemblyReferences.Add(_mscorlib);

            Dictionary<MethodDefinition, MethodDefinition> importedMethodMap = new Dictionary<MethodDefinition, MethodDefinition>();

            foreach (ModuleDefinition sourceModuleDefinition in sourceAssemblyDefinition.Modules)
            {
                // type definitions
                foreach (TypeDefinition sourceTypeDefinition in sourceModuleDefinition.Types)
                {
                    Console.WriteLine("Importing type: " + sourceTypeDefinition.AssemblyQualifiedName);
                    TypeDefinition importedType = Import(compileInfo, sourceTypeDefinition);

                    // TODO: build imported method map efficiently
                    foreach (MethodDefinition sourceMethodDefinition in sourceTypeDefinition.Methods)
                    {
                        MethodDefinition importedMethod = importedType.Methods.GetMethod(sourceMethodDefinition.Name, sourceMethodDefinition.Parameters);
                        if (importedMethod == null)
                        {
                            continue;
                            //throw new CompilerException("Unable to find imported method " + sourceMethodDefinition);
                        }
                        importedMethodMap[sourceMethodDefinition] = importedMethod;
                    }
                }
            }

            // entrypoint
            if (sourceAssemblyDefinition.EntryPoint != null)
            {
                MethodDefinition entryPointMethod;
                if (!importedMethodMap.TryGetValue(sourceAssemblyDefinition.EntryPoint, out entryPointMethod))
                {
                    throw new CompilerException("Unable to find imported entrypoint method " + sourceAssemblyDefinition.EntryPoint);
                }
                assemblyDefinition.EntryPoint = entryPointMethod;
            }

            AssemblyFactory.SaveAssembly(compileInfo.OutputAssemblyDefinition, compileInfo.OutputFilePath);

            if (sourceAssemblyDefinition.MainModule.Image.DebugHeader != null)
            {
                //CompileDebugInfo(compileInfo);
            }
        }
예제 #3
0
 public Importer(AssemblyCompileInfo compileInfo, CLRHandler handler)
     : base(compileInfo.OutputAssemblyDefinition.MainModule)
 {
     Handler = handler;
     CompileInfo = compileInfo;
 }
예제 #4
0
        private void TestPdb(AssemblyCompileInfo compileInfo)
        {
            AssemblyDefinition assemblyDefinition = _compileInfo.SourceAssemblyDefinition;
            assemblyDefinition.MainModule.LoadSymbols();
            assemblyDefinition.MainModule.FullLoad();

            assemblyDefinition.MainModule.SaveSymbols();
            AssemblyFactory.SaveAssembly(assemblyDefinition, "build/Test.CLR.exe");
        }
예제 #5
0
        private void TestPdb2(AssemblyCompileInfo compileInfo)
        {
            AssemblyDefinition sourceAssemblyDefinition = _compileInfo.SourceAssemblyDefinition;
            sourceAssemblyDefinition.MainModule.LoadSymbols();
            sourceAssemblyDefinition.MainModule.FullLoad();

            AssemblyDefinition assemblyDefinition = AssemblyFactory.DefineAssembly("Test.CLR", AssemblyKind.Console);

            assemblyDefinition.MainModule.Inject(sourceAssemblyDefinition.MainModule.Types[0]);
            assemblyDefinition.MainModule.Inject(sourceAssemblyDefinition.MainModule.Types[1]);
            assemblyDefinition.EntryPoint = assemblyDefinition.MainModule.Types[1].Methods[0];

            CustomAttribute sourceDebuggableAttribute = AttributeHelper.GetCustomAttribute(sourceAssemblyDefinition, "System.Diagnostics", "DebuggableAttribute");
            assemblyDefinition.CustomAttributes.Add(sourceDebuggableAttribute);

            // setup debug header
            assemblyDefinition.MainModule.Image.AddDebugHeader();
            DebugHeader debugHeader = assemblyDefinition.MainModule.Image.DebugHeader;
            DebugHeader sourceDebugHeader = sourceAssemblyDefinition.MainModule.Image.DebugHeader;

            debugHeader.AddressOfRawData = sourceDebugHeader.AddressOfRawData;
            debugHeader.Age = sourceDebugHeader.Age;
            debugHeader.Characteristics = sourceDebugHeader.Characteristics;
            debugHeader.FileName = sourceDebugHeader.FileName;
            //debugHeader.FileName = Path.GetFullPath(Path.ChangeExtension(GetOutputFilePath(compileInfo.SourceAssemblyDefinition), ".pdb"));
            debugHeader.Magic = sourceDebugHeader.Magic;
            debugHeader.MajorVersion = sourceDebugHeader.MajorVersion;
            debugHeader.MinorVersion = sourceDebugHeader.MinorVersion;
            debugHeader.PointerToRawData = sourceDebugHeader.PointerToRawData;
            debugHeader.Signature = sourceDebugHeader.Signature;
            debugHeader.SizeOfData = sourceDebugHeader.SizeOfData;
            debugHeader.TimeDateStamp = sourceDebugHeader.TimeDateStamp;//(uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
            debugHeader.Type = sourceDebugHeader.Type;

            assemblyDefinition.MainModule.SaveSymbols();
            AssemblyFactory.SaveAssembly(assemblyDefinition, "build/Test.CLR.exe");
        }
예제 #6
0
 private TypeReference Import(AssemblyCompileInfo compileInfo, TypeReference sourceTypeReference)
 {
     return compileInfo.OutputAssemblyDefinition.MainModule.Import(sourceTypeReference);
 }
예제 #7
0
 private AssemblyNameReference Import(AssemblyCompileInfo compileInfo, AssemblyNameReference sourceAssemblyNameReference)
 {
     AssemblyNameReference assemblyNameReference;
     if (TryGetReplacement(sourceAssemblyNameReference, out assemblyNameReference))
     {
         sourceAssemblyNameReference = assemblyNameReference;
     }
     compileInfo.OutputAssemblyDefinition.MainModule.AssemblyReferences.Add(sourceAssemblyNameReference);
     return sourceAssemblyNameReference;
 }
예제 #8
0
 private MethodDefinition Import(AssemblyCompileInfo compileInfo, MethodDefinition sourceMethodDefinition, TypeDefinition typeDefinitionContext)
 {
     MethodDefinition methodDefinition;
     if (!compileInfo.ImportedMethodDefinitions.TryGetValue(sourceMethodDefinition.ToString(), out methodDefinition))
     {
         compileInfo.OutputAssemblyDefinition.MainModule.Inject(sourceMethodDefinition, typeDefinitionContext);
         compileInfo.ImportedMethodDefinitions[sourceMethodDefinition.ToString()] = methodDefinition;
     }
     return methodDefinition;
 }
예제 #9
0
        private TypeDefinition Import(AssemblyCompileInfo compileInfo, TypeDefinition sourceTypeDefinition)
        {
            TypeDefinition typeDefinition;
            if (!compileInfo.ImportedTypeDefinitions.TryGetValue(sourceTypeDefinition.AssemblyQualifiedName, out typeDefinition))
            {
                // declaring type
                if (sourceTypeDefinition.DeclaringType != null)
                {
                    TypeDefinition declaringTypeDefinition = Import(compileInfo, ReferenceResolver.ResolveTypeReference(sourceTypeDefinition.DeclaringType, _compiler.Resolver));
                    typeDefinition = compileInfo.OutputAssemblyDefinition.MainModule.Inject(sourceTypeDefinition, declaringTypeDefinition);
                }
                else
                {
                    typeDefinition = compileInfo.OutputAssemblyDefinition.MainModule.Inject(sourceTypeDefinition);
                }
                typeDefinition.Module = compileInfo.OutputAssemblyDefinition.MainModule;

                compileInfo.ImportedTypeDefinitions[sourceTypeDefinition.AssemblyQualifiedName] = typeDefinition;
            }
            return typeDefinition;
        }
예제 #10
0
        private void CompileDebugInfo(AssemblyCompileInfo compileInfo)
        {
            AssemblyDefinition sourceAssemblyDefinition = compileInfo.SourceAssemblyDefinition;
            AssemblyDefinition assemblyDefinition = compileInfo.OutputAssemblyDefinition =
                AssemblyFactory.GetAssembly(compileInfo.OutputFilePath);
            ModuleDefinition moduleDefinition = assemblyDefinition.MainModule;

            PdbFactory pdbFactory = new PdbFactory();
                ISymbolWriter symbolWriter =
                pdbFactory.CreateWriter(moduleDefinition, compileInfo.OutputFilePath);
            ISymbolReader symbolReader =
                pdbFactory.CreateReader(sourceAssemblyDefinition.MainModule, sourceAssemblyDefinition.MainModule.Image.FileInformation.FullName);

            sourceAssemblyDefinition.MainModule.LoadSymbols(symbolReader);
            sourceAssemblyDefinition.MainModule.FullLoad();

            // setup debug header
            moduleDefinition.Image.AddDebugHeader();
            DebugHeader debugHeader = moduleDefinition.Image.DebugHeader;
            DebugHeader sourceDebugHeader = sourceAssemblyDefinition.MainModule.Image.DebugHeader;

            debugHeader.AddressOfRawData = sourceDebugHeader.AddressOfRawData;
            debugHeader.Age = sourceDebugHeader.Age;
            debugHeader.Characteristics = sourceDebugHeader.Characteristics;
            debugHeader.FileName = sourceDebugHeader.FileName;
            //debugHeader.FileName = Path.GetFullPath(Path.ChangeExtension(GetOutputFilePath(compileInfo.SourceAssemblyDefinition), ".pdb"));
            debugHeader.Magic = sourceDebugHeader.Magic;
            debugHeader.MajorVersion = sourceDebugHeader.MajorVersion;
            debugHeader.MinorVersion = sourceDebugHeader.MinorVersion;
            debugHeader.PointerToRawData = sourceDebugHeader.PointerToRawData;
            debugHeader.Signature = sourceDebugHeader.Signature;
            debugHeader.SizeOfData = sourceDebugHeader.SizeOfData;
            debugHeader.TimeDateStamp = sourceDebugHeader.TimeDateStamp;//(uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
            debugHeader.Type = sourceDebugHeader.Type;

            CustomAttribute sourceDebuggableAttribute = AttributeHelper.GetCustomAttribute(sourceAssemblyDefinition, "System.Diagnostics", "DebuggableAttribute");
            TypeDefinition debuggableAttributeType = ReferenceResolver.ResolveTypeReference(CoreTypes.GetCoreType("System.Diagnostics.DebuggableAttribute"), _compiler.Resolver);
            MethodDefinition debuggableAttributeCtor = debuggableAttributeType.Constructors.GetConstructor(false, new Type[] {
                typeof(bool),
                typeof(bool)
            });
            CustomAttribute debuggableAttribute = new CustomAttribute(moduleDefinition.Import(debuggableAttributeCtor));
            debuggableAttribute.ConstructorParameters.Add(true);
            debuggableAttribute.ConstructorParameters.Add(false);
            assemblyDefinition.CustomAttributes.Add(debuggableAttribute);

            // save files
            //moduleDefinition.SaveSymbols(symbolWriter);
            string tempFile = Path.GetTempFileName();
            AssemblyFactory.SaveAssembly(assemblyDefinition, tempFile);
            symbolWriter.Dispose();

            File.Delete(compileInfo.OutputFilePath);
            File.Move(tempFile, compileInfo.OutputFilePath);
        }
예제 #11
0
        public void Compile()
        {
            foreach (AssemblyDefinition assembly in _compiler.AssembliesToCompile)
            {
                Console.WriteLine("Compiling assembly: " + assembly);
                if (_compiler.Options.IncrementalCompilation)
                {
                    if (!_compiler.IncrementalCompilationState.ContainsValidPersistedState(assembly))
                    {
                        Console.WriteLine("Creating incremental compilation state for assembly: " + assembly);
                        _compiler.IncrementalCompilationState.Put(assembly);
                    }
                }
                AssemblyCompileInfo assemblyCompileInfo = new AssemblyCompileInfo(assembly);
                try
                {
                    foreach (ModuleDefinition module in assembly.Modules)
                    {
                        foreach (TypeDefinition typeDefinition in module.Types)
                        {
                            if (XaeiOSBackEnd.HasDummyAttribute(typeDefinition))
                            {
                                continue;
                            }
                            List<MethodDefinition> methodDefinitions = new List<MethodDefinition>();
                            foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                            {
                                methodDefinitions.Add(methodDefinition);
                            }
                            foreach (MethodDefinition methodDefinition in typeDefinition.Constructors)
                            {
                                methodDefinitions.Add(methodDefinition);
                            }
                            foreach (MethodDefinition method in methodDefinitions)
                            {
                                // shouldn't compile dummy methods
                                if (!XaeiOSBackEnd.HasDummyAttribute(method))
                                {
                                    assemblyCompileInfo.CreateMethodCompileInfo(method);
                                }
                            }
                        }
                    }

                    _compiler.FrontEnd.BuildCFG(assemblyCompileInfo);
                    _compiler.MiddleEnd.TransformAssembly(assemblyCompileInfo);

                    if (!DebugSettings.CompilingOneMethod)
                    {
                        _compiler.BackEnd.EmitAssembly(assemblyCompileInfo);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unable to compile assembly: " + assembly);
                    Console.WriteLine(e);
                    if (_compiler.Options.IncrementalCompilation)
                    {
                        _compiler.IncrementalCompilationState.Remove(assembly);
                    }
                }
            }

            if (_compiler.Options.IncrementalCompilation)
            {
                // TODO: extract out into a separate method
                string stateFile = Path.Combine(_compiler.Options.OutputPath, "IncrementalCompilationState.xml");
                Console.WriteLine("Saving incremental compilation state to: " + stateFile);
                foreach (AssemblyIncrementalCompilationState assemblyState in _compiler.IncrementalCompilationState.AssemblyStates)
                {
                    Console.WriteLine("Saving incremental compilation state for assembly: {0}", assemblyState.AssemblyName);
                }
                IncrementalCompilationState.Save(_compiler.IncrementalCompilationState, stateFile);
            }
        }
예제 #12
0
 public MethodCompileInfo(MethodDefinition method, AssemblyCompileInfo assemblyCompileInfo)
 {
     _method = method;
     AssemblyCompileInfo = assemblyCompileInfo;
 }