Example #1
0
        public TypeSig GetThisTypeSig()
        {
            ClassOrValueTypeSig tySig;

            if (IsValueType)
            {
                tySig = new ValueTypeSig(Def);
            }
            else
            {
                tySig = new ClassSig(Def);
            }

            TypeSig thisSig = tySig;

            if (HasGenArgs)
            {
                thisSig = new GenericInstSig(tySig, GenArgs);
            }
            if (IsValueType)
            {
                thisSig = new ByRefSig(thisSig);
            }
            return(thisSig);
        }
Example #2
0
        internal TypeSig CreateTypeSig(IList <TSpec> tspecs, TypeSig currentSig)
        {
            foreach (var tspec in tspecs)
            {
                switch (tspec.etype)
                {
                case ElementType.SZArray:
                    currentSig = new SZArraySig(currentSig);
                    break;

                case ElementType.Array:
                    var arraySpec = (ArraySpec)tspec;
                    currentSig = new ArraySig(currentSig, arraySpec.rank, arraySpec.sizes, arraySpec.lowerBounds);
                    break;

                case ElementType.GenericInst:
                    var ginstSpec = (GenericInstSpec)tspec;
                    currentSig = new GenericInstSig(currentSig as ClassOrValueTypeSig, ginstSpec.args);
                    break;

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

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

                default:
                    Verify(false, "Unknown TSpec");
                    break;
                }
            }
            return(currentSig);
        }
Example #3
0
        public TypeSig GetThisTypeSig()
        {
            TypeSig thisSig = GetTypeSig();

            if (IsValueType)
            {
                thisSig = new ByRefSig(thisSig);
            }
            return(thisSig);
        }
Example #4
0
        /// <summary>
        /// Tries to relocate the <see cref="ByRefSig"/>.
        /// </summary>
        /// <param name="byRefSig">The by reference sig.</param>
        /// <returns></returns>
        protected virtual TypeSig TryRelocateByRef(ByRefSig byRefSig)
        {
            var innerTypeSig = TryRelocateTypeSig(byRefSig.Next);

            if (innerTypeSig == null)
            {
                return(null);
            }

            return(new ByRefSig(innerTypeSig));
        }
Example #5
0
        internal static TypeSig CopyModifiers(TypeSig from, TypeSig to)
        {
            if (from is NonLeafSig current)
            {
                // There are additional signatures. Store all of the in a stack and process them one by one.
                var sigStack = new Stack <NonLeafSig>();
                while (current != null)
                {
                    sigStack.Push(current);
                    current = current.Next as NonLeafSig;
                }

                // Now process the entries on the stack one by one.
                while (sigStack.Any())
                {
                    current = sigStack.Pop();
                    if (current is SZArraySig arraySig)
                    {
                        to = new ArraySig(to, arraySig.Rank, arraySig.GetSizes(), arraySig.GetLowerBounds());
                    }
                    else if (current is ByRefSig)
                    {
                        to = new ByRefSig(to);
                    }
                    else if (current is CModReqdSig cModReqdSig)
                    {
                        to = new CModReqdSig(cModReqdSig.Modifier, to);
                    }
                    else if (current is CModOptSig cModOptSig)
                    {
                        to = new CModOptSig(cModOptSig.Modifier, to);
                    }
                    else if (current is PtrSig)
                    {
                        to = new PtrSig(to);
                    }
                    else if (current is PinnedSig)
                    {
                        to = new PinnedSig(to);
                    }
                    else
                    {
                        Debug.Fail("Unexpected leaf signature: " + current.GetType().FullName);
                    }
                }
            }

            return(to);
        }
