Example #1
0
 public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup)
     : base(context, compilationModuleGroup)
 {
 }
Example #2
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Log.WriteLine("Compiling " + method.ToString());

            SpecialMethodKind kind = method.DetectSpecialMethodKind();

            if (kind != SpecialMethodKind.Unknown)
            {
                string specialMethodCode = CompileSpecialMethod(method, kind);

                methodCodeNodeNeedingCode.SetCode(specialMethodCode, Array.Empty <Object>());
                return;
            }

            var methodIL = _compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            string methodCode;

            try
            {
                var ilImporter = new ILImporter(_compilation, this, method, methodIL);

                CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;

                if (!_compilation.Options.NoLineNumbers)
                {
                    IEnumerable <ILSequencePoint> sequencePoints = typeSystemContext.GetSequencePointsForMethod(method);
                    if (sequencePoints != null)
                    {
                        ilImporter.SetSequencePoints(sequencePoints);
                    }
                }

                IEnumerable <ILLocalVariable> localVariables = typeSystemContext.GetLocalVariableNamesForMethod(method);
                if (localVariables != null)
                {
                    ilImporter.SetLocalVariables(localVariables);
                }

                IEnumerable <string> parameters = typeSystemContext.GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    ilImporter.SetParameterNames(parameters);
                }

                ilImporter.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Log.WriteLine(e.Message + " (" + method + ")");

                methodCode = GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine;

                methodCodeNodeNeedingCode.SetCode(methodCode, Array.Empty <Object>());
            }
        }
Example #3
0
 public NodeFactory(CompilerTypeSystemContext context)
 {
     _target  = context.Target;
     _context = context;
     CreateNodeCaches();
 }
Example #4
0
 public ModuleTokenResolver(CompilationModuleGroup compilationModuleGroup, CompilerTypeSystemContext typeSystemContext)
 {
     _compilationModuleGroup = compilationModuleGroup;
     _typeSystemContext      = typeSystemContext;
 }
Example #5
0
 public ILScanNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, InteropStubManager interopStubManager, NameMangler nameMangler)
     : base(context, compilationModuleGroup, metadataManager, interopStubManager, nameMangler, new LazyGenericsDisabledPolicy(), new LazyVTableSliceProvider(), new LazyDictionaryLayoutProvider())
 {
 }
        public static void CompileMethod(WebAssemblyCodegenCompilation compilation, WebAssemblyMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            compilation.Logger.Writer.WriteLine("Compiling " + method.ToString());
            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                throw new NotImplementedException();
                //CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                //return;
            }

            if (method.IsRawPInvoke())
            {
                //CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                //return;
            }

            var methodIL = compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            ILImporter ilImporter = null;

            try
            {
                ilImporter = new ILImporter(compilation, method, methodIL, methodCodeNodeNeedingCode.GetMangledName(compilation.NameMangler));

                CompilerTypeSystemContext typeSystemContext = compilation.TypeSystemContext;

                //MethodDebugInformation debugInfo = compilation.GetDebugInfo(methodIL);

                /* if (!compilation.Options.HasOption(CppCodegenConfigProvider.NoLineNumbersString))*/
                {
                    //IEnumerable<ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();

                    /*if (sequencePoints != null)
                     *  ilImporter.SetSequencePoints(sequencePoints);*/
                }

                //IEnumerable<ILLocalVariable> localVariables = debugInfo.GetLocalVariables();

                /*if (localVariables != null)
                 *  ilImporter.SetLocalVariables(localVariables);*/

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);

                /*if (parameters != null)
                 *  ilImporter.SetParameterNames(parameters);*/

                ilImporter.Import();
                methodCodeNodeNeedingCode.CompilationCompleted = true;
            }
            catch (Exception e)
            {
                compilation.Logger.Writer.WriteLine(e.Message + " (" + method + ")");

                methodCodeNodeNeedingCode.CompilationCompleted = true;
//                methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies());
                //throw new NotImplementedException();
                //methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty<Object>());
            }

            // Ensure dependencies show up regardless of exceptions to avoid breaking LLVM
            methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies());
        }
