Ejemplo n.º 1
0
        static bool isCallMethod(MethodDef method)
        {
            int loadIndex       = 0;
            int methodArgsCount = DotNetUtils.getArgsCount(method);
            var instrs          = method.Body.Instructions;
            int i = 0;

            for (; i < instrs.Count && i < methodArgsCount; i++)
            {
                var instr = instrs[i];
                switch (instr.OpCode.Code)
                {
                case Code.Ldarg:
                case Code.Ldarg_S:
                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                case Code.Ldarga:
                case Code.Ldarga_S:
                    if (instr.GetParameterIndex() != loadIndex)
                    {
                        return(false);
                    }
                    loadIndex++;
                    continue;
                }
                break;
            }
            if (loadIndex != methodArgsCount)
            {
                return(false);
            }
            if (i + 1 >= instrs.Count)
            {
                return(false);
            }

            switch (instrs[i].OpCode.Code)
            {
            case Code.Call:
            case Code.Callvirt:
            case Code.Newobj:
            case Code.Ldfld:
            case Code.Ldflda:
            case Code.Ldftn:
            case Code.Ldvirtftn:
                break;

            default:
                return(false);
            }
            if (instrs[i + 1].OpCode.Code != Code.Ret)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex)
        {
            if (!isReturn(methodToInline, instrIndex))
            {
                return(false);
            }

            int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);

            for (int i = 0; i < methodArgsCount; i++)
            {
                block.insert(patchIndex++, Instruction.Create(OpCodes.Pop));
            }

            block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr));
            return(true);
        }
Ejemplo n.º 3
0
        protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex)
        {
            var instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);

            if (instr == null || instr.OpCode.Code != Code.Ret)
            {
                return(false);
            }

            int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);

            for (int i = 0; i < methodArgsCount; i++)
            {
                block.insert(patchIndex++, Instruction.Create(OpCodes.Pop));
            }

            block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr));
            return(true);
        }
Ejemplo n.º 4
0
 public UpdatedMethod(MethodDefinition method)
 {
     token       = method.MetadataToken.ToInt32();
     newArgTypes = new TypeReference[DotNetUtils.getArgsCount(method)];
 }
Ejemplo n.º 5
0
        protected InstructionPatcher tryInlineOtherMethod(int patchIndex, MethodDefinition methodToInline, Instruction instr, int instrIndex, int popLastArgs)
        {
            int  loadIndex       = 0;
            int  methodArgsCount = DotNetUtils.getArgsCount(methodToInline);
            bool foundLdarga     = false;

            while (instr != null && loadIndex < methodArgsCount)
            {
                bool isLdarg = true;
                switch (instr.OpCode.Code)
                {
                case Code.Ldarg:
                case Code.Ldarg_S:
                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                    break;

                case Code.Ldarga:
                case Code.Ldarga_S:
                    foundLdarga = true;
                    break;

                default:
                    isLdarg = false;
                    break;
                }
                if (!isLdarg)
                {
                    break;
                }

                if (DotNetUtils.getArgIndex(instr) != loadIndex)
                {
                    return(null);
                }
                loadIndex++;
                instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
            }
            if (instr == null || loadIndex != methodArgsCount - popLastArgs)
            {
                return(null);
            }

            if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt)
            {
                if (foundLdarga)
                {
                    return(null);
                }
                var callInstr    = instr;
                var calledMethod = callInstr.Operand as MethodReference;
                if (calledMethod == null)
                {
                    return(null);
                }

                if (!isCompatibleType(-1, calledMethod.MethodReturnType.ReturnType, methodToInline.MethodReturnType.ReturnType))
                {
                    return(null);
                }

                if (!checkSameMethods(calledMethod, methodToInline, popLastArgs))
                {
                    return(null);
                }

                return(new InstructionPatcher(patchIndex, instrIndex, callInstr));
            }
            else if (instr.OpCode.Code == Code.Newobj)
            {
                if (foundLdarga)
                {
                    return(null);
                }
                var newobjInstr = instr;
                var ctor        = newobjInstr.Operand as MethodReference;
                if (ctor == null)
                {
                    return(null);
                }

                if (!isCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodReturnType.ReturnType))
                {
                    return(null);
                }

                var methodArgs       = DotNetUtils.getArgs(methodToInline);
                var calledMethodArgs = DotNetUtils.getArgs(ctor);
                if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count)
                {
                    return(null);
                }
                for (int i = 1; i < calledMethodArgs.Count; i++)
                {
                    if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1]))
                    {
                        return(null);
                    }
                }

                return(new InstructionPatcher(patchIndex, instrIndex, newobjInstr));
            }
            else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldflda ||
                     instr.OpCode.Code == Code.Ldftn || instr.OpCode.Code == Code.Ldvirtftn)
            {
                var ldInstr = instr;
                if (methodArgsCount != 1)
                {
                    return(null);
                }

                return(new InstructionPatcher(patchIndex, instrIndex, ldInstr));
            }

            return(null);
        }
Ejemplo n.º 6
0
 public UpdatedMethod(MethodDef method)
 {
     token       = method.MDToken.ToInt32();
     newArgTypes = new TypeSig[DotNetUtils.getArgsCount(method)];
 }