Example #6
0
        /// <summary>
        /// Apply ByRef or Ptr "modifiers" to a TypeSig depending on the given modifiers
        /// stack.
        /// </summary>
        /// <param name="typeSig">TypeSig</param>
        /// <param name="modifiers">Modifiers stack</param>
        /// <returns>TypeSig</returns>
        TypeSig FixTypeAsRefOrPointer(TypeSig typeSig, Stack <String> modifiers)
        {
            while (modifiers.Count > 0 &&
                   (modifiers.Peek().Equals("*") || modifiers.Peek().Equals("&")))
            {
                if (modifiers.Pop().Equals("*"))                // Pointer
                {
                    typeSig = new PtrSig(typeSig);
                }
                else                 // ByRef
                {
                    typeSig = new ByRefSig(typeSig);
                }
            }

            return(typeSig);
        }
Example #7
0
        /// <summary>
        /// Apply a series of modifiers ("[]", "*", "&") to a base TypeSig.
        /// </summary>
        /// <param name="baseSig">Base TypeSig</param>
        /// <param name="modifiers">Modifier strings</param>
        /// <returns>TypeSig</returns>
        public static TypeSig FromBaseSig(TypeSig baseSig, Stack <String> modifiers)
        {
            String mod;

            while (modifiers.Count > 0)
            {
                mod = modifiers.Pop();
                switch (mod)
                {
                case "[]": baseSig = new SZArraySig(baseSig); break;

                case "*": baseSig = new PtrSig(baseSig); break;

                case "&": baseSig = new ByRefSig(baseSig); break;

                default:
                    throw new Exception(String.Format("Unknown modifier: {0}", mod));
                }
            }
            return(baseSig);
        }
        TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

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

            TypeSig result;

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

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

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

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

            case ElementType.SZArray: result = new SZArraySig(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, ResolveGenericArgs(typeSig.Next)); break;

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

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

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

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

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

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

            default:
                result = typeSig;
                break;
            }

            recursionCounter.Decrement();

            return(result);
        }
Example #9
0
 void AddByRefSig() => TypeSig = new ByRefSig(TypeSig);
        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);
        }
