예제 #1
0
        /// <summary>
        /// Read a type from a signature.
        /// </summary>
        /// <param name="p">Pointer to the signature to be read</param>
        /// <param name="f">CLIFileReader in use</param>
        /// <returns>
        /// A CLIType object representing a type. It is similar to a Reflection.Type
        /// object though it is less expensive and contains enough information to
        /// access type definitions in CLIFile table.
        /// </returns>
        private static CLITypeNode ReadTypeNode(ref MapPtr p, CLIFile f)
        {
            ELEMENT_TYPE t = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(ref p);

            switch (t)
            {
            case ELEMENT_TYPE.ELEMENT_TYPE_BOOLEAN:
            case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
            case ELEMENT_TYPE.ELEMENT_TYPE_I1:
            case ELEMENT_TYPE.ELEMENT_TYPE_U1:
            case ELEMENT_TYPE.ELEMENT_TYPE_I2:
            case ELEMENT_TYPE.ELEMENT_TYPE_U2:
            case ELEMENT_TYPE.ELEMENT_TYPE_I4:
            case ELEMENT_TYPE.ELEMENT_TYPE_U4:
            case ELEMENT_TYPE.ELEMENT_TYPE_I8:
            case ELEMENT_TYPE.ELEMENT_TYPE_U8:
            case ELEMENT_TYPE.ELEMENT_TYPE_R4:
            case ELEMENT_TYPE.ELEMENT_TYPE_R8:
            case ELEMENT_TYPE.ELEMENT_TYPE_I:
            case ELEMENT_TYPE.ELEMENT_TYPE_U:
            case ELEMENT_TYPE.ELEMENT_TYPE_STRING:
            case ELEMENT_TYPE.ELEMENT_TYPE_OBJECT:
            case ELEMENT_TYPE.ELEMENT_TYPE_TYPEDBYREF:
            case ELEMENT_TYPE.ELEMENT_TYPE_VOID:
                return(BaseType.TypeOf(t).type);

            case ELEMENT_TYPE.ELEMENT_TYPE_VAR:
                return(new VariableType(f, SignatureUtil.ReadCompressedInt(ref p)));

            case ELEMENT_TYPE.ELEMENT_TYPE_MVAR:
                return(new MethodVariableType(f, SignatureUtil.ReadCompressedInt(ref p)));

            case ELEMENT_TYPE.ELEMENT_TYPE_VALUETYPE:
            case ELEMENT_TYPE.ELEMENT_TYPE_CLASS:
                return(new CompoundType(f, SignatureUtil.ReadCompressedInt(ref p)));

            case ELEMENT_TYPE.ELEMENT_TYPE_GENERICINST:
            {
                ELEMENT_TYPE isClass = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(ref p);
                int          ttk     = SignatureUtil.ReadCompressedInt(ref p);
                int          count   = SignatureUtil.ReadCompressedInt(ref p);
                CLIType[]    args    = new CLIType[count];
                for (int i = 0; i < count; i++)
                {
                    args[i] = new CLIType(f, ReadTypeNode(ref p, f));
                }

                return(new CompoundType(f, ttk, args));
            }

            case ELEMENT_TYPE.ELEMENT_TYPE_PTR:
            {
                int          sz;
                ELEMENT_TYPE opt  = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(p, out sz);
                ELEMENT_TYPE?cmod = null;
                if (opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_OPT || opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_REQD)
                {
                    cmod = opt;
                    p   += 1;
                }
                CLITypeNode ptrt = new PointerType(ReadTypeNode(ref p, f));
                if (cmod.HasValue)
                {
                    ptrt = new CustomModType(cmod.Value, ptrt);
                }
                return(ptrt);
            }

            case ELEMENT_TYPE.ELEMENT_TYPE_FNPTR:
                return(new FunPointerType(f, p));

            case ELEMENT_TYPE.ELEMENT_TYPE_ARRAY:
            {
                CLITypeNode at   = ReadTypeNode(ref p, f);
                int         rank = SignatureUtil.ReadCompressedInt(ref p);
                int         sz   = SignatureUtil.ReadCompressedInt(ref p);
                int[]       szs  = new int[sz];
                for (int i = 0; i < sz; i++)
                {
                    szs[i] = SignatureUtil.ReadCompressedInt(ref p);
                }
                sz = SignatureUtil.ReadCompressedInt(ref p);
                int[] lb = new int[sz];
                for (int i = 0; i < sz; i++)
                {
                    lb[i] = SignatureUtil.ReadCompressedInt(ref p);
                }
                return(new ArrayType(at, rank, szs, lb));
            }

            case ELEMENT_TYPE.ELEMENT_TYPE_SZARRAY:
            {
                int          sz;
                ELEMENT_TYPE opt  = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(p, out sz);
                ELEMENT_TYPE?cmod = null;
                if (opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_OPT || opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_REQD)
                {
                    cmod = opt;
                    p   += 1;
                }
                CLITypeNode sat = new ArrayType(ReadTypeNode(ref p, f));
                if (cmod.HasValue)
                {
                    sat = new CustomModType(cmod.Value, sat);
                }
                return(sat);
            }

            default:
                throw new Exception("Internal error in CLI File Reader library!");
            }
        }
예제 #2
0
        public static CLIType Promote(CLIType nt1, CLIType nt2)
        {
            if (!(nt1.type is BaseType) || !(nt2.type is BaseType))
            {
                throw new Exception("Internal error");
            }

            BaseType t1 = (BaseType)nt1.type;
            BaseType t2 = (BaseType)nt2.type;

            switch (t1.type)
            {
            case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                case ELEMENT_TYPE.ELEMENT_TYPE_I8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                    return(nt1);

                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                    return(nt1);

                case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                case ELEMENT_TYPE.ELEMENT_TYPE_I8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                    return(nt1);

                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                    return(nt1);

                case ELEMENT_TYPE.ELEMENT_TYPE_I8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                    return(nt1);

                case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_I8:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                case ELEMENT_TYPE.ELEMENT_TYPE_I8:
                    return(nt1);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                case ELEMENT_TYPE.ELEMENT_TYPE_U8:
                    return(nt1);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_R4:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_R4:
                case ELEMENT_TYPE.ELEMENT_TYPE_R8:
                    return(nt2);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_R8:
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_R4:
                case ELEMENT_TYPE.ELEMENT_TYPE_R8:
                    return(nt1);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_I:
                // FIXME: Check this
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_I1:
                case ELEMENT_TYPE.ELEMENT_TYPE_I2:
                case ELEMENT_TYPE.ELEMENT_TYPE_I4:
                    return(nt1);
                }
                return(null);

            case ELEMENT_TYPE.ELEMENT_TYPE_U:
                // FIXME: Check this
                switch (t2.type)
                {
                case ELEMENT_TYPE.ELEMENT_TYPE_CHAR:
                case ELEMENT_TYPE.ELEMENT_TYPE_U1:
                case ELEMENT_TYPE.ELEMENT_TYPE_U2:
                case ELEMENT_TYPE.ELEMENT_TYPE_U4:
                    return(nt1);
                }
                return(null);

            default:
                return(null);
            }
        }