Example #7
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Log.WriteLine("Compiling " + method.ToString());
            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                return;
            }

            if (method.IsRawPInvoke())
            {
                CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                return;
            }

            var methodIL = _compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            // TODO: Remove this code once CppCodegen is able to generate code for the reflection startup path.
            //       The startup path runs before any user code is executed.
            //       For now we replace the startup path with a simple "ret". Reflection won't work, but
            //       programs not using reflection will.
            if (method.Name == ".cctor")
            {
                MetadataType owningType = method.OwningType as MetadataType;
                if (owningType != null &&
                    owningType.Name == "ReflectionExecution" && owningType.Namespace == "Internal.Reflection.Execution")
                {
                    methodIL = new Internal.IL.Stubs.ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ret }, Array.Empty <LocalVariableDefinition>(), null);
                }
            }

            try
            {
                // TODO: hacky special-case
                if (method.Name == "_ecvt_s")
                {
                    throw new NotImplementedException();
                }

                var ilImporter = new ILImporter(_compilation, this, method, methodIL);

                CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;

                MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL);

                if (!_compilation.Options.NoLineNumbers)
                {
                    IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();
                    if (sequencePoints != null)
                    {
                        ilImporter.SetSequencePoints(sequencePoints);
                    }
                }

                IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables();
                if (localVariables != null)
                {
                    ilImporter.SetLocalVariables(localVariables);
                }

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    ilImporter.SetParameterNames(parameters);
                }

                ilImporter.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Log.WriteLine(e.Message + " (" + method + ")");

                var builder = new CppGenerationBuffer();
                builder.AppendLine();
                builder.Append(GetCppMethodDeclaration(method, true));
                builder.AppendLine();
                builder.Append("{");
                builder.Indent();
                builder.AppendLine();
                builder.Append("throw 0xC000C000;");
                builder.Exdent();
                builder.AppendLine();
                builder.Append("}");

                methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>());
            }
        }
