예제 #1
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Logger.Writer.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
            {
                // 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.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.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Logger.Writer.WriteLine(e.Message + " (" + method + ")");

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

                methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty <Object>());
            }
        }
예제 #2
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Logger.Writer.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.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.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Logger.Writer.WriteLine(e.Message + " (" + method + ")");

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

                methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty <Object>());
            }
        }