예제 #1
0
        public CLRSigParamOrRetType(CLRSignatureParser parser, bool allowSentinel)
        {
            CustomMods = CLRSigType.ReadCustomMods(parser);

            CLRSignatureParser.Token token = parser.NextToken();

            if (token == CLRSignatureParser.Token.TYPEDBYREF)
            {
                TypeOfType = TypeOfTypeEnum.TypedByRef;
                parser.ConsumeToken();
            }
            else if (token == CLRSignatureParser.Token.SENTINEL)
            {
                if (!allowSentinel)
                    throw new ParseFailedException("Malformed signature");
                TypeOfType = TypeOfTypeEnum.Sentinel;
                parser.ConsumeToken();
            }
            else
            {
                bool allowVoid = AllowVoid;
                if (token == CLRSignatureParser.Token.BYREF)
                {
                    TypeOfType = TypeOfTypeEnum.ByRef;
                    token = parser.NextToken();
                    parser.ConsumeToken();
                    allowVoid = false;
                }
                else
                    TypeOfType = TypeOfTypeEnum.Value;
                Type = CLRSigType.Parse(parser, allowVoid);
            }
        }
예제 #2
0
        public CLRSigFieldSig(CLRSignatureParser parser)
        {
            if (parser.NextByte() != 0x6)
                throw new ParseFailedException("Malformed FieldSig");
            parser.ConsumeByte();

            CustomMods = CLRSigType.ReadCustomMods(parser);
            Type = CLRSigType.Parse(parser, false);
        }
예제 #3
0
        public CLRSigLocalVarSig(CLRSignatureParser parser)
        {
            if (parser.NextToken() != CLRSignatureParser.Token.LOCAL_SIG)
                throw new ParseFailedException("Invalid local var sig");
            parser.ConsumeToken();

            uint numLocals = parser.ReadCompressedUInt();

            LocalVars = new CLRSigLocalVar[numLocals];
            for (uint i = 0; i < numLocals; i++)
                LocalVars[i] = new CLRSigLocalVar(parser);
        }
예제 #4
0
        public CLRSigMethodSpec(CLRSignatureParser parser)
        {
            if (parser.NextToken() != CLRSignatureParser.Token.GENERICINST)
                throw new ParseFailedException("Malformed method spec");
            parser.ConsumeToken();
            uint numGenericParams = parser.ReadCompressedUInt();
            Types = new CLRSigType[numGenericParams];

            for (uint i = 0; i < numGenericParams; i++)
            {
                Types[i] = CLRSigType.Parse(parser, false);
            }
        }
        public CLRSigCustomAttributeNamedArg(CLRSignatureParser parser)
        {
            CLRSigType.ElementType baseType = (CLRSigType.ElementType)parser.ReadU8();

            if (baseType == CLRSigType.ElementType.Special_CustomAttribField)
                ArgKind = ArgKindEnum.Field;
            else if (baseType == CLRSigType.ElementType.Special_CustomAttribProperty)
                ArgKind = ArgKindEnum.Property;
            else
                throw new ParseFailedException("Unusual named arg type");

            CLRSigType argType = CLRSigCustomAttributeElem.ReadFieldOrPropType(parser);
            Name = CLRSigCustomAttributeElem.ReadUTF8String(parser);
            Arg = new CLRSigCustomAttributeFixedArg(parser, argType);
        }
예제 #6
0
        public static CLRSigType Parse(CLRSignatureParser parser, bool permitVoid)
        {
            ElementType eType = (ElementType)parser.NextByte();
            parser.ConsumeByte();

            switch (eType)
            {
                case ElementType.BOOLEAN:
                case ElementType.CHAR:
                case ElementType.I1:
                case ElementType.U1:
                case ElementType.I2:
                case ElementType.U2:
                case ElementType.I4:
                case ElementType.U4:
                case ElementType.I8:
                case ElementType.U8:
                case ElementType.R4:
                case ElementType.R8:
                case ElementType.I:
                case ElementType.U:
                case ElementType.OBJECT:
                case ElementType.STRING:
                    return new CLRSigTypeSimple(eType);
                case ElementType.VOID:
                    if (!permitVoid)
                        throw new ParseFailedException("Unexpected void type");
                    return new CLRSigTypeSimple(eType);
                case ElementType.ARRAY:
                    return new CLRSigTypeArray(eType, parser);
                case ElementType.CLASS:
                case ElementType.VALUETYPE:
                    return new CLRSigTypeStructured(eType, parser);
                case ElementType.FNPTR:
                    return new CLRSigTypeFunctionPointer(eType, parser);
                case ElementType.GENERICINST:
                    return new CLRSigTypeGenericInstantiation(eType, parser);
                case ElementType.MVAR:
                case ElementType.VAR:
                    return new CLRSigTypeVarOrMVar(eType, parser);
                case ElementType.PTR:
                    return new CLRSigTypePointer(eType, parser);
                case ElementType.SZARRAY:
                    return new CLRSigTypeSZArray(eType, parser);
                default:
                    throw new ParseFailedException("Unexpected sig type");
            }
        }