Example #8
0
        /// <summary>
        /// Parse an MIBC file for the methods that are interesting.
        /// The version bubble must be specified and will describe the restrict the set of methods parsed to those relevant to the compilation
        /// The onlyDefinedInAssembly parameter is used to restrict the set of types parsed to include only those which are defined in a specific module. Specify null to allow definitions from all modules.
        /// This limited parsing is not necessarily an exact set of prevention, so detailed algorithms that work at the individual method level are still necessary, but this allows avoiding excessive parsing.
        ///
        /// The format of the Mibc file is that of a .NET dll, with a global method named "AssemblyDictionary". Inside of that file are a series of references that are broken up by which assemblies define the individual methods.
        /// These references are encoded as IL code that represents the details.
        /// The format of these IL instruction is as follows.
        ///
        /// ldstr mibcGroupName
        /// ldtoken mibcGroupMethod
        /// pop
        /// {Repeat the above pattern N times, once per Mibc group}
        ///
        /// See comment above ReadMIbcGroup for details of the group format
        ///
        /// The mibcGroupName is in the following format "Assembly_{definingAssemblyName};{OtherAssemblyName};{OtherAssemblyName};...; (OtherAssemblyName is ; delimited)
        ///
        /// </summary>
        /// <returns></returns>
        public static ProfileData ParseMIbcFile(CompilerTypeSystemContext tsc, string filename, HashSet <string> assemblyNamesInVersionBubble, string onlyDefinedInAssembly)
        {
            byte[] peData;

            using (var zipFile = ZipFile.OpenRead(filename))
            {
                var mibcDataEntry = zipFile.GetEntry(Path.GetFileName(filename) + ".dll");
                using (var mibcDataStream = mibcDataEntry.Open())
                {
                    peData = new byte[mibcDataEntry.Length];
                    using (BinaryReader br = new BinaryReader(mibcDataStream))
                    {
                        peData = br.ReadBytes(checked ((int)mibcDataEntry.Length));
                    }
                }
            }

            using (var peReader = new System.Reflection.PortableExecutable.PEReader(System.Collections.Immutable.ImmutableArray.Create <byte>(peData)))
            {
                var mibcModule = EcmaModule.Create(tsc, peReader, null, null, new CustomCanonResolver(tsc));

                var assemblyDictionary = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod("AssemblyDictionary", null);
                IEnumerable <MethodProfileData> loadedMethodProfileData = Enumerable.Empty <MethodProfileData>();

                EcmaMethodIL ilBody        = EcmaMethodIL.Create(assemblyDictionary);
                byte[]       ilBytes       = ilBody.GetILBytes();
                int          currentOffset = 0;

                string mibcGroupName = "";
                while (currentOffset < ilBytes.Length)
                {
                    ILOpcode opcode = (ILOpcode)ilBytes[currentOffset];
                    if (opcode == ILOpcode.prefix1)
                    {
                        opcode = 0x100 + (ILOpcode)ilBytes[currentOffset + 1];
                    }
                    switch (opcode)
                    {
                    case ILOpcode.ldstr:
                        if (mibcGroupName == "")
                        {
                            UInt32 userStringToken = (UInt32)(ilBytes[currentOffset + 1] + (ilBytes[currentOffset + 2] << 8) + (ilBytes[currentOffset + 3] << 16) + (ilBytes[currentOffset + 4] << 24));
                            mibcGroupName = (string)ilBody.GetObject((int)userStringToken);
                        }
                        break;

                    case ILOpcode.ldtoken:
                        if (String.IsNullOrEmpty(mibcGroupName))
                        {
                            break;
                        }

                        string[] assembliesByName = mibcGroupName.Split(';');

                        bool hasMatchingDefinition = (onlyDefinedInAssembly == null) || assembliesByName[0].Equals(onlyDefinedInAssembly);

                        if (!hasMatchingDefinition)
                        {
                            break;
                        }

                        bool areAllEntriesInVersionBubble = true;
                        foreach (string s in assembliesByName)
                        {
                            if (string.IsNullOrEmpty(s))
                            {
                                continue;
                            }

                            if (!assemblyNamesInVersionBubble.Contains(s))
                            {
                                areAllEntriesInVersionBubble = false;
                                break;
                            }
                        }

                        if (!areAllEntriesInVersionBubble)
                        {
                            break;
                        }

                        uint token = (uint)(ilBytes[currentOffset + 1] + (ilBytes[currentOffset + 2] << 8) + (ilBytes[currentOffset + 3] << 16) + (ilBytes[currentOffset + 4] << 24));
                        loadedMethodProfileData = loadedMethodProfileData.Concat(ReadMIbcGroup(tsc, (EcmaMethod)ilBody.GetObject((int)token)));
                        break;

                    case ILOpcode.pop:
                        mibcGroupName = "";
                        break;
                    }

                    // This isn't correct if there is a switch opcode, but since we won't do that, its ok
                    currentOffset += opcode.GetSize();
                }

                return(new IBCProfileData(false, loadedMethodProfileData));
            }
        }
Example #9
0
 public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler)
     : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy())
 {
 }
