/// <summary> /// Returns pregenerated interop code for given PInvoke method if one exist /// </summary> public static MethodDesc TryGetPregeneratedPInvoke(MethodDesc method) { Debug.Assert(method.IsPInvoke); var metadataType = (MetadataType)method.OwningType; var module = metadataType.Module; var assemblyName = ((IAssemblyDesc)module).GetName(); var interopAssemblyName = new AssemblyName(); interopAssemblyName.Name = assemblyName.Name + AssemblyNameSuffix; interopAssemblyName.Version = assemblyName.Version; interopAssemblyName.SetPublicKeyToken(interopAssemblyName.GetPublicKeyToken()); interopAssemblyName.CultureName = assemblyName.CultureName; interopAssemblyName.ContentType = assemblyName.ContentType; var interopModule = module.Context.ResolveAssembly(interopAssemblyName, false); if (interopModule == null) return null; var pregeneratedMethod = GetMatchingMethod(interopModule, method); if (pregeneratedMethod == null) { // TODO: Better error message throw new MissingMemberException("Missing method in " + interopAssemblyName.Name + ":" + method.ToString()); } return pregeneratedMethod; }
public override string ToString() { var sb = new StringBuilder(_methodDef.ToString()); sb.Append('<'); sb.Append(_instantiation.ToString()); sb.Append('>'); return(sb.ToString()); }
public override string ToString() { var sb = new StringBuilder(_methodDef.ToString()); sb.Append('<'); for (int i = 0; i < _instantiation.Length; i++) { sb.Append(_instantiation[i].ToString()); } sb.Append('>'); return(sb.ToString()); }
public static MethodIL EmitIL(MethodDesc method) { if (!RequiresMarshalling(method)) return null; try { return new PInvokeMarshallingILEmitter(method).EmitIL(); } catch (NotSupportedException) { ILEmitter emitter = new ILEmitter(); string message = "Method '" + method.ToString() + "' requires non-trivial marshalling that is not yet supported by this compiler."; TypeSystemContext context = method.Context; MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void), new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) }); MethodDesc exceptionCtor = method.Context.GetWellKnownType(WellKnownType.Exception).GetKnownMethod(".ctor", ctorSignature); ILCodeStream codeStream = emitter.NewCodeStream(); codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message)); codeStream.Emit(ILOpcode.newobj, emitter.NewToken(exceptionCtor)); codeStream.Emit(ILOpcode.throw_); codeStream.Emit(ILOpcode.ret); return emitter.Link(); } }
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; }
/// <summary> /// Get the NativeLayout for a method from a ReadyToRun image. /// </summary> public bool TryGetMetadataNativeLayout(MethodDesc concreteMethod, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken) { nativeLayoutInfoModule = default(IntPtr); nativeLayoutInfoToken = 0; #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING var nativeMetadataType = concreteMethod.GetTypicalMethodDefinition() as TypeSystem.NativeFormat.NativeFormatMethod; if (nativeMetadataType == null) return false; var canonForm = concreteMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); var hashCode = canonForm.GetHashCode(); var loadedModulesCount = RuntimeAugments.GetLoadedModules(null); var loadedModuleHandles = new IntPtr[loadedModulesCount]; var loadedModules = RuntimeAugments.GetLoadedModules(loadedModuleHandles); Debug.Assert(loadedModulesCount == loadedModules); #if SUPPORTS_R2R_LOADING foreach (var moduleHandle in loadedModuleHandles) { ExternalReferencesTable externalFixupsTable; NativeHashtable methodTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.MetadataBasedGenericMethodsTemplateMap, out externalFixupsTable); if (methodTemplatesHashtable.IsNull) continue; var enumerator = methodTemplatesHashtable.Lookup(hashCode); var nativeMetadataUnit = nativeMetadataType.Context.ResolveMetadataUnit(moduleHandle); NativeParser entryParser; while (!(entryParser = enumerator.GetNext()).IsNull) { var entryTypeHandle = entryParser.GetUnsigned().AsHandle(); MethodDesc methodDesc = nativeMetadataUnit.GetMethod(entryTypeHandle, null); Debug.Assert(methodDesc != null); if (methodDesc == canonForm) { TypeLoaderLogger.WriteLine("Found metadata template for method " + concreteMethod.ToString() + ": " + methodDesc.ToString()); nativeLayoutInfoToken = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { throw new BadImageFormatException(); } nativeLayoutInfoModule = moduleHandle; return true; } } } #endif #endif return false; }