示例#1
0
 public TypeSig Replace(GenericVar genVarSig)
 {
     if (genVarSig.OwnerType == OwnerType)
     {
         return(TypeGenArgs[(int)genVarSig.Number]);
     }
     return(null);
 }
示例#2
0
 public TypeSig Replace(GenericVar genVar)
 {
     if (TypeEqualityComparer.Instance.Equals(genVar.OwnerType, OwnerType))
     {
         return(TypeGenArgs[(int)genVar.Number]);
     }
     return(genVar);
 }
示例#3
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            Instruction instruction = ctx.Body.Instructions[instrIndex];
            IMethod     operand     = (IMethod)instruction.Operand;

            if (!operand.DeclaringType.ResolveTypeDefThrow().IsValueType&& (operand.ResolveThrow().IsPublic || operand.ResolveThrow().IsAssembly))
            {
                MethodDef def;
                Tuple <Code, TypeDef, IMethod> key = Tuple.Create <Code, TypeDef, IMethod>(instruction.OpCode.Code, ctx.Method.DeclaringType, operand);
                if (!this.proxies.TryGetValue(key, out def))
                {
                    MethodSig methodSig = RPMode.CreateProxySignature(ctx, operand, instruction.OpCode.Code == Code.Newobj);
                    def = new MethodDefUser(NameService.RandomNameStatic(), methodSig)
                    {
                        Attributes     = MethodAttributes.CompilerControlled | MethodAttributes.Static,
                        ImplAttributes = MethodImplAttributes.IL
                    };
                    ctx.Method.DeclaringType.Methods.Add(def);
                    if ((instruction.OpCode.Code == Code.Call) && operand.ResolveThrow().IsVirtual)
                    {
                        def.IsStatic      = false;
                        methodSig.HasThis = true;
                        methodSig.Params.RemoveAt(0);
                    }
                    ctx.Marker.Mark(def, ctx.Protection);

                    /*ctx.Name.Analyze(def);
                     * ctx.Name.SetCanRename(def, false);*/
                    def.Body = new CilBody();
                    for (int i = 0; i < def.Parameters.Count; i++)
                    {
                        def.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, def.Parameters[i]));
                    }
                    def.Body.Instructions.Add(Instruction.Create(instruction.OpCode, operand));
                    def.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                    this.proxies[key] = def;
                }
                instruction.OpCode = OpCodes.Call;
                if (ctx.Method.DeclaringType.HasGenericParameters)
                {
                    GenericVar[] genArgs = new GenericVar[ctx.Method.DeclaringType.GenericParameters.Count];
                    for (int j = 0; j < genArgs.Length; j++)
                    {
                        genArgs[j] = new GenericVar(j);
                    }
                    instruction.Operand = new MemberRefUser(ctx.Module, def.Name, def.MethodSig, new GenericInstSig((ClassOrValueTypeSig)ctx.Method.DeclaringType.ToTypeSig(), genArgs).ToTypeDefOrRef());
                }
                else
                {
                    instruction.Operand = def;
                }
            }
        }
        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);
        }
示例#5
0
 void AddGenericVar() => TypeSig = new GenericVar(GenericVariableNumber.Value, options.OwnerType);
示例#6
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);
        }
示例#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();
            }
        }
        // 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);
        }
示例#9
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            var invoke = ctx.Body.Instructions[instrIndex];
            var target = (IMethod)invoke.Operand;

            // Value type proxy is not supported in mild mode.
            if (target.DeclaringType.ResolveTypeDefThrow().IsValueType)
            {
                return;
            }
            // Skipping visibility is not supported in mild mode.
            if (!target.ResolveThrow().IsPublic&& !target.ResolveThrow().IsAssembly)
            {
                return;
            }

            var key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);

            if (!proxies.TryGetValue(key, out var proxy))
            {
                var sig = CreateProxySignature(ctx, target, invoke.OpCode.Code == Code.Newobj);

                proxy = new MethodDefUser(ctx.Name.RandomName(), sig)
                {
                    Attributes     = MethodAttributes.PrivateScope | MethodAttributes.Static,
                    ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL
                };
                ctx.Method.DeclaringType.Methods.Add(proxy);

                // Fix peverify --- Non-virtual call to virtual methods must be done on this pointer
                if (invoke.OpCode.Code == Code.Call && target.ResolveThrow().IsVirtual)
                {
                    proxy.IsStatic = false;
                    sig.HasThis    = true;
                    sig.Params.RemoveAt(0);
                }

                ctx.Marker.Mark(proxy, ctx.Protection);
                ctx.Name.Analyze(proxy);
                ctx.Name.SetCanRename(proxy, false);

                proxy.Body = new CilBody();
                for (var i = 0; i < proxy.Parameters.Count; i++)
                {
                    proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, proxy.Parameters[i]));
                }

                proxy.Body.Instructions.Add(Instruction.Create(invoke.OpCode, target));
                proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

                proxies[key] = proxy;
            }

            invoke.OpCode = OpCodes.Call;
            if (ctx.Method.DeclaringType.HasGenericParameters)
            {
                var genArgs = new GenericVar[ctx.Method.DeclaringType.GenericParameters.Count];
                for (var i = 0; i < genArgs.Length; i++)
                {
                    genArgs[i] = new GenericVar(i);
                }

                invoke.Operand = new MemberRefUser(
                    ctx.Module,
                    proxy.Name,
                    proxy.MethodSig,
                    new GenericInstSig((ClassOrValueTypeSig)ctx.Method.DeclaringType.ToTypeSig(), genArgs).ToTypeDefOrRef());
            }
            else
            {
                invoke.Operand = proxy;
            }

            var targetDef = target.ResolveMethodDef();

            if (targetDef != null)
            {
                ctx.Context.Annotations.Set(targetDef, ReferenceProxyProtection.Targeted, ReferenceProxyProtection.Targeted);
            }
        }
