Esempio n. 1
0
        internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method,
                                                           int methodOrdinal,
                                                           AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                                                           AsyncIteratorInfo asyncIteratorInfo,
                                                           SyntheticBoundNodeFactory F,
                                                           FieldSymbol state,
                                                           FieldSymbol builder,
                                                           IReadOnlySet <Symbol> hoistedVariables,
                                                           IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
                                                           SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
                                                           ArrayBuilder <StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder,
                                                           VariableSlotAllocator slotAllocatorOpt,
                                                           int nextFreeHoistedLocalSlot,
                                                           BindingDiagnosticBag diagnostics)
            : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F,
                   state, builder, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals,
                   stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics)
        {
            Debug.Assert(asyncIteratorInfo != null);

            _asyncIteratorInfo    = asyncIteratorInfo;
            _currentDisposalLabel = _exprReturnLabel;
            _exprReturnLabelTrue  = F.GenerateLabel("yieldReturn");

            _iteratorStateAllocator = new ResumableStateMachineStateAllocator(
                slotAllocatorOpt,
                firstState: StateMachineStates.FirstResumableAsyncIteratorState,
                increasing: false);
        }
        public MethodToStateMachineRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            IReadOnlySet <Symbol> hoistedVariables,
            IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            ArrayBuilder <StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            BindingDiagnosticBag diagnostics)
            : base(slotAllocatorOpt, F.CompilationState, diagnostics)
        {
            Debug.Assert(F != null);
            Debug.Assert(originalMethod != null);
            Debug.Assert(state != null);
            Debug.Assert(nonReusableLocalProxies != null);
            Debug.Assert(diagnostics != null);
            Debug.Assert(hoistedVariables != null);
            Debug.Assert(nextFreeHoistedLocalSlot >= 0);

            this.F                    = F;
            this.stateField           = state;
            this.cachedState          = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), syntax: F.Syntax, kind: SynthesizedLocalKind.StateMachineCachedState);
            this.OriginalMethod       = originalMethod;
            _hoistedVariables         = hoistedVariables;
            _synthesizedLocalOrdinals = synthesizedLocalOrdinals;
            _nextFreeHoistedLocalSlot = nextFreeHoistedLocalSlot;

            foreach (var proxy in nonReusableLocalProxies)
            {
                this.proxies.Add(proxy.Key, proxy.Value);
            }

            // create cache local for reference type "this" in Release
            var thisParameter = originalMethod.ThisParameter;
            CapturedSymbolReplacement thisProxy;

            if ((object)thisParameter != null &&
                thisParameter.Type.IsReferenceType &&
                proxies.TryGetValue(thisParameter, out thisProxy) &&
                F.Compilation.Options.OptimizationLevel == OptimizationLevel.Release)
            {
                BoundExpression thisProxyReplacement = thisProxy.Replacement(F.Syntax, frameType => F.This());
                this.cachedThis = F.SynthesizedLocal(thisProxyReplacement.Type, syntax: F.Syntax, kind: SynthesizedLocalKind.FrameCache);
            }

            _stateDebugInfoBuilder = stateMachineStateDebugInfoBuilder;

            // Use the first state number that is not used by any previous version of the state machine
            // for the first added state that doesn't match any states of the previous state machine.
            // Note the initial states of the previous and the current state machine are always the same.
            // Note the previous state machine might not have any non-initial states.
            _resumableStateAllocator = new ResumableStateMachineStateAllocator(
                slotAllocatorOpt,
                firstState: FirstIncreasingResumableState,
                increasing: true);
        }