Пример #1
0
        TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!this.recursionCounter.Increment())
            {
                return(null);
            }

            if (this.ReplaceGenericArg(ref typeSig))
            {
                this.recursionCounter.Decrement();
                return(typeSig);
            }

            TypeSig result;

            switch (typeSig.ElementType)
            {
            case ElementType.Ptr:
                result = new PtrSig(this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.ByRef:
                result = new ByRefSig(this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Var:
                result = new GenericVar((typeSig as GenericVar).Number);
                break;

            case ElementType.ValueArray:
                result = new ValueArraySig(this.ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size);
                break;

            case ElementType.SZArray:
                result = new SZArraySig(this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.MVar:
                result = new GenericMVar((typeSig as GenericMVar).Number);
                break;

            case ElementType.CModReqd:
                result = new CModReqdSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.CModOpt:
                result = new CModOptSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Module:
                result = new ModuleSig((typeSig as ModuleSig).Index, this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Pinned:
                result = new PinnedSig(this.ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.FnPtr:
                throw new NotSupportedException("FnPtr is not supported.");

            case ElementType.Array:
                var arraySig = (ArraySig)typeSig;
                var sizes    = new List <uint>(arraySig.Sizes);
                var lbounds  = new List <int>(arraySig.LowerBounds);
                result = new ArraySig(this.ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds);
                break;

            case ElementType.GenericInst:
                var gis     = (GenericInstSig)typeSig;
                var genArgs = new List <TypeSig>(gis.GenericArguments.Count);
                foreach (TypeSig ga in gis.GenericArguments)
                {
                    genArgs.Add(this.ResolveGenericArgs(ga));
                }
                result = new GenericInstSig(this.ResolveGenericArgs(gis.GenericType) as ClassOrValueTypeSig, genArgs);
                break;

            default:
                result = typeSig;
                break;
            }

            this.recursionCounter.Decrement();

            return(result);
        }
        TypeSig Create2(TypeSig type)
        {
            if (type == null)
            {
                return(type);
            }
            TypeSig result;

            GenericSig varSig;

            switch (type.ElementType)
            {
            case ElementType.Void:
            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.String:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.Object:
                result = type;
                break;

            case ElementType.Ptr:
                result = new PtrSig(Create2(type.Next));
                break;

            case ElementType.ByRef:
                result = new ByRefSig(Create2(type.Next));
                break;

            case ElementType.Array:
                var ary = (ArraySig)type;
                result = new ArraySig(ary.Next, ary.Rank, ary.Sizes, ary.LowerBounds);
                break;

            case ElementType.SZArray:
                result = new SZArraySig(Create2(type.Next));
                break;

            case ElementType.Pinned:
                result = new PinnedSig(Create2(type.Next));
                break;

            case ElementType.ValueType:
            case ElementType.Class:
                result = type;
                break;

            case ElementType.Var:
                varSig = (GenericSig)type;
                if (genericArgs != null && varSig.Number < (uint)genericArgs.Count)
                {
                    result  = genericArgs[(int)varSig.Number];
                    updated = true;
                }
                else
                {
                    result = type;
                }
                break;

            case ElementType.MVar:
                varSig = (GenericSig)type;
                if (genericMethodArgs != null && varSig.Number < (uint)genericMethodArgs.Count)
                {
                    result  = genericMethodArgs[(int)varSig.Number];
                    updated = true;
                }
                else
                {
                    result = type;
                }
                break;

            case ElementType.GenericInst:
                var gis    = (GenericInstSig)type;
                var newGis = new GenericInstSig(Create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count);
                for (int i = 0; i < gis.GenericArguments.Count; i++)
                {
                    newGis.GenericArguments.Add(Create2(gis.GenericArguments[i]));
                }
                result = newGis;
                break;

            case ElementType.ValueArray:
                result = new ValueArraySig(type.Next, ((ValueArraySig)type).Size);
                break;

            case ElementType.Module:
                result = new ModuleSig(((ModuleSig)type).Index, type.Next);
                break;

            case ElementType.CModReqd:
                result = new CModReqdSig(((ModifierSig)type).Modifier, type.Next);
                break;

            case ElementType.CModOpt:
                result = new CModOptSig(((ModifierSig)type).Modifier, type.Next);
                break;

            case ElementType.FnPtr:
                result = new FnPtrSig(Create(((FnPtrSig)type).MethodSig));
                break;

            case ElementType.End:
            case ElementType.R:
            case ElementType.Sentinel:
            case ElementType.Internal:
            default:
                result = type;
                break;
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        private TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num;
            TypeSig nextType, result = null;

            switch ((ElementType)reader.ReadByte())
            {
            case ElementType.Void: result = corLibTypes.Void; break;

            case ElementType.Boolean: result = corLibTypes.Boolean; break;

            case ElementType.Char: result = corLibTypes.Char; break;

            case ElementType.I1: result = corLibTypes.SByte; break;

            case ElementType.U1: result = corLibTypes.Byte; break;

            case ElementType.I2: result = corLibTypes.Int16; break;

            case ElementType.U2: result = corLibTypes.UInt16; break;

            case ElementType.I4: result = corLibTypes.Int32; break;

            case ElementType.U4: result = corLibTypes.UInt32; break;

            case ElementType.I8: result = corLibTypes.Int64; break;

            case ElementType.U8: result = corLibTypes.UInt64; break;

            case ElementType.R4: result = corLibTypes.Single; break;

            case ElementType.R8: result = corLibTypes.Double; break;

            case ElementType.String: result = corLibTypes.String; break;

            case ElementType.TypedByRef: result = corLibTypes.TypedReference; break;

            case ElementType.I: result = corLibTypes.IntPtr; break;

            case ElementType.U: result = corLibTypes.UIntPtr; break;

            case ElementType.Object: result = corLibTypes.Object; break;

            case ElementType.Ptr: result = new PtrSig(ReadType()); break;

            case ElementType.ByRef: result = new ByRefSig(ReadType()); break;

            case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break;

            case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break;

            case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break;

            case ElementType.SZArray: result = new SZArraySig(ReadType()); break;

            case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.Sentinel: result = new SentinelSig(); break;

            case ElementType.Pinned: result = new PinnedSig(ReadType()); break;

            case ElementType.Var:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num, gpContext.Type);
                break;

            case ElementType.MVar:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericMVar(num, gpContext.Method);
                break;

            case ElementType.ValueArray:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ValueArraySig(nextType, num);
                break;

            case ElementType.Module:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ModuleSig(num, ReadType());
                break;

            case ElementType.GenericInst:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
                var args           = genericInstSig.GenericArguments;
                for (uint i = 0; i < num; i++)
                {
                    args.Add(ReadType());
                }
                result = genericInstSig;
                break;

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.ReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    uint size;
                    if (!reader.ReadCompressedUInt32(out size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    int size;
                    if (!reader.ReadCompressedInt32(out size))
                    {
                        goto exit;
                    }
                    lowerBounds.Add(size);
                }
                result = new ArraySig(nextType, rank, sizes, lowerBounds);
                break;

            case ElementType.Internal:
                IntPtr address;
                if (IntPtr.Size == 4)
                {
                    address = new IntPtr(reader.ReadInt32());
                }
                else
                {
                    address = new IntPtr(reader.ReadInt64());
                }
                result = helper.ConvertRTInternalAddress(address);
                break;

            case ElementType.End:
            case ElementType.R:
            default:
                result = null;
                break;
            }
exit:
            recursionCounter.Decrement();
            return(result);
        }
Пример #4
0
 void AddArraySig() => TypeSig = new ArraySig(TypeSig, ArrayRank.Value, ArraySizes.Value, ArrayLowerBounds.Value);
Пример #5
0
 void AddArraySig()
 {
     TypeSig = new ArraySig(TypeSig, arrayRank.Value, arraySizes.Value, arrayLowerBounds.Value);
 }
Пример #6
0
        public static void TypeSigName(StringBuilder sb, TypeSig tySig, bool printGenOwner, int depth = 0)
        {
            if (depth > 512)
            {
                throw new TypeLoadException("The TypeSig chain is too long. Or there are some recursive generics that are expanded");
            }

            if (tySig == null)
            {
                return;
            }

            switch (tySig.ElementType)
            {
            case ElementType.Class:
            case ElementType.ValueType:
            case ElementType.TypedByRef:
                ClassSigName(sb, tySig);
                return;

            case ElementType.Ptr:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                sb.Append('*');
                return;

            case ElementType.ByRef:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                sb.Append('&');
                return;

            case ElementType.Pinned:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                return;

            case ElementType.SZArray:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                sb.Append("[]");
                return;

            case ElementType.Array:
            {
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                ArraySig arySig = (ArraySig)tySig;
                GetArraySigPostfix(sb, arySig);
                return;
            }

            case ElementType.CModReqd:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                sb.Append(" modreq(");
                ClassSigName(sb, ((CModReqdSig)tySig).Modifier.ResolveTypeDef());
                sb.Append(')');
                return;

            case ElementType.CModOpt:
                TypeSigName(sb, tySig.Next, printGenOwner, depth + 1);
                sb.Append(" modopt(");
                ClassSigName(sb, ((CModOptSig)tySig).Modifier.ResolveTypeDef());
                sb.Append(')');
                return;

            case ElementType.GenericInst:
            {
                GenericInstSig genInstSig = (GenericInstSig)tySig;
                TypeSigName(sb, genInstSig.GenericType, printGenOwner, depth + 1);
                sb.Append('<');
                TypeSigListName(sb, genInstSig.GenericArguments, printGenOwner);
                sb.Append('>');
                return;
            }

            case ElementType.Var:
            case ElementType.MVar:
            {
                var genSig = (GenericSig)tySig;
                if (genSig.IsMethodVar)
                {
                    sb.Append("!!");
                }
                else
                {
                    sb.Append('!');
                    if (printGenOwner)
                    {
                        sb.Append('(');
                        ClassSigName(sb, genSig.OwnerType);
                        sb.Append(')');
                    }
                }
                sb.Append(genSig.Number);
                return;
            }

            default:
                if (tySig is CorLibTypeSig)
                {
                    ClassSigName(sb, tySig);
                    return;
                }

                throw new ArgumentOutOfRangeException();
            }
        }
Пример #7
0
        private static TypeSig ReplaceGenericSigImpl(TypeSig tySig, IGenericReplacer replacer)
        {
            if (tySig == null)
            {
                return(null);
            }

            switch (tySig.ElementType)
            {
            case ElementType.Class:
            case ElementType.ValueType:
            case ElementType.TypedByRef:
                return(tySig);

            case ElementType.Ptr:
                return(new PtrSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.ByRef:
                return(new ByRefSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.Pinned:
                return(new PinnedSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.SZArray:
                return(new SZArraySig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.Array:
            {
                ArraySig arySig = (ArraySig)tySig;
                return(new ArraySig(ReplaceGenericSigImpl(arySig.Next, replacer),
                                    arySig.Rank,
                                    arySig.Sizes,
                                    arySig.LowerBounds));
            }

            case ElementType.CModReqd:
            {
                CModReqdSig modreqdSig = (CModReqdSig)tySig;
                return(new CModReqdSig(modreqdSig.Modifier, ReplaceGenericSigImpl(modreqdSig.Next, replacer)));
            }

            case ElementType.CModOpt:
            {
                CModOptSig modoptSig = (CModOptSig)tySig;
                return(new CModOptSig(modoptSig.Modifier, ReplaceGenericSigImpl(modoptSig.Next, replacer)));
            }

            case ElementType.GenericInst:
            {
                GenericInstSig genInstSig = (GenericInstSig)tySig;
                return(new GenericInstSig(genInstSig.GenericType, ReplaceGenericSigListImpl(genInstSig.GenericArguments, replacer)));
            }

            case ElementType.Var:
            {
                GenericVar genVarSig = (GenericVar)tySig;
                TypeSig    result    = replacer.Replace(genVarSig);
                if (result != null)
                {
                    return(result);
                }
                return(genVarSig);
            }

            case ElementType.MVar:
            {
                GenericMVar genMVarSig = (GenericMVar)tySig;
                TypeSig     result     = replacer.Replace(genMVarSig);
                if (result != null)
                {
                    return(result);
                }
                return(genMVarSig);
            }

            default:
                if (tySig is CorLibTypeSig)
                {
                    return(tySig);
                }

                throw new NotSupportedException();
            }
        }