Esempio n. 1
0
            protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
            {
                MethodSymbol setResultMethod = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__SetResult, isOptional: true);

                if ((object)setResultMethod != null)
                {
                    setResultMethod = (MethodSymbol)setResultMethod.SymbolAsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type.TypeSymbol);
                }

                MethodSymbol setExceptionMethod = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__SetException, isOptional: true);

                if ((object)setExceptionMethod != null)
                {
                    setExceptionMethod = (MethodSymbol)setExceptionMethod.SymbolAsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type.TypeSymbol);
                }

                var rewriter = new AsyncMethodToStateMachineRewriter(
                    method: method,
                    methodOrdinal: _methodOrdinal,
                    asyncMethodBuilderMemberCollection: _asyncMethodBuilderMemberCollection,
                    asyncIteratorInfo: new AsyncIteratorInfo(_promiseOfValueOrEndField, _currentField, setResultMethod, setExceptionMethod),
                    F: F,
                    state: stateField,
                    builder: _builderField,
                    hoistedVariables: hoistedVariables,
                    nonReusableLocalProxies: nonReusableLocalProxies,
                    synthesizedLocalOrdinals: synthesizedLocalOrdinals,
                    slotAllocatorOpt: slotAllocatorOpt,
                    nextFreeHoistedLocalSlot: nextFreeHoistedLocalSlot,
                    diagnostics: diagnostics);

                rewriter.GenerateMoveNext(body, moveNextMethod);
            }
