Пример #1
0
        void AddAttributes(IKVM.Reflection.Type typeDefinition, IUnresolvedTypeDefinition targetEntity)
        {
            // SerializableAttribute
            if (typeDefinition.IsSerializable)
                targetEntity.Attributes.Add(serializableAttribute);

            // ComImportAttribute
            if (typeDefinition.IsImport)
                targetEntity.Attributes.Add(comImportAttribute);

            #region StructLayoutAttribute
            LayoutKind layoutKind = LayoutKind.Auto;
            switch (typeDefinition.Attributes & TypeAttributes.LayoutMask) {
                case TypeAttributes.SequentialLayout:
                layoutKind = LayoutKind.Sequential;
                break;
                case TypeAttributes.ExplicitLayout:
                layoutKind = LayoutKind.Explicit;
                break;
            }
            CharSet charSet = CharSet.None;
            switch (typeDefinition.Attributes & TypeAttributes.StringFormatMask) {
                case TypeAttributes.AnsiClass:
                charSet = CharSet.Ansi;
                break;
                case TypeAttributes.AutoClass:
                charSet = CharSet.Auto;
                break;
                case TypeAttributes.UnicodeClass:
                charSet = CharSet.Unicode;
                break;
            }

            int packingSize;
            int typeSize;
            if (typeDefinition.__GetLayout (out packingSize, out typeSize)) {
                LayoutKind defaultLayoutKind = (typeDefinition.IsValueType && !typeDefinition.IsEnum) ? LayoutKind.Sequential: LayoutKind.Auto;
                if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || packingSize > 0 || typeSize > 0) {
                    var structLayout = new DefaultUnresolvedAttribute(structLayoutAttributeTypeRef, new[] { layoutKindTypeRef });
                    structLayout.PositionalArguments.Add(CreateSimpleConstantValue(layoutKindTypeRef, (int)layoutKind));
                    if (charSet != CharSet.Ansi) {
                        structLayout.AddNamedFieldArgument("CharSet", CreateSimpleConstantValue(charSetTypeRef, (int)charSet));
                    }
                    if (packingSize > 0) {
                        structLayout.AddNamedFieldArgument("Pack", CreateSimpleConstantValue(KnownTypeReference.Int32, packingSize));
                    }
                    if (typeSize > 0) {
                        structLayout.AddNamedFieldArgument("Size", CreateSimpleConstantValue(KnownTypeReference.Int32, typeSize));
                    }
                    targetEntity.Attributes.Add(interningProvider.Intern(structLayout));
                }
            }
            #endregion

            AddCustomAttributes(typeDefinition.CustomAttributes, targetEntity.Attributes);

            if (typeDefinition.Attributes.HasFlag (TypeAttributes.HasSecurity)) {
                AddSecurityAttributes(CustomAttributeData.__GetDeclarativeSecurity(typeDefinition), targetEntity.Attributes);
            }
        }
Пример #2
0
        IUnresolvedAttribute ConvertMarshalInfo(FieldMarshal marshalInfo)
        {
            DefaultUnresolvedAttribute attr = new DefaultUnresolvedAttribute(marshalAsAttributeTypeRef, new[] { unmanagedTypeTypeRef });
            attr.PositionalArguments.Add(CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.UnmanagedType));

            if (marshalInfo.UnmanagedType ==UnmanagedType.ByValArray) {
                attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)marshalInfo.SizeConst));
                if (marshalInfo.ArraySubType.HasValue)
                    attr.AddNamedFieldArgument("ArraySubType", CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.ArraySubType.Value));
            }

            if (marshalInfo.UnmanagedType ==UnmanagedType.SafeArray) {
                attr.AddNamedFieldArgument("SafeArraySubType", CreateSimpleConstantValue(typeof(VarEnum).ToTypeReference(), (int)marshalInfo.SafeArraySubType));
            }

            if (marshalInfo.UnmanagedType == UnmanagedType.LPArray) {
                if (marshalInfo.ArraySubType != null)
                    attr.AddNamedFieldArgument("ArraySubType", CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.ArraySubType));
                if (marshalInfo.SizeConst >= 0)
                    attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)marshalInfo.SizeConst));
                if (marshalInfo.SizeParamIndex >= 0)
                    attr.AddNamedFieldArgument("SizeParamIndex", CreateSimpleConstantValue(KnownTypeReference.Int16, (short)marshalInfo.SizeParamIndex));
            }

            if (marshalInfo.UnmanagedType == UnmanagedType.CustomMarshaler) {
                attr.AddNamedFieldArgument("MarshalType", CreateSimpleConstantValue(KnownTypeReference.String, marshalInfo.MarshalTypeRef.FullName));
                if (!string.IsNullOrEmpty(marshalInfo.MarshalCookie))
                    attr.AddNamedFieldArgument("MarshalCookie", CreateSimpleConstantValue(KnownTypeReference.String, marshalInfo.MarshalCookie));
            }

            if (marshalInfo.UnmanagedType == UnmanagedType.ByValTStr) {
                attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)marshalInfo.SizeConst));
            }

            return InterningProvider.Intern(attr);
        }