Example #11
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num, i;
            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.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num, gpContext.Type);
                break;

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

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

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

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

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.TryReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank > MaxArrayRank)
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                if (num > MaxArrayRank)
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (i = 0; i < num; i++)
                {
                    if (!reader.TryReadCompressedUInt32(out uint size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                if (num > MaxArrayRank)
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (i = 0; i < num; i++)
                {
                    if (!reader.TryReadCompressedInt32(out int 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);
        }
Example #12
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            ArraySigBase arrayType = type as ArraySigBase;

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append('[');
                var lowerBounds = arrayType.GetLowerBounds();
                var sizes       = arrayType.GetSizes();
                for (int i = 0; i < arrayType.Rank; i++)
                {
                    if (i > 0)
                    {
                        b.Append(',');
                    }
                    if (i < lowerBounds.Count && i < sizes.Count)
                    {
                        b.Append(lowerBounds[i]);
                        b.Append(':');
                        b.Append(sizes[i] + lowerBounds[i] - 1);
                    }
                }
                b.Append(']');
                return;
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
                return;
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
                return;
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef = type.ToTypeDefOrRef();
                if (typeRef.DeclaringType != null)
                {
                    AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
        // Token: 0x06000231 RID: 561 RVA: 0x0001F4AC File Offset: 0x0001D6AC
        private TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!this.recursionCounter.Increment())
            {
                return(null);
            }
            if (this.ReplaceGenericArg(ref typeSig))
            {
                this.recursionCounter.Decrement();
                return(typeSig);
            }
            ElementType elementType = typeSig.ElementType;
            TypeSig     result;

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

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

            case ElementType.ValueType:
            case ElementType.Class:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.R:
            case ElementType.Object:
                break;

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

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

            case ElementType.GenericInst:
            {
                GenericInstSig gis     = (GenericInstSig)typeSig;
                List <TypeSig> 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);
                goto IL_265;
            }

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

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

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

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

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

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

            default:
                if (elementType == ElementType.Module)
                {
                    result = new ModuleSig((typeSig as ModuleSig).Index, this.ResolveGenericArgs(typeSig.Next));
                    goto IL_265;
                }
                if (elementType == ElementType.Pinned)
                {
                    result = new PinnedSig(this.ResolveGenericArgs(typeSig.Next));
                    goto IL_265;
                }
                break;
            }
            result = typeSig;
IL_265:
            this.recursionCounter.Decrement();
            return(result);
        }
Example #14
0
        void IntroducePropertyAccessInstructions(ILExpression expr, ILExpression parentExpr, int posInParent)
        {
            if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt)
            {
                IMethod method   = (IMethod)expr.Operand;
                var     declType = method.DeclaringType as dnlib.DotNet.TypeSpec;
                if (declType != null && (declType.TypeSig is ArraySig || declType.TypeSig is SZArraySig))
                {
                    switch (method.Name)
                    {
                    case "Get":
                        expr.Code = ILCode.CallGetter;
                        break;

                    case "Set":
                        expr.Code = ILCode.CallSetter;
                        break;

                    case "Address":
                        ByRefSig brt = method.MethodSig.RetType as ByRefSig;
                        if (brt != null)
                        {
                            IMethod getMethod = new MemberRefUser(method.Module, "Get", method.MethodSig.Clone());
                            getMethod.MethodSig.RetType = declType.TypeSig;
                            expr.Operand = getMethod;
                        }
                        expr.Code = ILCode.CallGetter;
                        if (parentExpr != null)
                        {
                            parentExpr.Arguments[posInParent] = new ILExpression(ILCode.AddressOf, null, expr);
                        }
                        break;
                    }
                }
                else
                {
                    MethodDef methodDef = method.Resolve();
                    if (methodDef != null)
                    {
                        if (methodDef.IsGetter())
                        {
                            expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter;
                        }
                        else if (methodDef.IsSetter())
                        {
                            expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter;
                        }
                    }
                }
            }
            else if (expr.Code == ILCode.Newobj && expr.Arguments.Count == 2)
            {
                // Might be 'newobj(SomeDelegate, target, ldvirtftn(F, target))'.
                ILVariable target;
                if (expr.Arguments[0].Match(ILCode.Ldloc, out target) &&
                    expr.Arguments[1].Code == ILCode.Ldvirtftn &&
                    expr.Arguments[1].Arguments.Count == 1 &&
                    expr.Arguments[1].Arguments[0].MatchLdloc(target))
                {
                    // Remove the 'target' argument from the ldvirtftn instruction.
                    // It's not needed in the translation to C#, and needs to be eliminated so that the target expression
                    // can be inlined.
                    expr.Arguments[1].Arguments.Clear();
                }
            }
        }
Example #15
0
 void AddByRefSig()
 {
     TypeSig = new ByRefSig(TypeSig);
 }
Example #16
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            ArraySigBase arrayType = type as ArraySigBase;

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append('[');
                var lowerBounds = arrayType.GetLowerBounds();
                var sizes       = arrayType.GetSizes();
                for (int i = 0; i < arrayType.Rank; i++)
                {
                    if (i > 0)
                    {
                        b.Append(',');
                    }
                    if (i < lowerBounds.Count && i < sizes.Count)
                    {
                        b.Append(lowerBounds[i]);
                        b.Append(':');
                        b.Append(sizes[i] + lowerBounds[i] - 1);
                    }
                }
                b.Append(']');
                return;
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
                return;
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
                return;
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef = type.ToTypeDefOrRef();
                if (typeRef.DeclaringType != null)
                {
                    AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    FullNameCreator.FullNameSB(type, false, null, null, null, b);
                }
            }
        }
