Пример #1
0
        protected override Instruction GetFirstInstruction(IList <Instruction> instrs, ref int index)
        {
            var instr = GetFirstInstruction(instrs, index);

            if (instr != null)
            {
                index = instrs.IndexOf(instr);
            }
            return(DotNetUtils.GetInstruction(instrs, ref index));
        }
 protected override Instruction OnAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex)
 {
     if (instr.OpCode.Code != Code.Box)
     {
         return(instr);
     }
     if (methodToInline.MethodSig.GetGenParamCount() == 0)
     {
         return(instr);
     }
     return(DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex));
 }
Пример #3
0
        static IField GetFieldRef(MethodDef method)
        {
            if (method == null || method.Body == null)
            {
                return(null);
            }
            var instructions = method.Body.Instructions;
            int index        = 0;
            var ldarg0       = DotNetUtils.GetInstruction(instructions, ref index);

            if (ldarg0 == null || ldarg0.GetParameterIndex() != 0)
            {
                return(null);
            }
            var ldfld = DotNetUtils.GetInstruction(instructions, ref index);

            if (ldfld == null || ldfld.OpCode.Code != Code.Ldfld)
            {
                return(null);
            }
            var ret = DotNetUtils.GetInstruction(instructions, ref index);

            if (ret == null)
            {
                return(null);
            }
            if (ret.IsStloc())
            {
                var local = ret.GetLocal(method.Body.Variables);
                ret = DotNetUtils.GetInstruction(instructions, ref index);
                if (ret == null || !ret.IsLdloc())
                {
                    return(null);
                }
                if (ret.GetLocal(method.Body.Variables) != local)
                {
                    return(null);
                }
                ret = DotNetUtils.GetInstruction(instructions, ref index);
            }
            if (ret == null || ret.OpCode.Code != Code.Ret)
            {
                return(null);
            }
            return(ldfld.Operand as IField);
        }
Пример #4
0
        protected virtual bool IsReturn(MethodDef methodToInline, int instrIndex)
        {
            var instr = DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex);

            return(instr != null && instr.OpCode.Code == Code.Ret);
        }
Пример #5
0
        protected InstructionPatcher TryInlineOtherMethod(int patchIndex, MethodDef 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 (instr.GetParameterIndex() != loadIndex)
                {
                    return(null);
                }
                loadIndex++;
                instr = DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex);
                instr = OnAfterLoadArg(methodToInline, instr, ref instrIndex);
            }
            if (instr == null || loadIndex != methodArgsCount - popLastArgs)
            {
                return(null);
            }

            switch (instr.OpCode.Code)
            {
            case Code.Call:
            case Code.Callvirt:
                if (foundLdarga)
                {
                    return(null);
                }
                var callInstr    = instr;
                var calledMethod = callInstr.Operand as IMethod;
                if (calledMethod == null)
                {
                    return(null);
                }

                if (!IsCompatibleType(-1, calledMethod.MethodSig.RetType, methodToInline.MethodSig.RetType))
                {
                    return(null);
                }

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

                if (!HasAccessTo(instr.Operand))
                {
                    return(null);
                }

                return(new InstructionPatcher(patchIndex, instrIndex, callInstr));

            case Code.Newobj:
                if (foundLdarga)
                {
                    return(null);
                }
                var newobjInstr = instr;
                var ctor        = newobjInstr.Operand as IMethod;
                if (ctor == null)
                {
                    return(null);
                }

                if (!IsCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodSig.RetType))
                {
                    return(null);
                }

                var methodArgs       = methodToInline.Parameters;
                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].Type))
                    {
                        return(null);
                    }
                }

                if (!HasAccessTo(instr.Operand))
                {
                    return(null);
                }

                return(new InstructionPatcher(patchIndex, instrIndex, newobjInstr));

            case Code.Ldfld:
            case Code.Ldflda:
            case Code.Ldftn:
            case Code.Ldvirtftn:
            case Code.Ldlen:
            case Code.Initobj:
            case Code.Isinst:
            case Code.Castclass:
            case Code.Newarr:
            case Code.Ldtoken:
            case Code.Unbox_Any:
                var ldInstr = instr;
                if (methodArgsCount != 1)
                {
                    return(null);
                }

                if (instr.OpCode.OperandType != OperandType.InlineNone && !HasAccessTo(instr.Operand))
                {
                    return(null);
                }

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

            default:
                return(null);
            }
        }
Пример #6
0
 protected virtual Instruction GetFirstInstruction(IList <Instruction> instrs, ref int index)
 {
     return(DotNetUtils.GetInstruction(instrs, ref index));
 }