示例#1
0
            public static SigTypeContext FromMethod(MetadataReader metadataReader, Handle methodHandle)
            {
                object typeContext;
                object methodContext;

                switch (methodHandle.HandleType)
                {
                case HandleType.MemberReference:
                    typeContext   = GetTypeContext(metadataReader, methodHandle);
                    methodContext = default(HandleCollection);
                    break;

                case HandleType.MethodInstantiation:
                    MethodInstantiation methodInst = methodHandle.ToMethodInstantiationHandle(metadataReader).GetMethodInstantiation(metadataReader);
                    typeContext   = GetTypeContext(metadataReader, methodInst.Method);
                    methodContext = methodInst.GenericTypeArguments;
                    break;

                case HandleType.QualifiedMethod:
                    QualifiedMethod qualifiedMethod = methodHandle.ToQualifiedMethodHandle(metadataReader).GetQualifiedMethod(metadataReader);
                    typeContext   = GetTypeContext(metadataReader, qualifiedMethod.EnclosingType);
                    methodContext = qualifiedMethod.Method.GetMethod(metadataReader).GenericParameters;
                    break;

                default:
                    Debug.Assert(false);
                    return(default(SigTypeContext));
                }

                return(new SigTypeContext(typeContext, methodContext));
            }
示例#2
0
        private MethodInfo GetEmittableMethodInstantiation(MethodInstantiation methodInstantiation)
        {
            var emittableGenericMethodDefinition = GetEmittableMethod(methodInstantiation.GetGenericMethodDefinition());
            var emittableTypeArguments           = methodInstantiation.GetGenericArguments().Select(GetEmittableType).ToArray();

            // Should *not* be MakeTypePipeGenericMethod.
            return(emittableGenericMethodDefinition.MakeGenericMethod(emittableTypeArguments));
        }
示例#3
0
 private void InitializeMethodInstantiation(Cts.MethodDesc entity, MethodInstantiation record)
 {
     Cts.InstantiatedMethod instantiation = (Cts.InstantiatedMethod)entity;
     record.Method = HandleQualifiedMethod(instantiation.GetMethodDefinition());
     record.GenericTypeArguments.Capacity = instantiation.Instantiation.Length;
     foreach (Cts.TypeDesc typeArgument in instantiation.Instantiation)
     {
         record.GenericTypeArguments.Add(HandleType(typeArgument));
     }
 }
示例#4
0
        /// <summary>
        /// Emit generic method instantiation to the output string builder.
        /// </summary>
        /// <param name="methodInstHandle">Method instantiation handle</param>
        private void EmitMethodInstantiationName(MethodInstantiationHandle methodInstHandle)
        {
            MethodInstantiation   methodInst      = _metadataReader.GetMethodInstantiation(methodInstHandle);
            MemberReferenceHandle methodRefHandle = methodInst.Method.ToMemberReferenceHandle(_metadataReader);
            MemberReference       methodRef       = methodRefHandle.GetMemberReference(_metadataReader);
            MethodSignature       methodSignature;

            EmitReturnTypeContainingTypeAndMethodName(methodRef, out methodSignature);
            EmitGenericArguments(methodInst.GenericTypeArguments);
            EmitMethodParameters(methodSignature);
        }
        public void SetUp()
        {
            _typeParameter           = MutableGenericParameterObjectMother.Create();
            _parameter               = CustomParameterInfoObjectMother.Create();
            _genericMethodDefinition = CustomMethodInfoObjectMother.Create(parameters: new[] { _parameter }, typeArguments: new[] { _typeParameter });
            _typeArgument            = CustomTypeObjectMother.Create();

            var info = new MethodInstantiationInfo(_genericMethodDefinition, new[] { _typeArgument });

            _instantiation = new MethodInstantiation(info);
        }
示例#6
0
        private Object ResolveMethodInstantiation(MethodInstantiationHandle handle)
        {
            MethodInstantiation     methodInstantiation = _metadataReader.GetMethodInstantiation(handle);
            MethodDesc              genericMethodDef    = (MethodDesc)GetObject(methodInstantiation.Method, null);
            ArrayBuilder <TypeDesc> instantiation       = new ArrayBuilder <TypeDesc>();

            foreach (Handle genericArgHandle in methodInstantiation.GenericTypeArguments)
            {
                instantiation.Add(GetType(genericArgHandle));
            }
            return(Context.GetInstantiatedMethod(genericMethodDef, new Instantiation(instantiation.ToArray())));
        }
        public void SetUp()
        {
            _typeArgument = ReflectionObjectMother.GetSomeType();

            var genericTypeDefinition = typeof(GenericType <>);

            _genericTypeParameter      = genericTypeDefinition.GetGenericArguments().Single();
            _declaringType             = TypeInstantiationObjectMother.Create(genericTypeDefinition, new[] { _typeArgument });
            _memberOnTypeInstantiation = MethodOnTypeInstantiationObjectMother.Create(_declaringType);

            var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T>());

            _genericMethodParameter = genericMethodDefinition.GetGenericArguments().Single();
            _methodInstantiation    = MethodInstantiationObjectMother.Create(genericMethodDefinition, typeArguments: new[] { _typeArgument });
        }