Пример #3
0
        void AddAttributes(MethodInfo methodDefinition, IList<IUnresolvedAttribute> attributes, ICollection<IUnresolvedAttribute> returnTypeAttributes)
        {
            var implAttributes = methodDefinition.MethodImplementationFlags;

            #region DllImportAttribute
            if (methodDefinition.Attributes.HasFlag (MethodAttributes.PinvokeImpl)) {

                ImplMapFlags flags;
                string importName;
                string importScope;
                if (methodDefinition.__TryGetImplMap(out flags, out importName, out importScope)) {
                    var dllImport = new DefaultUnresolvedAttribute(dllImportAttributeTypeRef, new[] { KnownTypeReference.String });
                    dllImport.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.String, importScope));

                    if (flags.HasFlag (ImplMapFlags.BestFitOff))
                        dllImport.AddNamedFieldArgument("BestFitMapping", falseValue);
                    if (flags.HasFlag (ImplMapFlags.BestFitOn))
                        dllImport.AddNamedFieldArgument("BestFitMapping", trueValue);

                    CallingConvention callingConvention;
                    switch (flags & ImplMapFlags.CallConvMask) {
                        case (ImplMapFlags)0:
                            Debug.WriteLine ("P/Invoke calling convention not set on:" + methodDefinition.Name);
                            callingConvention = CallingConvention.StdCall;
                            break;
                        case ImplMapFlags.CallConvCdecl:
                            callingConvention = CallingConvention.Cdecl;
                            break;
                        case ImplMapFlags.CallConvFastcall:
                            callingConvention = CallingConvention.FastCall;
                            break;
                        case ImplMapFlags.CallConvStdcall:
                            callingConvention = CallingConvention.StdCall;
                            break;
                        case ImplMapFlags.CallConvThiscall:
                            callingConvention = CallingConvention.ThisCall;
                            break;
                        case ImplMapFlags.CallConvWinapi:
                            callingConvention = CallingConvention.Winapi;
                            break;
                        default:
                            throw new NotSupportedException("unknown calling convention");
                    }
                    if (!flags.HasFlag (ImplMapFlags.CallConvWinapi))
                        dllImport.AddNamedFieldArgument("CallingConvention", CreateSimpleConstantValue(callingConventionTypeRef, (int)callingConvention));

                    CharSet charSet = CharSet.None;
                    switch (flags & ImplMapFlags.CharSetMask) {
                        case ImplMapFlags.CharSetAnsi:
                            charSet = CharSet.Ansi;
                            break;
                        case ImplMapFlags.CharSetAuto:
                            charSet = CharSet.Auto;
                            break;
                        case ImplMapFlags.CharSetUnicode:
                            charSet = CharSet.Unicode;
                            break;
                    }
                    if (charSet != CharSet.None)
                        dllImport.AddNamedFieldArgument("CharSet", CreateSimpleConstantValue(charSetTypeRef, (int)charSet));

                    if (!string.IsNullOrEmpty(importName) && importName != methodDefinition.Name)
                        dllImport.AddNamedFieldArgument("EntryPoint", CreateSimpleConstantValue(KnownTypeReference.String, importName));

                    if (flags.HasFlag (ImplMapFlags.NoMangle))
                        dllImport.AddNamedFieldArgument("ExactSpelling", trueValue);

                    if ((implAttributes & MethodImplAttributes.PreserveSig) == MethodImplAttributes.PreserveSig)
                        implAttributes &= ~MethodImplAttributes.PreserveSig;
                    else
                        dllImport.AddNamedFieldArgument("PreserveSig", falseValue);

                    if (flags.HasFlag (ImplMapFlags.SupportsLastError))
                        dllImport.AddNamedFieldArgument("SetLastError", trueValue);

                    if (flags.HasFlag (ImplMapFlags.CharMapErrorOff))
                        dllImport.AddNamedFieldArgument("ThrowOnUnmappableChar", falseValue);
                    if (flags.HasFlag (ImplMapFlags.CharMapErrorOn))
                        dllImport.AddNamedFieldArgument("ThrowOnUnmappableChar", trueValue);

                    attributes.Add(interningProvider.Intern(dllImport));
                }
            }
            #endregion

            #region PreserveSigAttribute
            if (implAttributes == MethodImplAttributes.PreserveSig) {
                attributes.Add(preserveSigAttribute);
                implAttributes = (MethodImplAttributes)0;
            }
            #endregion

            #region MethodImplAttribute
            if (implAttributes != MethodImplAttributes.IL) {
                var methodImpl = new DefaultUnresolvedAttribute(methodImplAttributeTypeRef, new[] { methodImplOptionsTypeRef });
                methodImpl.PositionalArguments.Add(CreateSimpleConstantValue(methodImplOptionsTypeRef, (int)implAttributes));
                attributes.Add(interningProvider.Intern(methodImpl));
            }
            #endregion

            var customAttributes = methodDefinition.CustomAttributes;
            AddCustomAttributes (customAttributes, attributes);

            if (methodDefinition.Attributes.HasFlag (MethodAttributes.HasSecurity)) {
                AddSecurityAttributes(CustomAttributeData.__GetDeclarativeSecurity (methodDefinition), attributes);
            }

            FieldMarshal marshalInfo;
            if (methodDefinition.ReturnParameter.__TryGetFieldMarshal (out marshalInfo)) {
                returnTypeAttributes.Add(ConvertMarshalInfo(marshalInfo));
            }
            // TODO: Not needed in ikvm - maybe a work around for a cecil bug ?
            //			AddCustomAttributes(methodDefinition.ReturnType.CustomAttributes, returnTypeAttributes);
        }