예제 #7
0
        public CLRSigCustomMod(CLRSignatureParser parser)
        {
            byte token = parser.NextByte();
            parser.ConsumeByte();

            if (token == 0x1f)
                IsOptional = false;
            else if (token == 0x20)
                IsOptional = true;
            else
                throw new ParseFailedException("Strange custom mod token");

            IndexedType = parser.ReadTypeDefOrRefOrSpecEncoded();

            throw new NotSupportedException("Custom modifiers are not supported");
        }
예제 #8
0
        public CLRSigTypeSpec(CLRSignatureParser parser)
        {
            byte token = parser.NextByte();

            // VAR and MVAR aren't permitted by the spec, but that appears to be an error
            if (token != (byte)CLRSigType.ElementType.PTR &&
                token != (byte)CLRSigType.ElementType.FNPTR &&
                token != (byte)CLRSigType.ElementType.ARRAY &&
                token != (byte)CLRSigType.ElementType.SZARRAY &&
                token != (byte)CLRSigType.ElementType.GENERICINST &&
                token != (byte)CLRSigType.ElementType.MVAR &&
                token != (byte)CLRSigType.ElementType.VAR)
                throw new ParseFailedException("Invalid sig type for type spec");

            Type = CLRSigType.Parse(parser, false);
        }
예제 #9
0
 public static string ReadUTF8String(CLRSignatureParser parser)
 {
     byte firstByte = parser.NextByte();
     if (firstByte == 0xff)
         return null;
     else
     {
         uint stringLengthBytes = parser.ReadCompressedUInt();
         if (stringLengthBytes == 0)
             return "";
         else
         {
             byte[] utf8chars = new byte[stringLengthBytes];
             parser.ReadBytes(utf8chars, stringLengthBytes);
             return System.Text.Encoding.UTF8.GetString(utf8chars);
         }
     }
 }
예제 #10
0
        public CLRSigPropertySig(CLRSignatureParser parser)
        {
            CLRSignatureParser.Token headToken = parser.NextToken();
            parser.ConsumeToken();

            if (headToken == CLRSignatureParser.Token.PROPERTY_HASTHIS)
                HasThis = true;
            else if (headToken == CLRSignatureParser.Token.PROPERTY)
                HasThis = false;
            else
                throw new ParseFailedException("Malformed PropertySig");

            uint paramCount = parser.ReadCompressedUInt();
            CustomMods = CLRSigType.ReadCustomMods(parser);

            Type = CLRSigType.Parse(parser, false);

            Parameters = new CLRSigParamType[paramCount];
            for (uint i = 0; i < paramCount; i++)
                Parameters[i] = new CLRSigParamType(parser, false);
        }
예제 #11
0
        public static CLRSigType ReadFieldOrPropType(CLRSignatureParser parser)
        {
            CLRSigType.ElementType basicType = (CLRSigType.ElementType)parser.ReadU8();

            switch (basicType)
            {
                case CLRSigType.ElementType.BOOLEAN:
                case CLRSigType.ElementType.CHAR:
                case CLRSigType.ElementType.R4:
                case CLRSigType.ElementType.R8:
                case CLRSigType.ElementType.I1:
                case CLRSigType.ElementType.U1:
                case CLRSigType.ElementType.I2:
                case CLRSigType.ElementType.U2:
                case CLRSigType.ElementType.I4:
                case CLRSigType.ElementType.U4:
                case CLRSigType.ElementType.I8:
                case CLRSigType.ElementType.U8:
                case CLRSigType.ElementType.STRING:
                    return new CLRSigTypeSimple(basicType);
                case CLRSigType.ElementType.Special_CustomAttribBoxedObject:
                    return new CLRSigTypeSimple(CLRSigType.ElementType.OBJECT);
                case CLRSigType.ElementType.Special_CustomAttribEnum:
                    {
                        string typeName = ReadUTF8String(parser);
                        throw new NotImplementedException();
                    }
                    break;
                case CLRSigType.ElementType.Special_SystemType:
                    // CLARITYTODO: Look up System.Type
                    throw new NotImplementedException();
                case CLRSigType.ElementType.SZARRAY:
                    {
                        CLRSigType containedType = ReadFieldOrPropType(parser);
                        return new CLRSigTypeArray(CLRSigType.ElementType.SZARRAY, containedType);
                    }
                default:
                    throw new ParseFailedException("Unexpected field or prop type");
            }
        }
