예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
        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));
        }
예제 #4
0
        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);
        }
예제 #5
0
        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());
        }
예제 #6
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }