public void AddOnExceptionCall(
            NamedInstructionBlockChain createAspectInstance,
            InstructionBlockChain callAspectOnException,
            NamedInstructionBlockChain setMethodExecutionArgsExceptionFromStack)
        {
            // add leave
            _markLeaveTryBlock = _processor.Create(OpCodes.Leave, _markEnd2BeforeOnExitCall);
            _processor.InsertBefore(_markEnd2BeforeOnExitCall, _markLeaveTryBlock);

            // add catch handler after leave
            _markExceptionHandlerStart = _processor.Create(OpCodes.Nop);
            _processor.InsertAfter(_markLeaveTryBlock, _markExceptionHandlerStart);
            var current = setMethodExecutionArgsExceptionFromStack.InsertAfter(_markExceptionHandlerStart, _processor);

            current = AddCreateAspectInstance(createAspectInstance, current);
            current = callAspectOnException.InsertAfter(current, _processor);
            _markExceptionHandlerEnd = _processor.Create(OpCodes.Rethrow);
            _processor.InsertAfter(current, _markExceptionHandlerEnd);

            // add exception handler
            _methodBody.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
            {
                CatchType    = setMethodExecutionArgsExceptionFromStack.TypeReference,
                TryStart     = _markStart4BeforeRealBodyStartExceptionHandler,
                TryEnd       = _markExceptionHandlerStart,
                HandlerStart = _markExceptionHandlerStart,
                HandlerEnd   = _markExceptionHandlerEnd.Next
            });
        }
        public void AddOnEntryCall(
            NamedInstructionBlockChain createAspectInstance,
            InstructionBlockChain callAspectOnEntry)
        {
            var current = AddCreateAspectInstance(createAspectInstance, _markStart3BeforeOnEntryCall);

            callAspectOnEntry.InsertAfter(current, _processor);
        }
        public void AddOnExitCall(
            NamedInstructionBlockChain createAspectInstance,
            InstructionBlockChain callAspectOnExit,
            InstructionBlockChain setMethodExecutionArgsReturnValue)
        {
            var current = setMethodExecutionArgsReturnValue.InsertAfter(_markEnd2BeforeOnExitCall, _processor);

            current = AddCreateAspectInstance(createAspectInstance, current);
            callAspectOnExit.InsertAfter(current, _processor);
        }
Exemple #4
0
        private Instruction AddCreateAspectInstance(InstructionBlockChain createAspectInstance, Instruction current)
        {
            if (_aspectInstanceCreated)
            {
                return(current);
            }

            current = createAspectInstance.InsertAfter(current, _processor);
            _aspectInstanceCreated = true;
            return(current);
        }
Exemple #5
0
 protected override void AddToSetup(InstructionBlockChain chain)
 {
     if (_setupPointer == null)
     {
         chain.Prepend(_ilProcessor);
     }
     else
     {
         chain.InsertAfter(_setupPointer, _ilProcessor);
     }
     _setupPointer = chain.Last;
 }
Exemple #6
0
        public void AddOnEntryCall(
            NamedInstructionBlockChain createAspectInstance,
            InstructionBlockChain callAspectOnEntry,
            InstructionBlockChain getSkipVar,
            NamedInstructionBlockChain conditionalExecutionInstance)
        {
            var current = AddCreateAspectInstance(createAspectInstance, _markStart3BeforeOnEntryCall);

            current = callAspectOnEntry.InsertAfter(current, _processor);
            current = getSkipVar.InsertAfter(current, _processor);
            current = conditionalExecutionInstance.InsertAfter(current, _processor);
            _processor.InsertAfter(current, _processor.Create(OpCodes.Brfalse, _markEnd2BeforeOnExitCall));
        }