Example #10
0
        /// <summary>
        /// Parse an MIBC file for the methods that are interesting.
        /// The version bubble must be specified and will describe the restrict the set of methods parsed to those relevant to the compilation
        /// The onlyDefinedInAssembly parameter is used to restrict the set of types parsed to include only those which are defined in a specific module. Specify null to allow definitions from all modules.
        /// This limited parsing is not necessarily an exact set of prevention, so detailed algorithms that work at the individual method level are still necessary, but this allows avoiding excessive parsing.
        ///
        /// The format of the Mibc file is that of a .NET dll, with a global method named "AssemblyDictionary". Inside of that file are a series of references that are broken up by which assemblies define the individual methods.
        /// These references are encoded as IL code that represents the details.
        /// The format of these IL instruction is as follows.
        ///
        /// ldstr mibcGroupName
        /// ldtoken mibcGroupMethod
        /// pop
        /// {Repeat the above pattern N times, once per Mibc group}
        ///
        /// See comment above ReadMIbcGroup for details of the group format
        ///
        /// The mibcGroupName is in the following format "Assembly_{definingAssemblyName};{OtherAssemblyName};{OtherAssemblyName};...; (OtherAssemblyName is ; delimited)
        ///
        /// </summary>
        /// <returns></returns>
        public static ProfileData ParseMIbcFile(CompilerTypeSystemContext tsc, string filename, HashSet <string> assemblyNamesInVersionBubble, string onlyDefinedInAssembly)
        {
            byte[]   peData = null;
            PEReader unprotectedPeReader = null;

            {
                FileStream fsMibcFile         = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 0x1000, useAsync: false);
                bool       disposeOnException = true;

                try
                {
                    byte firstByte  = (byte)fsMibcFile.ReadByte();
                    byte secondByte = (byte)fsMibcFile.ReadByte();
                    fsMibcFile.Seek(0, SeekOrigin.Begin);
                    if (firstByte == 0x4d && secondByte == 0x5a)
                    {
                        // Uncompressed Mibc format, starts with 'MZ' prefix like all other PE files
                        unprotectedPeReader = new PEReader(fsMibcFile, PEStreamOptions.Default);
                        disposeOnException  = false;
                    }
                    else
                    {
                        using (var zipFile = new ZipArchive(fsMibcFile, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: null))
                        {
                            disposeOnException = false;
                            var mibcDataEntry = zipFile.GetEntry(Path.GetFileName(filename) + ".dll");
                            using (var mibcDataStream = mibcDataEntry.Open())
                            {
                                peData = new byte[mibcDataEntry.Length];
                                using (BinaryReader br = new BinaryReader(mibcDataStream))
                                {
                                    peData = br.ReadBytes(checked ((int)mibcDataEntry.Length));
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (disposeOnException)
                    {
                        fsMibcFile.Dispose();
                    }
                }
            }

            if (peData != null)
            {
                unprotectedPeReader = new PEReader(System.Collections.Immutable.ImmutableArray.Create <byte>(peData));
            }

            using (var peReader = unprotectedPeReader)
            {
                var mibcModule = EcmaModule.Create(tsc, peReader, null, null, new CustomCanonResolver(tsc));

                var assemblyDictionary = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod("AssemblyDictionary", null);
                IEnumerable <MethodProfileData> loadedMethodProfileData = Enumerable.Empty <MethodProfileData>();

                EcmaMethodIL ilBody        = EcmaMethodIL.Create(assemblyDictionary);
                byte[]       ilBytes       = ilBody.GetILBytes();
                int          currentOffset = 0;

                string mibcGroupName = "";
                while (currentOffset < ilBytes.Length)
                {
                    ILOpcode opcode = (ILOpcode)ilBytes[currentOffset];
                    if (opcode == ILOpcode.prefix1)
                    {
                        opcode = 0x100 + (ILOpcode)ilBytes[currentOffset + 1];
                    }
                    switch (opcode)
                    {
                    case ILOpcode.ldstr:
                        if (mibcGroupName == "")
                        {
                            UInt32 userStringToken = BinaryPrimitives.ReadUInt32LittleEndian(ilBytes.AsSpan(currentOffset + 1));
                            mibcGroupName = (string)ilBody.GetObject((int)userStringToken);
                        }
                        break;

                    case ILOpcode.ldtoken:
                        if (String.IsNullOrEmpty(mibcGroupName))
                        {
                            break;
                        }

                        string[] assembliesByName = mibcGroupName.Split(';');

                        bool hasMatchingDefinition = (onlyDefinedInAssembly == null) || assembliesByName[0].Equals(onlyDefinedInAssembly);

                        if (!hasMatchingDefinition)
                        {
                            break;
                        }

                        bool areAllEntriesInVersionBubble = true;
                        foreach (string s in assembliesByName)
                        {
                            if (string.IsNullOrEmpty(s))
                            {
                                continue;
                            }

                            if (!assemblyNamesInVersionBubble.Contains(s))
                            {
                                areAllEntriesInVersionBubble = false;
                                break;
                            }
                        }

                        if (!areAllEntriesInVersionBubble)
                        {
                            break;
                        }

                        uint token = BinaryPrimitives.ReadUInt32LittleEndian(ilBytes.AsSpan(currentOffset + 1));
                        loadedMethodProfileData = loadedMethodProfileData.Concat(ReadMIbcGroup(tsc, (EcmaMethod)ilBody.GetObject((int)token)));
                        break;

                    case ILOpcode.pop:
                        mibcGroupName = "";
                        break;
                    }

                    // This isn't correct if there is a switch opcode, but since we won't do that, its ok
                    currentOffset += opcode.GetSize();
                }

                return(new IBCProfileData(false, loadedMethodProfileData));
            }
        }
Example #11
0
 public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager,
                          InteropStubManager interopStubManager, NameMangler nameMangler, VTableSliceProvider vtableSliceProvider, DictionaryLayoutProvider dictionaryLayoutProvider)
     : base(context, compilationModuleGroup, metadataManager, interopStubManager, nameMangler, new LazyGenericsDisabledPolicy(), vtableSliceProvider, dictionaryLayoutProvider, new ExternSymbolsImportedNodeProvider())
 {
 }
 public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager)
     : base(context, compilationModuleGroup, metadataManager, new CoreRTNameMangler(new CppNodeMangler(), true))
 {
 }
Example #13
0
        public void Trim(ILCompilerOptions options, ILogWriter logWriter)
        {
            ComputeDefaultOptions(out var targetOS, out var targetArchitecture);
            var targetDetails = new TargetDetails(targetArchitecture, targetOS, TargetAbi.NativeAot);
            CompilerTypeSystemContext typeSystemContext =
                new CompilerTypeSystemContext(targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All);

            typeSystemContext.InputFilePaths     = options.InputFilePaths;
            typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths;
            typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(DefaultSystemModule));

            List <EcmaModule> inputModules = new List <EcmaModule> ();

            foreach (var inputFile in typeSystemContext.InputFilePaths)
            {
                EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);
                inputModules.Add(module);
            }

            CompilationModuleGroup compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules);

            List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider> ();
            EcmaModule?entrypointModule = null;

            foreach (var inputFile in typeSystemContext.InputFilePaths)
            {
                EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value);

                if (module.PEReader.PEHeaders.IsExe)
                {
                    if (entrypointModule != null)
                    {
                        throw new Exception("Multiple EXE modules");
                    }
                    entrypointModule = module;
                }

                compilationRoots.Add(new ExportedMethodsRootProvider(module));
            }

            compilationRoots.Add(new MainMethodRootProvider(entrypointModule, CreateInitializerList(typeSystemContext, options)));

            ILProvider ilProvider = new NativeAotILProvider();

            ilProvider = new FeatureSwitchManager(ilProvider, options.FeatureSwitches);

            Logger logger = new Logger(logWriter, isVerbose: true);

            UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager(
                compilationGroup,
                typeSystemContext,
                new NoMetadataBlockingPolicy(),
                new ManifestResourceBlockingPolicy(options.FeatureSwitches),
                logFile: null,
                new NoStackTraceEmissionPolicy(),
                new NoDynamicInvokeThunkGenerationPolicy(),
                new FlowAnnotations(logger, ilProvider),
                UsageBasedMetadataGenerationOptions.ReflectionILScanning,
                logger,
                Array.Empty <KeyValuePair <string, bool> > (),
                Array.Empty <string> (),
                options.TrimAssemblies.ToArray());

            CompilationBuilder builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup)
                                         .UseILProvider(ilProvider)
                                         .UseCompilationUnitPrefix("");

            IILScanner scanner = builder.GetILScannerBuilder()
                                 .UseCompilationRoots(compilationRoots)
                                 .UseMetadataManager(metadataManager)
                                 .UseParallelism(System.Diagnostics.Debugger.IsAttached ? 1 : -1)
                                 .ToILScanner();

            ILScanResults results = scanner.Scan();
        }
