/src/LinFu.AOP/Emitters/GetInterceptionDisabled.cs

http://github.com/philiplaureano/LinFu · C# · 74 lines · 45 code · 9 blank · 20 comment · 1 complexity · 184fd05fcde1a604bb87d8514289911c MD5 · raw file

  1. using LinFu.AOP.Cecil.Interfaces;
  2. using LinFu.AOP.Interfaces;
  3. using LinFu.Reflection.Emit;
  4. using Mono.Cecil;
  5. using Mono.Cecil.Cil;
  6. namespace LinFu.AOP.Cecil
  7. {
  8. /// <summary>
  9. /// Represents a class that emits the instructions that determine whether or not method interception is disabled.
  10. /// </summary>
  11. public class GetInterceptionDisabled : IInstructionEmitter
  12. {
  13. private readonly MethodReference _hostMethod;
  14. private readonly VariableDefinition _interceptionDisabled;
  15. /// <summary>
  16. /// Initializes a new instance of the <see cref="GetInterceptionDisabled" /> class.
  17. /// </summary>
  18. /// <param name="parameters">The <see cref="IMethodBodyRewriterParameters" /> instance.</param>
  19. public GetInterceptionDisabled(IMethodBodyRewriterParameters parameters)
  20. {
  21. _hostMethod = parameters.TargetMethod;
  22. _interceptionDisabled = parameters.InterceptionDisabled;
  23. }
  24. /// <summary>
  25. /// Initializes a new instance of the <see cref="GetInterceptionDisabled" /> class.
  26. /// </summary>
  27. /// <param name="hostMethod">The target method.</param>
  28. /// <param name="interceptionDisabled">The local variable that determines whether or not method interception is disabled.</param>
  29. public GetInterceptionDisabled(MethodReference hostMethod, VariableDefinition interceptionDisabled)
  30. {
  31. _hostMethod = hostMethod;
  32. _interceptionDisabled = interceptionDisabled;
  33. }
  34. /// <summary>
  35. /// Emits the instructions that determine whether or not method interception is disabled.
  36. /// </summary>
  37. /// <param name="IL">
  38. /// The <see cref="ILProcessor" /> instance responsible for adding or removing instructions to the method
  39. /// body.
  40. /// </param>
  41. public void Emit(ILProcessor IL)
  42. {
  43. var module = IL.Body.Method.DeclaringType.Module;
  44. var modifiableType = module.ImportType<IModifiableType>();
  45. var getInterceptionDisabledMethod =
  46. module.ImportMethod<IModifiableType>("get_IsInterceptionDisabled");
  47. if (!_hostMethod.HasThis)
  48. {
  49. IL.Emit(OpCodes.Ldc_I4_0);
  50. IL.Emit(OpCodes.Stloc, _interceptionDisabled);
  51. return;
  52. }
  53. var skipLabel = IL.Create(OpCodes.Nop);
  54. // var interceptionDisabled = this.IsInterceptionDisabled;
  55. IL.Emit(OpCodes.Ldarg_0);
  56. IL.Emit(OpCodes.Isinst, modifiableType);
  57. IL.Emit(OpCodes.Brfalse, skipLabel);
  58. IL.Emit(OpCodes.Ldarg_0);
  59. IL.Emit(OpCodes.Isinst, modifiableType);
  60. IL.Emit(OpCodes.Callvirt, getInterceptionDisabledMethod);
  61. IL.Emit(OpCodes.Stloc, _interceptionDisabled);
  62. IL.Append(skipLabel);
  63. }
  64. }
  65. }