Esempio n. 2
0
            protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
            {
                MethodSymbol setResultMethod = F.WellKnownMethod(
                    WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__SetResult,
                    isOptional: true
                    );

                if (setResultMethod is { })
Esempio n. 3
0
        private void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
        {
            var rewriter = new AsyncMethodToStateMachineRewriter(
                method: method,
                asyncMethodBuilderMemberCollection: asyncMethodBuilderMemberCollection,
                F: F,
                state: stateField,
                builder: builderField,
                variablesCaptured: variablesCaptured,
                nonReusableLocalProxies: nonReusableLocalProxies,
                diagnostics: diagnostics);

            rewriter.GenerateMoveNext(body, moveNextMethod);
        }
Esempio n. 4
0
        private void GenerateMoveNextAndDispose(
            SynthesizedImplementationMethod moveNextMethod,
            SynthesizedImplementationMethod disposeMethod)
        {
            var rewriter = new IteratorMethodToStateMachineRewriter(
                F,
                method,
                stateField,
                currentField,
                variablesCaptured,
                nonReusableLocalProxies,
                diagnostics);

            rewriter.GenerateMoveNextAndDispose(body, moveNextMethod, disposeMethod);
        }
Esempio n. 5
0
        private void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
        {
            var rewriter = new AsyncMethodToClassRewriter(
                method: method,
                asyncMethodBuilderMemberCollection: asyncMethodBuilderMemberCollection,
                F: F,
                state: stateField,
                builder: builderField,
                variablesCaptured: variablesCaptured,
                initialProxies: variableProxies,
                diagnostics: diagnostics,
                generateDebugInfo: generateDebugInfo);

            rewriter.GenerateMoveNext(body, moveNextMethod);
        }
Esempio n. 6
0
        private void GenerateMoveNextAndDispose(
            SynthesizedImplementationMethod moveNextMethod,
            SynthesizedImplementationMethod disposeMethod)
        {
            var rewriter = new IteratorMethodToClassRewriter(
                F,
                method,
                stateField,
                currentField,
                variablesCaptured,
                variableProxies,
                diagnostics,
                generateDebugInfo);

            rewriter.GenerateMoveNextAndDispose(body, moveNextMethod, disposeMethod);
        }
Esempio n. 7
0
        private void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
        {
            var rewriter = new AsyncMethodToStateMachineRewriter(
                method: method,
                methodOrdinal: _methodOrdinal,
                asyncMethodBuilderMemberCollection: _asyncMethodBuilderMemberCollection,
                F: F,
                state: stateField,
                builder: _builderField,
                hoistedVariables: hoistedVariables,
                nonReusableLocalProxies: nonReusableLocalProxies,
                synthesizedLocalOrdinals: synthesizedLocalOrdinals,
                slotAllocatorOpt: slotAllocatorOpt,
                nextFreeHoistedLocalSlot: nextFreeHoistedLocalSlot,
                diagnostics: diagnostics);

            rewriter.GenerateMoveNext(body, moveNextMethod);
        }
Esempio n. 8
0
        private void GenerateMoveNextAndDispose(
            SynthesizedImplementationMethod moveNextMethod,
            SynthesizedImplementationMethod disposeMethod)
        {
            var rewriter = new IteratorMethodToStateMachineRewriter(
                F,
                method,
                stateField,
                _currentField,
                hoistedVariables,
                nonReusableLocalProxies,
                synthesizedLocalOrdinals,
                slotAllocatorOpt,
                nextFreeHoistedLocalSlot,
                diagnostics);

            rewriter.GenerateMoveNextAndDispose(body, moveNextMethod, disposeMethod);
        }
        internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImplementationMethod moveNextMethod, SynthesizedImplementationMethod disposeMethod)
        {
            // scan body for yielding try blocks
            _yieldsInTryAnalysis = new YieldsInTryAnalysis(body);
            if (_yieldsInTryAnalysis.ContainsYieldsInTrys())
            {
                // adjust for the method Try/Fault block that we will put around the body.
                _tryNestingLevel++;
            }

            ///////////////////////////////////
            // Generate the body for MoveNext()
            ///////////////////////////////////

            F.CurrentFunction = moveNextMethod;
            int initialState;
            GeneratedLabelSymbol initialLabel;

            AddState(out initialState, out initialLabel);
            var newBody = (BoundStatement)Visit(body);

            // switch(cachedState) {
            //    case 0: goto state_0;
            //    case 1: goto state_1;
            //    //etc
            //    default: return false;
            // }
            // state_0:
            // state = -1;
            // [optional: cachedThis = capturedThis;]
            // [[rewritten body]]
            newBody = F.Block((object)cachedThis == null ?
                              ImmutableArray.Create(cachedState) :
                              ImmutableArray.Create(cachedState, cachedThis),

                              F.HiddenSequencePoint(),
                              F.Assignment(F.Local(cachedState), F.Field(F.This(), stateField)),
                              CacheThisIfNeeded(),
                              Dispatch(),
                              GenerateReturn(finished: true),
                              F.Label(initialLabel),
                              F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.NotStartedStateMachine)),
                              newBody);

            //
            // C# spec requires that iterators trap all exceptions and self-dispose eagerly.
            //
            // 10.14.4.1 The MoveNext method
            // . . .
            // When an exception is thrown and propagated out of the iterator block:
            // o   Appropriate finally blocks in the iterator body will have been executed by the exception propagation.
            // o   The state of the enumerator object is changed to after.
            // o   The exception propagation continues to the caller of the MoveNext method.
            // . . .
            //
            if (_yieldsInTryAnalysis.ContainsYieldsInTrys())
            {
                // try
                // {
                //    body;
                // }
                // fault
                // {
                //    this.Dispose();
                // }

                var faultBlock = F.Block(F.ExpressionStatement(F.Call(F.This(), disposeMethod)));
                newBody = F.Fault((BoundBlock)newBody, faultBlock);
            }

            newBody = HandleReturn(newBody);
            F.CloseMethod(F.SequencePoint(body.Syntax, newBody));

            ///////////////////////////////////
            // Generate the body for Dispose().
            ///////////////////////////////////
            F.CurrentFunction = disposeMethod;
            var rootFrame = _currentFinallyFrame;

            if (rootFrame.knownStates == null)
            {
                // nothing to finalize
                F.CloseMethod(F.Return());
            }
            else
            {
                var stateLocal = F.SynthesizedLocal(stateField.Type.TypeSymbol);
                var state      = F.Local(stateLocal);

                var disposeBody = F.Block(
                    ImmutableArray.Create <LocalSymbol>(stateLocal),
                    F.Assignment(F.Local(stateLocal), F.Field(F.This(), stateField)),
                    EmitFinallyFrame(rootFrame, state),
                    F.Return());

                F.CloseMethod(disposeBody);
            }
        }