Example #14
0
 public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup)
     : base(context, compilationModuleGroup, new CompilerGeneratedMetadataManager(compilationModuleGroup, context))
 {
 }
Example #15
0
        public static void CompileMethod(WebAssemblyCodegenCompilation compilation, WebAssemblyMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            if (compilation.Logger.IsVerbose)
            {
                string methodName = method.ToString();
                compilation.Logger.Writer.WriteLine("Compiling " + methodName);
            }

            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                methodCodeNodeNeedingCode.CompilationCompleted = true;
                //throw new NotImplementedException();
                //CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                //return;
            }

            if (method.IsRawPInvoke())
            {
                //CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                //return;
            }

            var methodIL = compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            ILImporter ilImporter = null;

            try
            {
                string mangledName;

                // TODO: Better detection of the StartupCodeMain method
                if (methodCodeNodeNeedingCode.Method.Signature.IsStatic && methodCodeNodeNeedingCode.Method.Name == "StartupCodeMain")
                {
                    mangledName = "StartupCodeMain";
                }
                else
                {
                    mangledName = compilation.NameMangler.GetMangledMethodName(methodCodeNodeNeedingCode.Method).ToString();
                }

                ilImporter = new ILImporter(compilation, method, methodIL, mangledName);

                CompilerTypeSystemContext typeSystemContext = compilation.TypeSystemContext;

                //MethodDebugInformation debugInfo = compilation.GetDebugInfo(methodIL);

                /* if (!compilation.Options.HasOption(CppCodegenConfigProvider.NoLineNumbersString))*/
                {
                    //IEnumerable<ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();

                    /*if (sequencePoints != null)
                     *  ilImporter.SetSequencePoints(sequencePoints);*/
                }

                //IEnumerable<ILLocalVariable> localVariables = debugInfo.GetLocalVariables();

                /*if (localVariables != null)
                 *  ilImporter.SetLocalVariables(localVariables);*/

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);

                /*if (parameters != null)
                 *  ilImporter.SetParameterNames(parameters);*/

                ilImporter.Import();

                methodCodeNodeNeedingCode.CompilationCompleted = true;
            }
            catch (Exception e)
            {
                compilation.Logger.Writer.WriteLine(e.Message + " (" + method + ")");

                methodCodeNodeNeedingCode.CompilationCompleted = true;
//                methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies());
                //throw new NotImplementedException();
                //methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty<Object>());
            }

            // Uncomment the block below to get specific method failures when LLVM fails for cryptic reasons
