private static PCNode GeneratePCStructureForMethodWithBody(MethodInfo methodInfo, HashSet <ArmadaPC> loopHeads) { ArmadaStatement parsedBody = methodInfo.ParsedBody; PCNode endNode = new ReturningPCNode(parsedBody.EndPC); PCNode startNode = parsedBody.GeneratePCStructureForStatement(endNode, null, null, loopHeads); return(new StartingPCNode(parsedBody.StartPC, startNode)); }
public MethodInfo(Program i_prog, ArmadaSymbolTable i_symbols, Method i_method) { prog = i_prog; symbols = i_symbols; method = i_method; numPCs = 0; constraints = new Dictionary <ArmadaPC, EnablingConstraintCollector>(); returnPCs = new List <ArmadaPC>(); nonyieldingPCs = new HashSet <ArmadaPC>(); parsedBody = null; atomicCallsAndReturns = false; }
public NextRoutine(Program i_prog, ArmadaSymbolTable i_symbols, NextType i_nextType, MethodInfo i_methodInfo, ArmadaStatement i_armadaStatement, Statement i_stmt, ArmadaPC i_startPC, ArmadaPC i_endPC, List <NextFormal> i_formals, string i_nameSuffix, bool i_undefinedBehavior, bool i_stopping) { prog = i_prog; symbols = i_symbols; nextType = i_nextType; methodInfo = i_methodInfo; armadaStatement = i_armadaStatement; stmt = i_stmt; startPC = i_startPC; endPC = i_endPC; formals = new List <NextFormal>(i_formals); nameSuffix = i_nameSuffix; undefinedBehavior = i_undefinedBehavior; stopping = i_stopping; }
public NextRoutineConstructor(Program i_prog, ArmadaSymbolTable i_symbols, NextType i_nextType, MethodInfo i_methodInfo, ArmadaStatement i_armadaStatement, Statement i_stmt, ArmadaPC i_startPC, ArmadaPC i_endPC) { prog = i_prog; symbols = i_symbols; nextType = i_nextType; validDefinedStepBuilder = new PredicateBuilder(i_prog, true); validUndefinedStepBuilder = new PredicateBuilder(i_prog, false); getNextStateBuilder = new ExpressionBuilder(i_prog); methodInfo = i_methodInfo; method = methodInfo == null ? null : methodInfo.method; armadaStatement = i_armadaStatement; stmt = i_stmt; startPC = i_startPC; endPC = i_endPC; formals = new List <NextFormal>(); valid = true; hasUndefinedBehaviorAvoidanceConstraint = false; definedBehaviorNextRoutine = null; undefinedBehaviorNextRoutine = null; s = ReserveVariableName("s"); entry = ReserveVariableName("entry"); tid = ReserveVariableName("tid"); t = ReserveVariableName("t"); locv = ReserveVariableName("locv"); if (startPC != null) { AddConjunct($"{t}.pc.{startPC}?"); AddConjunct($"{t}.top.Armada_StackFrame_{startPC.methodName}?"); if (methodInfo != null) { var constraints = methodInfo.GetEnablingConstraintCollector(startPC); if (constraints != null && !constraints.Empty) { AddConjunct($"Armada_EnablingConditions_{startPC}(s, tid)"); } } AddConjunct("Armada_UniversalStepConstraint(s, tid)"); } }
public void ParseMethodBody(ArmadaSymbolTable symbols) { var parse = new ParseInfo(prog, symbols, this); parsedBody = ArmadaStatement.ParseStatement(parse, method.Body); var startPC = GenerateOnePC(); returnPC = parsedBody.AssignPCs(startPC); ArmadaStatement.ComputeNonyieldingPCs(parsedBody, nonyieldingPCs); symbols.AssociateLabelWithPC("Start", startPC); symbols.AssociateLabelWithPC("End", returnPC); foreach (var statement in parsedBody) { statement.AssociateLabelsWithPCs(); statement.GenerateEnablingConstraints(); } }
public void ParseMethodBody(ArmadaSymbolTable symbols) { var context = new ParseContext(prog, symbols, this); parsedBody = ArmadaStatement.ParseStatement(context, method.Body); var startPC = GenerateOnePC(); var endPC = parsedBody.AssignPCs(prog, symbols, this, startPC); ArmadaStatement.CollectReturnPCs(parsedBody, returnPCs); ArmadaStatement.ComputeNonyieldingPCs(parsedBody, nonyieldingPCs); foreach (var statement in parsedBody) { if (statement is ArmadaAssumeStatement) { var s = (ArmadaAssumeStatement)statement; var assumePC = s.StartPC; if (!constraints.ContainsKey(assumePC)) { constraints[assumePC] = new EnablingConstraintCollector(prog); } s.AddEnablingConstraint(symbols, this, constraints[assumePC]); } } symbols.AssociateLabelWithPC("Start", startPC); symbols.AssociateLabelWithPC("End", endPC); foreach (var statement in parsedBody) { var stmt = statement.Stmt; if (stmt != null) { for (var lbl = stmt.Labels; lbl != null; lbl = lbl.Next) { if (lbl.Data != null && lbl.Data.Name != null) { symbols.AssociateLabelWithPC(lbl.Data.Name, statement.StartPC); } } } } }
private bool IsHiddenStatement(string methodName, ArmadaStatement stmt) { if (stmt is ArmadaUpdateStatement aus) { var us = (UpdateStmt)aus.Stmt; return(us.Lhss.All(lhs => IsVariableHidden(methodName, AH.GetLValueRootVariable(lhs)))); } else if (stmt is ArmadaSomehowStatement ashs) { var shs = (SomehowStmt)ashs.Stmt; return(shs.Mod.Expressions.Any() && shs.Mod.Expressions.All(lhs => IsVariableHidden(methodName, AH.GetLValueRootVariable(lhs)))); } else if (stmt is ArmadaVarDeclStatement avds) { var vds = (VarDeclStmt)avds.Stmt; return(vds.Locals.All(v => IsVariableHidden(methodName, v.Name))); } return(false); }
private void GenerateVarHidingPCMapForBlocks(string methodName, ArmadaStatement blockLow, ArmadaStatement blockHigh) { if (blockLow == null) { return; } if (blockHigh == null) { AH.PrintError(pgp.prog, $"No block in high level corresponding to block at {AH.TokenToString(blockLow.Stmt.Tok)} in low level."); return; } var pcLow = blockLow.StartPC; var pcHigh = blockHigh.StartPC; pcMap[pcLow] = pcHigh; var stmtsHigh = blockHigh.GetStatementsInBody().ToArray(); int whichStmtHigh = 0; foreach (var stmtLow in blockLow.GetStatementsInBody()) { if (IsHiddenStatement(methodName, stmtLow)) { pcMap[stmtLow.EndPC] = pcHigh; continue; } if (whichStmtHigh >= stmtsHigh.Length) { AH.PrintError(pgp.prog, $"Could not figure out how the low-level statement at {AH.TokenToString(stmtLow.Stmt.Tok)} is a hidden-variable assignment, but it doesn't seem to correspond to any high-level statement."); pcMap[stmtLow.EndPC] = pcHigh; continue; } var stmtHigh = stmtsHigh[whichStmtHigh]; if (stmtLow.RoughlyMatches(stmtHigh)) { if (stmtLow is ArmadaIfStatement ifLow) { var ifHigh = (ArmadaIfStatement)stmtHigh; GenerateVarHidingPCMapForBlocks(methodName, ifLow.ThenClause, ifHigh.ThenClause); GenerateVarHidingPCMapForBlocks(methodName, ifLow.ElseClause, ifHigh.ElseClause); } else if (stmtLow is ArmadaWhileStatement whileLow) { var whileHigh = (ArmadaWhileStatement)stmtHigh; GenerateVarHidingPCMapForBlocks(methodName, whileLow.Body, whileHigh.Body); } } else { AH.PrintError(pgp.prog, $"Could not figure out how the low-level statement at {AH.TokenToString(stmtLow.Stmt.Tok)} correponds to the high-level statement at {AH.TokenToString(stmtHigh.Stmt.Tok)}."); } pcHigh = stmtHigh.EndPC; pcMap[stmtLow.EndPC] = pcHigh; ++whichStmtHigh; } }
public NextRoutine(Program i_prog, ArmadaSymbolTable i_symbols, NextType i_nextType, MethodInfo methodInfo, ArmadaStatement i_armadaStatement, Statement i_stmt, ArmadaPC i_pc, ArmadaPC i_endPC) { prog = i_prog; symbols = i_symbols; nextType = i_nextType; validStepBuilder = new PredicateBuilder(i_prog); crashAvoidanceBuilder = new PredicateBuilder(i_prog); getNextStateBuilder = new ExpressionBuilder(i_prog); method = methodInfo != null ? methodInfo.method : null; armadaStatement = i_armadaStatement; stmt = i_stmt; pc = i_pc; endPC = i_endPC; formals = new List <NextFormal>(); valid = true; s = ReserveVariableName("s", "Armada_TotalState"); tid = ReserveVariableName("tid", "Armada_ThreadHandle"); locv = null; // s.stop_reason.Armada_NotStopped? var stop_reason = AH.MakeExprDotName(s, "stop_reason", "Armada_StopReason"); var not_stopped = AH.MakeExprDotName(stop_reason, "Armada_NotStopped?", new BoolType()); AddConjunct(not_stopped); // tid in s.threads var threads = AH.MakeExprDotName(s, "threads", AH.MakeThreadsType()); var tid_in_threads = AH.MakeInExpr(tid, threads); AddConjunct(tid_in_threads); // var t := s.threads[tid]; t = AddVariableDeclaration("t", AH.MakeSeqSelectExpr(threads, tid, "Armada_Thread")); // var locv := Armada_GetThreadLocalView(s, tid); locv = AH.MakeApply2("Armada_GetThreadLocalView", s, tid, "Armada_SharedMemory"); locv = AddVariableDeclaration("locv", locv); if (pc != null) { var current_pc = AH.MakeExprDotName(t, "pc", "Armada_PC"); var pc_correct = AH.MakeEqExpr(current_pc, AH.MakeNameSegment(pc.ToString(), "Armada_PC")); AddConjunct(pc_correct); // t.top.Armada_StackFrame_{methodName}? var top = AH.MakeExprDotName(t, "top", "Armada_StackFrame"); var top_frame_correct = AH.MakeExprDotName(top, $"Armada_StackFrame_{pc.methodName}?", new BoolType()); AddConjunct(top_frame_correct); if (methodInfo != null) { var constraints = methodInfo.GetEnablingConstraintCollector(pc); if (constraints != null && !constraints.Empty) { var enabling_condition = AH.MakeApply2($"Armada_EnablingConditions_{pc}", s, tid, new BoolType()); AddConjunct(enabling_condition); } } } }