예제 #12
0
        public CLRSigCustomAttribute(CLRSignatureParser parser, CLRTableRow constructor)
        {
            Constructor = constructor;

            if (parser.ReadU16() != 0x0001)
                throw new NotSupportedException("Unusual CA prolog");

            CLRSigMethodDefOrRefSig methodSig = null;
            if (constructor is CLRMethodDefRow)
            {
                CLRMethodDefRow methodDef = (CLRMethodDefRow)constructor;
                methodSig = methodDef.Signature;
            }
            else if (constructor is CLRMemberRefRow)
            {
                CLRMemberRefRow memberRef = (CLRMemberRefRow)constructor;
                methodSig = memberRef.MethodSig;
                if (methodSig == null)
                    throw new ParseFailedException("Bad CA constructor");
            }
            else
                throw new ParseFailedException("Missing CA constructor");

            int numFixedArgs = methodSig.ParamTypes.Length;
            FixedArgs = new CLRSigCustomAttributeFixedArg[numFixedArgs];
            for (int i = 0; i < numFixedArgs; i++)
            {
                CLRSigType paramType = methodSig.ParamTypes[i].Type;
                CLRSigType containedType = paramType;
                if (paramType is CLRSigTypeArray)
                    containedType = ((CLRSigTypeArray)paramType).ContainedType;
                FixedArgs[i] = new CLRSigCustomAttributeFixedArg(parser, paramType);
            }

            uint numNamedArgs = parser.ReadU16();
            NamedArgs = new CLRSigCustomAttributeNamedArg[numNamedArgs];
            for (uint i = 0; i < numNamedArgs; i++)
                NamedArgs[i] = new CLRSigCustomAttributeNamedArg(parser);
        }
예제 #13
0
        public CLRSigTypeArray(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            ContainedType = CLRSigType.Parse(parser, false);

            // ArrayShape (II.23.2.13)
            Rank = parser.ReadCompressedUInt();
            uint numSizes = parser.ReadCompressedUInt();
            if (numSizes > Rank)
                throw new ParseFailedException("Invalid array");

            Sizes = new uint[numSizes];
            for (uint i = 0; i < numSizes; i++)
                Sizes[i] = parser.ReadCompressedUInt();

            uint numLowBounds = parser.ReadCompressedUInt();
            if (numLowBounds > Rank)
                throw new ParseFailedException("Invalid array");

            LowBounds = new int[numLowBounds];
            for (uint i = 0; i < numLowBounds; i++)
                LowBounds[i] = parser.ReadCompressedInt();
        }
