/// <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; }
private List <CustomAttribute> HandleCustomAttributes(Cts.Ecma.EcmaModule module, Ecma.CustomAttributeHandleCollection attributes) { List <CustomAttribute> customAttributes = new List <CustomAttribute>(attributes.Count); var attributeTypeProvider = new Cts.Ecma.CustomAttributeTypeProvider(module); Ecma.MetadataReader reader = module.MetadataReader; foreach (var attributeHandle in attributes) { if (!_policy.GeneratesMetadata(module, attributeHandle)) { continue; } Ecma.CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); // TODO-NICE: We can intern the attributes based on the CA constructor and blob bytes Cts.MethodDesc constructor = module.GetMethod(attribute.Constructor); var decodedValue = attribute.DecodeValue(attributeTypeProvider); customAttributes.Add(HandleCustomAttribute(constructor, decodedValue)); } return(customAttributes); }
public override bool IsMethodInCompilationGroup(MethodDesc method) { if (method.GetTypicalMethodDefinition().ContainsGenericVariables) return true; return IsTypeInCompilationGroup(method.OwningType); }
public static MethodIL EmitIL(MethodDesc target) { Debug.Assert(target.Name == "Call"); Debug.Assert(target.Signature.Length > 0 && target.Signature[0] == target.Context.GetWellKnownType(WellKnownType.IntPtr)); ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); // Load all the arguments except the first one (IntPtr address) for (int i = 1; i < target.Signature.Length; i++) { codeStream.EmitLdArg(i); } // now load IntPtr address codeStream.EmitLdArg(0); // Create a signature for the calli by copying the signature of the containing method // while skipping the first argument MethodSignature template = target.Signature; TypeDesc returnType = template.ReturnType; TypeDesc[] parameters = new TypeDesc[template.Length - 1]; for (int i = 1; i < template.Length; i++) { parameters[i - 1] = template[i]; } var signature = new MethodSignature(template.Flags, 0, returnType, parameters); codeStream.Emit(ILOpcode.calli, emitter.NewToken(signature)); codeStream.Emit(ILOpcode.ret); return emitter.Link(); }
/// <summary> /// Returns true if <paramref name="method"/> requires a stub to be generated. /// </summary> public static bool IsStubRequired(MethodDesc method) { Debug.Assert(method.IsPInvoke); // TODO: true if there are any custom marshalling rules on the parameters // TODO: true if SetLastError is true TypeDesc returnType = method.Signature.ReturnType; if (!IsBlittableType(returnType) && !returnType.IsVoid) return true; for (int i = 0; i < method.Signature.Length; i++) { if (!IsBlittableType(method.Signature[i])) { return true; } } if (UseLazyResolution(method, method.GetPInvokeMethodMetadata().Module)) { return true; } return false; }
public override bool ContainsMethod(MethodDesc method) { if (method.GetTypicalMethodDefinition().ContainsGenericVariables) return true; return ContainsType(method.OwningType); }
private void InitializeMethods() { int numCtors; if (IsSzArray) { numCtors = 1; var t = this.ElementType; while (t.IsSzArray) { t = ((ArrayType)t).ElementType; numCtors++; } } else { // ELEMENT_TYPE_ARRAY has two ctor functions, one with and one without lower bounds numCtors = 2; } MethodDesc[] methods = new MethodDesc[(int)ArrayMethodKind.Ctor + numCtors]; for (int i = 0; i < methods.Length; i++) methods[i] = new ArrayMethod(this, (ArrayMethodKind)i); Interlocked.CompareExchange(ref _methods, methods, null); }
/// <summary> /// Returns method as defined on a non-generic base class or on a base /// instantiation. /// For example, If Foo<T> : Bar<T> and overrides method M, /// if method is Bar<string>.M(), then this returns Bar<T>.M() /// but if Foo : Bar<string>, then this returns Bar<string>.M() /// </summary> /// <param name="typeExamine">A potentially derived type</param> /// <param name="method">A base class's virtual method</param> static public MethodDesc FindMethodOnTypeWithMatchingTypicalMethod(this TypeDesc targetType, MethodDesc method) { // If method is nongeneric and on a nongeneric type, then it is the matching method if (!method.HasInstantiation && !method.OwningType.HasInstantiation) { return method; } // Since method is an instantiation that may or may not be the same as typeExamine's hierarchy, // find a matching base class on an open type and then work from the instantiation in typeExamine's // hierarchy TypeDesc typicalTypeOfTargetMethod = method.GetTypicalMethodDefinition().OwningType; TypeDesc targetOrBase = targetType; do { TypeDesc openTargetOrBase = targetOrBase; if (openTargetOrBase is InstantiatedType) { openTargetOrBase = openTargetOrBase.GetTypeDefinition(); } if (openTargetOrBase == typicalTypeOfTargetMethod) { // Found an open match. Now find an equivalent method on the original target typeOrBase MethodDesc matchingMethod = targetOrBase.FindMethodOnExactTypeWithMatchingTypicalMethod(method); return matchingMethod; } targetOrBase = targetOrBase.BaseType; } while (targetOrBase != null); Debug.Assert(false, "method has no related type in the type hierarchy of type"); return null; }
public static MethodIL EmitIL(MethodDesc target) { Debug.Assert(target.Name == "EETypePtrOf"); Debug.Assert(target.Signature.Length == 0 && target.Signature.ReturnType == target.OwningType); Debug.Assert(target.Instantiation.Length == 1); ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); TypeSystemContext context = target.Context; TypeDesc runtimeTypeHandleType = context.GetWellKnownType(WellKnownType.RuntimeTypeHandle); MethodDesc getValueInternalMethod = runtimeTypeHandleType.GetKnownMethod("GetValueInternal", null); MethodDesc eetypePtrCtorMethod = context.SystemModule .GetKnownType("System", "EETypePtr") .GetKnownMethod(".ctor", new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void), new TypeDesc[] { context.GetWellKnownType(WellKnownType.IntPtr) })); // The sequence of these instructions is important. JIT is able to optimize out // the LDTOKEN+GetValueInternal call into "load EEType pointer onto the evaluation stack". codeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(context.GetSignatureVariable(0, true))); codeStream.Emit(ILOpcode.call, emitter.NewToken(getValueInternalMethod)); codeStream.Emit(ILOpcode.newobj, emitter.NewToken(eetypePtrCtorMethod)); codeStream.Emit(ILOpcode.ret); return emitter.Link(target); }
public sealed override bool ContainsMethod(MethodDesc method) { if (method.HasInstantiation) return true; return ContainsType(method.OwningType); }
public FixupCellMetadataResolver(NativeFormatMetadataUnit metadataUnit, MethodDesc methodContext) { _metadataUnit = metadataUnit; _methodContext = methodContext; _typeContext = methodContext.OwningType; _loadContextFromNativeLayout = null; }
/// <summary> /// Constructs a new instance of <see cref="DelegateCreationInfo"/> set up to construct a delegate of type /// '<paramref name="delegateType"/>' pointing to '<paramref name="targetMethod"/>'. /// </summary> public static DelegateCreationInfo Create(TypeDesc delegateType, MethodDesc targetMethod, NodeFactory factory) { var context = (CompilerTypeSystemContext)delegateType.Context; var systemDelegate = targetMethod.Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; int paramCountTargetMethod = targetMethod.Signature.Length; if (!targetMethod.Signature.IsStatic) { paramCountTargetMethod++; } DelegateInfo delegateInfo = context.GetDelegateInfo(delegateType.GetTypeDefinition()); int paramCountDelegateClosed = delegateInfo.Signature.Length + 1; bool closed = false; if (paramCountDelegateClosed == paramCountTargetMethod) { closed = true; } else { Debug.Assert(paramCountDelegateClosed == paramCountTargetMethod + 1); } if (targetMethod.Signature.IsStatic) { MethodDesc invokeThunk; if (!closed) { // Open delegate to a static method invokeThunk = delegateInfo.Thunks[DelegateThunkKind.OpenStaticThunk]; } else { // Closed delegate to a static method (i.e. delegate to an extension method that locks the first parameter) invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ClosedStaticThunk]; } var instantiatedDelegateType = delegateType as InstantiatedType; if (instantiatedDelegateType != null) invokeThunk = context.GetMethodForInstantiatedType(invokeThunk, instantiatedDelegateType); // We use InitializeClosedStaticThunk for both because RyuJIT generates same code for both, // but passes null as the first parameter for the open one. return new DelegateCreationInfo( factory.MethodEntrypoint(systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null)), factory.MethodEntrypoint(targetMethod), factory.MethodEntrypoint(invokeThunk)); } else { if (!closed) throw new NotImplementedException("Open instance delegates"); bool useUnboxingStub = targetMethod.OwningType.IsValueType; return new DelegateCreationInfo( factory.MethodEntrypoint(systemDelegate.GetKnownMethod("InitializeClosedInstance", null)), factory.MethodEntrypoint(targetMethod, useUnboxingStub)); } }
private bool IsBlockedCustomAttribute(Cts.MethodDesc constructor, Ecma.CustomAttributeValue <Cts.TypeDesc> decodedValue) { if (IsBlocked(constructor.OwningType)) { return(true); } foreach (var fixedArgument in decodedValue.FixedArguments) { if (IsBlockedCustomAttributeConstantValue(fixedArgument.Type, fixedArgument.Value)) { return(true); } if (fixedArgument.Type.IsEnum && IsBlocked(fixedArgument.Type)) { return(true); } } foreach (var namedArgument in decodedValue.NamedArguments) { if (IsBlockedCustomAttributeConstantValue(namedArgument.Type, namedArgument.Value)) { return(true); } } return(false); }
private CustomAttribute HandleCustomAttribute(Cts.MethodDesc constructor, Ecma.CustomAttributeValue <Cts.TypeDesc> decodedValue) { CustomAttribute result = new CustomAttribute { Constructor = HandleQualifiedMethod(constructor), }; result.FixedArguments.Capacity = decodedValue.FixedArguments.Length; foreach (var decodedArgument in decodedValue.FixedArguments) { var fixedArgument = HandleCustomAttributeConstantValue(decodedArgument.Type, decodedArgument.Value); result.FixedArguments.Add(fixedArgument); } result.NamedArguments.Capacity = decodedValue.NamedArguments.Length; foreach (var decodedArgument in decodedValue.NamedArguments) { var namedArgument = new NamedArgument { Flags = decodedArgument.Kind == Ecma.CustomAttributeNamedArgumentKind.Field ? NamedArgumentMemberKind.Field : NamedArgumentMemberKind.Property, Name = HandleString(decodedArgument.Name), Type = HandleType(decodedArgument.Type), Value = HandleCustomAttributeConstantValue(decodedArgument.Type, decodedArgument.Value) }; result.NamedArguments.Add(namedArgument); } return(result); }
public override MetadataRecord HandleQualifiedMethod(Cts.MethodDesc method) { MetadataRecord rec; if (method is Cts.InstantiatedMethod) { rec = HandleMethodInstantiation(method); } else if (method.IsTypicalMethodDefinition && _policy.GeneratesMetadata(method)) { rec = new QualifiedMethod { EnclosingType = (TypeDefinition)HandleType(method.OwningType), Method = HandleMethodDefinition(method), }; } else { rec = HandleMethodReference(method); } Debug.Assert(rec is QualifiedMethod || rec is MemberReference || rec is MethodInstantiation); return(rec); }
/// <summary> /// Given a virtual method decl, return its VTable slot if the method is used on its containing type. /// Return -1 if the virtual method is not used. /// </summary> public static int GetVirtualMethodSlot(NodeFactory factory, MethodDesc method) { // TODO: More efficient lookup of the slot TypeDesc owningType = method.OwningType; int baseSlots = 0; var baseType = owningType.BaseType; while (baseType != null) { List<MethodDesc> baseVirtualSlots; factory.VirtualSlots.TryGetValue(baseType, out baseVirtualSlots); if (baseVirtualSlots != null) baseSlots += baseVirtualSlots.Count; baseType = baseType.BaseType; } List<MethodDesc> virtualSlots = factory.VirtualSlots[owningType]; int methodSlot = -1; for (int slot = 0; slot < virtualSlots.Count; slot++) { if (virtualSlots[slot] == method) { methodSlot = slot; break; } } return methodSlot == -1 ? -1 : baseSlots + methodSlot; }
private void AppendMethodSignature(StringBuilder sb, MethodDesc method) { // If this is an instantiated generic method, the formatted signature should // be uninstantiated (e.g. "void Foo::Bar<int>(!!0 param)", not "void Foo::Bar<int>(int param)") MethodSignature signature = method.GetMethodDefinition().Signature; AppendSignaturePrefix(sb, signature); sb.Append(' '); AppendOwningType(sb, method.OwningType); sb.Append("::"); sb.Append(method.Name); if (method.HasInstantiation) { sb.Append('<'); for (int i = 0; i < method.Instantiation.Length; i++) { if (i != 0) sb.Append(", "); _typeNameFormatter.AppendNameWithValueClassPrefix(sb, method.Instantiation[i]); } sb.Append('>'); } sb.Append('('); AppendSignatureArgumentList(sb, signature); sb.Append(')'); }
public DelegateInfo(Compilation compilation, MethodDesc target) { this.Target = target; var systemDelegate = compilation.TypeSystemContext.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; // TODO: delegates on virtuals if (target.IsVirtual && !target.IsFinal) throw new NotImplementedException("Delegate to virtual"); // TODO: Delegates on valuetypes if (target.OwningType.IsValueType) throw new NotImplementedException("Delegate to valuetype"); if (target.Signature.IsStatic) { this.ShuffleThunk = new DelegateShuffleThunk(target); this.Ctor = systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null); } else { this.Ctor = systemDelegate.GetKnownMethod("InitializeClosedInstance", null); } }
public MethodIL GetMethodIL(MethodDesc method) { if (method is EcmaMethod) { // TODO: Workaround: we should special case methods with Intrinsic attribute, but since // CoreLib source is still not in the repo, we have to work with what we have, which is // an MCG attribute on the type itself... if (((MetadataType)method.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute")) { if (method.Name == "Call") { return CalliIntrinsic.EmitIL(method); } } if (method.IsIntrinsic) { MethodIL result = TryGetIntrinsicMethodIL(method); if (result != null) return result; } if (method.IsPInvoke) { return PInvokeMarshallingILEmitter.EmitIL(method); } return EcmaMethodIL.Create((EcmaMethod)method); } else if (method is MethodForInstantiatedType) { var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition()); if (methodDefinitionIL == null) return null; return new InstantiatedMethodIL(methodDefinitionIL, method.OwningType.Instantiation, new Instantiation()); } else if (method is InstantiatedMethod) { var methodDefinitionIL = GetMethodIL(method.GetMethodDefinition()); if (methodDefinitionIL == null) return null; return new InstantiatedMethodIL(methodDefinitionIL, new Instantiation(), method.Instantiation); } else if (method is ILStubMethod) { return ((ILStubMethod)method).EmitIL(); } else if (method is ArrayMethod) { return ArrayMethodILEmitter.EmitIL((ArrayMethod)method); } else { return null; } }
public FatFunctionPointerNode(MethodDesc methodRepresented) { // We should not create these for methods that don't have a canonical method body Debug.Assert(methodRepresented.GetCanonMethodTarget(CanonicalFormKind.Specific) != methodRepresented); Method = methodRepresented; }
// Returns null if no matching method is found private static MethodDesc GetMatchingMethod(ModuleDesc module, MethodDesc method) { var matchingType = GetMatchingType(module, method.OwningType); if (matchingType == null) return null; return matchingType.GetMethod(method.Name, method.Signature); }
private List <CustomAttribute> HandleCustomAttributes(Cts.Ecma.EcmaModule module, Ecma.CustomAttributeHandleCollection attributes) { List <CustomAttribute> customAttributes = new List <CustomAttribute>(attributes.Count); var attributeTypeProvider = new Cts.Ecma.CustomAttributeTypeProvider(module); foreach (var attributeHandle in attributes) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); // TODO-NICE: We can intern the attributes based on the CA constructor and blob bytes try { Cts.MethodDesc constructor = module.GetMethod(attribute.Constructor); var decodedValue = attribute.DecodeValue(attributeTypeProvider); if (IsBlockedCustomAttribute(constructor, decodedValue)) { continue; } customAttributes.Add(HandleCustomAttribute(constructor, decodedValue)); } catch (Cts.TypeSystemException) { // TODO: We should emit unresolvable custom attributes instead of skipping these } } return(customAttributes); }
private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) { record.Name = HandleString(entity.Name); record.Signature = HandleMethodSignature(entity.Signature); if (entity.HasInstantiation) { var genericParams = new List <GenericParameter>(entity.Instantiation.Length); foreach (var p in entity.Instantiation) { genericParams.Add(HandleGenericParameter((Cts.GenericParameterDesc)p)); } record.GenericParameters = genericParams; } if (entity.Signature.Length > 0) { List <Parameter> parameters = new List <Parameter>(entity.Signature.Length); for (ushort i = 0; i < entity.Signature.Length; i++) { parameters.Add(new Parameter { Sequence = i }); } var ecmaEntity = entity as Cts.Ecma.EcmaMethod; if (ecmaEntity != null) { Ecma.MetadataReader reader = ecmaEntity.MetadataReader; Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaEntity.Handle); Ecma.ParameterHandleCollection paramHandles = methodDef.GetParameters(); Debug.Assert(paramHandles.Count == entity.Signature.Length); int i = 0; foreach (var paramHandle in paramHandles) { Ecma.Parameter param = reader.GetParameter(paramHandle); parameters[i].Flags = param.Attributes; parameters[i].Name = HandleString(reader.GetString(param.Name)); // TODO: CustomAttributes // TODO: DefaultValue i++; } } record.Parameters = parameters; } record.Flags = GetMethodAttributes(entity); record.ImplFlags = GetMethodImplAttributes(entity); //TODO: MethodImpls //TODO: RVA //TODO: CustomAttributes }
internal MethodIL GetMethodIL(MethodDesc method) { // Flush the cache when it grows too big if (_methodILCache.Count > 1000) _methodILCache = new ILProvider(); return _methodILCache.GetMethodIL(method); }
internal InstantiatedMethod(MethodDesc methodDef, Instantiation instantiation) { Debug.Assert(!(methodDef is InstantiatedMethod)); _methodDef = methodDef; Debug.Assert(instantiation.Length > 0); _instantiation = instantiation; }
public static MethodIL EmitIL(MethodDesc method) { ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc typeLoadExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowTypeLoadException"); codeStream.EmitCallThrowHelper(emit, typeLoadExceptionHelper); return emit.Link(); }
/// <summary> /// Resolve a MethodDesc to a callable method address and unboxing stub address by searching /// by searching in the InvokeMaps. This function is a wrapper around TryGetMethodInvokeDataFromInvokeMap /// that produces output in the format which matches the code table system. /// </summary> /// <param name="method">Native metadata method description object</param> /// <param name="methodAddress">Resolved method address</param> /// <param name="unboxingStubAddress">Resolved unboxing stub address</param> /// <returns>true when the resolution succeeded, false when not</returns> private static bool TryGetMethodAddressFromTypeSystemMethodViaInvokeMap( MethodDesc method, out IntPtr methodAddress, out IntPtr unboxingStubAddress, out MethodAddressType foundAddressType) { methodAddress = IntPtr.Zero; unboxingStubAddress = IntPtr.Zero; foundAddressType = MethodAddressType.None; #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING NativeFormatMethod nativeFormatMethod = method.GetTypicalMethodDefinition() as NativeFormatMethod; if (nativeFormatMethod == null) return false; MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer( nativeFormatMethod.MetadataReader, nativeFormatMethod.Handle); // Try to find a specific canonical match, or if that fails, a universal match if (TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Specific, out methodAddress, out foundAddressType) || TryGetMethodInvokeDataFromInvokeMap( nativeFormatMethod, method, ref methodSignatureComparer, CanonicalFormKind.Universal, out methodAddress, out foundAddressType)) { if (method.OwningType.IsValueType && !method.Signature.IsStatic) { // In this case the invoke map found an unboxing stub, and we should pull the method address out as well unboxingStubAddress = methodAddress; methodAddress = RuntimeAugments.GetCodeTarget(unboxingStubAddress); if (!method.HasInstantiation && ((foundAddressType != MethodAddressType.Exact) || method.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))) { IntPtr underlyingTarget; // unboxing and instantiating stub handling if (!TypeLoaderEnvironment.TryGetTargetOfUnboxingAndInstantiatingStub(methodAddress, out underlyingTarget)) { Environment.FailFast("Expected this to be an unboxing and instantiating stub."); } methodAddress = underlyingTarget; } } return true; } #endif return false; }
// Returns null if no matching method is found private static MethodDesc GetMatchingMethod(ModuleDesc module, MethodDesc method) { // TODO:Enable this once mcg generated code match GetMatchingType // type lookup. // var matchingType = GetMatchingType(module, method.OwningType); var matchingType = TryGetMcgGeneratedType(module); if (matchingType == null) return null; return matchingType.GetMethod(method.Name, method.Signature); }
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)); } }
public static IntrinsicMethodKind GetIntrinsicMethodClassification(MethodDesc method) { // TODO: make this reliable if (method.Name == "InitializeArray" && method.OwningType.Name == "System.Runtime.CompilerServices.RuntimeHelpers") { return IntrinsicMethodKind.RuntimeHelpersInitializeArray; } return IntrinsicMethodKind.None; }
/// <summary> /// Returns true if <paramref name="method"/> is pregenerated interop code /// </summary> public static bool IsPregeneratedInterop(MethodDesc method) { var metadataType = (MetadataType)method.OwningType; var module = metadataType.Module; var assemblyName = ((IAssemblyDesc)module).GetName(); var simpleName = assemblyName.Name; return simpleName.EndsWith(AssemblyNameSuffix); }
public MethodCode CompileMethod(MethodDesc method) { try { CORINFO_METHOD_INFO methodInfo; Get_CORINFO_METHOD_INFO(method, out methodInfo); uint flags = (uint)( CorJitFlag.CORJIT_FLG_SKIP_VERIFICATION | CorJitFlag.CORJIT_FLG_READYTORUN | CorJitFlag.CORJIT_FLG_RELOC | CorJitFlag.CORJIT_FLG_DEBUG_INFO | CorJitFlag.CORJIT_FLG_PREJIT); if (!_compilation.Options.NoLineNumbers) { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; IEnumerable<ILSequencePoint> ilSequencePoints = typeSystemContext.GetSequencePointsForMethod(method); if (ilSequencePoints != null) { Dictionary<int, SequencePoint> sequencePoints = new Dictionary<int, SequencePoint>(); foreach (var point in ilSequencePoints) { sequencePoints.Add(point.Offset, new SequencePoint() { Document = point.Document, LineNumber = point.LineNumber }); } _sequencePoints = sequencePoints; } } IntPtr nativeEntry; uint codeSize; _compile(_jit, _comp, ref methodInfo, flags, out nativeEntry, out codeSize); if (_relocs != null) _relocs.Sort((x, y) => (x.Block != y.Block) ? (x.Block - y.Block) : (x.Offset - y.Offset)); return new MethodCode() { Code = _code, ColdCode = _coldCode, RODataAlignment = _roDataAlignment, ROData = _roData, Relocs = (_relocs != null) ? _relocs.ToArray() : null, FrameInfos = _frameInfos, DebugLocInfos = _debugLocInfos }; } finally { FlushPins(); } }
/// <summary> /// Validates that it will be possible to generate '<paramref name="method"/>' based on the types /// in its signature. Unresolvable types in a method's signature prevent RyuJIT from generating /// even a stubbed out throwing implementation. /// </summary> private static void CheckCanGenerateMethod(MethodDesc method) { MethodSignature signature = method.Signature; CheckTypeCanBeUsedInSignature(signature.ReturnType); for (int i = 0; i < signature.Length; i++) { CheckTypeCanBeUsedInSignature(signature[i]); } }
protected override IMethodNode CreateMethodEntrypointNode(MethodDesc method) { if (CompilationModuleGroup.ContainsMethod(method)) { return new CppMethodCodeNode(method); } else { return new ExternMethodSymbolNode(method); } }
private PInvokeMarshallingILEmitter(MethodDesc targetMethod) { Debug.Assert(targetMethod.IsPInvoke); Debug.Assert(RequiresMarshalling(targetMethod)); _targetMethod = targetMethod; _importMetadata = targetMethod.GetPInvokeMethodMetadata(); _emitter = null; _marshallingCodeStream = null; }
private MethodImplAttributes GetMethodImplAttributes(Cts.MethodDesc method) { var ecmaMethod = method as Cts.Ecma.EcmaMethod; if (ecmaMethod != null) { Ecma.MetadataReader reader = ecmaMethod.MetadataReader; Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaMethod.Handle); return methodDef.ImplAttributes; } else throw new NotImplementedException(); }
public static MethodIL EmitIL(MethodDesc target) { Debug.Assert(target.Name == "Call"); Debug.Assert(target.Signature.Length > 0 && target.Signature[0] == target.Context.GetWellKnownType(WellKnownType.IntPtr)); ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); // Load all the arguments except the first one (IntPtr address) for (int i = 1; i < target.Signature.Length; i++) { codeStream.EmitLdArg(i); } // now load IntPtr address codeStream.EmitLdArg(0); // Create a signature for the calli by copying the signature of the containing method // while skipping the first argument MethodSignature template = target.Signature; TypeDesc returnType = template.ReturnType; TypeDesc[] parameters = new TypeDesc[template.Length - 1]; for (int i = 1; i < template.Length; i++) { parameters[i - 1] = template[i]; } var signature = new MethodSignature(template.Flags, 0, returnType, parameters); bool useTransformedCalli = true; if ((signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) != 0) { // Fat function pointer only ever exist for managed targets. useTransformedCalli = false; } if (((MetadataType)target.OwningType).Name == "RawCalliHelper") { // RawCalliHelper doesn't need the transform. useTransformedCalli = false; } if (useTransformedCalli) EmitTransformedCalli(emitter, codeStream, signature); else codeStream.Emit(ILOpcode.calli, emitter.NewToken(signature)); codeStream.Emit(ILOpcode.ret); return emitter.Link(target); }
public InstantiatedMethodIL(MethodDesc owningMethod, MethodIL methodIL) { Debug.Assert(methodIL.GetMethodILDefinition() == methodIL); Debug.Assert(owningMethod.HasInstantiation || owningMethod.OwningType.HasInstantiation); Debug.Assert(owningMethod.GetTypicalMethodDefinition() == methodIL.OwningMethod); _methodIL = methodIL; _method = owningMethod; _typeInstantiation = owningMethod.OwningType.Instantiation; _methodInstantiation = owningMethod.Instantiation; }
/// <summary> /// Attempts to retrieve a <see cref="Method"/> record corresponding to the specified /// <paramref name="method"/>. Returns null if not found. /// </summary> public Method GetTransformedMethodDefinition(Cts.MethodDesc method) { Debug.Assert(method.IsTypicalMethodDefinition); MetadataRecord rec; if (!_transform._methods.TryGet(method, out rec)) { return(null); } return(rec as Method); }
public void TestMethodImplMetadata() { // Test that custom attributes referring to blocked types don't show up in metadata var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly"); Cts.MetadataType iCloneable = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ICloneable"); Cts.MetadataType implementsICloneable = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ImplementsICloneable"); Cts.MethodDesc iCloneableDotClone = iCloneable.GetMethod("Clone", null); Cts.MethodDesc iCloneableImplementation = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.Clone", null); Cts.MethodDesc iCloneableDotGenericClone = iCloneable.GetMethod("GenericClone", null); Cts.MethodDesc iCloneableGenericImplementation = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.GenericClone", null); var policy = new SingleFileMetadataPolicy(); var transformResult = MetadataTransform.Run(policy, new[] { _systemModule, sampleMetadataModule }); var iCloneableType = transformResult.GetTransformedTypeDefinition(iCloneable); var implementsICloneableType = transformResult.GetTransformedTypeDefinition(implementsICloneable); Assert.Equal(2, implementsICloneableType.MethodImpls.Count); // non-generic MethodImpl Method iCloneableDotCloneMethod = transformResult.GetTransformedMethodDefinition(iCloneableDotClone); Method iCloneableImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableImplementation); QualifiedMethod methodImplMethodDecl = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodDeclaration; QualifiedMethod methodImplMethodBody = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodBody; Assert.Equal(iCloneableDotCloneMethod, methodImplMethodDecl.Method); Assert.Equal(iCloneableType, methodImplMethodDecl.EnclosingType); Assert.Equal(iCloneableImplementationMethod, methodImplMethodBody.Method); Assert.Equal(implementsICloneableType, methodImplMethodBody.EnclosingType); // generic MethodImpl Method iCloneableDotGenericCloneMethod = transformResult.GetTransformedMethodDefinition(iCloneableDotGenericClone); Method iCloneableGenericImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableGenericImplementation); QualifiedMethod methodImplGenericMethodDecl = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodDeclaration; QualifiedMethod methodImplGenericMethodBody = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodBody; Assert.Equal(iCloneableDotGenericCloneMethod, methodImplGenericMethodDecl.Method); Assert.Equal(iCloneableType, methodImplGenericMethodDecl.EnclosingType); Assert.Equal(iCloneableGenericImplementationMethod, methodImplGenericMethodBody.Method); Assert.Equal(implementsICloneableType, methodImplGenericMethodBody.EnclosingType); }
private MetadataRecord HandleMethod(Cts.MethodDesc method) { // TODO: MethodSpecs Debug.Assert(method.IsTypicalMethodDefinition); MetadataRecord rec; if (_policy.GeneratesMetadata(method)) { rec = HandleMethodDefinition(method); } else { rec = _methods.GetOrCreate(method, _initMethodRef ?? (_initMethodRef = InitializeMethodReference)); } Debug.Assert(rec is Method || rec is MemberReference); return(rec); }
private MetadataRecord HandleQualifiedMethod(Cts.MethodDesc method) { MetadataRecord rec; if (_policy.GeneratesMetadata(method)) { rec = new QualifiedMethod { EnclosingType = (TypeDefinition)HandleType(method.OwningType), Method = HandleMethodDefinition(method), }; } else { rec = HandleMethodReference(method); } Debug.Assert(rec is QualifiedMethod || rec is MemberReference); return(rec); }
public override MethodDesc ResolveInterfaceMethodToVirtualMethodOnType(MethodDesc interfaceMethod, TypeDesc currentType) { return(ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, (MetadataType)currentType)); }
private MethodInstantiation HandleMethodInstantiation(Cts.MethodDesc method) { return((MethodInstantiation)_methods.GetOrCreate(method, _initMethodInst ??= InitializeMethodInstantiation)); }
private void InitializeMethodReference(Cts.MethodDesc entity, MemberReference record) { record.Name = HandleString(entity.Name); record.Parent = HandleType(entity.OwningType); record.Signature = HandleMethodSignature(entity.GetTypicalMethodDefinition().Signature); }
private MemberReference HandleMethodReference(Cts.MethodDesc method) { Debug.Assert(method.IsMethodDefinition); return((MemberReference)_methods.GetOrCreate(method, _initMethodRef ??= InitializeMethodReference)); }
// Return true if the slot that defines methodToVerify matches slotDefiningMethod private static bool VerifyMethodsHaveTheSameVirtualSlot(MethodDesc methodToVerify, MethodDesc slotDefiningMethod) { MethodDesc slotDefiningMethodOfMethodToVerify = FindSlotDefiningMethodForVirtualMethod(methodToVerify); return(slotDefiningMethodOfMethodToVerify == slotDefiningMethod); }
private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) { record.Name = HandleString(entity.Name); record.Signature = HandleMethodSignature(entity.Signature); if (entity.HasInstantiation) { record.GenericParameters.Capacity = entity.Instantiation.Length; foreach (var p in entity.Instantiation) { record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p)); } } var ecmaEntity = entity as Cts.Ecma.EcmaMethod; if (ecmaEntity != null) { Ecma.MetadataReader reader = ecmaEntity.MetadataReader; Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaEntity.Handle); Ecma.ParameterHandleCollection paramHandles = methodDef.GetParameters(); record.Parameters.Capacity = paramHandles.Count; foreach (var paramHandle in paramHandles) { Ecma.Parameter param = reader.GetParameter(paramHandle); Parameter paramRecord = new Parameter { Flags = param.Attributes, Name = HandleString(reader.GetString(param.Name)), Sequence = checked ((ushort)param.SequenceNumber) }; Ecma.ConstantHandle defaultValue = param.GetDefaultValue(); if (!defaultValue.IsNil) { paramRecord.DefaultValue = HandleConstant(ecmaEntity.Module, defaultValue); } Ecma.CustomAttributeHandleCollection paramAttributes = param.GetCustomAttributes(); if (paramAttributes.Count > 0) { paramRecord.CustomAttributes = HandleCustomAttributes(ecmaEntity.Module, paramAttributes); } record.Parameters.Add(paramRecord); } Ecma.CustomAttributeHandleCollection attributes = methodDef.GetCustomAttributes(); if (attributes.Count > 0) { record.CustomAttributes = HandleCustomAttributes(ecmaEntity.Module, attributes); } } else { throw new NotImplementedException(); } record.Flags = GetMethodAttributes(entity); record.ImplFlags = GetMethodImplAttributes(entity); //TODO: RVA }
// Helper routine used during implicit interface implementation discovery private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnTypeRecursive(MethodDesc interfaceMethod, MetadataType currentType) { while (true) { if (currentType == null) { return(null); } MetadataType interfaceType = (MetadataType)interfaceMethod.OwningType; if (!IsInterfaceImplementedOnType(currentType, interfaceType)) { // If the interface isn't implemented on this type at all, don't go searching return(null); } MethodDesc currentTypeInterfaceResolution = ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, currentType); if (currentTypeInterfaceResolution != null) { return(currentTypeInterfaceResolution); } currentType = currentType.MetadataBaseType; } }
public UnificationGroup(MethodDesc definingMethod) { DefiningMethod = definingMethod; // TODO! Add assertion that DefiningMethod is a slot defining method }
private Event HandleEvent(Cts.Ecma.EcmaModule module, Ecma.EventDefinitionHandle eventHandle) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.EventDefinition eventDef = reader.GetEventDefinition(eventHandle); Ecma.EventAccessors acc = eventDef.GetAccessors(); Cts.MethodDesc adderMethod = acc.Adder.IsNil ? null : module.GetMethod(acc.Adder); Cts.MethodDesc raiserMethod = acc.Raiser.IsNil ? null : module.GetMethod(acc.Raiser); Cts.MethodDesc removerMethod = acc.Remover.IsNil ? null : module.GetMethod(acc.Remover); bool adderHasMetadata = adderMethod != null && _policy.GeneratesMetadata(adderMethod); bool raiserHasMetadata = raiserMethod != null && _policy.GeneratesMetadata(raiserMethod); bool removerHasMetadata = removerMethod != null && _policy.GeneratesMetadata(removerMethod); // Policy: If none of the accessors has metadata, event doesn't have metadata if (!adderHasMetadata && !raiserHasMetadata && !removerHasMetadata) { return(null); } Event result = new Event { Name = HandleString(reader.GetString(eventDef.Name)), Flags = eventDef.Attributes, Type = HandleType(module.GetType(eventDef.Type)), }; if (adderHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.AddOn, Method = HandleMethodDefinition(adderMethod), }); } if (raiserHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Fire, Method = HandleMethodDefinition(raiserMethod), }); } if (removerHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.RemoveOn, Method = HandleMethodDefinition(removerMethod), }); } Ecma.CustomAttributeHandleCollection customAttributes = eventDef.GetCustomAttributes(); if (customAttributes.Count > 0) { result.CustomAttributes = HandleCustomAttributes(module, customAttributes); } return(result); }
/// <summary> /// Retrieves an existing <see cref="QualifiedMethod"/>, <see cref="MemberReference"/>, or <see cref="MethodInstantiation"/> /// record representing specified method in the metadata writer object model, or creates a new one. /// </summary> public abstract MetadataRecord HandleQualifiedMethod(Cts.MethodDesc method);
private static void FindBaseUnificationGroup(MetadataType currentType, UnificationGroup unificationGroup) { MethodDesc originalDefiningMethod = unificationGroup.DefiningMethod; MethodDesc methodImpl = FindImplFromDeclFromMethodImpls(currentType, unificationGroup.DefiningMethod); if (methodImpl != null) { unificationGroup.SetDefiningMethod(methodImpl); } MethodDesc nameSigMatchMethod = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(unificationGroup.DefiningMethod, currentType); MetadataType baseType = currentType.MetadataBaseType; // Unless the current type has a name/sig match for the group, look to the base type to define the unification group further if ((nameSigMatchMethod == null) && (baseType != null)) { FindBaseUnificationGroup(baseType, unificationGroup); } Debug.Assert(unificationGroup.IsInGroupOrIsDefiningSlot(originalDefiningMethod)); // Now, we have the unification group from the type, or have discovered its defined on the current type. // Adjust the group to contain all of the elements that are added to it on this type, remove the components that // have seperated themselves from the group // Start with removing methods that seperated themselves from the group via name/sig matches MethodDescHashtable separatedMethods = null; foreach (MethodDesc memberMethod in unificationGroup) { MethodDesc nameSigMatchMemberMethod = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(memberMethod, currentType); if (nameSigMatchMemberMethod != null) { if (separatedMethods == null) { separatedMethods = new MethodDescHashtable(); } separatedMethods.AddOrGetExisting(memberMethod); } } if (separatedMethods != null) { foreach (MethodDesc seperatedMethod in MethodDescHashtable.Enumerator.Get(separatedMethods)) { unificationGroup.RemoveFromGroup(seperatedMethod); } } // Next find members which have seperated or added themselves to the group via MethodImpls foreach (MethodImplRecord methodImplRecord in currentType.VirtualMethodImplsForType) { MethodDesc declSlot = FindSlotDefiningMethodForVirtualMethod(methodImplRecord.Decl); MethodDesc implSlot = FindSlotDefiningMethodForVirtualMethod(methodImplRecord.Body); if (unificationGroup.IsInGroup(declSlot) && !unificationGroup.IsInGroupOrIsDefiningSlot(implSlot)) { unificationGroup.RemoveFromGroup(declSlot); if (separatedMethods == null) { separatedMethods = new MethodDescHashtable(); } separatedMethods.AddOrGetExisting(declSlot); continue; } if (!unificationGroup.IsInGroupOrIsDefiningSlot(declSlot) && unificationGroup.IsInGroupOrIsDefiningSlot(implSlot)) { // Add decl to group. // To do so, we need to have the Unification Group of the decl slot, as it may have multiple members itself UnificationGroup addDeclGroup = new UnificationGroup(declSlot); FindBaseUnificationGroup(baseType, addDeclGroup); Debug.Assert(addDeclGroup.IsInGroupOrIsDefiningSlot(declSlot)); // Add all members from the decl's unification group except for ones that have been seperated by name/sig matches // or previously processed methodimpls. NOTE: This implies that method impls are order dependent. if (separatedMethods == null || !separatedMethods.Contains(addDeclGroup.DefiningMethod)) { unificationGroup.AddToGroup(addDeclGroup.DefiningMethod); } foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup) { if (separatedMethods == null || !separatedMethods.Contains(addDeclGroupMemberMethod)) { unificationGroup.AddToGroup(addDeclGroupMemberMethod); } } } } }
internal Enumerator(MethodDesc[] arrayToEnumerate) { _arrayToEnumerate = arrayToEnumerate; _index = 0; _current = default(MethodDesc); }
private Method HandleMethodDefinition(Cts.MethodDesc method) { Debug.Assert(method.IsTypicalMethodDefinition); Debug.Assert(_policy.GeneratesMetadata(method)); return((Method)_methods.GetOrCreate(method, _initMethodDef ??= InitializeMethodDefinition)); }
//////////////////////// INTERFACE RESOLUTION //Interface function resolution // Interface function resolution follows the following rules // 1. Apply any method impl that may exist, if once of these exists, resolve to target immediately. // 2. If an interface is explicitly defined on a type, then attempt to perform a namesig match on the // current type to resolve.If the interface isn’t resolved, if it isn’t implemented on a base type, // scan all base types for name / sig matches. // 3. If implicitly defined, attempt to perform a namesig match if the interface method implementation // has not been found on some base type. // The above will resolve an interface to a virtual method slot. From there perform virtual resolution // to find out the actual target.Note, to preserve correct behavior in the presence of variance, this // function returns null if the interface method implementation is not defined by the current type in // the hierarchy.For variance to work correctly, this requires that interfaces be queried in correct order. // See current interface call resolution for details on how that happens. private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnType(MethodDesc interfaceMethod, MetadataType currentType) { if (currentType.IsInterface) { return(null); } MethodDesc methodImpl = FindImplFromDeclFromMethodImpls(currentType, interfaceMethod); if (methodImpl != null) { return(methodImpl); } MetadataType interfaceType = (MetadataType)interfaceMethod.OwningType; // If interface is explicitly defined on a type, search for a name/sig match. bool foundExplicitInterface = IsInterfaceExplicitlyImplementedOnType(currentType, interfaceType); MetadataType baseType = currentType.MetadataBaseType; if (foundExplicitInterface) { MethodDesc foundOnCurrentType = FindMatchingVirtualMethodOnTypeByNameAndSig(interfaceMethod, currentType); foundOnCurrentType = FindSlotDefiningMethodForVirtualMethod(foundOnCurrentType); if (baseType == null) { return(foundOnCurrentType); } if (foundOnCurrentType == null && (ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, baseType) == null)) { // TODO! Does this handle the case where the base type explicitly implements the interface, but is abstract // and doesn't actually have an implementation? if (!IsInterfaceImplementedOnType(baseType, interfaceType)) { return(FindNameSigOverrideForInterfaceMethodRecursive(interfaceMethod, baseType)); } } return(foundOnCurrentType); } else { // Implicit interface case if (!IsInterfaceImplementedOnType(currentType, interfaceType)) { // If the interface isn't implemented on this type at all, don't go searching return(null); } // This is an implicitly implemented interface method. Only return a vlaue if this is the first type in the class // hierarchy that implements the interface. NOTE: If we pay attention to whether or not the parent type is // abstract or not, we may be able to be more efficient here, but let's skip that for now MethodDesc baseClassImplementationOfInterfaceMethod = ResolveInterfaceMethodToVirtualMethodOnTypeRecursive(interfaceMethod, baseType); if (baseClassImplementationOfInterfaceMethod != null) { return(null); } else { return(FindNameSigOverrideForInterfaceMethodRecursive(interfaceMethod, currentType)); } } }
private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property); Ecma.PropertyAccessors acc = propDef.GetAccessors(); Cts.MethodDesc getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter); Cts.MethodDesc setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter); bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod); bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod); // Policy: If neither the getter nor setter have metadata, property doesn't have metadata if (!getterHasMetadata && !setterHasMetadata) { return(null); } Ecma.BlobReader sigBlobReader = reader.GetBlobReader(propDef.Signature); Cts.PropertySignature sig = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature(); Property result = new Property { Name = HandleString(reader.GetString(propDef.Name)), Flags = propDef.Attributes, Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, Type = HandleType(sig.ReturnType) }, }; result.Signature.Parameters.Capacity = sig.Length; for (int i = 0; i < sig.Length; i++) { result.Signature.Parameters.Add(HandleType(sig[i])); } if (getterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Getter, Method = HandleMethodDefinition(getterMethod), }); } if (setterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Setter, Method = HandleMethodDefinition(setterMethod), }); } Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue(); if (!defaultValue.IsNil) { result.DefaultValue = HandleConstant(module, defaultValue); } Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes(); if (customAttributes.Count > 0) { result.CustomAttributes = HandleCustomAttributes(module, customAttributes); } return(result); }
private void InitializeScopeDefinition(Cts.ModuleDesc module, ScopeDefinition scopeDefinition) { var assemblyDesc = module as Cts.IAssemblyDesc; if (assemblyDesc != null) { var assemblyName = assemblyDesc.GetName(); scopeDefinition.Name = HandleString(assemblyName.Name); #if NETFX_45 // With NET 4.5 contract System.Reflection 4.0.0.0 EcmaModule has no way // to set Culture in its AssemblyName. scopeDefinition.Culture = HandleString(assemblyName.CultureName ?? ""); #else scopeDefinition.Culture = HandleString(assemblyName.CultureName); #endif scopeDefinition.MajorVersion = checked ((ushort)assemblyName.Version.Major); scopeDefinition.MinorVersion = checked ((ushort)assemblyName.Version.Minor); scopeDefinition.BuildNumber = checked ((ushort)assemblyName.Version.Build); scopeDefinition.RevisionNumber = checked ((ushort)assemblyName.Version.Revision); Debug.Assert((int)AssemblyFlags.PublicKey == (int)AssemblyNameFlags.PublicKey); Debug.Assert((int)AssemblyFlags.Retargetable == (int)AssemblyNameFlags.Retargetable); scopeDefinition.Flags = (AssemblyFlags)assemblyName.Flags; if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime) { scopeDefinition.Flags |= (AssemblyFlags)((int)AssemblyContentType.WindowsRuntime << 9); } if ((scopeDefinition.Flags & AssemblyFlags.PublicKey) != 0) { scopeDefinition.PublicKey = assemblyName.GetPublicKey(); } else { scopeDefinition.PublicKey = assemblyName.GetPublicKeyToken(); } Cts.MetadataType moduleType = module.GetGlobalModuleType(); if (moduleType != null && _policy.GeneratesMetadata(moduleType)) { scopeDefinition.GlobalModuleType = (TypeDefinition)HandleType(moduleType); } Cts.Ecma.EcmaAssembly ecmaAssembly = module as Cts.Ecma.EcmaAssembly; if (ecmaAssembly != null) { Ecma.CustomAttributeHandleCollection customAttributes = ecmaAssembly.AssemblyDefinition.GetCustomAttributes(); if (customAttributes.Count > 0) { scopeDefinition.CustomAttributes = HandleCustomAttributes(ecmaAssembly, customAttributes); } Cts.MethodDesc entryPoint = ecmaAssembly.EntryPoint; if (entryPoint != null && _policy.GeneratesMetadata(entryPoint)) { scopeDefinition.EntryPoint = (QualifiedMethod)HandleQualifiedMethod(entryPoint); } } } else { throw new NotSupportedException("Multi-module assemblies"); } }
private MemberReference HandleMethodReference(Cts.MethodDesc method) { Debug.Assert(method.IsTypicalMethodDefinition); Debug.Assert(!_policy.GeneratesMetadata(method)); return((MemberReference)_methods.GetOrCreate(method, _initMethodRef ?? (_initMethodRef = InitializeMethodReference))); }
private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record) { Debug.Assert(entity.IsTypeDefinition); Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType; if (containingType != null) { var enclosingType = (TypeDefinition)HandleType(containingType); record.EnclosingType = enclosingType; enclosingType.NestedTypes.Add(record); var namespaceDefinition = HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace); record.NamespaceDefinition = namespaceDefinition; } else { var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace); record.NamespaceDefinition = namespaceDefinition; namespaceDefinition.TypeDefinitions.Add(record); } record.Name = HandleString(entity.Name); Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout(); record.Size = checked ((uint)layoutMetadata.Size); record.PackingSize = checked ((ushort)layoutMetadata.PackingSize); record.Flags = GetTypeAttributes(entity); if (entity.HasBaseType) { record.BaseType = HandleType(entity.BaseType); } record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length; foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces) { if (IsBlocked(interfaceType)) { continue; } record.Interfaces.Add(HandleType(interfaceType)); } if (entity.HasInstantiation) { record.GenericParameters.Capacity = entity.Instantiation.Length; foreach (var p in entity.Instantiation) { record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p)); } } foreach (var field in entity.GetFields()) { if (_policy.GeneratesMetadata(field)) { record.Fields.Add(HandleFieldDefinition(field)); } } foreach (var method in entity.GetMethods()) { if (_policy.GeneratesMetadata(method)) { record.Methods.Add(HandleMethodDefinition(method)); } } var ecmaEntity = entity as Cts.Ecma.EcmaType; if (ecmaEntity != null) { Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle); foreach (var e in ecmaRecord.GetEvents()) { Event evt = HandleEvent(ecmaEntity.EcmaModule, e); if (evt != null) { record.Events.Add(evt); } } foreach (var property in ecmaRecord.GetProperties()) { Property prop = HandleProperty(ecmaEntity.EcmaModule, property); if (prop != null) { record.Properties.Add(prop); } } Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes(); if (customAttributes.Count > 0) { record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes); } foreach (var miHandle in ecmaRecord.GetMethodImplementations()) { Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader; Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle); Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody); if (_policy.IsBlocked(methodBody)) { continue; } Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration); if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition())) { continue; } MethodImpl methodImplRecord = new MethodImpl { MethodBody = HandleQualifiedMethod(methodBody), MethodDeclaration = HandleQualifiedMethod(methodDecl) }; record.MethodImpls.Add(methodImplRecord); } } }