예제 #1
0
        public static TypeSig Read(ReaderContext ctxt, BlobReader reader)
        {
            var tag = (TypeSigTag)reader.ReadCompressedUInt32();
            var res = default(TypeSig);
            switch (tag)
            {
                case TypeSigTag.END:
                    return null;
                case TypeSigTag.SENTINEL:
                    res = new SentinelPsuedoTypeSig();
                    break;
                case TypeSigTag.PINNED:
                    res = new PinnedPsuedoTypeSig();
                    break;
                case TypeSigTag.VOID:
                case TypeSigTag.BOOLEAN:
                case TypeSigTag.CHAR:
                case TypeSigTag.I1:
                case TypeSigTag.U1:
                case TypeSigTag.I2:
                case TypeSigTag.U2:
                case TypeSigTag.I4:
                case TypeSigTag.U4:
                case TypeSigTag.I8:
                case TypeSigTag.U8:
                case TypeSigTag.R4:
                case TypeSigTag.R8:
                case TypeSigTag.STRING:
                case TypeSigTag.I:
                case TypeSigTag.U:
                case TypeSigTag.OBJECT:
                case TypeSigTag.SYSTYPE_ARGUMENT: // NOTE: Not mentioned in spec...
                case TypeSigTag.TYPEDBYREF:
                    res = new PrimitiveTypeSig { PrimitiveType = PrimitiveTypeSig.FromTag(tag) };
                    break;
                case TypeSigTag.PTR:
                    res = new UnmanagedPointerTypeSig();
                    break;
                case TypeSigTag.BYREF:
                    res = new ManagedPointerTypeSig();
                    break;
                case TypeSigTag.SZARRAY:
                    res = new ArrayTypeSig();
                    break;
                case TypeSigTag.ARRAY:
                    res = new MultiDimArrayTypeSig();
                    break;
                case TypeSigTag.VALUETYPE:
                case TypeSigTag.CLASS:
                    res = new TypeDefOrRefSig { IsValueType = tag == TypeSigTag.VALUETYPE };
                    break;
                case TypeSigTag.CMOD_REQD:
                case TypeSigTag.CMOD_OPT:
                    res = new CustomModPseudoTypeSig { IsRequired = tag == TypeSigTag.CMOD_REQD };
                    break;
                case TypeSigTag.VAR:
                    res = new TypeParameterTypeSig();
                    break;
                case TypeSigTag.GENERICINST:
                    res = new ApplicationTypeSig();
                    break;
                case TypeSigTag.MVAR:
                    res = new MethodParameterTypeSig();
                    break;
                case TypeSigTag.FNPTR:
                    res = new FunctionPointerTypeSig();
                    break;
                case TypeSigTag.INTERNAL:
                case TypeSigTag.RESERVED:
                    throw new PEException("unimplemented type tag");
                case TypeSigTag.CUSTOM_ATTRIBUTE_BOXED_ARGUMENT:
                case TypeSigTag.CUSTOM_ATTRIBUTE_FIELD:
                case TypeSigTag.CUSTOM_ATTRIBUTE_PROPERTY:
                case TypeSigTag.CUSTOM_ATTRIBUTE_ENUM:
                    throw new PEException("unexpected custom attribute in type");
                default:
                    throw new PEException("unrecognised type tag");
            }

            res.ReadRest(ctxt, reader);
            return res;
        }
