/// <summary> /// Initializes a new instance of the <see cref="MethodBodyRewriterParameters"/> class. /// </summary> /// <param name="IL">The CilWorker that is responsible for the current method body.</param> /// <param name="oldInstructions">The value indicating the list of old instructions in the current method body.</param> /// <param name="interceptionDisabled">The value that determines whether or not interception is disabled.</param> /// <param name="invocationInfo">The local variable that will store the <see cref="IInvocationInfo"/> instance.</param> /// <param name="returnValue">The value indicating the local variable that will store the return value.</param> /// <param name="methodReplacementProvider">The <see cref="IMethodReplacementProvider"/> instance.</param> /// <param name="aroundInvokeProvider">The <see cref="IAroundInvokeProvider"/> instance.</param> /// <param name="classMethodReplacementProvider">The class-level<see cref="IMethodReplacementProvider"/> instance.</param> /// <param name="getMethodReplacementProviderMethod">The functor that resolves the GetMethodReplacementProvider method.</param> /// <param name="registryType">The interception registry type that will be responsible for handling class-level interception events.</param> public MethodBodyRewriterParameters(CilWorker IL, IEnumerable <Instruction> oldInstructions, VariableDefinition interceptionDisabled, VariableDefinition invocationInfo, VariableDefinition returnValue, VariableDefinition methodReplacementProvider, VariableDefinition aroundInvokeProvider, VariableDefinition classMethodReplacementProvider, Func <ModuleDefinition, MethodReference> getMethodReplacementProviderMethod, Type registryType) { if (methodReplacementProvider.VariableType.FullName != typeof(IMethodReplacementProvider).FullName) { throw new ArgumentException("methodReplacementProvider"); } if (aroundInvokeProvider.VariableType.FullName != typeof(IAroundInvokeProvider).FullName) { throw new ArgumentException("aroundInvokeProvider"); } _cilWorker = IL; _oldInstructions = oldInstructions; _interceptionDisabled = interceptionDisabled; _invocationInfo = invocationInfo; _returnValue = returnValue; _methodReplacementProvider = methodReplacementProvider; _aroundInvokeProvider = aroundInvokeProvider; _classMethodReplacementProvider = classMethodReplacementProvider; _getMethodReplacementProviderMethod = getMethodReplacementProviderMethod; _registryType = registryType; }
/// <summary> /// Emits the IL instructions to obtain an <see cref="IInterceptor"/> instance for the proxy type. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> responsible for emitting the method body.</param> /// <param name="proxyType">The proxy type.</param> /// <param name="getInterceptorMethod">The getter method for the interceptor.</param> protected virtual void EmitGetInterceptorInstruction(CilWorker IL, TypeReference proxyType, MethodReference getInterceptorMethod) { IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Isinst, proxyType); IL.Emit(OpCodes.Callvirt, getInterceptorMethod); }
public void Emit(CilWorker IL) { var module = IL.GetModule(); var modifiableType = module.ImportType <IModifiableType>(); var getInterceptionDisabledMethod = module.ImportMethod <IModifiableType>("get_IsInterceptionDisabled"); if (!_hostMethod.HasThis) { IL.Emit(OpCodes.Ldc_I4_0); IL.Emit(OpCodes.Stloc, _interceptionDisabled); return; } var skipLabel = IL.Create(OpCodes.Nop); // var interceptionDisabled = this.IsInterceptionDisabled; IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Isinst, modifiableType); IL.Emit(OpCodes.Brfalse, skipLabel); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Isinst, modifiableType); IL.Emit(OpCodes.Callvirt, getInterceptionDisabledMethod); IL.Emit(OpCodes.Stloc, _interceptionDisabled); IL.Append(skipLabel); }
/// <summary> /// Rewrites a target method using the given CilWorker. /// </summary> /// <param name="method">The target method.</param> /// <param name="IL">The CilWorker that will be used to rewrite the target method.</param> /// <param name="oldInstructions">The original instructions from the target method body.</param> public void Rewrite(MethodDefinition method, CilWorker IL, IEnumerable <Instruction> oldInstructions) { if (!ShouldRewrite(method)) { return; } var declaringType = method.DeclaringType; var body = IL.GetBody(); body.InitLocals = true; var module = declaringType.Module; // Interfaces and Enums cannot be modified if (declaringType.IsInterface || declaringType.IsEnum) { return; } ImportReferences(module); AddLocals(method); if (!_modifiedTypes.Contains(declaringType)) { AddAdditionalMembers(declaringType); _modifiedTypes.Add(declaringType); } RewriteMethodBody(method, IL, oldInstructions); }
private static TypeDefinition GetFactoryMapType(IAssembly assembly) { foreach (TypeDefinition type in assembly.Types) { if (type.FullName == FactoryMapTypeNamespace + '.' + FactoryMapTypeName) { assembly.Types.Remove(type); break; } } // Now we create the actual type and stuff... TypeReference objectType = assembly.Import(typeof(Object)); MethodReference objectCtor = assembly.Import(typeof(Object).GetConstructor(new Type[0])); TypeDefinition mapType = new TypeDefinition(FactoryMapTypeName, FactoryMapTypeNamespace, TypeAttributes.Public, objectType); mapType.Interfaces.Add(assembly.Import(typeof(IRuntimeFactoryInformation))); MethodDefinition defaultCtor = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, assembly.Import(typeof(void))); CilWorker worker = defaultCtor.Body.CilWorker; worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Call, objectCtor)); worker.Append(worker.Create(OpCodes.Ret)); mapType.Constructors.Add(defaultCtor); return(mapType); }
private void EmitInterceptorCall(CilWorker IL) { // var result = replacement.Intercept(info); IL.Emit(OpCodes.Ldloc, _replacement); IL.Emit(OpCodes.Ldloc, _invocationInfo); IL.Emit(OpCodes.Callvirt, _intercept); }
private static void GetMethodReplacementInstance(MethodDefinition method, CilWorker IL, VariableDefinition methodReplacement, VariableDefinition methodReplacementProvider, VariableDefinition invocationInfo) { var declaringType = method.DeclaringType; var module = declaringType.Module; var pushInstance = method.HasThis ? IL.Create(OpCodes.Ldarg_0) : IL.Create(OpCodes.Ldnull); var getReplacement = module.ImportMethod <IMethodReplacementProvider>("GetMethodReplacement"); IL.Emit(OpCodes.Ldloc, methodReplacementProvider); var skipGetMethodReplacement = IL.Create(OpCodes.Nop); IL.Emit(OpCodes.Brfalse, skipGetMethodReplacement); IL.Emit(OpCodes.Ldloc, methodReplacementProvider); IL.Append(pushInstance); IL.Emit(OpCodes.Ldloc, invocationInfo); IL.Emit(OpCodes.Callvirt, getReplacement); IL.Emit(OpCodes.Stloc, methodReplacement); IL.Append(skipGetMethodReplacement); }
private void AddOriginalInstructions(CilWorker IL, IEnumerable <Instruction> oldInstructions) { foreach (Instruction instruction in oldInstructions) { IL.Append(instruction); } }
/// <summary> /// Saves the current <see cref="IExceptionHandlerInfo"/> instance. /// </summary> /// <param name="targetMethod">The target method.</param> /// <param name="emitter">The <see cref="IEmitInvocationInfo"/> instance that will emit the current method context.</param> private void SaveExceptionInfo(MethodDefinition targetMethod, IEmitInvocationInfo emitter) { CilWorker IL = targetMethod.GetILGenerator(); ModuleDefinition module = IL.GetModule(); emitter.Emit(targetMethod, targetMethod, _invocationInfo); IL.Emit(OpCodes.Ldloc, _exception); IL.Emit(OpCodes.Ldloc, _invocationInfo); MethodReference exceptionInfoConstructor = module.ImportConstructor <ExceptionHandlerInfo>( typeof(Exception), typeof(IInvocationInfo)); IL.Emit(OpCodes.Newobj, exceptionInfoConstructor); IL.Emit(OpCodes.Stloc, _exceptionInfo); TypeReference returnType = targetMethod.ReturnType.ReturnType; if (returnType == _voidType || _returnValue == null) { return; } // exceptionInfo.ReturnValue = returnValue; MethodReference setReturnValue = module.ImportMethod <IExceptionHandlerInfo>("set_ReturnValue"); IL.Emit(OpCodes.Ldloc, _exceptionInfo); IL.Emit(OpCodes.Ldloc, _returnValue); IL.Emit(OpCodes.Callvirt, setReturnValue); }
private static void Emit(CilWorker IL, ModuleDefinition module, VariableDefinition surroundingImplementation, VariableDefinition invocationInfo, VariableDefinition returnValue) { var skipInvoke = IL.Create(OpCodes.Nop); var skipPrint = IL.Create(OpCodes.Nop); IL.Emit(OpCodes.Ldloc, surroundingImplementation); IL.Emit(OpCodes.Brtrue, skipPrint); IL.Append(skipPrint); IL.Emit(OpCodes.Ldloc, surroundingImplementation); IL.Emit(OpCodes.Brfalse, skipInvoke); var aroundInvoke = module.ImportMethod <IAfterInvoke>("AfterInvoke"); IL.Emit(OpCodes.Ldloc, surroundingImplementation); IL.Emit(OpCodes.Ldloc, invocationInfo); IL.Emit(OpCodes.Ldloc, returnValue); IL.Emit(OpCodes.Callvirt, aroundInvoke); IL.Append(skipInvoke); }
/// <summary> /// Rewrites a target method using the given CilWorker. /// </summary> /// <param name="method">The target method.</param> /// <param name="IL">The CilWorker that will be used to rewrite the target method.</param> /// <param name="oldInstructions">The original instructions from the target method body.</param> public void Rewrite(MethodDefinition method, CilWorker IL, IEnumerable <Instruction> oldInstructions) { var declaringType = method.DeclaringType; var module = declaringType.Module; // Interfaces and Enums cannot be modified if (declaringType.IsInterface || declaringType.IsEnum) { return; } ImportReferences(module); AddLocals(method); if (!_modifiedTypes.Contains(declaringType)) { AddAdditionalMembers(declaringType); _modifiedTypes.Add(declaringType); } var newInstructions = new Queue <Instruction>(); foreach (var instruction in oldInstructions) { // Intercept only the load field and the load static field instruction if (!ShouldReplace(instruction, method)) { IL.Append(instruction); continue; } Replace(instruction, method, IL); } }
public void AddEmptyMethod(MethodElement me) { // Console.WriteLine("\t" + me.Name); TypeReference returnType = _resolver.ForceResolve(me.ReturnType); MethodDefinition newMethod = new MethodDefinition(me.Name, MethodAttributes.Public, returnType); foreach (ParameterElement pe in me.Parameters) { TypeReference paramType = _resolver.ForceResolve(pe.Type); ParameterDefinition param = new ParameterDefinition(paramType); param.Name = pe.Name; // Console.WriteLine("\t\t" + param.Name + " :: " + param.ParameterType); newMethod.Parameters.Add(param); } Type exceptionType = typeof(NotImplementedException); MethodReference cons = _type.Module.Import(exceptionType.GetConstructor(new Type[] {})); CilWorker worker = newMethod.Body.CilWorker; worker.Append(worker.Create(OpCodes.Nop)); worker.Append(worker.Create(OpCodes.Newobj, cons)); worker.Append(worker.Create(OpCodes.Throw)); _type.Methods.Add(newMethod); }
public MethodContext(CilWorker worker, VariableDefinition currentArguments, MethodReference currentMethod, VariableDefinition currentArgument) { CilWorker = worker; CurrentArguments = currentArguments; CurrentMethod = currentMethod; CurrentArgument = currentArgument; }
/// <summary> /// Pushes the current <paramref name="method"/> onto the stack. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param> /// <param name="method">The method that represents the <see cref="MethodInfo"/> that will be pushed onto the stack.</param> /// <param name="module">The module that contains the host method.</param> public static void PushMethod(this CilWorker IL, MethodReference method, ModuleDefinition module) { var getMethodFromHandle = module.ImportMethod <MethodBase>("GetMethodFromHandle", typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle)); var declaringType = method.DeclaringType; // Instantiate the generic type before determining // the current method if (declaringType.GenericParameters.Count > 0) { var genericType = new GenericInstanceType(declaringType); foreach (GenericParameter parameter in declaringType.GenericParameters) { genericType.GenericArguments.Add(parameter); } declaringType = genericType; } IL.Emit(OpCodes.Ldtoken, method); IL.Emit(OpCodes.Ldtoken, declaringType); IL.Emit(OpCodes.Call, getMethodFromHandle); }
/// <summary> /// Obtains the module that contains the current <see cref="CilWorker"/>. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> responsible for the method body.</param> /// <returns>The host module.</returns> public static ModuleDefinition GetModule(this CilWorker IL) { var method = IL.GetMethod(); var declaringType = method.DeclaringType; return(declaringType.Module); }
/// <summary> /// Obtains the method definition that contains the current <see cref="CilWorker"/>. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> responsible for the method body.</param> /// <returns>A method definition.</returns> public static MethodDefinition GetMethod(this CilWorker IL) { var body = IL.GetBody(); var targetMethod = body.Method; return(targetMethod); }
/// <summary> /// Stores the <paramref name="param">current parameter value</paramref> /// into the array of method <paramref name="arguments"/>. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param> /// <param name="arguments">The local variable that will store the method arguments.</param> /// <param name="index">The array index that indicates where the parameter value will be stored in the array of arguments.</param> /// <param name="param">The current argument value being stored.</param> private static void PushParameter(this CilWorker IL, int index, VariableDefinition arguments, ParameterDefinition param) { var parameterType = param.ParameterType; IL.Emit(OpCodes.Ldloc, arguments); IL.Emit(OpCodes.Ldc_I4, index); // Zero out the [out] parameters if (param.IsOut || param.IsByRef()) { IL.Emit(OpCodes.Ldnull); IL.Emit(OpCodes.Stelem_Ref); return; } IL.Emit(OpCodes.Ldarg, param); if (parameterType.IsValueType || parameterType is GenericParameter) { IL.Emit(OpCodes.Box, param.ParameterType); } IL.Emit(OpCodes.Stelem_Ref); }
private void EmitCreateInstance(CilWorker IL) { // T instance = this.Activator.CreateInstance(context); IL.Emit(OpCodes.Ldloc, _currentActivator); IL.Emit(OpCodes.Ldloc, _methodContext); IL.Emit(OpCodes.Callvirt, _createInstance); }
protected override void Replace(Instruction oldInstruction, MethodDefinition hostMethod, CilWorker IL) { var targetMethod = (MethodReference)oldInstruction.Operand; var callOriginalMethod = IL.Create(OpCodes.Nop); var returnType = targetMethod.ReturnType.ReturnType; var endLabel = IL.Create(OpCodes.Nop); var module = hostMethod.DeclaringType.Module; // Create the stack that will hold the method arguments IL.Emit(OpCodes.Newobj, _stackCtor); IL.Emit(OpCodes.Stloc, _currentArguments); SaveInvocationInfo(IL, targetMethod, module, returnType); var getInterceptionDisabled = new GetInterceptionDisabled(hostMethod, _interceptionDisabled); getInterceptionDisabled.Emit(IL); var surroundMethodBody = new SurroundMethodBody(_methodReplacementProvider, _aroundInvokeProvider, _invocationInfo, _interceptionDisabled, _returnValue, typeof(AroundInvokeMethodCallRegistry)); surroundMethodBody.AddProlog(IL); // Use the MethodReplacementProvider attached to the // current host instance Replace(IL, oldInstruction, targetMethod, hostMethod, endLabel, callOriginalMethod); IL.Append(endLabel); surroundMethodBody.AddEpilog(IL); }
public void StoreFactoryMap(IAssembly assembly, FactoryMap factoryMap) { MethodInfo getTypeFromHandleReflect = typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); MethodReference getTypeFromHandle = assembly.Import(getTypeFromHandleReflect); TypeReference systemType = assembly.Import(typeof(Type)); TypeReference arrayOfTypes = assembly.Import(typeof(Type[])); TypeReference arrayOfArrayOfTypes = assembly.Import(typeof(Type[][])); // Now we create the actual type and stuff... TypeDefinition mapType = GetFactoryMapType(assembly); MethodDefinition getFactoriesMethod = new MethodDefinition(FactoryMapMethodName, MethodAttributes.Public, arrayOfArrayOfTypes); getFactoriesMethod.IsVirtual = true; mapType.Methods.Add(getFactoriesMethod); getFactoriesMethod.Body.Variables.Add(new VariableDefinition("map", 0, getFactoriesMethod, arrayOfArrayOfTypes)); getFactoriesMethod.Body.Variables.Add(new VariableDefinition("row", 1, getFactoriesMethod, arrayOfTypes)); getFactoriesMethod.Body.InitLocals = true; CilWorker worker = getFactoriesMethod.Body.CilWorker; List <Factory> factories = new List <Factory>(factoryMap.Factories); worker.Append(worker.Create(OpCodes.Nop)); worker.Append(worker.Create(OpCodes.Ldc_I4, factories.Count)); worker.Append(worker.Create(OpCodes.Newarr, arrayOfTypes)); worker.Append(worker.Create(OpCodes.Stloc_0)); worker.Append(worker.Create(OpCodes.Ldloc_0)); int index = 0; foreach (Factory factory in factories) { worker.Append(worker.Create(OpCodes.Ldc_I4, index)); worker.Append(worker.Create(OpCodes.Ldc_I4, 2)); worker.Append(worker.Create(OpCodes.Newarr, systemType)); worker.Append(worker.Create(OpCodes.Stloc_1)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldc_I4_0)); worker.Append(worker.Create(OpCodes.Ldtoken, factory.ObjectType)); worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle)); worker.Append(worker.Create(OpCodes.Stelem_Ref)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldc_I4_1)); worker.Append(worker.Create(OpCodes.Ldtoken, factory.FactoryType)); worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle)); worker.Append(worker.Create(OpCodes.Stelem_Ref)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Stelem_Ref)); index++; worker.Append(worker.Create(OpCodes.Ldloc_0)); } worker.Append(worker.Create(OpCodes.Ret)); assembly.Inject(mapType); }
private void IgnoreLocal(CilWorker IL, VariableDefinition targetVariable, ModuleDefinition module) { IL.Emit(OpCodes.Ldloc, targetVariable); var addInstance = module.Import(typeof(IgnoredInstancesRegistry).GetMethod("AddInstance")); IL.Emit(OpCodes.Call, addInstance); }
public Instruction CreateConditionalBranch() { Instruction branch = CilWorker.Create(OpCodes.Nop); Instruction instruction = CilWorker.Create(OpCodes.Brtrue, branch); instruction.Next = CilWorker.Create(OpCodes.Nop); return(instruction); }
/// <summary> /// Emits a Console.WriteLine call to using the current CilWorker that will only be called if the contents /// of the target variable are null at runtime. /// </summary> /// <param name="IL">The target CilWorker.</param> /// <param name="text">The text that will be written to the console.</param> /// <param name="targetVariable">The target variable that will be checked for null at runtime.</param> public static void EmitWriteLineIfNull(this CilWorker IL, string text, VariableDefinition targetVariable) { var skipWrite = IL.Create(OpCodes.Nop); IL.Emit(OpCodes.Ldloc, targetVariable); IL.Emit(OpCodes.Brtrue, skipWrite); IL.EmitWriteLine(text); IL.Append(skipWrite); }
/// <summary> /// Rewrites the instructions in the target method body. /// </summary> /// <param name="method">The target method.</param> /// <param name="IL">The <see cref="CilWorker"/> instance that represents the method body.</param> /// <param name="oldInstructions">The IL instructions of the original method body.</param> protected override void RewriteMethodBody(MethodDefinition method, CilWorker IL, IEnumerable <Instruction> oldInstructions) { if (IsExcluded(method)) { AddOriginalInstructions(IL, oldInstructions); return; } VariableDefinition interceptionDisabled = method.AddLocal <bool>(); VariableDefinition invocationInfo = method.AddLocal <IInvocationInfo>(); VariableDefinition aroundInvokeProvider = method.AddLocal <IAroundInvokeProvider>(); VariableDefinition methodReplacementProvider = method.AddLocal <IMethodReplacementProvider>(); VariableDefinition returnValue = method.AddLocal <object>(); VariableDefinition classMethodReplacementProvider = method.AddLocal <IMethodReplacementProvider>(); Func <ModuleDefinition, MethodReference> getInstanceMethodReplacementProviderMethod = module => module.Import(typeof(IMethodReplacementHost).GetMethod("get_MethodBodyReplacementProvider")); var parameters = new MethodBodyRewriterParameters(IL, oldInstructions, interceptionDisabled, invocationInfo, returnValue, methodReplacementProvider, aroundInvokeProvider, classMethodReplacementProvider, getInstanceMethodReplacementProviderMethod, typeof(AroundMethodBodyRegistry)); var emitter = new InvocationInfoEmitter(true); IInstructionEmitter getMethodReplacementProvider = new GetMethodReplacementProvider(methodReplacementProvider, method, getInstanceMethodReplacementProviderMethod); IInstructionEmitter getInterceptionDisabled = new GetInterceptionDisabled(parameters); ISurroundMethodBody surroundMethodBody = new SurroundMethodBody(parameters, "AroundMethodBodyProvider"); IInstructionEmitter getClassMethodReplacementProvider = new GetClassMethodReplacementProvider(parameters, module => module.Import( typeof( MethodBodyReplacementProviderRegistry ). GetMethod ("GetProvider"))); IInstructionEmitter addMethodReplacement = new AddMethodReplacementImplementation(parameters); var rewriter = new InterceptAndSurroundMethodBody(emitter, getInterceptionDisabled, surroundMethodBody, getMethodReplacementProvider, getClassMethodReplacementProvider, addMethodReplacement, parameters); // Determine whether or not the method should be intercepted rewriter.Rewrite(method, IL, oldInstructions); }
public void StartCilWork() { if (this.asm != null) { foreach (TypeDefinition type in this.asm.MainModule.Types) { if (type.Name != "<Module>") { foreach (MethodDefinition method in type.Methods) { if (this.Filter.Contains(method.Name)) { CilWorker worker = method.Body.CilWorker; string s = string.Concat("Code added in: ", method.Name); // Import StreamWriter constructor. ConstructorInfo ci = typeof(StreamWriter).GetConstructor(new Type[] { typeof(string) }); VariableReference streamw = asm.MainModule.Import(ci); streamw.Name = "sw"; // Get streamw's methods. WriteLine and Flush this.writeLine = streamw.GetType().GetMethod("WriteLine", new Type[] { typeof(string) }); this.flush = streamw.GetType().GetMethod("Flush"); // Create a MSIL instructions. Instruction fileName = worker.Create(OpCodes.Ldstr, "debug-methods.log"); Instruction insertText = worker.Create(OpCodes.Ldstr, s); // Create the streamwriter variable: Instruction createVar = worker.Create(OpCodes.Newobj, streamw); // CIL Instruction for calling StreamWriter.WriteLine() Instruction callWriteLine = worker.Create(OpCodes.Call, this.writeLine); // CIL Instruction for calling StreamWriter.Flush() Instruction callFlush = worker.Create(OpCodes.Call, this.flush); // Get the first instruction of the method. Instruction ins = method.Body.Instructions[0]; // Insert instructions to method body. method.Body.CilWorker.InsertBefore(ins, fileName); worker.InsertAfter(fileName, createVar); worker.InsertAfter(createVar, insertText); worker.InsertAfter(insertText, writeLine); worker.InsertAfter(writeLine, flush); } } } asm.MainModule.Import(type); } // Save the modified assembly. AssemblyFactory.SaveAssembly(this.asm, this.Path); Console.WriteLine("Deep Logging enabled"); } }
/// <summary> /// Emits the call to the <see cref="IAfterInvoke"/> instance. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> that points to the current method body.</param> public void Emit(CilWorker IL) { var module = IL.GetModule(); // instanceAroundInvoke.AfterInvoke(info, returnValue); Emit(IL, module, _surroundingImplementation, _invocationInfo, _returnValue); // classAroundInvoke.AfterInvoke(info, returnValue); Emit(IL, module, _surroundingClassImplementation, _invocationInfo, _returnValue); }
public Instruction CreateSwitchBranch() { Instruction branch1 = CilWorker.Create(OpCodes.Nop); Instruction branch2 = CilWorker.Create(OpCodes.Nop); Instruction branch3 = CilWorker.Create(OpCodes.Nop); Instruction instruction = CilWorker.Create(OpCodes.Switch, new Instruction[] { branch1, branch2, branch3 }); instruction.Next = CilWorker.Create(OpCodes.Nop); return(instruction); }
private static void InvokeInterceptor(ModuleDefinition module, CilWorker IL, VariableDefinition methodReplacement, TypeReference returnType, VariableDefinition invocationInfo) { var interceptMethod = module.ImportMethod <IInterceptor>("Intercept"); IL.Emit(OpCodes.Ldloc, methodReplacement); IL.Emit(OpCodes.Ldloc, invocationInfo); IL.Emit(OpCodes.Callvirt, interceptMethod); IL.PackageReturnValue(module, returnType); }
/// <summary> /// Pushes a <paramref name="Type"/> instance onto the stack. /// </summary> /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param> /// <param name="type">The type that represents the <see cref="Type"/> that will be pushed onto the stack.</param> /// <param name="module">The module that contains the host method.</param> public static void PushType(this CilWorker IL, TypeReference type, ModuleDefinition module) { var getTypeFromHandle = module.ImportMethod <Type>("GetTypeFromHandle", typeof(RuntimeTypeHandle)); // Instantiate the generic type before pushing it onto the stack var declaringType = GetDeclaringType(type); IL.Emit(OpCodes.Ldtoken, declaringType); IL.Emit(OpCodes.Call, getTypeFromHandle); }
public void codeBlock_CallToMethod(MethodDefinition targetMethod, MethodInfo methodToCall) { CilWorker cliWorker = targetMethod.Body.CilWorker; var lsInstructions = new List <Instruction> { cliWorker.Create(OpCodes.Call, getMethodReference(methodToCall)) }; CecilOpCodeUtils.addInstructionsToMethod_InsertAtEnd(targetMethod, lsInstructions); }