private static void InsertTerminateLifetimeBehindTerminal( Terminal lifetimeSource, TerminateLifetimeNode terminateLifetime, int index, LifetimeVariableAssociation lifetimeVariableAssociation) { Terminal terminateLifetimeInput = terminateLifetime.InputTerminals.ElementAt(index), terminateLifetimeOutput = terminateLifetime.OutputTerminals.ElementAt(index); // wiring: output if (lifetimeSource.IsConnected) { lifetimeSource.ConnectedTerminal.ConnectTo(terminateLifetimeOutput); } lifetimeSource.WireTogether(terminateLifetimeInput, SourceModelIdSource.NoSourceModelId); // variables: output terminateLifetimeInput.GetFacadeVariable().MergeInto(lifetimeSource.GetTrueVariable()); VariableReference facadeVariable = lifetimeSource.GetFacadeVariable(); terminateLifetimeOutput.GetFacadeVariable().MergeInto(facadeVariable); if (lifetimeVariableAssociation.IsLive(facadeVariable)) { lifetimeVariableAssociation.MarkVariableLive(facadeVariable, terminateLifetimeOutput); } }
protected void RunCompilationUpToAutomaticNodeInsertion(DfirRoot dfirRoot, CompileCancellationToken cancellationToken = null) { cancellationToken = cancellationToken ?? new CompileCancellationToken(); var lifetimeVariableAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToValidation(dfirRoot, cancellationToken, lifetimeVariableAssociation); if (DfirMessageHelper.CalculateIsBroken(dfirRoot)) { var messageBuilder = new StringBuilder("Compilation failed because DfirRoot has semantic errors:\n"); foreach (DfirNodeMessagePair messagePair in DfirMessageHelper.ListAllNodeUserMessages(dfirRoot, false)) { messageBuilder.AppendLine($"{messagePair.Node}: {messagePair.Message.Descriptor}"); } Assert.Fail(messageBuilder.ToString()); } new AutoBorrowTransform(lifetimeVariableAssociation).Execute(dfirRoot, cancellationToken); var nodeInsertionTypeUnificationResultFactory = new NodeInsertionTypeUnificationResultFactory(); new InsertTerminateLifetimeTransform(lifetimeVariableAssociation, nodeInsertionTypeUnificationResultFactory) .Execute(dfirRoot, cancellationToken); new InsertDropTransform(lifetimeVariableAssociation, nodeInsertionTypeUnificationResultFactory) .Execute(dfirRoot, cancellationToken); }
protected void RunCompilationUpToAutomaticNodeInsertion(DfirRoot dfirRoot, CompileCancellationToken cancellationToken = null) { cancellationToken = cancellationToken ?? new CompileCancellationToken(); var lifetimeVariableAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToValidation(dfirRoot, cancellationToken, lifetimeVariableAssociation); new AutoBorrowTransform(lifetimeVariableAssociation).Execute(dfirRoot, cancellationToken); new InsertTerminateLifetimeTransform(lifetimeVariableAssociation).Execute(dfirRoot, cancellationToken); new InsertDropTransform(lifetimeVariableAssociation).Execute(dfirRoot, cancellationToken); }
public void SetInterruptedVariables(LifetimeVariableAssociation lifetimeVariableAssociation) { if (_borrowRequired) { foreach (var facade in _facades) { lifetimeVariableAssociation.AddVariableInterruptedByLifetime(facade.FacadeVariable, BorrowLifetime); } } }
internal void RunSemanticAnalysisUpToValidation( DfirRoot dfirRoot, CompileCancellationToken cancellationToken = null, LifetimeVariableAssociation lifetimeVariableAssociation = null) { cancellationToken = cancellationToken ?? new CompileCancellationToken(); var unificationResults = new TerminalTypeUnificationResults(); RunSemanticAnalysisUpToSetVariableTypes(dfirRoot, cancellationToken, unificationResults, lifetimeVariableAssociation); new ValidateVariableUsagesTransform(unificationResults).Execute(dfirRoot, cancellationToken); }
public void CreateBorrowAndTerminateLifetimeNodes(LifetimeVariableAssociation lifetimeVariableAssociation) { if (_borrowRequired) { Node parentNode = _facades.First().Terminal.ParentNode; BorrowMode borrowMode = _mutableBorrow ? BorrowMode.Mutable : BorrowMode.Immutable; int borrowInputCount = _facades.Count; Diagram inputParentDiagram = _facades.First().Terminal.ParentDiagram; var explicitBorrow = new ExplicitBorrowNode(inputParentDiagram, borrowMode, borrowInputCount, true, false); AutoBorrowNodeFacade borrowNodeFacade = AutoBorrowNodeFacade.GetNodeFacade(explicitBorrow); foreach (var terminal in explicitBorrow.Terminals) { borrowNodeFacade[terminal] = new SimpleTerminalFacade(terminal, default(TypeVariableReference)); } int index = 0; foreach (var facade in _facades) { Terminal input = facade.Terminal; VariableReference ownerVariable = input.GetFacadeVariable(), borrowVariable; ((AutoborrowingInputTerminalFacade)facade).AddPostBorrowCoercion(ref input, out borrowVariable); InsertBorrowAheadOfTerminal(input, explicitBorrow, index, ownerVariable, borrowVariable); ++index; } List <TerminateLifetimeOutputTerminalFacade> terminates = new List <TerminateLifetimeOutputTerminalFacade>(); foreach (var terminal in parentNode.OutputTerminals) { var terminateFacade = _nodeFacade[terminal] as TerminateLifetimeOutputTerminalFacade; if (terminateFacade != null && _facades.Contains(terminateFacade.InputFacade)) { terminates.Add(terminateFacade); } } if (terminates.Count == borrowInputCount) { Diagram outputParentDiagram = terminates.First().Terminal.ParentDiagram; var terminateLifetime = TerminateLifetimeNodeHelpers.CreateTerminateLifetimeWithFacades(outputParentDiagram, borrowInputCount, borrowInputCount); index = 0; foreach (var terminate in terminates) { InsertTerminateLifetimeBehindTerminal(terminate.Terminal, terminateLifetime, index, lifetimeVariableAssociation); ++index; } } else if (terminates.Count > 0) { throw new InvalidOperationException("Mismatched terminates and borrows; not sure what to do"); } } }
internal void RunSemanticAnalysisUpToSetVariableTypes( DfirRoot dfirRoot, CompileCancellationToken cancellationToken = null, TerminalTypeUnificationResults unificationResults = null, LifetimeVariableAssociation lifetimeVariableAssociation = null) { cancellationToken = cancellationToken ?? new CompileCancellationToken(); unificationResults = unificationResults ?? new TerminalTypeUnificationResults(); lifetimeVariableAssociation = lifetimeVariableAssociation ?? new LifetimeVariableAssociation(); RunSemanticAnalysisUpToCreateNodeFacades(dfirRoot, cancellationToken); new MergeVariablesAcrossWiresTransform(lifetimeVariableAssociation, unificationResults).Execute(dfirRoot, cancellationToken); new FinalizeAutoBorrowsTransform().Execute(dfirRoot, cancellationToken); new MarkConsumedVariablesTransform(lifetimeVariableAssociation).Execute(dfirRoot, cancellationToken); }
public void LoopConditionTunnel_SetVariableTypes_OutputLifetimeHasCorrectInterruptedVariables() { DfirRoot function = DfirRoot.Create(); Loop loop = new Loop(function.BlockDiagram); LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop); var lifetimeAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToSetVariableTypes(function, null, null, lifetimeAssociation); VariableReference loopConditionOutputVariable = loopConditionTunnel.OutputTerminals[0].GetTrueVariable(), loopConditionInputVariable = loopConditionTunnel.InputTerminals[0].GetTrueVariable(); Lifetime lifetime = loopConditionOutputVariable.Lifetime; IEnumerable <VariableReference> interruptedVariables = lifetimeAssociation.GetVariablesInterruptedByLifetime(lifetime); Assert.AreEqual(1, interruptedVariables.Count()); Assert.AreEqual(loopConditionInputVariable, interruptedVariables.First()); }
public void ABLAndACRBorrowNodeWithTwoNonReferenceInputsWired_SetVariableTypes_LifetimeInterruptsExpectedVariables() { DfirRoot function = DfirRoot.Create(); ExplicitBorrowNode borrow = new ExplicitBorrowNode(function.BlockDiagram, BorrowMode.Immutable, 2, true, true); ConnectConstantToInputTerminal(borrow.InputTerminals[0], NITypes.Int32, false); ConnectConstantToInputTerminal(borrow.InputTerminals[1], NITypes.Int32, false); var lifetimeVariableAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToSetVariableTypes(function, null, null, lifetimeVariableAssociation); VariableReference borrowOutput = borrow.OutputTerminals[0].GetTrueVariable(); IEnumerable <VariableReference> interruptedVariables = lifetimeVariableAssociation.GetVariablesInterruptedByLifetime(borrowOutput.Lifetime); Assert.AreEqual(2, interruptedVariables.Count()); Assert.IsTrue(interruptedVariables.Contains(borrow.InputTerminals[0].GetTrueVariable())); Assert.IsTrue(interruptedVariables.Contains(borrow.InputTerminals[1].GetTrueVariable())); }
public override MocTransformManager GenerateMocTransformManager( CompileSpecification compileSpecification, DfirRoot sourceDfir, CompileCancellationToken cancellationToken) { TerminalTypeUnificationResults unificationResults = new TerminalTypeUnificationResults(); LifetimeVariableAssociation lifetimeVariableAssociation = new LifetimeVariableAssociation(); List <IDfirTransformBase> semanticAnalysisTransforms = new List <IDfirTransformBase>() { new CreateNodeFacadesTransform(), new MergeVariablesAcrossWiresTransform(lifetimeVariableAssociation, unificationResults), new FinalizeAutoBorrowsTransform(), new MarkConsumedVariablesTransform(lifetimeVariableAssociation), new ValidateVariableUsagesTransform(unificationResults), new ReflectVariablesToTerminalsTransform(), }; if (RebarFeatureToggles.IsRebarTargetEnabled) { semanticAnalysisTransforms.Add(new RebarSupportedTargetTransform(SemanticAnalysisTargetInfo)); } semanticAnalysisTransforms.Add(new StandardTypeReflectionTransform()); ReflectErrorsTransform.AddErrorReflection(semanticAnalysisTransforms, CompilePhase.SemanticAnalysis); if (!RebarFeatureToggles.IsRebarTargetEnabled) { semanticAnalysisTransforms.Add(new EmptyTargetDfirTransform()); } var nodeInsertionTypeUnificationResultFactory = new NodeInsertionTypeUnificationResultFactory(); List <IDfirTransformBase> toTargetDfirTransforms = new List <IDfirTransformBase>() { new AutoBorrowTransform(lifetimeVariableAssociation), new InsertTerminateLifetimeTransform(lifetimeVariableAssociation, nodeInsertionTypeUnificationResultFactory), new InsertDropTransform(lifetimeVariableAssociation, nodeInsertionTypeUnificationResultFactory), }; return(new StandardMocTransformManager( compileSpecification, sourceDfir, semanticAnalysisTransforms, toTargetDfirTransforms, _host.GetSharedExportedValue <ScheduledActivityManager>())); }
public void IterateTunnelWithIterableTypeWired_SetVariableTypes_OutputLifetimeHasCorrectInterruptedVariables() { DfirRoot function = DfirRoot.Create(); Loop loop = new Loop(function.BlockDiagram); var borrowTunnel = CreateIterateTunnel(loop); ConnectConstantToInputTerminal(borrowTunnel.InputTerminals[0], PFTypes.Int32, false); var lifetimeAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToSetVariableTypes(function, null, null, lifetimeAssociation); VariableReference borrowOutputVariable = borrowTunnel.OutputTerminals[0].GetTrueVariable(), borrowInputVariable = borrowTunnel.InputTerminals[0].GetTrueVariable(); Lifetime lifetime = borrowOutputVariable.Lifetime; IEnumerable <VariableReference> interruptedVariables = lifetimeAssociation.GetVariablesInterruptedByLifetime(lifetime); Assert.AreEqual(1, interruptedVariables.Count()); Assert.AreEqual(borrowInputVariable, interruptedVariables.First()); }
public void LockTunnel_SetVariableTypes_OutputLifetimeHasCorrectInterruptedVariables() { DfirRoot function = DfirRoot.Create(); Frame frame = Frame.Create(function.BlockDiagram); var lockTunnel = CreateLockTunnel(frame); FunctionalNode createLockingCell = ConnectCreateLockingCellToInputTerminal(lockTunnel.InputTerminals[0]); ConnectConstantToInputTerminal(createLockingCell.InputTerminals[0], PFTypes.Int32, false); var lifetimeAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToSetVariableTypes(function, null, null, lifetimeAssociation); VariableReference lockOutputVariable = lockTunnel.OutputTerminals[0].GetTrueVariable(), lockInputVariable = lockTunnel.InputTerminals[0].GetTrueVariable(); Lifetime lifetime = lockOutputVariable.Lifetime; IEnumerable <VariableReference> interruptedVariables = lifetimeAssociation.GetVariablesInterruptedByLifetime(lifetime); Assert.AreEqual(1, interruptedVariables.Count()); Assert.AreEqual(lockInputVariable, interruptedVariables.First()); }
public void FunctionNodeWithImmutableInOutParameter_SetVariableTypes_TrueVariableLifetimeInterruptsCorrectTypes() { NIType signatureType = Signatures.ImmutablePassthroughType; DfirRoot dfirRoot = DfirRoot.Create(); FunctionalNode functionalNode = new FunctionalNode(dfirRoot.BlockDiagram, signatureType); ConnectConstantToInputTerminal(functionalNode.InputTerminals[0], NITypes.Int32, false); var lifetimeVariableAssociation = new LifetimeVariableAssociation(); RunSemanticAnalysisUpToSetVariableTypes(dfirRoot, null, null, lifetimeVariableAssociation); Lifetime lifetime = functionalNode.InputTerminals[0].GetTrueVariable().Lifetime; Assert.IsTrue(lifetime.IsBounded); VariableReference inputVariable = functionalNode.InputTerminals[0].GetFacadeVariable(); IEnumerable <VariableReference> interruptedVariables = lifetimeVariableAssociation.GetVariablesInterruptedByLifetime(lifetime); Assert.AreEqual(1, interruptedVariables.Count()); Assert.AreEqual(inputVariable, interruptedVariables.First()); }
public InsertTerminateLifetimeTransform(LifetimeVariableAssociation lifetimeVariableAssociation) { _lifetimeVariableAssociation = lifetimeVariableAssociation; }
public void UpdateTerminateLifetimeOutputs(TerminateLifetimeNode terminateLifetimeNode, LifetimeVariableAssociation lifetimeVariableAssociation) { if (CommonLifetime != null) { IEnumerable <VariableReference> interruptedVariables = lifetimeVariableAssociation.GetVariablesInterruptedByLifetime(CommonLifetime); int outputCount = interruptedVariables.Count(); terminateLifetimeNode.RequiredOutputCount = outputCount; terminateLifetimeNode.UpdateOutputTerminals(outputCount); foreach (var outputTerminalPair in terminateLifetimeNode.OutputTerminals.Zip(interruptedVariables)) { Terminal outputTerminal = outputTerminalPair.Key; VariableReference decomposedVariable = outputTerminalPair.Value; if (decomposedVariable.IsValid) { outputTerminal.GetFacadeVariable().MergeInto(decomposedVariable); } } } else { foreach (Terminal outputTerminal in terminateLifetimeNode.OutputTerminals) { outputTerminal.GetFacadeVariable().MergeInto(outputTerminal.CreateNewVariableForUnwiredTerminal()); } } }
public InsertDropTransform(LifetimeVariableAssociation lifetimeVariableAssociation) { _lifetimeVariableAssociation = lifetimeVariableAssociation; }
public AutoBorrowTransform(LifetimeVariableAssociation lifetimeVariableAssociation) { _lifetimeVariableAssociation = lifetimeVariableAssociation; }
public void FinalizeTerminateLifetimeInputs(TerminateLifetimeNode terminateLifetimeNode, LifetimeVariableAssociation lifetimeVariableAssociation) { if (CommonLifetime != null && _state == State.VariablesInLifetimeRemaining) { // assume that none of the lifetimes of our inputs are going to change after this point foreach (var inputVariable in _inputVariables) { lifetimeVariableAssociation.MarkVariableConsumed(inputVariable); } List <VariableReference> unconsumedVariables = _parentDiagram .GetVariableSet() .GetUniqueVariableReferences() .Where(variable => variable.Lifetime == CommonLifetime && !lifetimeVariableAssociation.IsVariableConsumed(variable)) .ToList(); if (unconsumedVariables.Count == 0) { _state = State.AllVariablesInLifetimeTerminated; } int requiredInputCount = _inputVariables.Count + unconsumedVariables.Count; terminateLifetimeNode.RequiredInputCount = requiredInputCount; terminateLifetimeNode.UpdateInputTerminals(requiredInputCount); } UpdateTerminateLifetimeErrorState(terminateLifetimeNode); }
public InsertDropTransform(LifetimeVariableAssociation lifetimeVariableAssociation, ITypeUnificationResultFactory unificationResultFactory) { _lifetimeVariableAssociation = lifetimeVariableAssociation; _unificationResultFactory = unificationResultFactory; }
public MarkConsumedVariablesTransform(LifetimeVariableAssociation lifetimeVariableAssociation) { _lifetimeVariableAssociation = lifetimeVariableAssociation; }
public void CreateBorrowAndTerminateLifetimeNodes(LifetimeVariableAssociation lifetimeVariableAssociation) { DoForEachLifetimeGroup(l => l.CreateBorrowAndTerminateLifetimeNodes(lifetimeVariableAssociation)); }
public void SetLifetimeInterruptedVariables(LifetimeVariableAssociation lifetimeVariableAssociation) { DoForEachLifetimeGroup(l => l.SetInterruptedVariables(lifetimeVariableAssociation)); }
public MergeVariablesAcrossWiresTransform(LifetimeVariableAssociation lifetimeVariableAssociation, TerminalTypeUnificationResults typeUnificationResults) { _lifetimeVariableAssociation = lifetimeVariableAssociation; _typeUnificationResults = typeUnificationResults; }