예제 #2
0
        private PE.TypeSig TypeSigFromTypeRef(DllSaveContext ctxt, TypeRef typeRef)
        {
            if (typeRef.Equals(rootEnv.Global.TypedReferenceRef))
            {
                return new PE.PrimitiveTypeSig {
                           PrimitiveType = PE.PrimitiveType.TypedRef
                }
            }
            ;
            else
            {
                var tyconEnv = typeRef.EnterConstructor(rootEnv);

                switch (tyconEnv.Type.Flavor)
                {
                case TypeDefFlavor.Pointer:
                {
                    var p = (PointerTypeDef)tyconEnv.Type;
                    switch (p.PointerFlavor)
                    {
                    case PointerFlavor.Unmanaged:
                        return(new PE.UnmanagedPointerTypeSig {
                                ElementType = TypeWithCustomModsFromTypeRef(ctxt, typeRef.Arguments[0])
                            });

                    case PointerFlavor.Managed:
                        return(new PE.ManagedPointerTypeSig {
                                ElementType = TypeSigFromTypeRef(ctxt, typeRef.Arguments[0])
                            });

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                case TypeDefFlavor.CodePointer:
                {
                    var p = (CodePointerTypeDef)tyconEnv.Type;
                    switch (p.CodePointerFlavor)
                    {
                    case CodePointerFlavor.Function:
                        throw new NotImplementedException();

                    case CodePointerFlavor.Action:
                        throw new NotImplementedException();

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    break;
                }

                case TypeDefFlavor.Array:
                    return(new PE.ArrayTypeSig {
                        ElementType = TypeWithCustomModsFromTypeRef(ctxt, typeRef.Arguments[0])
                    });

                case TypeDefFlavor.MultiDimArray:
                {
                    var a = (MultiDimArrayTypeDef)tyconEnv.Type;
                    return(new PE.MultiDimArrayTypeSig
                        {
                            ElementType = TypeSigFromTypeRef(ctxt, typeRef.Arguments[0]),
                            Rank = a.Rank,
                            LoBounds = a.Bounds.LoBounds(),
                            Sizes = a.Bounds.Sizes()
                        });
                }

                case TypeDefFlavor.Box:
                    throw new InvalidOperationException("unexpected box type");

                case TypeDefFlavor.Null:
                    throw new InvalidOperationException("unexpected null type");

                case TypeDefFlavor.Parameter:
                {
                    var p = (ParameterTypeDef)tyconEnv.Type;
                    switch (p.ParameterFlavor)
                    {
                    case ParameterFlavor.Type:
                        return(new PE.TypeParameterTypeSig {
                                Index = p.Index
                            });

                    case ParameterFlavor.Method:
                        return(new PE.MethodParameterTypeSig {
                                Index = p.Index
                            });

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                case TypeDefFlavor.Handle:
                case TypeDefFlavor.Nullable:
                case TypeDefFlavor.Enum:
                case TypeDefFlavor.Struct:
                {
                    var applicand = new PE.TypeDefOrRefSig
                    {
                        IsValueType  = true,
                        TypeDefOrRef = { Value = TypeDefOrRefRowFromQualifiedTypeName(ctxt, typeRef.QualifiedTypeName) }
                    };
                    if (typeRef.Arguments.Count > 0)
                    {
                        return new PE.ApplicationTypeSig
                               {
                                   Applicand = applicand,
                                   Arguments = typeRef.Arguments.Select(t => TypeSigFromTypeRef(ctxt, t)).ToSeq()
                               }
                    }
                    ;
                    else
                    {
                        return(applicand);
                    }
                }

                case TypeDefFlavor.Void:
                    return(new PE.PrimitiveTypeSig {
                        PrimitiveType = PE.PrimitiveType.Void
                    });

                case TypeDefFlavor.Number:
                {
                    var n = (NumberTypeDef)tyconEnv.Type;
                    var p = default(PE.PrimitiveType);
                    switch (n.NumberFlavor)
                    {
                    case NumberFlavor.Int8:
                        p = PE.PrimitiveType.Int8;
                        break;

                    case NumberFlavor.Int16:
                        p = PE.PrimitiveType.Int16;
                        break;

                    case NumberFlavor.Int32:
                        p = PE.PrimitiveType.Int32;
                        break;

                    case NumberFlavor.Int64:
                        p = PE.PrimitiveType.Int64;
                        break;

                    case NumberFlavor.IntNative:
                        p = PE.PrimitiveType.IntNative;
                        break;

                    case NumberFlavor.UInt8:
                        p = PE.PrimitiveType.UInt8;
                        break;

                    case NumberFlavor.UInt16:
                        p = PE.PrimitiveType.UInt16;
                        break;

                    case NumberFlavor.UInt32:
                        p = PE.PrimitiveType.UInt32;
                        break;

                    case NumberFlavor.UInt64:
                        p = PE.PrimitiveType.UInt64;
                        break;

                    case NumberFlavor.UIntNative:
                        p = PE.PrimitiveType.UIntNative;
                        break;

                    case NumberFlavor.Single:
                        p = PE.PrimitiveType.Single;
                        break;

                    case NumberFlavor.Double:
                        p = PE.PrimitiveType.Double;
                        break;

                    case NumberFlavor.Boolean:
                        p = PE.PrimitiveType.Boolean;
                        break;

                    case NumberFlavor.Char:
                        p = PE.PrimitiveType.Char;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    return(new PE.PrimitiveTypeSig {
                            PrimitiveType = p
                        });
                }

                case TypeDefFlavor.Delegate:
                case TypeDefFlavor.Class:
                case TypeDefFlavor.Interface:
                case TypeDefFlavor.GenericIEnumerable:
                {
                    var applicand = new PE.TypeDefOrRefSig
                    {
                        IsValueType  = false,
                        TypeDefOrRef = { Value = TypeDefOrRefRowFromQualifiedTypeName(ctxt, typeRef.QualifiedTypeName) }
                    };
                    if (typeRef.Arguments.Count > 0)
                    {
                        return new PE.ApplicationTypeSig
                               {
                                   Applicand = applicand,
                                   Arguments = typeRef.Arguments.Select(t => TypeSigFromTypeRef(ctxt, t)).ToSeq()
                               }
                    }
                    ;
                    else
                    {
                        return(applicand);
                    }
                }

                case TypeDefFlavor.Object:
                    return(new PE.PrimitiveTypeSig {
                        PrimitiveType = PE.PrimitiveType.Object
                    });

                case TypeDefFlavor.String:
                    return(new PE.PrimitiveTypeSig {
                        PrimitiveType = PE.PrimitiveType.String
                    });

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
예제 #3
0
        private PE.TypeSig TypeSigFromTypeRef(DllSaveContext ctxt, TypeRef typeRef)
        {
            if (typeRef.Equals(rootEnv.Global.TypedReferenceRef))
                return new PE.PrimitiveTypeSig { PrimitiveType = PE.PrimitiveType.TypedRef };
            else
            {
                var tyconEnv = typeRef.EnterConstructor(rootEnv);

                switch (tyconEnv.Type.Flavor)
                {
                    case TypeDefFlavor.Pointer:
                        {
                            var p = (PointerTypeDef)tyconEnv.Type;
                            switch (p.PointerFlavor)
                            {
                                case PointerFlavor.Unmanaged:
                                    return new PE.UnmanagedPointerTypeSig { ElementType = TypeWithCustomModsFromTypeRef(ctxt, typeRef.Arguments[0]) };
                                case PointerFlavor.Managed:
                                    return new PE.ManagedPointerTypeSig { ElementType = TypeSigFromTypeRef(ctxt, typeRef.Arguments[0]) };
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                    case TypeDefFlavor.CodePointer:
                        {
                            var p = (CodePointerTypeDef)tyconEnv.Type;
                            switch (p.CodePointerFlavor)
                            {
                                case CodePointerFlavor.Function:
                                    throw new NotImplementedException();
                                case CodePointerFlavor.Action:
                                    throw new NotImplementedException();
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            break;
                        }
                    case TypeDefFlavor.Array:
                        return new PE.ArrayTypeSig { ElementType = TypeWithCustomModsFromTypeRef(ctxt, typeRef.Arguments[0]) };
                    case TypeDefFlavor.MultiDimArray:
                        {
                            var a = (MultiDimArrayTypeDef)tyconEnv.Type;
                            return new PE.MultiDimArrayTypeSig
                                   {
                                       ElementType = TypeSigFromTypeRef(ctxt, typeRef.Arguments[0]),
                                       Rank = a.Rank,
                                       LoBounds = a.Bounds.LoBounds(),
                                       Sizes = a.Bounds.Sizes()
                                   };
                        }
                    case TypeDefFlavor.Box:
                        throw new InvalidOperationException("unexpected box type");
                    case TypeDefFlavor.Null:
                        throw new InvalidOperationException("unexpected null type");
                    case TypeDefFlavor.Parameter:
                        {
                            var p = (ParameterTypeDef)tyconEnv.Type;
                            switch (p.ParameterFlavor)
                            {
                                case ParameterFlavor.Type:
                                    return new PE.TypeParameterTypeSig { Index = p.Index };
                                case ParameterFlavor.Method:
                                    return new PE.MethodParameterTypeSig { Index = p.Index };
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                    case TypeDefFlavor.Handle:
                    case TypeDefFlavor.Nullable:
                    case TypeDefFlavor.Enum:
                    case TypeDefFlavor.Struct:
                        {
                            var applicand = new PE.TypeDefOrRefSig
                                            {
                                                IsValueType = true,
                                                TypeDefOrRef = { Value = TypeDefOrRefRowFromQualifiedTypeName(ctxt, typeRef.QualifiedTypeName) }
                                            };
                            if (typeRef.Arguments.Count > 0)
                                return new PE.ApplicationTypeSig
                                       {
                                           Applicand = applicand,
                                           Arguments = typeRef.Arguments.Select(t => TypeSigFromTypeRef(ctxt, t)).ToSeq()
                                       };
                            else
                                return applicand;
                        }
                    case TypeDefFlavor.Void:
                        return new PE.PrimitiveTypeSig { PrimitiveType = PE.PrimitiveType.Void };
                    case TypeDefFlavor.Number:
                        {
                            var n = (NumberTypeDef)tyconEnv.Type;
                            var p = default(PE.PrimitiveType);
                            switch (n.NumberFlavor)
                            {
                                case NumberFlavor.Int8:
                                    p = PE.PrimitiveType.Int8;
                                    break;
                                case NumberFlavor.Int16:
                                    p = PE.PrimitiveType.Int16;
                                    break;
                                case NumberFlavor.Int32:
                                    p = PE.PrimitiveType.Int32;
                                    break;
                                case NumberFlavor.Int64:
                                    p = PE.PrimitiveType.Int64;
                                    break;
                                case NumberFlavor.IntNative:
                                    p = PE.PrimitiveType.IntNative;
                                    break;
                                case NumberFlavor.UInt8:
                                    p = PE.PrimitiveType.UInt8;
                                    break;
                                case NumberFlavor.UInt16:
                                    p = PE.PrimitiveType.UInt16;
                                    break;
                                case NumberFlavor.UInt32:
                                    p = PE.PrimitiveType.UInt32;
                                    break;
                                case NumberFlavor.UInt64:
                                    p = PE.PrimitiveType.UInt64;
                                    break;
                                case NumberFlavor.UIntNative:
                                    p = PE.PrimitiveType.UIntNative;
                                    break;
                                case NumberFlavor.Single:
                                    p = PE.PrimitiveType.Single;
                                    break;
                                case NumberFlavor.Double:
                                    p = PE.PrimitiveType.Double;
                                    break;
                                case NumberFlavor.Boolean:
                                    p = PE.PrimitiveType.Boolean;
                                    break;
                                case NumberFlavor.Char:
                                    p = PE.PrimitiveType.Char;
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            return new PE.PrimitiveTypeSig { PrimitiveType = p };
                        }
                    case TypeDefFlavor.Delegate:
                    case TypeDefFlavor.Class:
                    case TypeDefFlavor.Interface:
                    case TypeDefFlavor.GenericIEnumerable:
                        {
                            var applicand = new PE.TypeDefOrRefSig
                                            {
                                                IsValueType = false,
                                                TypeDefOrRef = { Value = TypeDefOrRefRowFromQualifiedTypeName(ctxt, typeRef.QualifiedTypeName) }
                                            };
                            if (typeRef.Arguments.Count > 0)
                                return new PE.ApplicationTypeSig
                                       {
                                           Applicand = applicand,
                                           Arguments = typeRef.Arguments.Select(t => TypeSigFromTypeRef(ctxt, t)).ToSeq()
                                       };
                            else
                                return applicand;
                        }
                    case TypeDefFlavor.Object:
                        return new PE.PrimitiveTypeSig { PrimitiveType = PE.PrimitiveType.Object };
                    case TypeDefFlavor.String:
                        return new PE.PrimitiveTypeSig { PrimitiveType = PE.PrimitiveType.String };
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }