public void TestSignatureMatchesModOptAtStartOfSigAndAfterByRef() { MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); MethodSignature methodWithModOptAtStartOfSigAndAfterByRef = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method2")).Signature; // A modopts after an E_T_BYREF will look like 0.1.1.2.1.1 Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[0].index); Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[1].index); Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[2].index); Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.2.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWithModOptAtStartOfSigAndAfterByRef)); }
public void TestSignatureMatches2ModOptsAtStartOfSig() { MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); MethodSignature methodWith2ModOptsAtStartOfSig = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method")).Signature; // All modopts that are at the very beginning of the signature are given index 0.1.1.1 // Both the index and the order in the modopt array are significant for signature comparison Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[0].index); Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[1].index); Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[2].index); Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWith2ModOptsAtStartOfSig)); }
public void TestSignatureMatchesForArrayShapeDetails_HandlingOfCasesWhichDoNotNeedEmbeddeSignatureData() { // Test that ensure the typical case (where the loBounds is 0, and the hibounds is unspecified) doesn't produce an // EmbeddedSignatureData, but that other cases do. This isn't a complete test as ilasm won't actually properly generate the metadata for many of these cases MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method5")).Signature; _output.WriteLine($"Found ModOptData '{GetModOptMethodSignatureInfo(methodWithModOpt)}'"); Assert.Equal(2, methodWithModOpt.GetEmbeddedSignatureData().Length); Assert.EndsWith(methodWithModOpt.GetEmbeddedSignatureData()[0].index.Split('|')[0], MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1)); Assert.EndsWith(methodWithModOpt.GetEmbeddedSignatureData()[1].index.Split('|')[0], MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2)); Assert.Equal("ArrayShape1.2.2.1||0<null>ArrayShape1.2.3.1||<null>", GetModOptMethodSignatureInfo(methodWithModOpt)); }
public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMetadata[] paramMetadata) { for (int i = 0, paramIndex = 0; i < methodSig.Length + 1; i++) { ParameterMetadata parameterMetadata = (paramIndex == paramMetadata.Length || i < paramMetadata[paramIndex].Index) ? new ParameterMetadata(i, ParameterMetadataAttributes.None, null) : paramMetadata[paramIndex++]; TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind( parameterType, parameterIndex: i, customModifierData: methodSig.GetEmbeddedSignatureData(), parameterMetadata.MarshalAsDescriptor, parameterMetadata.Return, isAnsi: true, MarshallerType.Argument, out MarshallerKind elementMarshallerKind); if (IsMarshallingRequired(marshallerKind)) { return(true); } } return(false); }
private static string GetModOptMethodSignatureInfo(MethodSignature signature) { if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null) { return(""); } StringBuilder sb = new StringBuilder(); foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData()) { sb.Append(data.kind.ToString()); sb.Append(data.index); sb.Append(((MetadataType)data.type).Name); } return(sb.ToString()); }
private static Marshaller[] GetMarshallers( MethodSignature methodSig, PInvokeFlags flags, ParameterMetadata[] parameterMetadataArray, bool runtimeMarshallingEnabled) { Marshaller[] marshallers = new Marshaller[methodSig.Length + 1]; for (int i = 0, parameterIndex = 0; i < marshallers.Length; i++) { Debug.Assert(parameterIndex == parameterMetadataArray.Length || i <= parameterMetadataArray[parameterIndex].Index); ParameterMetadata parameterMetadata; if (parameterIndex == parameterMetadataArray.Length || i < parameterMetadataArray[parameterIndex].Index) { // if we don't have metadata for the parameter, create a dummy one parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null); } else { Debug.Assert(i == parameterMetadataArray[parameterIndex].Index); parameterMetadata = parameterMetadataArray[parameterIndex++]; } TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type if (runtimeMarshallingEnabled) { marshallers[i] = CreateMarshaller(parameterType, parameterIndex, methodSig.GetEmbeddedSignatureData(), MarshallerType.Argument, parameterMetadata.MarshalAsDescriptor, MarshalDirection.Forward, marshallers, parameterMetadata.Index, flags, parameterMetadata.In, parameterMetadata.Out, parameterMetadata.Return); } else { marshallers[i] = CreateDisabledMarshaller( parameterType, parameterIndex, MarshallerType.Argument, MarshalDirection.Forward, marshallers, parameterMetadata.Index, flags, parameterMetadata.Return); } } return(marshallers); }
public void TestSignatureMatchesForArrayShapeDetails() { MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method4")).Signature; Assert.Equal(6, methodWithModOpt.GetEmbeddedSignatureData().Length); Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(0), methodWithModOpt.GetEmbeddedSignatureData()[0].index); Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1), methodWithModOpt.GetEmbeddedSignatureData()[2].index); Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2), methodWithModOpt.GetEmbeddedSignatureData()[4].index); Assert.Equal("OptionalCustomModifier0.1.1.2.1.1VoidArrayShape1.2.1.1|3,4|0,1<null>OptionalCustomModifier0.1.1.2.2.1FooModifierArrayShape1.2.2.1|0,9|2,0<null>OptionalCustomModifier0.1.1.2.3.1FooModifierArrayShape1.2.3.1||0<null>", GetModOptMethodSignatureInfo(methodWithModOpt)); }
public static Marshaller[] GetMarshallersForMethod(MethodDesc targetMethod) { Debug.Assert(targetMethod.IsPInvoke); MarshalDirection direction = MarshalDirection.Forward; MethodSignature methodSig = targetMethod.Signature; PInvokeFlags flags = targetMethod.GetPInvokeMethodMetadata().Flags; ParameterMetadata[] parameterMetadataArray = targetMethod.GetParameterMetadata(); Marshaller[] marshallers = new Marshaller[methodSig.Length + 1]; ParameterMetadata parameterMetadata; for (int i = 0, parameterIndex = 0; i < marshallers.Length; i++) { Debug.Assert(parameterIndex == parameterMetadataArray.Length || i <= parameterMetadataArray[parameterIndex].Index); if (parameterIndex == parameterMetadataArray.Length || i < parameterMetadataArray[parameterIndex].Index) { // if we don't have metadata for the parameter, create a dummy one parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null); } else { Debug.Assert(i == parameterMetadataArray[parameterIndex].Index); parameterMetadata = parameterMetadataArray[parameterIndex++]; } TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type marshallers[i] = CreateMarshaller(parameterType, parameterIndex, methodSig.GetEmbeddedSignatureData(), MarshallerType.Argument, parameterMetadata.MarshalAsDescriptor, direction, marshallers, parameterMetadata.Index, flags, parameterMetadata.In, parameterMetadata.Out, parameterMetadata.Return); } return(marshallers); }
private bool ComputeTypeReferenceVersionsWithCode(TypeDesc type) { // Type represented by simple element type if (type.IsPrimitive || type.IsVoid || type.IsObject || type.IsString) { return(true); } if (VersionsWithType(type)) { return(true); } if (type.IsParameterizedType) { return(VersionsWithTypeReference(type.GetParameterType())); } if (type.IsFunctionPointer) { MethodSignature ptrSignature = ((FunctionPointerType)type).Signature; if (!VersionsWithTypeReference(ptrSignature.ReturnType)) { return(false); } for (int i = 0; i < ptrSignature.Length; i++) { if (!VersionsWithTypeReference(ptrSignature[i])) { return(false); } } if (ptrSignature.HasEmbeddedSignatureData) { foreach (var embeddedSigData in ptrSignature.GetEmbeddedSignatureData()) { if (embeddedSigData.type != null) { if (!VersionsWithTypeReference(embeddedSigData.type)) { return(false); } } } } } if (type is EcmaType ecmaType) { return(!_tokenResolver.GetModuleTokenForType(ecmaType, false).IsNull); } if (type.GetTypeDefinition() == type) { // Must not be an ECMA type, which are the only form of simple type which cannot reach here return(false); } if (type.HasInstantiation) { if (!VersionsWithTypeReference(type.GetTypeDefinition())) { return(false); } foreach (TypeDesc instParam in type.Instantiation) { if (!VersionsWithTypeReference(instParam)) { return(false); } } return(true); } Debug.Assert(false, "Unhandled form of type in VersionsWithTypeReference"); return(false); }
public void TestSignatureMatchesModoptOnPointerOrRefModifiedType() { MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method3")).Signature; Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(0), methodWithModOpt.GetEmbeddedSignatureData()[0].index); Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1), methodWithModOpt.GetEmbeddedSignatureData()[1].index); Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2), methodWithModOpt.GetEmbeddedSignatureData()[2].index); }