public void CompileMethod(MethodDesc method) { _compilation.Log.WriteLine("Compiling " + method.ToString()); SpecialMethodKind kind = method.DetectSpecialMethodKind(); if (kind != SpecialMethodKind.Unknown) { string specialMethodCode = CompileSpecialMethod(method, kind); _compilation.GetRegisteredMethod(method).MethodCode = specialMethodCode; 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 <LocalVariable> localVariables = typeSystemContext.GetLocalVariableNamesForMethod(method); if (localVariables != null) { ilImporter.SetLocalVariables(localVariables); } IEnumerable <string> parameters = typeSystemContext.GetParameterNamesForMethod(method); if (parameters != null) { ilImporter.SetParameterNames(parameters); } methodCode = ilImporter.Compile(); } catch (Exception e) { _compilation.Log.WriteLine(e.Message + " (" + method + ")"); methodCode = GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine; } _compilation.GetRegisteredMethod(method).MethodCode = methodCode; }
string CompileSpecialMethod(MethodDesc method, SpecialMethodKind kind) { StringBuilder builder = new StringBuilder(); switch (kind) { case SpecialMethodKind.PInvoke: case SpecialMethodKind.RuntimeImport: { EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetRuntimeImportEntryPointName(); if (importName == null) { importName = method.Name; } // TODO: hacky special-case if (importName != "memmove" && importName != "malloc") // some methods are already declared by the CRT headers { builder.AppendLine(GetCppMethodDeclaration(method, false, importName)); } builder.AppendLine(GetCppMethodDeclaration(method, true)); builder.AppendLine("{"); builder.Append(" "); if (GetCppSignatureTypeName(method.Signature.ReturnType) != "void") { builder.Append("return "); } builder.AppendLine("::" + importName + "(" + GetCppMethodCallParamList(method) + ");"); builder.AppendLine("}"); return(builder.ToString()); } default: // TODO: hacky special-case if (method.Name == "BlockCopy") { return(null); } return(GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine); } }
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; } 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 + ")"); 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>()); } }
private string CompileSpecialMethod(MethodDesc method, SpecialMethodKind kind) { var builder = new CppGenerationBuffer(); switch (kind) { case SpecialMethodKind.PInvoke: case SpecialMethodKind.RuntimeImport: { EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetAttributeStringValue("System.Runtime", "RuntimeImportAttribute"); if (importName == null) { importName = method.Name; } MethodSignature methodSignature = method.Signature; bool slotCastRequired = false; MethodSignature externCSignature; if (_externCSignatureMap.TryGetValue(importName, out externCSignature)) { slotCastRequired = !externCSignature.Equals(method.Signature); } else { _externCSignatureMap.Add(importName, methodSignature); externCSignature = methodSignature; } builder.AppendLine(); builder.Append(GetCppMethodDeclaration(method, true)); builder.AppendLine(); builder.Append("{"); builder.Indent(); if (slotCastRequired) { AppendSlotTypeDef(builder, method); } builder.AppendLine(); if (!method.Signature.ReturnType.IsVoid) { builder.Append("return "); } if (slotCastRequired) { builder.Append("((__slot__" + GetCppMethodName(method) + ")"); } builder.Append("::"); builder.Append(importName); if (slotCastRequired) { builder.Append(")"); } builder.Append("("); builder.Append(GetCppMethodCallParamList(method)); builder.Append(");"); builder.Exdent(); builder.AppendLine(); builder.Append("}"); return(builder.ToString()); } default: 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("}"); return(builder.ToString()); } }
private string CompileSpecialMethod(MethodDesc method, SpecialMethodKind kind) { StringBuilder builder = new StringBuilder(); switch (kind) { case SpecialMethodKind.PInvoke: case SpecialMethodKind.RuntimeImport: { EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetAttributeStringValue("System.Runtime", "RuntimeImportAttribute"); if (importName == null) importName = method.Name; MethodSignature methodSignature = method.Signature; bool slotCastRequired = false; MethodSignature externCSignature; if (_externCSignatureMap.TryGetValue(importName, out externCSignature)) { slotCastRequired = !externCSignature.Equals(method.Signature); } else { _externCSignatureMap.Add(importName, methodSignature); externCSignature = methodSignature; } builder.AppendLine(GetCppMethodDeclaration(method, true)); builder.AppendLine("{"); if (slotCastRequired) { AppendSlotTypeDef(builder, method); } if (!method.Signature.ReturnType.IsVoid) { builder.Append("return "); } if (slotCastRequired) builder.Append("((__slot__" + GetCppMethodName(method) + ")"); builder.Append("::"); builder.Append(importName); if (slotCastRequired) builder.Append(")"); builder.Append("("); builder.Append(GetCppMethodCallParamList(method)); builder.AppendLine(");"); builder.AppendLine("}"); return builder.ToString(); } default: return GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine; } }
private void CreateNodeCaches() { _typeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) => { Debug.Assert(type.IsTypeDefinition || !type.HasSameTypeDefinition(ArrayOfTClass), "Asking for Array<T> EEType"); if (_compilationModuleGroup.ContainsType(type)) { return(new EETypeNode(type, false)); } else { return(new ExternEETypeSymbolNode(type)); } }); _constructedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) => { Debug.Assert(type.IsTypeDefinition || !type.HasSameTypeDefinition(ArrayOfTClass), "Asking for Array<T> EEType"); if (_compilationModuleGroup.ContainsType(type)) { return(new EETypeNode(type, true)); } else { return(new ExternEETypeSymbolNode(type)); } }); _nonGCStatics = new NodeCache <MetadataType, NonGCStaticsNode>((MetadataType type) => { return(new NonGCStaticsNode(type, this)); }); _GCStatics = new NodeCache <MetadataType, GCStaticsNode>((MetadataType type) => { return(new GCStaticsNode(type)); }); _GCStaticIndirectionNodes = new NodeCache <MetadataType, EmbeddedObjectNode>((MetadataType type) => { ISymbolNode gcStaticsNode = TypeGCStaticsSymbol(type); Debug.Assert(gcStaticsNode is GCStaticsNode); return(GCStaticsRegion.NewNode((GCStaticsNode)gcStaticsNode)); }); _threadStatics = new NodeCache <MetadataType, ThreadStaticsNode>((MetadataType type) => { return(new ThreadStaticsNode(type, this)); }); _GCStaticEETypes = new NodeCache <bool[], GCStaticEETypeNode>((bool[] gcdesc) => { return(new GCStaticEETypeNode(gcdesc, this)); }, new BoolArrayEqualityComparer()); _readOnlyDataBlobs = new NodeCache <Tuple <string, byte[], int>, BlobNode>((Tuple <string, byte[], int> key) => { return(new BlobNode(key.Item1, ObjectNodeSection.TextSection, key.Item2, key.Item3)); }, new BlobTupleEqualityComparer()); _externSymbols = new NodeCache <string, ExternSymbolNode>((string name) => { return(new ExternSymbolNode(name)); }); _internalSymbols = new NodeCache <Tuple <ObjectNode, int, string>, ObjectAndOffsetSymbolNode>( (Tuple <ObjectNode, int, string> key) => { return(new ObjectAndOffsetSymbolNode(key.Item1, key.Item2, key.Item3)); }); _methodEntrypoints = new NodeCache <MethodDesc, IMethodNode>((MethodDesc method) => { if (!_cppCodeGen) { SpecialMethodKind kind = method.DetectSpecialMethodKind(); if (kind == SpecialMethodKind.PInvoke) { return(new PInvokeMethodNode(method)); } else if (kind == SpecialMethodKind.RuntimeImport) { return(new RuntimeImportMethodNode(method)); } } if (_compilationModuleGroup.ContainsMethod(method)) { if (_cppCodeGen) { return(new CppMethodCodeNode(method)); } else { return(new MethodCodeNode(method)); } } else { return(new ExternMethodSymbolNode(method)); } }); _unboxingStubs = new NodeCache <MethodDesc, IMethodNode>((MethodDesc method) => { return(new UnboxingStubNode(method)); }); _virtMethods = new NodeCache <MethodDesc, VirtualMethodUseNode>((MethodDesc method) => { return(new VirtualMethodUseNode(method)); }); _readyToRunHelpers = new NodeCache <Tuple <ReadyToRunHelperId, Object>, ReadyToRunHelperNode>((Tuple <ReadyToRunHelperId, Object> helper) => { return(new ReadyToRunHelperNode(helper.Item1, helper.Item2)); }); _stringDataNodes = new NodeCache <string, StringDataNode>((string data) => { return(new StringDataNode(data)); }); _stringIndirectionNodes = new NodeCache <string, StringIndirectionNode>((string data) => { return(new StringIndirectionNode(data)); }); _typeOptionalFields = new NodeCache <EETypeOptionalFieldsBuilder, EETypeOptionalFieldsNode>((EETypeOptionalFieldsBuilder fieldBuilder) => { return(new EETypeOptionalFieldsNode(fieldBuilder, this.Target)); }); _interfaceDispatchCells = new NodeCache <MethodDesc, InterfaceDispatchCellNode>((MethodDesc method) => { return(new InterfaceDispatchCellNode(method)); }); _interfaceDispatchMaps = new NodeCache <TypeDesc, InterfaceDispatchMapNode>((TypeDesc type) => { return(new InterfaceDispatchMapNode(type)); }); _interfaceDispatchMapIndirectionNodes = new NodeCache <TypeDesc, EmbeddedObjectNode>((TypeDesc type) => { var dispatchMap = InterfaceDispatchMap(type); return(DispatchMapTable.NewNodeWithSymbol(dispatchMap, (indirectionNode) => { dispatchMap.SetDispatchMapIndex(this, DispatchMapTable.IndexOfEmbeddedObject(indirectionNode)); })); }); _eagerCctorIndirectionNodes = new NodeCache <MethodDesc, EmbeddedObjectNode>((MethodDesc method) => { Debug.Assert(method.IsStaticConstructor); Debug.Assert(TypeInitializationManager.HasEagerStaticConstructor((MetadataType)method.OwningType)); return(EagerCctorTable.NewNode(MethodEntrypoint(method))); }); _vTableNodes = new NodeCache <TypeDesc, VTableSliceNode>((TypeDesc type ) => { if (CompilationModuleGroup.ShouldProduceFullType(type)) { return(new EagerlyBuiltVTableSliceNode(type)); } else { return(new LazilyBuiltVTableSliceNode(type)); } }); _jumpThunks = new NodeCache <Tuple <ExternSymbolNode, ISymbolNode>, SingleArgumentJumpThunk>((Tuple <ExternSymbolNode, ISymbolNode> data) => { return(new SingleArgumentJumpThunk(data.Item1, data.Item2)); }); }
public void AddSpecialMethod(SpecialMethodKind setup, MethodInfo method) { mySpecialMethods[setup] = method; }
private string CompileSpecialMethod(MethodDesc method, SpecialMethodKind kind) { StringBuilder builder = new StringBuilder(); switch (kind) { case SpecialMethodKind.PInvoke: case SpecialMethodKind.RuntimeImport: { EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetAttributeStringValue("System.Runtime", "RuntimeImportAttribute"); if (importName == null) importName = method.Name; // TODO: hacky special-case if (importName != "memmove" && importName != "malloc") // some methods are already declared by the CRT headers { builder.AppendLine(GetCppMethodDeclaration(method, false, importName)); } builder.AppendLine(GetCppMethodDeclaration(method, true)); builder.AppendLine("{"); builder.Append(" "); if (GetCppSignatureTypeName(method.Signature.ReturnType) != "void") { builder.Append("return "); } builder.AppendLine("::" + importName + "(" + GetCppMethodCallParamList(method) + ");"); builder.AppendLine("}"); return builder.ToString(); } default: // TODO: hacky special-case if (method.Name == "BlockCopy") return null; return GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine; } }
private string CompileSpecialMethod(MethodDesc method, SpecialMethodKind kind) { StringBuilder builder = new StringBuilder(); switch (kind) { case SpecialMethodKind.PInvoke: case SpecialMethodKind.RuntimeImport: { EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetAttributeStringValue("System.Runtime", "RuntimeImportAttribute"); if (importName == null) { importName = method.Name; } MethodSignature methodSignature = method.Signature; bool slotCastRequired = false; MethodSignature externCSignature; if (_externCSignatureMap.TryGetValue(importName, out externCSignature)) { slotCastRequired = !externCSignature.Equals(method.Signature); } else { externCSignature = methodSignature; } // TODO: hacky special-case if (importName != "memmove" && importName != "malloc") // some methods are already declared by the CRT headers { builder.AppendLine(GetCppMethodDeclaration(method, false, importName, externCSignature)); } builder.AppendLine(GetCppMethodDeclaration(method, true)); builder.AppendLine("{"); if (slotCastRequired) { AppendSlotTypeDef(builder, method); } if (!method.Signature.ReturnType.IsVoid) { builder.Append("return "); } if (slotCastRequired) { builder.Append("((__slot__" + GetCppMethodName(method) + ")"); } builder.Append("::"); builder.Append(importName); if (slotCastRequired) { builder.Append(")"); } builder.Append("("); builder.Append(GetCppMethodCallParamList(method)); builder.AppendLine(");"); builder.AppendLine("}"); return(builder.ToString()); } default: return(GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine); } }