示例#10
0
        public TypeSig Duplicate(TypeSig typeSig)
        {
            if (!IsDuplicateNeeded(typeSig))
            {
                return(typeSig);
            }

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

            case ElementType.Ptr:
                return(new PtrSig(Duplicate(typeSig.Next)));

            case ElementType.ByRef:
                return(new ByRefSig(Duplicate(typeSig.Next)));

            case ElementType.SZArray:
                return(new SZArraySig(Duplicate(typeSig.Next)));

            case ElementType.Pinned:
                return(new PinnedSig(Duplicate(typeSig.Next)));

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

            case ElementType.Var:
            {
                GenericVar genVar = (GenericVar)typeSig;
                TypeSig    result = GenReplacer.Replace(genVar);
                if (result != null)
                {
                    return(result);
                }
                return(new GenericVar(genVar.Number, genVar.OwnerType));
            }

            case ElementType.MVar:
            {
                GenericMVar genMVar = (GenericMVar)typeSig;
                TypeSig     result  = GenReplacer.Replace(genMVar);
                if (result != null)
                {
                    return(result);
                }
                return(new GenericMVar(genMVar.Number, genMVar.OwnerMethod));
            }

            case ElementType.GenericInst:
            {
                GenericInstSig genSig = (GenericInstSig)typeSig;
                return(new GenericInstSig(genSig.GenericType, Duplicate(genSig.GenericArguments)));
            }

            case ElementType.CModReqd:
            {
                CModReqdSig modreq = (CModReqdSig)typeSig;
                return(new CModReqdSig(modreq.Modifier, Duplicate(modreq.Next)));
            }

            case ElementType.CModOpt:
            {
                CModOptSig modopt = (CModOptSig)typeSig;
                return(new CModOptSig(modopt.Modifier, Duplicate(modopt.Next)));
            }

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

                throw new ArgumentOutOfRangeException("Duplicate TypeSig " + typeSig.GetType().Name);
            }
        }
示例#11
0
        /// <summary>
        /// Create a list of all possible combinations of types/generic types that would make
        /// sense as parameters. This is necessary because the serialized method data does not
        /// contain information about which parameters map to which generic types (indices),
        /// neither GenericVars (declaring type) or GenericMVars (method itself).
        ///
        /// TODO: Factor in context generics (generics from virtualized method itself and
        /// declaring type?)
        /// </summary>
        /// <param name="parameters">Parameters (with no generic type information)</param>
        /// <param name="generics">Generics visible to the method</param>
        /// <returns>Combinations with at least one item (original parameters)</returns>
        public static IList <IList <TypeSig> > CreateGenericParameterCombinations_(IList <TypeSig> parameters,
                                                                                   IList <TypeSig> typeGenerics, IList <TypeSig> methodGenerics)
        {
            IList <IList <TypeSig> > list = new List <IList <TypeSig> >();

            list.Add(parameters);

            for (UInt16 p = 0; p < parameters.Count; p++)
            {
                TypeSig         paramtype = parameters[p];
                IList <TypeSig> ptypes    = new TypeSig[] { paramtype };

                // Might be something like: DoSomething(IList<!0> someList)
                if (paramtype.IsGenericInstanceType)
                {
                    ptypes = PossibleTypeSigs(paramtype, typeGenerics, methodGenerics);
                }

                for (UInt16 g = 0; g < typeGenerics.Count; g++)
                {
                    var gtype = typeGenerics[g];

                    foreach (var ptype in ptypes)
                    {
                        // Better comparison?
                        //if (ptype.FullName.Equals(gtype.FullName))
                        //{
                        Int32 length = list.Count;
                        for (Int32 i = 0; i < length; i++)
                        {
                            // Copy param list
                            List <TypeSig> newParams = new List <TypeSig>();
                            newParams.AddRange(list[i]);

                            GenericVar gvar = new GenericVar(g);
                            newParams[p] = gvar;

                            list.Add(newParams);
                        }
                        //}
                    }
                }

                for (UInt16 g = 0; g < methodGenerics.Count; g++)
                {
                    var gtype = methodGenerics[g];

                    foreach (var ptype in ptypes)
                    {
                        //if (ptype.FullName.Equals(gtype.FullName))
                        //{
                        Int32 length = list.Count;
                        for (Int32 i = 0; i < length; i++)
                        {
                            List <TypeSig> newParams = new List <TypeSig>();
                            newParams.AddRange(list[i]);

                            GenericMVar gmvar = new GenericMVar(g);
                            newParams[p] = gmvar;

                            list.Add(newParams);
                        }
                        //}
                    }
                }
            }

            return(list);
        }