public static bool TryGetVirtualResolveData(IntPtr moduleHandle, RuntimeTypeHandle methodHandleDeclaringType, RuntimeTypeHandle[] genericArgs, ref MethodSignatureComparer methodSignatureComparer, out VirtualResolveDataResult lookupResult) { throw new NotImplementedException(); }
/// <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> /// <param name="foundAddressType">Output - The type of method address match found. A canonical address may require extra parameters to call.</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); }
private static bool TryGetVirtualMethodFromSlot(TypeDesc definingType, int vtableSlotIndex, out MethodDesc slotDefiningMethod) { MethodNameAndSignature methodNameAndSig; bool success = TypeLoaderEnvironment.TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType (definingType.Context, definingType.GetRuntimeTypeHandle(), vtableSlotIndex, out methodNameAndSig); if (!success) { slotDefiningMethod = null; return(false); } TypeSystem.NativeFormat.NativeFormatType metadataDefiningType = definingType.GetClosestDefType().GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType; // We're working with a NoMetadataType, or an ArrayType, neither of which have full metadata if (metadataDefiningType == null) { slotDefiningMethod = null; return(false); } // TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType is expected to only return methodNameAndSig with NativeLayoutSignatures in them. // If we start hitting the more general case, we can improve this algorithm. Debug.Assert(methodNameAndSig.Signature.IsNativeLayoutSignature); foreach (TypeSystem.NativeFormat.NativeFormatMethod method in metadataDefiningType.GetMethods()) { if (!method.IsVirtual) { continue; } if (method.HasInstantiation) { continue; } if (!method.Name.Equals(methodNameAndSig.Name)) { continue; } MethodSignatureComparer sigComparer = new MethodSignatureComparer(method.MetadataReader, method.Handle); if (!sigComparer.IsMatchingNativeLayoutMethodNameAndSignature(methodNameAndSig.Name, methodNameAndSig.Signature)) { continue; } // At this point we've matched slotDefiningMethod = method; return(true); } // Didn't find the method slotDefiningMethod = null; return(false); }
public static bool TryGetMethodInvokeMetadata( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, MethodHandle methodHandle, RuntimeTypeHandle[] genericMethodTypeArgumentHandles, ref MethodSignatureComparer methodSignatureComparer, CanonicalFormKind canonFormKind, out MethodInvokeMetadata methodInvokeMetadata) { throw new NotImplementedException(); }
public static bool TryGetMethodInvokeMetadata( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, MethodHandle methodHandle, RuntimeTypeHandle[] genericMethodTypeArgumentHandles, ref MethodSignatureComparer methodSignatureComparer, CanonicalFormKind canonFormKind, out MethodInvokeMetadata methodInvokeMetadata) { throw new NotImplementedException(); }
public bool CompareMethodSignatures(RuntimeMethodSignature signature1, RuntimeMethodSignature signature2) { IntPtr nativeLayoutSignature1 = signature1.NativeLayoutSignature; IntPtr nativeLayoutSignature2 = signature2.NativeLayoutSignature; if ((nativeLayoutSignature1 != IntPtr.Zero) && (nativeLayoutSignature2 != IntPtr.Zero)) { if (nativeLayoutSignature1 == nativeLayoutSignature2) { return(true); } NativeReader reader1 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature1)); NativeParser parser1 = new NativeParser(reader1, reader1.AddressToOffset(nativeLayoutSignature1)); NativeReader reader2 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature2)); NativeParser parser2 = new NativeParser(reader2, reader2.AddressToOffset(nativeLayoutSignature2)); return(CompareMethodSigs(parser1, parser2)); } else if (nativeLayoutSignature1 != IntPtr.Zero) { int token = signature2.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature2.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature1)); } else if (nativeLayoutSignature2 != IntPtr.Zero) { int token = signature1.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature1.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature2)); } else { // For now, RuntimeMethodSignatures are only used to compare for method signature equality (along with their Name) // So we can implement this with the simple equals check if (signature1.Token != signature2.Token) { return(false); } if (signature1.ModuleHandle != signature2.ModuleHandle) { return(false); } return(true); } }
public bool CompareMethodSignatures(RuntimeSignature signature1, RuntimeSignature signature2) { if (signature1.IsNativeLayoutSignature && signature2.IsNativeLayoutSignature) { if (signature1.StructuralEquals(signature2)) { return(true); } NativeFormatModuleInfo module1 = ModuleList.GetModuleInfoByHandle(new TypeManagerHandle(signature1.ModuleHandle)); NativeReader reader1 = GetNativeLayoutInfoReader(signature1); NativeParser parser1 = new NativeParser(reader1, signature1.NativeLayoutOffset); NativeFormatModuleInfo module2 = ModuleList.GetModuleInfoByHandle(new TypeManagerHandle(signature2.ModuleHandle)); NativeReader reader2 = GetNativeLayoutInfoReader(signature2); NativeParser parser2 = new NativeParser(reader2, signature2.NativeLayoutOffset); return(CompareMethodSigs(parser1, module1, parser2, module2)); } else if (signature1.IsNativeLayoutSignature) { int token = signature2.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(new TypeManagerHandle(signature2.ModuleHandle)); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(signature1)); } else if (signature2.IsNativeLayoutSignature) { int token = signature1.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(new TypeManagerHandle(signature1.ModuleHandle)); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(signature2)); } else { // For now, RuntimeSignatures are only used to compare for method signature equality (along with their Name) // So we can implement this with the simple equals check if (signature1.Token != signature2.Token) { return(false); } if (signature1.ModuleHandle != signature2.ModuleHandle) { return(false); } return(true); } }
public bool CompareMethodSignatures(RuntimeMethodSignature signature1, RuntimeMethodSignature signature2) { IntPtr nativeLayoutSignature1 = signature1.NativeLayoutSignature; IntPtr nativeLayoutSignature2 = signature2.NativeLayoutSignature; if ((nativeLayoutSignature1 != IntPtr.Zero) && (nativeLayoutSignature2 != IntPtr.Zero)) { if (nativeLayoutSignature1 == nativeLayoutSignature2) return true; NativeReader reader1 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature1)); NativeParser parser1 = new NativeParser(reader1, reader1.AddressToOffset(nativeLayoutSignature1)); NativeReader reader2 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature2)); NativeParser parser2 = new NativeParser(reader2, reader2.AddressToOffset(nativeLayoutSignature2)); return CompareMethodSigs(parser1, parser2); } else if (nativeLayoutSignature1 != IntPtr.Zero) { int token = signature2.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature2.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature1); } else if (nativeLayoutSignature2 != IntPtr.Zero) { int token = signature1.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature1.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature2); } else { // For now, RuntimeMethodSignatures are only used to compare for method signature equality (along with their Name) // So we can implement this with the simple equals check if (signature1.Token != signature2.Token) return false; if (signature1.ModuleHandle != signature2.ModuleHandle) return false; return true; } }
/// <summary> /// Get the virtual slot index of a given virtual method. (This is only valid for non-interface virtuals) /// </summary> /// <param name="virtualMethod">virtual method to get slot index of</param> /// <returns>slot index, or -1</returns> public static int VirtualMethodToSlotIndex(MethodDesc virtualMethod) { Debug.Assert(virtualMethod.IsVirtual); Debug.Assert(!virtualMethod.OwningType.IsInterface); MethodDesc definingMethod = virtualMethod; // If not newslot, make sure we've got the defining method here if (!definingMethod.IsNewSlot) { definingMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(definingMethod); } TypeDesc definingType = definingMethod.OwningType; // Two possible cases for determining slot index that will work // 1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata. Its possible to not get a slot index. In that case return -1 // 2. The definingType is pregenerated, but we can go from metadata to slot index via the runtime mapping tables. if (!IsPregeneratedOrTemplateTypeLoaded(definingType)) { // Case 1 MetadataType definingMetadataType = (MetadataType)definingType; int baseTypeSlotCount = 0; if (definingMetadataType.BaseType != null) { unsafe { if (definingMetadataType.BaseType.RetrieveRuntimeTypeHandleIfPossible()) { baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots; } else { baseTypeSlotCount = definingMetadataType.BaseType.GetOrCreateTypeBuilderState().NumVTableSlots; } } } int currentSlot = baseTypeSlotCount; if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Specific)) { // Deal with the space reserved for the canonical dictionary currentSlot++; } foreach (MethodDesc method in definingMetadataType.GetMethods()) { if (!MethodDefinesVTableSlot(method)) { continue; } if (method == definingMethod) { return(currentSlot); } else { currentSlot++; } } // No slot index defined. return(-1); } else { // Case 2, pregenerated type TypeSystem.NativeFormat.NativeFormatMethod definingMethodOpenType = (TypeSystem.NativeFormat.NativeFormatMethod)definingMethod.GetTypicalMethodDefinition(); MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer( definingMethodOpenType.MetadataReader, definingMethodOpenType.Handle); if (!definingType.RetrieveRuntimeTypeHandleIfPossible()) { new TypeBuilder().BuildType(definingType); } TypeSystem.NativeFormat.NativeFormatType definingNativeFormatType = (TypeSystem.NativeFormat.NativeFormatType)definingType.GetTypeDefinition(); NativeFormatModuleInfo moduleToLookIn = definingNativeFormatType.MetadataUnit.RuntimeModuleInfo; TypeLoaderEnvironment.VirtualResolveDataResult virtualSlotInfo; if (!TypeLoaderEnvironment.TryGetVirtualResolveData(moduleToLookIn, definingType.RuntimeTypeHandle, Array.Empty <RuntimeTypeHandle>(), ref methodSignatureComparer, out virtualSlotInfo)) { return(-1); } Debug.Assert(!virtualSlotInfo.IsGVM); return(virtualSlotInfo.SlotIndex); } }
public static bool TryGetVirtualResolveData(IntPtr moduleHandle, RuntimeTypeHandle methodHandleDeclaringType, RuntimeTypeHandle[] genericArgs, ref MethodSignatureComparer methodSignatureComparer, out VirtualResolveDataResult lookupResult) { throw new NotImplementedException(); }
private static bool TryGetVirtualMethodFromSlot(TypeDesc definingType, int vtableSlotIndex, out MethodDesc slotDefiningMethod) { MethodNameAndSignature methodNameAndSig; bool success = TypeLoaderEnvironment.TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType (definingType.Context, definingType.GetRuntimeTypeHandle(), vtableSlotIndex, out methodNameAndSig); if (!success) { slotDefiningMethod = null; return false; } TypeSystem.NativeFormat.NativeFormatType metadataDefiningType = definingType.GetClosestDefType().GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType; // We're working with a NoMetadataType, or an ArrayType, neither of which have full metadata if (metadataDefiningType == null) { slotDefiningMethod = null; return false; } // TryGetMethodMethodNameAndSigFromVTableSlotForPregeneratedOrTemplateType is expected to only return methodNameAndSig with NativeLayoutSignatures in them. // If we start hitting the more general case, we can improve this algorithm. Debug.Assert(methodNameAndSig.Signature.IsNativeLayoutSignature); foreach (TypeSystem.NativeFormat.NativeFormatMethod method in metadataDefiningType.GetMethods()) { if (!method.IsVirtual) continue; if (method.HasInstantiation) continue; if (!method.Name.Equals(methodNameAndSig.Name)) continue; MethodSignatureComparer sigComparer = new MethodSignatureComparer(method.MetadataReader, method.Handle); if (!sigComparer.IsMatchingNativeLayoutMethodNameAndSignature(methodNameAndSig.Name, methodNameAndSig.Signature.NativeLayoutSignature)) continue; // At this point we've matched slotDefiningMethod = method; return true; } // Didn't find the method slotDefiningMethod = null; return false; }
/// <summary> /// Get the virtual slot index of a given virtual method. (This is only valid for non-interface virtuals) /// </summary> /// <param name="virtualMethod">virtual method to get slot index of</param> /// <returns>slot index, or -1</returns> public static int VirtualMethodToSlotIndex(MethodDesc virtualMethod) { Debug.Assert(virtualMethod.IsVirtual); Debug.Assert(!virtualMethod.OwningType.IsInterface); MethodDesc definingMethod = virtualMethod; // If not newslot, make sure we've got the defining method here if (!definingMethod.IsNewSlot) { definingMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(definingMethod); } TypeDesc definingType = definingMethod.OwningType; // Two possible cases for determining slot index that will work // 1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata. Its possible to not get a slot index. In that case return -1 // 2. The definingType is pregenerated, but we can go from metadata to slot index via the runtime mapping tables. if (!IsPregeneratedOrTemplateTypeLoaded(definingType)) { // Case 1 MetadataType definingMetadataType = (MetadataType)definingType; int baseTypeSlotCount = 0; if (definingMetadataType.BaseType != null) { unsafe { if (definingMetadataType.BaseType.RetrieveRuntimeTypeHandleIfPossible()) { baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots; } else { baseTypeSlotCount = definingMetadataType.BaseType.GetOrCreateTypeBuilderState().NumVTableSlots; } } } int currentSlot = baseTypeSlotCount; if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Specific)) { // Deal with the space reserved for the canonical dictionary currentSlot++; } foreach (MethodDesc method in definingMetadataType.GetMethods()) { if (!MethodDefinesVTableSlot(method)) continue; if (method == definingMethod) return currentSlot; else currentSlot++; } // No slot index defined. return -1; } else { // Case 2, pregenerated type TypeSystem.NativeFormat.NativeFormatMethod definingMethodOpenType = (TypeSystem.NativeFormat.NativeFormatMethod)definingMethod.GetTypicalMethodDefinition(); MethodSignatureComparer methodSignatureComparer = new MethodSignatureComparer( definingMethodOpenType.MetadataReader, definingMethodOpenType.Handle); if (!definingType.RetrieveRuntimeTypeHandleIfPossible()) { new TypeBuilder().BuildType(definingType); } TypeSystem.NativeFormat.NativeFormatType definingNativeFormatType = (TypeSystem.NativeFormat.NativeFormatType)definingType.GetTypeDefinition(); IntPtr moduleToLookIn = definingNativeFormatType.MetadataUnit.RuntimeModule; TypeLoaderEnvironment.VirtualResolveDataResult virtualSlotInfo; if (!TypeLoaderEnvironment.TryGetVirtualResolveData(moduleToLookIn, definingType.RuntimeTypeHandle, Array.Empty<RuntimeTypeHandle>(), ref methodSignatureComparer, out virtualSlotInfo)) return -1; Debug.Assert(!virtualSlotInfo.IsGVM); return virtualSlotInfo.SlotIndex; } }
/// <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; }