Пример #1
0
        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));
        }
Пример #2
0
 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;
 }
Пример #3
0
 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;
 }
Пример #4
0
        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)");
            }
        }
Пример #5
0
        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();
            }
        }
Пример #6
0
        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);
                        }
                    }
                }
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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;
            }
        }
Пример #9
0
        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);
                    }
                }
            }
        }