/// <summary> /// Generate the body for <c>MoveNext()</c>. /// </summary> protected override void CreateMoveNext() { Method asyncMethod = _method.Method; BooMethodBuilder methodBuilder = _stateMachineClass.AddVirtualMethod("MoveNext", TypeSystemServices.VoidType); methodBuilder.Method.LexicalInfo = asyncMethod.LexicalInfo; _moveNext = methodBuilder.Entity; TransformLocalsIntoFields(asyncMethod); TransformParametersIntoFieldsInitializedByConstructor(_method.Method); _exprReturnLabel = CodeBuilder.CreateLabel(methodBuilder.Method, "exprReturn", 0); _exitLabel = CodeBuilder.CreateLabel(methodBuilder.Method, "exitLabel", 0); _isGenericTask = _method.ReturnType.ConstructedInfo != null; _exprRetValue = _isGenericTask ? CodeBuilder.DeclareTempLocal(_moveNext.Method, _methodToStateMachineMapper.MapType(_asyncMethodBuilderMemberCollection.ResultType)) : null; _cachedState = CodeBuilder.DeclareLocal(methodBuilder.Method, UniqueName("state"), TypeSystemServices.IntType); _seenAwait = false; var rewrittenBody = (Block)Visit(_method.Method.Body); if (!_seenAwait) { Context.Warnings.Add(CompilerWarningFactory.AsyncNoAwait(_method.Method)); } var bodyBuilder = methodBuilder.Body; bodyBuilder.Add(CodeBuilder.CreateAssignment( CodeBuilder.CreateLocalReference(_cachedState), CodeBuilder.CreateMemberReference(_state))); CheckForTryExcept(); Block bodyBlock; if (_labels.Count > 0) { var dispatch = CodeBuilder.CreateSwitch( this.LexicalInfo, CodeBuilder.CreateLocalReference(_cachedState), _labels); CheckTryJumps((MethodInvocationExpression)((ExpressionStatement)dispatch).Expression); bodyBlock = new Block(dispatch, rewrittenBody); } else { bodyBlock = rewrittenBody; } InternalLocal exceptionLocal; bodyBuilder.Add(CodeBuilder.CreateTryExcept( this.LexicalInfo, bodyBlock, new ExceptionHandler { Declaration = CodeBuilder.CreateDeclaration( methodBuilder.Method, UniqueName("exception"), TypeSystemServices.ExceptionType, out exceptionLocal), Block = new Block( CodeBuilder.CreateFieldAssignment( this.LexicalInfo, _state, CodeBuilder.CreateIntegerLiteral(StateMachineStates.FinishedStateMachine)), new ExpressionStatement( CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateMemberReference( CodeBuilder.CreateSelfReference(_stateMachineClass.Entity), (IField)_asyncMethodBuilderField.Entity), _asyncMethodBuilderMemberCollection.SetException, CodeBuilder.CreateLocalReference(exceptionLocal))), GenerateReturn()) })); // ReturnLabel (for the rewritten return expressions in the user's method body) bodyBuilder.Add(_exprReturnLabel.LabelStatement); // this.state = finishedState bodyBuilder.Add(CodeBuilder.CreateFieldAssignment( this.LexicalInfo, _state, CodeBuilder.CreateIntegerLiteral(StateMachineStates.FinishedStateMachine))); // builder.SetResult([RetVal]) var setResultInvocation = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateMemberReference( CodeBuilder.CreateSelfReference(_stateMachineClass.Entity), (IField)_asyncMethodBuilderField.Entity), _asyncMethodBuilderMemberCollection.SetResult); if (_isGenericTask) { setResultInvocation.Arguments.Add(CodeBuilder.CreateLocalReference(_exprRetValue)); } bodyBuilder.Add(new ExpressionStatement(setResultInvocation)); // this code is hidden behind a hidden sequence point. bodyBuilder.Add(_exitLabel.LabelStatement); bodyBuilder.Add(new ReturnStatement()); }