#if false
            LLVMBool result = LLVM.VerifyFunction(ilImporter._llvmFunction, LLVMVerifierFailureAction.LLVMPrintMessageAction);
            if (result.Value != 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"Error compliling {method.OwningType}.{method}");
                Console.ResetColor();
            }
#endif // false

            // Ensure dependencies show up regardless of exceptions to avoid breaking LLVM
            methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies());
        }
Example #16
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Log.WriteLine("Compiling " + method.ToString());

            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                return;
            }

            if (method.IsRawPInvoke())
            {
                CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                return;
            }

            var methodIL = _compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            try
            {
                var ilImporter = new ILImporter(_compilation, this, method, methodIL);

                CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;

                MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL);

                if (!_compilation.Options.NoLineNumbers)
                {
                    IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();
                    if (sequencePoints != null)
                    {
                        ilImporter.SetSequencePoints(sequencePoints);
                    }
                }

                IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables();
                if (localVariables != null)
                {
                    ilImporter.SetLocalVariables(localVariables);
                }

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    ilImporter.SetParameterNames(parameters);
                }

                ilImporter.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Log.WriteLine(e.Message + " (" + method + ")");

                var builder = new CppGenerationBuffer();
                builder.AppendLine();
                builder.Append(GetCppMethodDeclaration(method, true));
                builder.AppendLine();
                builder.Append("{");
                builder.Indent();
                builder.AppendLine();
                builder.Append("throw 0xC000C000;");
                builder.Exdent();
                builder.AppendLine();
                builder.Append("}");

                methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>());
            }
        }
Example #17
0
 public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup)
     : base(context, compilationModuleGroup, new CompilerGeneratedMetadataManager(compilationModuleGroup, context), new CoreRTNameMangler(false))
 {
 }
 public WebAssemblyCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager,
                                      InteropStubManager interopStubManager, NameMangler nameMangler, VTableSliceProvider vtableSliceProvider, DictionaryLayoutProvider dictionaryLayoutProvider)
     : base(context, compilationModuleGroup, metadataManager, interopStubManager, nameMangler, new LazyGenericsDisabledPolicy(), vtableSliceProvider, dictionaryLayoutProvider)
 {
 }
Example #19
0
 public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup)
     : base(context, compilationModuleGroup)
 {
 }
Example #20
0
 public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager,
                          InteropStubManager interopStubManager, NameMangler nameMangler, VTableSliceProvider vtableSliceProvider)
     : base(context, compilationModuleGroup, metadataManager, interopStubManager, nameMangler, new LazyGenericsDisabledPolicy(), vtableSliceProvider)
 {
 }