예제 #14
0
        private void Parse(CLRSignatureParser parser, CLRSigType elemType)
        {
            ElementType = elemType.BasicType;

            switch (elemType.BasicType)
            {
                case CLRSigType.ElementType.BOOLEAN:
                    Value = (parser.ReadU8() != 0);
                    break;
                case CLRSigType.ElementType.CHAR:
                    Value = (char)(parser.ReadU16());
                    break;
                case CLRSigType.ElementType.R4:
                    Value = parser.ReadF32();
                    break;
                case CLRSigType.ElementType.R8:
                    Value = parser.ReadF64();
                    break;
                case CLRSigType.ElementType.I1:
                    Value = parser.ReadS8();
                    break;
                case CLRSigType.ElementType.U1:
                    Value = parser.ReadU8();
                    break;
                case CLRSigType.ElementType.I2:
                    Value = parser.ReadS16();
                    break;
                case CLRSigType.ElementType.U2:
                    Value = parser.ReadU16();
                    break;
                case CLRSigType.ElementType.I4:
                    Value = parser.ReadS32();
                    break;
                case CLRSigType.ElementType.U4:
                    Value = parser.ReadU32();
                    break;
                case CLRSigType.ElementType.I8:
                    Value = parser.ReadS64();
                    break;
                case CLRSigType.ElementType.U8:
                    Value = parser.ReadU64();
                    break;
                case CLRSigType.ElementType.STRING:
                    Value = ReadUTF8String(parser);
                    break;
                case CLRSigType.ElementType.OBJECT:
                    Parse(parser, ReadFieldOrPropType(parser));
                    return;
                case CLRSigType.ElementType.CLASS:
                case CLRSigType.ElementType.VALUETYPE:
                    {
                        CLRSigTypeStructured st = (CLRSigTypeStructured)elemType;
                        CLRTableRow underlyingType = st.TypeDefOrRefOrSpec;
                        string typeNamespace, typeName;
                        if (underlyingType is CLRTypeDefRow)
                        {
                            CLRTypeDefRow typeDef = (CLRTypeDefRow)underlyingType;
                            typeNamespace = typeDef.TypeNamespace;
                            typeName = typeDef.TypeName;
                        }
                        else if (underlyingType is CLRTypeRefRow)
                        {
                            CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                            typeNamespace = typeRef.TypeNamespace;
                            typeName = typeRef.TypeName;
                        }
                        else
                            throw new ParseFailedException("Unusual CA type");

                        if (typeNamespace == "System" && typeName == "Type")
                        {
                            Parse(parser, new CLRSigTypeSimple(CLRSigType.ElementType.STRING));
                            return;
                        }

                        // Must be an enum
                        {
                            CLRTypeDefRow enumType;

                            if (underlyingType is CLRTypeDefRow)
                                enumType = (CLRTypeDefRow)underlyingType;
                            else if (underlyingType is CLRTypeRefRow)
                            {
                                CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                                if (typeRef.Resolution == null)
                                    throw new ParseFailedException("Custom attribute references unresolved enum type");
                                enumType = typeRef.Resolution;
                            }
                            else
                                throw new ParseFailedException("Unexpected CA underlying type");

                            CLRSigType valueType = null;

                            foreach (CLRFieldRow field in enumType.Fields)
                            {
                                if (!field.Static)
                                {
                                    valueType = field.Signature.Type;
                                    break;
                                }
                            }

                            if (valueType == null)
                                throw new ParseFailedException("Unknown CA enum type");
                            Parse(parser, valueType);
                        }
                    }
                    break;
                default:
                    throw new NotSupportedException("Unsupported custom attrib type");
            }
        }
예제 #15
0
 public CLRSigRetType(CLRSignatureParser parser)
     : base(parser, false)
 {
 }
예제 #16
0
        public CLRSigTypeVarOrMVar(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            Value = parser.ReadCompressedUInt();
        }
예제 #17
0
        public CLRSigTypeStructured(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            TypeDefOrRefOrSpec = parser.ReadTypeDefOrRefOrSpecEncoded();
        }
예제 #18
0
        public CLRSigTypeSZArray(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            CustomMods = CLRSigType.ReadCustomMods(parser);
            ContainedType = CLRSigType.Parse(parser, true);
        }
예제 #19
0
        public CLRSigTypePointer(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            CustomMods = CLRSigType.ReadCustomMods(parser);
            PointedToType = CLRSigType.Parse(parser, true);
        }
예제 #20
0
        public CLRSigTypeGenericInstantiation(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            ElementType instType = (ElementType)parser.NextByte();
            parser.ConsumeByte();
            if (instType == ElementType.CLASS)
                InstantiationType = InstType.Class;
            else if (instType == ElementType.VALUETYPE)
                InstantiationType = InstType.ValueType;
            else
                throw new ParseFailedException("Unexpected instantiation type");
            GenericType = parser.ReadTypeDefOrRefOrSpecEncoded();
            uint genArgCount = parser.ReadCompressedUInt();

            ArgTypes = new CLRSigType[genArgCount];
            for (uint i = 0; i < genArgCount; i++)
                ArgTypes[i] = CLRSigType.Parse(parser, false);
        }
예제 #21
0
 public CLRSigCustomAttributeElem(CLRSignatureParser parser, CLRSigType overallType)
 {
     Parse(parser, overallType);
 }
예제 #22
0
        public static CLRSigCustomMod[] ReadCustomMods(CLRSignatureParser parser)
        {
            List<CLRSigCustomMod> customMods = new List<CLRSigCustomMod>();

            byte nextToken = parser.NextByte();
            while (nextToken == (byte)ElementType.CMOD_OPT || nextToken == (byte)ElementType.CMOD_REQD)
            {
                customMods.Add(new CLRSigCustomMod(parser));
                nextToken = parser.NextByte();
                throw new NotImplementedException();
            }
            return customMods.ToArray();
        }
