Represents a class that emits the instructions that obtain the current IAroundInvoke instance.
Inheritance: IInstructionEmitter
Esempio n. 1
0
        /// <summary>
        /// Adds a prolog to the given method body.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that points to the given method body.</param>
        public void AddProlog(CilWorker IL)
        {
            MethodDefinition method = IL.GetMethod();

            _surroundingImplementation      = method.AddLocal <IAroundInvoke>();
            _surroundingClassImplementation = method.AddLocal <IAroundInvoke>();

            Instruction      skipProlog     = IL.Create(OpCodes.Nop);
            TypeDefinition   declaringType  = method.DeclaringType;
            ModuleDefinition module         = declaringType.Module;
            TypeReference    modifiableType = module.ImportType <IModifiableType>();

            if (method.HasThis)
            {
                IL.Emit(OpCodes.Ldarg_0);
                IL.Emit(OpCodes.Isinst, modifiableType);
                IL.Emit(OpCodes.Brfalse, skipProlog);
            }

            IL.Emit(OpCodes.Ldloc, _interceptionDisabled);
            IL.Emit(OpCodes.Brtrue, skipProlog);

            // var provider = this.MethodReplacementProvider;

            if (_getMethodReplacementProvider != null)
            {
                _getMethodReplacementProvider.Emit(IL);
            }

            var getAroundInvokeProvider = new GetAroundInvokeProvider(_aroundInvokeProvider, _providerName);

            getAroundInvokeProvider.Emit(IL);

            // if (aroundInvokeProvider != null ) {
            Instruction skipGetSurroundingImplementation     = IL.Create(OpCodes.Nop);
            var         getSurroundingImplementationInstance = new GetSurroundingImplementationInstance(_aroundInvokeProvider,
                                                                                                        _invocationInfo,
                                                                                                        _surroundingImplementation,
                                                                                                        skipGetSurroundingImplementation);

            getSurroundingImplementationInstance.Emit(IL);

            // }

            IL.Append(skipGetSurroundingImplementation);
            var emitBeforeInvoke = new EmitBeforeInvoke(_invocationInfo, _surroundingClassImplementation,
                                                        _surroundingImplementation, _registryType);

            emitBeforeInvoke.Emit(IL);

            IL.Append(skipProlog);
        }
Esempio n. 2
0
        /// <summary>
        /// Adds a prolog to the given method body.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that points to the given method body.</param>
        public void AddProlog(CilWorker IL)
        {
            var method = IL.GetMethod();
            _surroundingImplementation = method.AddLocal<IAroundInvoke>();
            _surroundingClassImplementation = method.AddLocal<IAroundInvoke>();

            var skipProlog = IL.Create(OpCodes.Nop);
            var declaringType = method.DeclaringType;
            var module = declaringType.Module;
            var modifiableType = module.ImportType<IModifiableType>();

            if (method.HasThis)
            {
                IL.Emit(OpCodes.Ldarg_0);
                IL.Emit(OpCodes.Isinst, modifiableType);
                IL.Emit(OpCodes.Brfalse, skipProlog);
            }

            IL.Emit(OpCodes.Ldloc, _interceptionDisabled);
            IL.Emit(OpCodes.Brtrue, skipProlog);

            // var provider = this.MethodReplacementProvider;

            if (_getMethodReplacementProvider != null)
                _getMethodReplacementProvider.Emit(IL);

            var getAroundInvokeProvider = new GetAroundInvokeProvider(_aroundInvokeProvider, _providerName);
            getAroundInvokeProvider.Emit(IL);

            // if (aroundInvokeProvider != null ) {
            var skipGetSurroundingImplementation = IL.Create(OpCodes.Nop);
            var getSurroundingImplementationInstance = new GetSurroundingImplementationInstance(_aroundInvokeProvider,
                _invocationInfo,
                _surroundingImplementation,
                skipGetSurroundingImplementation);

            getSurroundingImplementationInstance.Emit(IL);

            // }

            IL.Append(skipGetSurroundingImplementation);
            var emitBeforeInvoke = new EmitBeforeInvoke(_invocationInfo, _surroundingClassImplementation,
                _surroundingImplementation, _registryType);
            emitBeforeInvoke.Emit(IL);

            IL.Append(skipProlog);
        }