private Instruction AddInterceptCall(ILProcessor ilProcessor, MethodDefinition methDef, MethodDefinition interceptMethDef, CustomAttribute att, Instruction insertBefore) { var methRef = _assemblyDefinition.MainModule.ImportReference(interceptMethDef); ilProcessor.InsertBefore(insertBefore, ilProcessor.CreateLoadInstruction(methDef.Name)); int methodParamCount = methDef.Parameters.Count; int arrayVarNr = methDef.Body.Variables.Count; if (methodParamCount > 0) { ArrayType objArrType = new ArrayType(_assemblyDefinition.MainModule.TypeSystem.Object); methDef.Body.Variables.Add(new VariableDefinition(objArrType)); methDef.Body.InitLocals = true; ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldc_I4, methodParamCount)); ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Newarr, _assemblyDefinition.MainModule.TypeSystem.Object)); ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Stloc, arrayVarNr)); bool pointerToValueTypeVariable; TypeSpecification referencedTypeSpec = null; for (int i = 0; i < methodParamCount; i++) { var paramMetaData = methDef.Parameters[i].ParameterType.MetadataType; if (paramMetaData == MetadataType.UIntPtr || paramMetaData == MetadataType.FunctionPointer || paramMetaData == MetadataType.IntPtr || paramMetaData == MetadataType.Pointer) { break; } ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldloc, arrayVarNr)); ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldc_I4, i)); if (methDef.IsStatic) { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldarg, i)); } else { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldarg, i + 1)); } pointerToValueTypeVariable = false; TypeReference paramType = methDef.Parameters[i].ParameterType; if (paramType.IsByReference) { referencedTypeSpec = paramType as TypeSpecification; if (referencedTypeSpec != null) { switch (referencedTypeSpec.ElementType.MetadataType) { case MetadataType.Boolean: case MetadataType.SByte: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_I1)); pointerToValueTypeVariable = true; break; case MetadataType.Int16: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_I2)); pointerToValueTypeVariable = true; break; case MetadataType.Int32: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_I4)); pointerToValueTypeVariable = true; break; case MetadataType.Int64: case MetadataType.UInt64: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_I8)); pointerToValueTypeVariable = true; break; case MetadataType.Byte: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_U1)); pointerToValueTypeVariable = true; break; case MetadataType.UInt16: case MetadataType.Char: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_U2)); pointerToValueTypeVariable = true; break; case MetadataType.UInt32: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_U4)); pointerToValueTypeVariable = true; break; case MetadataType.Single: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_R4)); pointerToValueTypeVariable = true; break; case MetadataType.Double: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_R8)); pointerToValueTypeVariable = true; break; case MetadataType.IntPtr: case MetadataType.UIntPtr: ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_I)); pointerToValueTypeVariable = true; break; default: if (referencedTypeSpec.ElementType.IsValueType) { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldobj, referencedTypeSpec.ElementType)); pointerToValueTypeVariable = true; } else { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldind_Ref)); pointerToValueTypeVariable = false; } break; } } else { } } if (paramType.IsValueType || pointerToValueTypeVariable) { if (pointerToValueTypeVariable) { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Box, referencedTypeSpec.ElementType)); } else { ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Box, paramType)); } } ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Stelem_Ref)); } ilProcessor.InsertBefore(insertBefore, ilProcessor.Create(OpCodes.Ldloc, arrayVarNr)); } var ins = ilProcessor.Create(OpCodes.Callvirt, methDef.Module.ImportReference(interceptMethDef)); ilProcessor.InsertBefore(insertBefore, ins); return(ins); }