예제 #1
0
        protected BoundStatement Rewrite()
        {
            if (this.body.HasErrors)
            {
                return(this.body);
            }

            F.OpenNestedType(stateMachineType);

            GenerateControlFields();

            if (PreserveInitialParameterValuesAndThreadId && CanGetThreadId())
            {
                // if it is an enumerable or async-enumerable, and either Environment.CurrentManagedThreadId or Thread.ManagedThreadId are available
                // add a field: int initialThreadId
                initialThreadIdField = F.StateMachineField(
                    F.SpecialType(SpecialType.System_Int32),
                    GeneratedNames.MakeIteratorCurrentThreadIdFieldName()
                    );
            }

            // fields for the initial values of all the parameters of the method
            if (PreserveInitialParameterValuesAndThreadId)
            {
                initialParameters = new Dictionary <Symbol, CapturedSymbolReplacement>();
            }

            // fields for the captured variables of the method
            var variablesToHoist = IteratorAndAsyncCaptureWalker.Analyze(
                F.Compilation,
                method,
                body,
                diagnostics.DiagnosticBag
                );

            if (diagnostics.HasAnyErrors())
            {
                // Avoid triggering assertions in further lowering.
                return(new BoundBadStatement(
                           F.Syntax,
                           ImmutableArray <BoundNode> .Empty,
                           hasErrors: true
                           ));
            }

            CreateNonReusableLocalProxies(
                variablesToHoist,
                out this.nonReusableLocalProxies,
                out this.nextFreeHoistedLocalSlot
                );

            this.hoistedVariables = variablesToHoist;

            GenerateMethodImplementations();

            // Return a replacement body for the kickoff method
            return(GenerateKickoffMethodBody());
        }
예제 #2
0
        protected override void GenerateControlFields()
        {
            this.stateField = F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeStateMachineStateFieldName());

            // Add a field: T current
            _currentField = F.StateMachineField(_elementType, GeneratedNames.MakeIteratorCurrentFieldName());

            // if it is an enumerable, and either Environment.CurrentManagedThreadId or Thread.ManagedThreadId are available
            // add a field: int initialThreadId
            bool addInitialThreadId = _isEnumerable && CanGetThreadId();

            _initialThreadIdField = addInitialThreadId
                ? F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeIteratorCurrentThreadIdFieldName())
                : null;
        }
예제 #3
0
        protected override void GenerateControlFields()
        {
            this.stateField = F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeStateMachineStateFieldName());

            // Add a field: T current
            _currentField = F.StateMachineField(_elementType, GeneratedNames.MakeIteratorCurrentFieldName());

            // if it is an enumerable, and either Environment.CurrentManagedThreadId or System.Thread are available
            // add a field: int initialThreadId
            bool addInitialThreadId =
                _isEnumerable &&
                ((object)F.WellKnownMember(WellKnownMember.System_Threading_Thread__ManagedThreadId, isOptional: true) != null ||
                 (object)F.WellKnownMember(WellKnownMember.System_Environment__CurrentManagedThreadId, isOptional: true) != null);

            _initialThreadIdField = addInitialThreadId
                ? F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeIteratorCurrentThreadIdFieldName())
                : null;
        }