예제 #23
0
        public static void ReadCustomModsAndConstraints(CLRSignatureParser parser, out CLRSigCustomMod[] outCustomMods, out CLRSigConstraint[] outConstraints)
        {
            List<CLRSigCustomMod> customMods = new List<CLRSigCustomMod>();
            List<CLRSigConstraint> constraints = new List<CLRSigConstraint>();

            byte nextToken = parser.NextByte();
            while (true)
            {
                if (nextToken == (byte)ElementType.PINNED)
                {
                    constraints.Add(new CLRSigConstraint(CLRSigConstraint.ConstraintTypeEnum.Pinned));
                    parser.ConsumeByte();
                }
                else if (nextToken == (byte)ElementType.CMOD_OPT || nextToken == (byte)ElementType.CMOD_REQD)
                {
                    customMods.Add(new CLRSigCustomMod(parser));
                    nextToken = parser.NextByte();
                }
                else
                    break;
            }
            outCustomMods = customMods.ToArray();
            outConstraints = constraints.ToArray();
        }
예제 #24
0
        public CLRSigMethodDefOrRefSig(CLRSignatureParser parser, Kind allowedKind)
        {
            byte baseByte = parser.NextByte();
            parser.ConsumeByte();

            CLRSignatureParser.Token callingConvention = (CLRSignatureParser.Token)(baseByte & 0x0f);

            if ((baseByte & (byte)CLRSignatureParser.Token.HASTHIS) != 0)
            {
                HasThis = true;
                if ((baseByte & (byte)CLRSignatureParser.Token.EXPLICITTHIS) != 0)
                    ExplicitThis = true;
            }

            if ((baseByte & (int)CLRSignatureParser.Token.GENERIC) != 0)
            {
                if (allowedKind != Kind.Def && allowedKind != Kind.DefOrRef && allowedKind != Kind.Ref)
                    throw new ParseFailedException("Invalid method signature");
                allowedKind = Kind.Def;
                NumGenericParameters = parser.ReadCompressedUInt();
            }

            switch (callingConvention)
            {
                case CLRSignatureParser.Token.DEFAULT:
                    if (allowedKind != Kind.Def && allowedKind != Kind.DefOrRef && allowedKind != Kind.Ref)
                        throw new ParseFailedException("Invalid method signature");
                    allowedKind = Kind.Def;
                    CallingConvention = CallingConventionType.Default;
                    break;
                case CLRSignatureParser.Token.VARARG:
                    CallingConvention = CallingConventionType.VarArg;
                    break;
                case CLRSignatureParser.Token.C:
                    if (allowedKind != Kind.StandAlone)
                        throw new ParseFailedException("Invalid method signature");
                    CallingConvention = CallingConventionType.C;
                    break;
                case CLRSignatureParser.Token.STDCALL:
                    if (allowedKind != Kind.StandAlone)
                        throw new ParseFailedException("Invalid method signature");
                    CallingConvention = CallingConventionType.StdCall;
                    break;
                case CLRSignatureParser.Token.THISCALL:
                    if (allowedKind != Kind.StandAlone)
                        throw new ParseFailedException("Invalid method signature");
                    CallingConvention = CallingConventionType.ThisCall;
                    break;
                case CLRSignatureParser.Token.FASTCALL:
                    if (allowedKind != Kind.StandAlone)
                        throw new ParseFailedException("Invalid method signature");
                    CallingConvention = CallingConventionType.FastCall;
                    break;
                default:
                    throw new ParseFailedException("Unexpected signature token");
            }
            uint paramCount = parser.ReadCompressedUInt();

            // Return type
            RetType = new CLRSigRetType(parser);

            ParamTypes = new CLRSigParamType[paramCount];

            bool allowSentinel = (allowedKind == Kind.StandAlone) && (CallingConvention == CallingConventionType.C || CallingConvention == CallingConventionType.VarArg);

            // Parameter types
            for (uint i = 0; i < paramCount; i++)
                ParamTypes[i] = new CLRSigParamType(parser, allowSentinel);
        }
예제 #25
0
        public CLRSigTypeFunctionPointer(ElementType type, CLRSignatureParser parser)
        {
            BasicType = type;

            MethodDefOrRefSig = new CLRSigMethodDefOrRefSig(parser, CLRSigMethodDefOrRefSig.Kind.DefOrRef);
        }