Exemple #7
0
        protected virtual void WeaveOnException(IList <AspectData> allAspects, Instruction instructionCallStart, Instruction instructionCallEnd, Instruction instructionAfterCall, IPersistable returnValue)
        {
            var realInstructionAfterCall = instructionAfterCall ?? instructionCallEnd.Next;
            var tryLeaveInstruction      = Instruction.Create(OpCodes.Leave, realInstructionAfterCall);

            _ilProcessor.InsertAfter(instructionCallEnd, tryLeaveInstruction);

            var exception = _creator.SaveThrownException();
            var exceptionHandlerCurrent = exception.InsertAfter(tryLeaveInstruction, _ilProcessor);

            var pushException = _creator.LoadValueOnStack(exception);

            exceptionHandlerCurrent = pushException.InsertAfter(exceptionHandlerCurrent, _ilProcessor);

            var setExceptionFromStack =
                _creator.SetMethodExecutionArgsExceptionFromStack(ExecutionArgs);

            exceptionHandlerCurrent = setExceptionFromStack.InsertAfter(exceptionHandlerCurrent, _ilProcessor);

            var returnAfterHandling = new InstructionBlockChain();

            if (returnValue != null)
            {
                returnAfterHandling.Add(returnValue.Load(false, false));
            }
            returnAfterHandling.Add(new InstructionBlock("Return", Instruction.Create(OpCodes.Ret)));

            var indices = allAspects
                          .Select((asp, index) => new { asp, index })
                          .Where(x => (x.asp.AspectMethods & AspectMethods.OnException) != 0)
                          .Select(x => x.index)
                          .Reverse()
                          .ToList();

            foreach (var index in indices)
            {
                var onExceptionAspect = allAspects[index];
                if (HasMultipleAspects)
                {
                    var load = _creator.LoadMethodExecutionArgsTagFromPersistable(ExecutionArgs,
                                                                                  onExceptionAspect.TagPersistable);
                    exceptionHandlerCurrent = load.InsertAfter(exceptionHandlerCurrent, _ilProcessor);
                }

                var callAspectOnException =
                    _creator.CallAspectOnException(onExceptionAspect, ExecutionArgs);
                var nop = new InstructionBlock("Nop", Instruction.Create(OpCodes.Nop));

                var callOnExitsAndReturn = new InstructionBlockChain();
                for (var i = index - 1; i >= 0; --i)
                {
                    var jthAspect = allAspects[i];
                    if ((jthAspect.AspectMethods & AspectMethods.OnExit) == 0)
                    {
                        continue;
                    }
                    if (HasMultipleAspects)
                    {
                        callOnExitsAndReturn.Add(_creator.LoadMethodExecutionArgsTagFromPersistable(ExecutionArgs, jthAspect.TagPersistable));
                    }
                    callOnExitsAndReturn.Add(_creator.CallAspectOnExit(jthAspect, ExecutionArgs));
                }

                if (returnValue != null)
                {
                    callOnExitsAndReturn.Add(_creator.ReadReturnValue(ExecutionArgs, returnValue));
                }

                callOnExitsAndReturn.Add(new InstructionBlock("Leave", Instruction.Create(OpCodes.Leave_S, returnAfterHandling.First)));

                callAspectOnException.Add(_creator.IfFlowBehaviorIsAnyOf(ExecutionArgs, nop.First, callOnExitsAndReturn, 1, 3));

                callAspectOnException.Add(nop);
                callAspectOnException.InsertAfter(exceptionHandlerCurrent, _ilProcessor);
                exceptionHandlerCurrent = callAspectOnException.Last;
            }

            var flowBehaviorHandler = new InstructionBlockChain();

            flowBehaviorHandler.Add(new InstructionBlock("throw", Instruction.Create(OpCodes.Rethrow)));
            flowBehaviorHandler.Add(new InstructionBlock("Leave", Instruction.Create(OpCodes.Leave_S, realInstructionAfterCall)));
            flowBehaviorHandler.InsertAfter(exceptionHandlerCurrent, _ilProcessor);

            returnAfterHandling.InsertAfter(flowBehaviorHandler.Last, _ilProcessor);

            _method.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
            {
                CatchType    = _creator.GetExceptionTypeReference(),
                TryStart     = instructionCallStart,
                TryEnd       = tryLeaveInstruction.Next,
                HandlerStart = tryLeaveInstruction.Next,
                HandlerEnd   = flowBehaviorHandler.Last.Next
            });
        }
        public void AddOnExceptionCall(
            NamedInstructionBlockChain createAspectInstance,
            InstructionBlockChain callAspectOnException,
            NamedInstructionBlockChain setMethodExecutionArgsExceptionFromStack)
        {
            // add leave
            _markLeaveTryBlock = _processor.Create(OpCodes.Leave, _markEnd2BeforeOnExitCall);
            _processor.InsertBefore(_markEnd2BeforeOnExitCall, _markLeaveTryBlock);

            // add catch handler after leave
            _markExceptionHandlerStart = _processor.Create(OpCodes.Nop);
            _processor.InsertAfter(_markLeaveTryBlock, _markExceptionHandlerStart);
            var current = setMethodExecutionArgsExceptionFromStack.InsertAfter(_markExceptionHandlerStart, _processor);
            current = AddCreateAspectInstance(createAspectInstance, current);
            current = callAspectOnException.InsertAfter(current, _processor);
            _markExceptionHandlerEnd = _processor.Create(OpCodes.Rethrow);
            _processor.InsertAfter(current, _markExceptionHandlerEnd);

            // add exception handler
            _methodBody.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
            {
                CatchType = setMethodExecutionArgsExceptionFromStack.TypeReference,
                TryStart = _markStart4BeforeRealBodyStartExceptionHandler,
                TryEnd = _markExceptionHandlerStart,
                HandlerStart = _markExceptionHandlerStart,
                HandlerEnd = _markExceptionHandlerEnd.Next
            });
        }
 public void AddOnExitCall(
     NamedInstructionBlockChain createAspectInstance,
     InstructionBlockChain callAspectOnExit,
     InstructionBlockChain setMethodExecutionArgsReturnValue)
 {
     var current = setMethodExecutionArgsReturnValue.InsertAfter(_markEnd2BeforeOnExitCall, _processor);
     current = AddCreateAspectInstance(createAspectInstance, current);
     callAspectOnExit.InsertAfter(current, _processor);
 }
 public void AddOnEntryCall(
     NamedInstructionBlockChain createAspectInstance,
     InstructionBlockChain callAspectOnEntry)
 {
     var current = AddCreateAspectInstance(createAspectInstance, _markStart3BeforeOnEntryCall);
     callAspectOnEntry.InsertAfter(current, _processor);
 }