Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
        public override string ToString()
        {
            var sb = new StringBuilder(_methodDef.ToString());

            sb.Append('<');
            sb.Append(_instantiation.ToString());
            sb.Append('>');
            return(sb.ToString());
        }
Ejemplo n.º 3
0
        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());
        }
Ejemplo n.º 4
0
        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();
            }
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        /// <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;
        }