Пример #1
0
        public void Execute(DfirRoot dfirRoot, CompileCancellationToken cancellationToken)
        {
            var lifetimeGraphTree = dfirRoot.GetLifetimeGraphTree();
            BoundedLifetimeLiveVariableSet boundedLifetimeLiveVariableSet;

            while (_lifetimeVariableAssociation.TryGetBoundedLifetimeWithLiveVariables(out boundedLifetimeLiveVariableSet))
            {
                if (lifetimeGraphTree.IsDiagramLifetimeOfAnyLifetimeGraph(boundedLifetimeLiveVariableSet.Lifetime))
                {
                    // Since we assume there are no semantic errors at this point, just mark any remaining live variables
                    // in a diagram lifetime as consumed.
                    boundedLifetimeLiveVariableSet.LiveVariables.Select(l => l.Variable).ForEach(_lifetimeVariableAssociation.MarkVariableConsumed);
                    continue;
                }

                int inputVariableCount = boundedLifetimeLiveVariableSet.LiveVariables.Count();
                IEnumerable <VariableReference> interruptedVariables = _lifetimeVariableAssociation.GetVariablesInterruptedByLifetime(boundedLifetimeLiveVariableSet.Lifetime);
                int outputVariableCount = interruptedVariables.Count();

                Diagram startSearch = boundedLifetimeLiveVariableSet.LiveVariables.First().Terminal.ParentDiagram;
                LifetimeGraphIdentifier originGraphIdentifier = lifetimeGraphTree.GetBoundedLifetimeGraphIdentifier(boundedLifetimeLiveVariableSet.Lifetime);
                Diagram originDiagram = originGraphIdentifier.FindDiagramForGraphIdentifier(startSearch);

                LiveVariable[] liveVariables = boundedLifetimeLiveVariableSet.LiveVariables.ToArray();
                for (int i = 0; i < liveVariables.Length; ++i)
                {
                    LiveVariable liveVariable = liveVariables[i];
                    while (liveVariable.Terminal.ParentDiagram != originDiagram)
                    {
                        liveVariable = PullLiveVariableUpToNextHigherDiagram(liveVariable);
                    }
                    liveVariables[i] = liveVariable;
                }

                TerminateLifetimeNode terminateLifetime = TerminateLifetimeNodeHelpers.CreateTerminateLifetimeWithFacades(originDiagram, inputVariableCount, outputVariableCount);
                int inputIndex = 0;
                foreach (LiveVariable liveVariable in liveVariables)
                {
                    // TODO: maybe assert that liveVariable.Terminal is unwired here?
                    Terminal terminateLifetimeInputTerminal = terminateLifetime.InputTerminals[inputIndex];
                    Wire.Create(originDiagram, liveVariable.Terminal, terminateLifetimeInputTerminal);
                    terminateLifetimeInputTerminal.GetFacadeVariable().MergeInto(liveVariable.Variable);
                    _lifetimeVariableAssociation.MarkVariableConsumed(liveVariable.Variable);

                    ++inputIndex;
                }
                int outputIndex = 0;
                foreach (VariableReference interruptedVariable in interruptedVariables)
                {
                    Terminal terminateLifetimeOutputTerminal = terminateLifetime.OutputTerminals[outputIndex];
                    terminateLifetimeOutputTerminal.GetFacadeVariable().MergeInto(interruptedVariable);
                    _lifetimeVariableAssociation.MarkVariableLive(interruptedVariable, terminateLifetimeOutputTerminal);

                    ++outputIndex;
                }
            }
        }