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)); }
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); }
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); }
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); } }
protected virtual Instruction GetFirstInstruction(IList <Instruction> instrs, ref int index) { return(DotNetUtils.GetInstruction(instrs, ref index)); }