예제 #1
0
 private VariableDefinition GetMoveNextConfigParameterVariable()
 {
     if (_moveNextConfigParameter == null)
     {
         _moveNextConfigParameter = _moveNextBody.DeclareVariable("$configParameters", _typeReferenceProvider.StringTupleArray);
     }
     return(_moveNextConfigParameter);
 }
예제 #2
0
        protected override void WeaveTraceLeave(Dictionary <string, string> configParameters)
        {
            _moveNextDefinition =
                _generatedType.Methods.Single(it => it.Name.Equals("MoveNext", StringComparison.OrdinalIgnoreCase));
            _moveNextBody = _moveNextDefinition.Body;

            _moveNextBody.SimplifyMacros();

            //find the leave part in the generated async state machine
            var setResultInstr    = _moveNextBody.Instructions.FirstOrDefault(IsCallSetResult);
            var setExceptionInstr = _moveNextBody.Instructions.FirstOrDefault(IsCallSetException);

            VariableDefinition returnValueDef = null;
            var processor = _moveNextBody.GetILProcessor();

            VariableDefinition configParamDef = _moveNextBody.DeclareVariable("$configParameters", _typeReferenceProvider.StringTupleArray);

            if (setResultInstr != null) //rarely it might happen that there is not SetResult
            {
                //if we have return value store it in a local var
                if (HasReturnValue)
                {
                    var retvalDupInstructions = CreateReturnValueSavingInstructions(out returnValueDef);
                    setResultInstr.InsertBefore(processor, retvalDupInstructions);
                }


                //do the exit logging
                setResultInstr.InsertBefore(processor, CreateTraceReturnLoggingInstructions(returnValueDef, configParamDef, configParameters));
            }

            if (setExceptionInstr != null)
            {
                //do the exception exit logging
                VariableDefinition exceptionValueDef = _moveNextBody.DeclareVariable("$exception",
                                                                                     _typeReferenceProvider.Exception);

                var exceptionDupInstructions = new List <Instruction>()
                {
                    Instruction.Create(OpCodes.Dup),
                    Instruction.Create(OpCodes.Stloc, exceptionValueDef)
                };

                setExceptionInstr.InsertBefore(processor, exceptionDupInstructions);
                setExceptionInstr.InsertBefore(processor, CreateTraceReturnWithExceptionLoggingInstructions(exceptionValueDef, configParamDef, configParameters));
            }

            //search and replace static log calls in moveNext
            SearchForAndReplaceStaticLogCallsInMoveNext();

            _moveNextBody.InitLocals = true;
            _moveNextBody.OptimizeMacros();
        }
예제 #3
0
        private List <Instruction> CreateReturnValueSavingInstructions(out VariableDefinition returnValueDef)
        {
            //Declare local variable for the return value
            returnValueDef = _moveNextBody.DeclareVariable("$returnValue", _typeReferenceProvider.Object);

            var instructions = new List <Instruction>();

            instructions.Add(Instruction.Create(OpCodes.Dup));
            if (ReturnType.IsGenericParameter)
            {
                //use the generic parameter of the generated state machine
                var varType = _generatedType.GenericParameters[0];
                instructions.Add(Instruction.Create(OpCodes.Box, varType));
            }
            else
            {
                if (IsBoxingNeeded(ReturnType))
                {
                    instructions.Add(Instruction.Create(OpCodes.Box, ReturnType));
                }
            }
            instructions.Add(Instruction.Create(OpCodes.Stloc, returnValueDef)); //store return value in local variable

            return(instructions);
        }