示例#8
0
        /// <summary>
        /// Emit generic method instantiation to the output string builder.
        /// </summary>
        /// <param name="methodInstHandle">Method instantiation handle</param>
        private void EmitMethodInstantiationName(MethodInstantiationHandle methodInstHandle)
        {
            MethodInstantiation methodInst = _metadataReader.GetMethodInstantiation(methodInstHandle);
            MethodSignature     methodSignature;

            if (methodInst.Method.HandleType == HandleType.MemberReference)
            {
                MemberReferenceHandle methodRefHandle = methodInst.Method.ToMemberReferenceHandle(_metadataReader);
                MemberReference       methodRef       = methodRefHandle.GetMemberReference(_metadataReader);
                EmitContainingTypeAndMethodName(methodRef, out methodSignature);
            }
            else
            {
                QualifiedMethodHandle qualifiedMethodHandle = methodInst.Method.ToQualifiedMethodHandle(_metadataReader);
                QualifiedMethod       qualifiedMethod       = _metadataReader.GetQualifiedMethod(qualifiedMethodHandle);
                EmitContainingTypeAndMethodName(qualifiedMethod, out methodSignature);
            }
            EmitGenericArguments(methodInst.GenericTypeArguments);
            EmitMethodParameters(methodSignature);
        }
示例#9
0
        protected void ComputeMetadata <TPolicy>(
            TPolicy policy,
            NodeFactory factory,
            out byte[] metadataBlob,
            out List <MetadataMapping <MetadataType> > typeMappings,
            out List <MetadataMapping <MethodDesc> > methodMappings,
            out List <MetadataMapping <FieldDesc> > fieldMappings,
            out List <MetadataMapping <MethodDesc> > stackTraceMapping) where TPolicy : struct, IMetadataPolicy
        {
            var transformed             = MetadataTransform.Run(policy, GetCompilationModulesWithMetadata());
            MetadataTransform transform = transformed.Transform;

            // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate
            //       TypeReference records for _typeDefinitionsGenerated that don't have metadata.
            //       (To be used in MissingMetadataException messages)

            // Generate metadata blob
            var writer = new MetadataWriter();

            writer.ScopeDefinitions.AddRange(transformed.Scopes);

            // Generate entries in the blob for methods that will be necessary for stack trace purposes.
            var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >();

            foreach (var methodBody in GetCompiledMethodBodies())
            {
                MethodDesc method = methodBody.Method;

                MethodDesc typicalMethod = method.GetTypicalMethodDefinition();

                // Methods that will end up in the reflection invoke table should not have an entry in stack trace table
                // We'll try looking them up in reflection data at runtime.
                if (transformed.GetTransformedMethodDefinition(typicalMethod) != null &&
                    ShouldMethodBeInInvokeMap(method) &&
                    (GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) != 0)
                {
                    continue;
                }

                if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method))
                {
                    continue;
                }

                MetadataRecord record = transform.HandleQualifiedMethod(typicalMethod);

                // As a twist, instantiated generic methods appear as if instantiated over their formals.
                if (typicalMethod.HasInstantiation)
                {
                    var methodInst = new MethodInstantiation
                    {
                        Method = record,
                    };
                    methodInst.GenericTypeArguments.Capacity = typicalMethod.Instantiation.Length;
                    foreach (EcmaGenericParameter typeArgument in typicalMethod.Instantiation)
                    {
                        var genericParam = new TypeReference
                        {
                            TypeName = (ConstantStringValue)typeArgument.Name,
                        };
                        methodInst.GenericTypeArguments.Add(genericParam);
                    }
                    record = methodInst;
                }

                stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>(
                                          method,
                                          record));

                writer.AdditionalRootRecords.Add(record);
            }

            var ms = new MemoryStream();

            // .NET metadata is UTF-16 and UTF-16 contains code points that don't translate to UTF-8.
            var noThrowUtf8Encoding = new UTF8Encoding(false, false);

            using (var logWriter = _metadataLogFile != null ? new StreamWriter(File.Open(_metadataLogFile, FileMode.Create, FileAccess.Write, FileShare.Read), noThrowUtf8Encoding) : null)
            {
                writer.LogWriter = logWriter;
                writer.Write(ms);
            }

            metadataBlob = ms.ToArray();

            typeMappings      = new List <MetadataMapping <MetadataType> >();
            methodMappings    = new List <MetadataMapping <MethodDesc> >();
            fieldMappings     = new List <MetadataMapping <FieldDesc> >();
            stackTraceMapping = new List <MetadataMapping <MethodDesc> >();

            // Generate type definition mappings
            foreach (var type in factory.MetadataManager.GetTypesWithEETypes())
            {
                MetadataType definition = type.IsTypeDefinition ? type as MetadataType : null;
                if (definition == null)
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedTypeDefinition(definition);

                // Reflection requires that we maintain type identity. Even if we only generated a TypeReference record,
                // if there is an EEType for it, we also need a mapping table entry for it.
                if (record == null)
                {
                    record = transformed.GetTransformedTypeReference(definition);
                }

                if (record != null)
                {
                    typeMappings.Add(new MetadataMapping <MetadataType>(definition, writer.GetRecordHandle(record)));
                }
            }

            foreach (var method in GetCompiledMethods())
            {
                if (method.IsCanonicalMethod(CanonicalFormKind.Specific))
                {
                    // Canonical methods are not interesting.
                    continue;
                }

                if (IsReflectionBlocked(method.Instantiation) || IsReflectionBlocked(method.OwningType.Instantiation))
                {
                    continue;
                }

                if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0)
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition());

                if (record != null)
                {
                    methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record)));
                }
            }

            foreach (var eetypeGenerated in GetTypesWithEETypes())
            {
                if (eetypeGenerated.IsGenericDefinition)
                {
                    continue;
                }

                if (eetypeGenerated.HasInstantiation)
                {
                    // Collapsing of field map entries based on canonicalization, to avoid redundant equivalent entries

                    TypeDesc canonicalType = eetypeGenerated.ConvertToCanonForm(CanonicalFormKind.Specific);
                    if (canonicalType != eetypeGenerated && TypeGeneratesEEType(canonicalType))
                    {
                        continue;
                    }
                }

                foreach (FieldDesc field in eetypeGenerated.GetFields())
                {
                    if (IsReflectionBlocked(field.OwningType.Instantiation))
                    {
                        continue;
                    }

                    Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition());
                    if (record != null)
                    {
                        fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record)));
                    }
                }
            }

            // Generate stack trace metadata mapping
            foreach (var stackTraceRecord in stackTraceRecords)
            {
                stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value)));
            }
        }