Example #17
0
        bool ReadCore(out TypeSig type, out object value)
        {
            if (!recursionCounter.Increment())
            {
                type  = null;
                value = null;
                return(false);
            }

            bool          res;
            ITypeDefOrRef tdr;
            UTF8String    ns, name;
            var           et = (ElementType)reader.ReadByte();

            switch (et)
            {
            case ElementType.Boolean:
                type  = module.CorLibTypes.Boolean;
                value = reader.ReadBoolean();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.Char:
                type  = module.CorLibTypes.Char;
                value = reader.ReadChar();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I1:
                type  = module.CorLibTypes.SByte;
                value = reader.ReadSByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U1:
                type  = module.CorLibTypes.Byte;
                value = reader.ReadByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I2:
                type  = module.CorLibTypes.Int16;
                value = reader.ReadInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U2:
                type  = module.CorLibTypes.UInt16;
                value = reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I4:
                type  = module.CorLibTypes.Int32;
                value = reader.ReadInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U4:
                type  = module.CorLibTypes.UInt32;
                value = reader.ReadUInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I8:
                type  = module.CorLibTypes.Int64;
                value = reader.ReadInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U8:
                type  = module.CorLibTypes.UInt64;
                value = reader.ReadUInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.R4:
                type  = module.CorLibTypes.Single;
                value = reader.ReadSingle();
                res   = true;
                break;

            case ElementType.R8:
                type  = module.CorLibTypes.Double;
                value = reader.ReadDouble();
                res   = true;
                break;

            case ElementType.String:
                type  = module.CorLibTypes.String;
                value = ReadString();
                res   = true;
                break;

            case ElementType.Ptr:
                res = ReadCatch(out type, out value);
                if (res)
                {
                    type = new PtrSig(type);
                }
                break;

            case ElementType.ByRef:
                res = ReadCatch(out type, out value);
                if (res)
                {
                    type = new ByRefSig(type);
                }
                break;

            case ElementType.Object:
                type  = module.CorLibTypes.Object;
                value = null;
                res   = true;
                break;

            case ElementType.ValueType:
                tdr   = ReadTypeDefOrRef();
                type  = tdr.ToTypeSig();
                value = null;
                if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib())
                {
                    if (name == stringDecimal)
                    {
                        if (reader.Length - reader.Position != 13)
                        {
                            goto default;
                        }
                        try {
                            byte b = reader.ReadByte();
                            value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F));
                        }
                        catch {
                            goto default;
                        }
                    }
                    else if (name == stringDateTime)
                    {
                        if (reader.Length - reader.Position != 8)
                        {
                            goto default;
                        }
                        try {
                            value = new DateTime(reader.ReadInt64());
                        }
                        catch {
                            goto default;
                        }
                    }
                }
                if (value == null && reader.Position != reader.Length)
                {
                    value = reader.ReadRemainingBytes();
                }
                res = true;
                break;

            case ElementType.Class:
                type  = new ClassSig(ReadTypeDefOrRef());
                value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes();
                res   = true;
                break;

            case ElementType.CModReqd:
                tdr = ReadTypeDefOrRef();
                res = ReadCatch(out type, out value);
                if (res)
                {
                    type = new CModReqdSig(tdr, type);
                }
                break;

            case ElementType.CModOpt:
                tdr = ReadTypeDefOrRef();
                res = ReadCatch(out type, out value);
                if (res)
                {
                    type = new CModOptSig(tdr, type);
                }
                break;

            case ElementType.Var:
            case ElementType.Array:
            case ElementType.GenericInst:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.FnPtr:
            case ElementType.SZArray:
            case ElementType.MVar:
            case ElementType.End:
            case ElementType.Void:
            case ElementType.ValueArray:
            case ElementType.R:
            case ElementType.Internal:
            case ElementType.Module:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            default:
                Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString());
                res   = false;
                type  = null;
                value = null;
                break;
            }

            recursionCounter.Decrement();
            return(res);
        }
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            SZArraySig arrayType = type as SZArraySig;              // TODO: multi-dimensional array

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append("[]");
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef  = type.ToTypeDefOrRef();
                var declType = Decompiler.DnlibExtensions.GetDeclaringType(typeRef);
                if (declType != null)
                {
                    AppendTypeName(b, declType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }