protected override bool LocalFunctionEnd(
            LocalFunctionState savedState,
            LocalFunctionState currentState,
            ref LocalState stateAtReturn
            )
        {
            if (currentState.CapturedMask.IsNull)
            {
                currentState.CapturedMask         = GetCapturedBitmask();
                currentState.InvertedCapturedMask = currentState.CapturedMask.Clone();
                currentState.InvertedCapturedMask.Invert();
            }
            // Filter the modified state variables to only captured variables
            stateAtReturn.Assigned.IntersectWith(currentState.CapturedMask);
            if (NonMonotonicState.HasValue)
            {
                var state = NonMonotonicState.Value;
                state.Assigned.UnionWith(currentState.InvertedCapturedMask);
                NonMonotonicState = state;
            }

            // Build a list of variables that are both captured and read before assignment
            var capturedAndRead = currentState.ReadVars;

            capturedAndRead.IntersectWith(currentState.CapturedMask);

            // Union and check to see if there are any changes
            return(savedState.ReadVars.UnionWith(capturedAndRead));
        }
예제 #2
0
        /// <summary>
        /// State changes are handled by the base class. We override to find captured variables that
        /// have been read before they were assigned and determine if the set has changed.
        /// </summary>
        protected override bool LocalFunctionEnd(
            LocalFunctionState savedState,
            LocalFunctionState currentState,
            ref LocalState stateAtReturn)
        {
            // Build a list of variables that are both captured and read before assignment
            var capturedMask    = GetCapturedBitmask(ref currentState.ReadVars);
            var capturedAndRead = currentState.ReadVars;

            capturedAndRead.IntersectWith(capturedMask);

            // Union and check to see if there are any changes
            return(savedState.ReadVars.UnionWith(capturedAndRead));
        }
예제 #3
0
        protected override LocalFunctionState LocalFunctionStart(LocalFunctionState startState)
        {
            // Captured variables are definitely assigned if they are assigned on
            // all branches into the local function, so we store all reads from
            // possibly unassigned captured variables and later report definite
            // assignment errors if any of the captured variables is not assigned
            // on a particular branch.

            var savedState = new LocalFunctionState(UnreachableState());

            savedState.ReadVars = startState.ReadVars.Clone();
            startState.ReadVars.Clear();
            return(savedState);
        }
        /// <summary>
        /// At the local function's use site, checks that all variables read are assigned.
        /// </summary>
        protected override void VisitLocalFunctionUse(LocalFunctionSymbol localFunc, LocalFunctionState localFunctionState, SyntaxNode syntax)
        {
            _usedLocalFunctions.Add(localFunc);

            var reads = localFunctionState.ReadVars;

            // Start at slot 1 (slot 0 just indicates reachability)
            for (int slot = 1; slot < reads.Capacity; slot++)
            {
                if (reads[slot])
                {
                    var symbol = variableBySlot[slot].Symbol;
                    CheckIfAssignedDuringLocalFunctionReplay(symbol, syntax, slot);
                }
            }
        }
예제 #5
0
        protected override void VisitLocalFunctionUse(
            LocalFunctionSymbol localFunc,
            LocalFunctionState localFunctionState,
            SyntaxNode syntax,
            bool isCall)
        {
            _usedLocalFunctions.Add(localFunc);

            // Check variables that were read before being definitely assigned.
            var reads = localFunctionState.ReadVars;

            // Start at slot 1 (slot 0 just indicates reachability)
            for (int slot = 1; slot < reads.Capacity; slot++)
            {
                if (reads[slot])
                {
                    var symbol = variableBySlot[slot].Symbol;
                    CheckIfAssignedDuringLocalFunctionReplay(symbol, syntax, slot);
                }
            }

            base.VisitLocalFunctionUse(localFunc, localFunctionState, syntax, isCall);
        }