示例#10
0
        private List <MetadataMapping <MethodDesc> > GenerateStackTraceMetadata(NodeFactory factory)
        {
            var transformed             = MetadataTransform.Run(new NoDefinitionMetadataPolicy(), Array.Empty <ModuleDesc>());
            MetadataTransform transform = transformed.Transform;

            // Generate metadata blob
            var writer = new MetadataWriter();

            // Only emit stack trace metadata for those methods which don't have reflection metadata
            HashSet <MethodDesc> methodInvokeMap = new HashSet <MethodDesc>();

            foreach (var mappingEntry in GetMethodMapping(factory))
            {
                var method = mappingEntry.Entity;
                if (ShouldMethodBeInInvokeMap(method))
                {
                    methodInvokeMap.Add(method);
                }
            }

            // Generate entries in the blob for methods that will be necessary for stack trace purposes.
            var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >();

            foreach (var methodBody in GetCompiledMethodBodies())
            {
                NonExternMethodSymbolNode methodNode = methodBody as NonExternMethodSymbolNode;
                if (methodNode != null && !methodNode.HasCompiledBody)
                {
                    continue;
                }

                MethodDesc method = methodBody.Method;

                if (methodInvokeMap.Contains(method))
                {
                    continue;
                }

                if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method))
                {
                    continue;
                }

                // In the metadata, we only represent the generic definition
                MethodDesc     methodToGenerateMetadataFor = method.GetTypicalMethodDefinition();
                MetadataRecord record = transform.HandleQualifiedMethod(methodToGenerateMetadataFor);

                // As a twist, instantiated generic methods appear as if instantiated over their formals.
                if (methodToGenerateMetadataFor.HasInstantiation)
                {
                    var methodInst = new MethodInstantiation
                    {
                        Method = record,
                    };
                    methodInst.GenericTypeArguments.Capacity = methodToGenerateMetadataFor.Instantiation.Length;
                    foreach (EcmaGenericParameter typeArgument in methodToGenerateMetadataFor.Instantiation)
                    {
                        var genericParam = new TypeReference
                        {
                            TypeName = (ConstantStringValue)typeArgument.Name,
                        };
                        methodInst.GenericTypeArguments.Add(genericParam);
                    }
                    record = methodInst;
                }

                stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>(
                                          method,
                                          record));

                writer.AdditionalRootRecords.Add(record);
            }

            var ms = new MemoryStream();

            writer.Write(ms);

            _stackTraceBlob = ms.ToArray();

            var result = new List <MetadataMapping <MethodDesc> >();

            // Generate stack trace metadata mapping
            foreach (var stackTraceRecord in stackTraceRecords)
            {
                result.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value)));
            }

            return(result);
        }