private VariableDefinition GetMoveNextConfigParameterVariable() { if (_moveNextConfigParameter == null) { _moveNextConfigParameter = _moveNextBody.DeclareVariable("$configParameters", _typeReferenceProvider.StringTupleArray); } return(_moveNextConfigParameter); }
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(); }
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); }