Exemplo n.º 1
0
        public Expression AddVariableDeclaration(string varName, Expression value)
        {
            if (!valid)
            {
                Debug.Assert(false);
                return(null);
            }

            int count;

            if (variableUseCount.TryGetValue(varName, out count))
            {
                variableUseCount[varName] = count + 1;
                varName = $"{varName}{count+1}";
            }
            else
            {
                variableUseCount[varName] = 1;
            }

            var block = new PredicateBuilderBlock();

            block.AddVariableDeclaration(varName, value);
            blocks.Insert(0, block);

            return(AH.MakeNameSegment(varName, value.Type));
        }
Exemplo n.º 2
0
        private void ExtractOldVariablesForBodylessMethod(Program prog, ArmadaSymbolTable symbols, Method meth, ArmadaSingleMethodSymbolTable smst)
        {
            if (meth.Ens == null)
            {
                return;
            }
            if (!meth.Ens.Any())
            {
                return;
            }

            var s   = AH.MakeNameSegment("s", "Armada_TotalState");
            var tid = AH.MakeNameSegment("tid", "Armada_ThreadHandle");
            var failureCollector = new SimpleFailureReporter(prog);
            var ensContext       = new BodylessMethodSnapshotResolutionContext(s, tid, meth.Name, symbols, failureCollector);

            foreach (var ens in meth.Ens)
            {
                var ensResolvedJustToGetOldValues = ensContext.ResolveAsRValue(ens.E);
            }
            int whichOldValue = 0;

            foreach (var oldValue in ensContext.OldValues)
            {
                var varName = $"Armada_Old{whichOldValue}";
                var v       = new MethodStackFrameUnaddressableLocalArmadaVariable(varName, oldValue.Type, oldValue, ArmadaVarType.ExternOld, meth.Name);
                ++whichOldValue;
                smst.AddVariable(prog, v);
            }
        }
Exemplo n.º 3
0
 public override Expression GetStoreBufferLocationInfo(ref List <Expression> fields)
 {
     if (parent.NoTSO())
     {
         return(null);
     }
     if (parent is GlobalsArmadaLValue)
     {
         return(AH.MakeNameSegment($"Armada_GlobalStaticVar_{fieldName}", "Armada_GlobalStaticVar"));
     }
     else if (!(parent.Type is UserDefinedType))
     {
         return(null);
     }
     else
     {
         var ut  = (UserDefinedType)parent.Type;
         var ret = parent.GetStoreBufferLocationInfo(ref fields);
         if (ret == null)
         {
             return(null);
         }
         var struct_field_type = AH.MakeNameSegment($"Armada_FieldType_{ut.Name}'{fieldName}", "Armada_FieldType");
         var field             = AH.MakeApply1("Armada_FieldStruct", struct_field_type, "Armada_Field");
         fields.Add(field);
         return(ret);
     }
 }
Exemplo n.º 4
0
        protected override void GenerateConvertStackFrame_HL()
        {
            var cases       = new List <MatchCaseExpr>();
            var methodNames = pgp.symbolsHigh.MethodNames;

            foreach (var methodName in methodNames)
            {
                var smst = pgp.symbolsHigh.GetMethodSymbolTable(methodName);
                var ps   = new List <Expression>();
                var bvs  = new List <BoundVar>();
                foreach (var v in smst.AllVariablesInOrder)
                {
                    var ty = (v is AddressableArmadaVariable) ? AH.ReferToType("Armada_Pointer") : v.ty;
                    var e  = AH.MakeNameSegment(v.FieldName, ty);
                    if (methodName != strategy.MethodName || v.name != strategy.VariableName)
                    {
                        ps.Add(e);
                    }
                    var bv = AH.MakeBoundVar(v.FieldName, v.GetFlattenedType(pgp.symbolsHigh));
                    bvs.Add(bv);
                }
                var case_body = AH.MakeApplyN($"L.Armada_StackFrame_{methodName}", ps, "L.Armada_StackFrame");
                cases.Add(AH.MakeMatchCaseExpr($"Armada_StackFrame_{methodName}", bvs, case_body));
            }

            var source  = AH.MakeNameSegment("frame", "H.Armada_StackFrame");
            var body    = AH.MakeMatchExpr(source, cases, "L.Armada_StackFrame");
            var formals = new List <Formal> {
                AH.MakeFormal("frame", "H.Armada_StackFrame")
            };
            var fn = AH.MakeFunction("ConvertStackFrame_HL", formals, body);

            pgp.AddDefaultClassDecl(fn, "convert");
        }
Exemplo n.º 5
0
        protected MatchCaseExpr GetTraceEntryCaseForUpdateToUpdateNextRoutine_LH(NextRoutine nextRoutine)
        {
            var highNextRoutine = nextRoutineMap[nextRoutine];
            var lowStmt         = (UpdateStmt)nextRoutine.armadaStatement.Stmt;
            var lowExprs        = lowStmt.Lhss;

            var highStmt  = (UpdateStmt)highNextRoutine.armadaStatement.Stmt;
            var highExprs = highStmt.Lhss;

            var pi = GetMatchingLowLevelLhssForHighLevelLhss(lowExprs, highExprs);

            var bvs = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };

            bvs.AddRange(nextRoutine.Formals.Select(f => AH.MakeBoundVar(f.LocalVarName, AddModuleNameToArmadaType(f.VarType, "L"))));

            var ps = new List <Expression> {
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };

            // ps.AddRange(nextRoutine.Formals.Select(f => AH.MakeNameSegment(f.LocalVarName, f.VarType))); // Use the tid (and any other) parameters from the bound vars in the case statement

            for (int i = 0; i < highExprs.Count; i++)
            {
                var context = new NormalResolutionContext(nextRoutine, pgp.symbolsLow);
                // Add the pi[i]'th rhs from the low-level update statement
                var        rhs = lowStmt.Rhss.ElementAt(pi[i]);
                Expression newRhs;
                if (rhs is ExprRhs)
                {
                    var erhs         = (ExprRhs)rhs;
                    var newRhsRValue = context.ResolveAsRValue(erhs.Expr);
                    newRhs = newRhsRValue.Val;
                }
                else // rhs must be HavocRhs here
                {
                    newRhs = AH.MakeNameSegment($"nondet{i}", lowExprs[pi[i]].Type);
                }
                if (highStmt.Rhss.ElementAt(i) is HavocRhs) // If the high level is a havoc-rhs, then it needs to be given the values
                {
                    ps.Add(newRhs);
                }
            }

            string nextRoutineName = nextRoutine.NameSuffix;
            string hname           = nextRoutineMap[nextRoutine].NameSuffix;
            var    case_body       = AH.MakeApplyN($"H.Armada_TraceEntry_{hname}", ps, "H.Armada_TraceEntry");
            var    case0           = AH.MakeMatchCaseExpr($"Armada_TraceEntry_{nextRoutineName}", bvs, case_body);

            return(case0);
        }
Exemplo n.º 6
0
        public Expression GetStoreBufferEntry(Expression val_new)
        {
            var loc = GetStoreBufferLocation();

            if (loc == null)
            {
                return(null);
            }
            var primitive_value_constructor = AH.MakeNameSegment(AH.GetPrimitiveValueConstructorName(val_new.Type), "Armada_PrimitiveValue");
            var boxed_val_new = AH.MakeApply1(primitive_value_constructor, val_new, "Armada_PrimitiveValue");

            return(AH.MakeApply2("Armada_StoreBufferEntry", loc, boxed_val_new, "Armada_StoreBufferEntry"));
        }
Exemplo n.º 7
0
 public Expression ReserveVariableName(string varName, Type ty)
 {
     if (variableUseCount.ContainsKey(varName))
     {
         AH.PrintError(prog, $"Internal error:  Attempt to reserve variable name that's already in use ({varName}).");
         return(null);
     }
     else
     {
         variableUseCount[varName] = 1;
         return(AH.MakeNameSegment(varName, ty));
     }
 }
Exemplo n.º 8
0
        protected MatchCaseExpr GetTraceEntryCaseForUpdateToSomehowNextRoutine_LH(NextRoutine nextRoutine)
        {
            var highNextRoutine = nextRoutineMap[nextRoutine];
            var lowStmt         = (UpdateStmt)nextRoutine.armadaStatement.Stmt;
            var lowExprs        = lowStmt.Lhss;

            var highStmt  = (SomehowStmt)highNextRoutine.armadaStatement.Stmt;
            var highExprs = highStmt.Mod.Expressions;

            var pi = GetMatchingLowLevelLhssForHighLevelLhss(lowExprs, highExprs);

            var bvs = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };

            bvs.AddRange(nextRoutine.Formals.Select(f => AH.MakeBoundVar(f.LocalVarName, AddModuleNameToArmadaType(f.VarType, "L"))));

            var ps = new List <Expression> {
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };

            ps.AddRange(nextRoutine.Formals.Select(f => AH.MakeNameSegment(f.LocalVarName, f.VarType))); // Use the tid (and any other) parameters from the bound vars in the case statement

            for (int i = 0; i < highExprs.Count; i++)
            {
                var context = new NormalResolutionContext(nextRoutine, pgp.symbolsLow);
                // Add the pi[i]'th rhs from the low-level update statement
                var        rhs = lowStmt.Rhss.ElementAt(pi[i]);
                Expression newRhs;
                if (rhs is ExprRhs)
                {
                    var erhs         = (ExprRhs)rhs;
                    var newRhsRValue = context.ResolveAsRValue(erhs.Expr);
                    newRhs = newRhsRValue.Val;
                }
                else
                {
                    AH.PrintError(pgp.prog, "Havoc RHS not yet supported");
                    return(null);
                }

                ps.Add(newRhs);
            }

            string nextRoutineName = nextRoutine.NameSuffix;
            string hname           = nextRoutineMap[nextRoutine].NameSuffix;
            var    case_body       = AH.MakeApplyN($"H.Armada_TraceEntry_{hname}", ps, "H.Armada_TraceEntry");
            var    case0           = AH.MakeMatchCaseExpr($"Armada_TraceEntry_{nextRoutineName}", bvs, case_body);

            return(case0);
        }
Exemplo n.º 9
0
        protected override void GenerateConvertStackFrame_LH()
        {
            var cases       = new List <MatchCaseExpr>();
            var methodNames = pgp.symbolsLow.MethodNames;

            foreach (var methodName in methodNames)
            {
                var smst        = pgp.symbolsLow.GetMethodSymbolTable(methodName);
                var ps          = new List <Expression>();
                var bvs         = new List <BoundVar>();
                var lowVarNames = new List <string>(smst.AllVariableNamesInOrder);
                foreach (var varName in lowVarNames)
                {
                    var v  = smst.LookupVariable(varName);
                    var ty = (v is AddressableArmadaVariable) ? AH.ReferToType("Armada_Pointer") : v.ty;
                    var e  = AH.MakeNameSegment(v.FieldName, ty);
                    ps.Add(e);
                    var bv = AH.MakeBoundVar(v.FieldName, v.GetFlattenedType(pgp.symbolsLow));
                    bvs.Add(bv);
                }

                smst = pgp.symbolsHigh.GetMethodSymbolTable(methodName);
                var highVars = new List <ArmadaVariable>(smst.AllVariablesInOrder);

                if (highVars.Count() != lowVarNames.Count())
                {
                    for (var i = 0; i < highVars.Count(); ++i)
                    {
                        if (!lowVarNames.Contains(highVars[i].name))
                        {
                            var v  = highVars[i];
                            var ty = (v is AddressableArmadaVariable) ? AH.ReferToType("Armada_Pointer") : v.ty;
                            ps.Insert(i, AH.MakeNameSegment(strategy.InitializationExpression, ty));
                        }
                    }
                }

                var case_body = AH.MakeApplyN($"H.Armada_StackFrame_{methodName}", ps, "H.Armada_StackFrame");
                cases.Add(AH.MakeMatchCaseExpr($"Armada_StackFrame_{methodName}", bvs, case_body));
            }

            var source  = AH.MakeNameSegment("frame", "L.Armada_StackFrame");
            var body    = AH.MakeMatchExpr(source, cases, "H.Armada_StackFrame");
            var formals = new List <Formal> {
                AH.MakeFormal("frame", "L.Armada_StackFrame")
            };
            var fn = AH.MakeFunction("ConvertStackFrame_LH", formals, body);

            pgp.AddDefaultClassDecl(fn, "convert");
        }
Exemplo n.º 10
0
        public override ArmadaLValue ApplyExprDotName(IToken i_tok, ResolutionContext context, string fieldName, Type ty)
        {
            if (!(type is UserDefinedType))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non-struct type {type}");
                return(null);
            }
            UserDefinedType ut = (UserDefinedType)type;

            if (!context.symbols.DoesStructExist(ut.Name))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non struct type {ut.Name}");
                return(null);
            }
            Type fieldType = context.symbols.GetStructFieldType(ut.Name, fieldName);

            if (fieldType == null)
            {
                context.Fail(i_tok, $"Attempt to take non-existent field ({fieldName}) in struct type {ut.Name}");
                return(null);
            }
            if (!AH.TypesMatch(fieldType, ty))
            {
                context.Fail(i_tok, $"Field {fieldName} of type {fieldType} used as type {ty}");
                return(null);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance;

            var s    = context.GetLValueState();
            var mem  = AH.MakeExprDotName(s, "mem", "Armada_SharedMemory");
            var h    = AH.MakeExprDotName(mem, "heap", "Armada_Heap");
            var tree = AH.MakeExprDotName(h, "tree", "Armada_Tree");

            crashAvoidance.Add(AH.MakeInExpr(address.Val, tree));

            var node     = AH.MakeSeqSelectExpr(tree, address.Val, "Armada_Node");
            var children = AH.MakeExprDotName(node, "children", AH.MakeChildrenType());
            var field    = AH.MakeApply1("Armada_FieldStruct",
                                         AH.MakeNameSegment($"Armada_FieldType_{ut.Name}'{fieldName}", "Armada_FieldType"),
                                         "Armada_Field");
            var child = AH.MakeSeqSelectExpr(children, field, new PointerType(fieldType));

            crashAvoidance.Add(AH.MakeInExpr(field, children));

            return(new AddressableArmadaLValue(i_tok, fieldType, new ArmadaRValue(crashAvoidance, child)));
        }
Exemplo n.º 11
0
        protected MatchCaseExpr GetTraceEntryCaseForIfToIfNextRoutine_LH(NextRoutine nextRoutine)
        {
            var highNextRoutine = nextRoutineMap[nextRoutine];
            var lowStmt         = (IfStmt)nextRoutine.armadaStatement.Stmt;
            var highStmt        = (IfStmt)highNextRoutine.armadaStatement.Stmt;

            var bvs = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };

            bvs.AddRange(nextRoutine.Formals.Select(f => AH.MakeBoundVar(f.LocalVarName, AddModuleNameToArmadaType(f.VarType, "L"))));

            var ps = new List <Expression> {
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };
            string nextRoutineName = nextRoutine.NameSuffix;
            string hname           = nextRoutineMap[nextRoutine].NameSuffix;
            var    case_body       = AH.MakeApplyN($"H.Armada_TraceEntry_{hname}", ps, "H.Armada_TraceEntry");
            var    case0           = AH.MakeMatchCaseExpr($"Armada_TraceEntry_{nextRoutineName}", bvs, case_body);

            return(case0);
        }
Exemplo n.º 12
0
        protected override MatchCaseExpr GetTraceEntryCaseForNormalNextRoutine_LH(NextRoutine nextRoutine)
        {
            string nextRoutineName = nextRoutine.NameSuffix;

            var bvs = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };

            bvs.AddRange(nextRoutine.Formals.Select(f => AH.MakeBoundVar(f.LocalVarName, AddModuleNameToArmadaType(f.VarType, "L"))));

            var ps = new List <Expression> {
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };

            ps.AddRange(nextRoutine.Formals.Select(f => AH.MakeNameSegment(f.LocalVarName, f.VarType)));

            if (nextRoutine.nextType == NextType.Call &&
                ((ArmadaCallStatement)nextRoutine.armadaStatement).CalleeName == strategy.MethodName ||
                nextRoutine.nextType == NextType.CreateThread &&
                ((nextRoutine.stmt as UpdateStmt).Rhss[0] as CreateThreadRhs).MethodName.val == strategy.MethodName)
            {
                var highRoutine = LiftNextRoutine(nextRoutine);
                var highFormals = new List <NextFormal>(highRoutine.Formals);
                for (var i = 0; i < highFormals.Count(); ++i)
                {
                    if (!nextRoutine.Formals.Any(f => f.LocalVarName == highFormals[i].LocalVarName))
                    {
                        ps.Insert(i + 1, AH.MakeNameSegment(strategy.InitializationExpression, highFormals[i].VarType));
                        break;
                    }
                }
            }

            string hname     = LiftNextRoutine(nextRoutine).NameSuffix;
            var    case_body = AH.MakeApplyN($"H.Armada_TraceEntry_{hname}", ps, "H.Armada_TraceEntry");
            var    case0     = AH.MakeMatchCaseExpr($"Armada_TraceEntry_{nextRoutineName}", bvs, case_body);

            return(case0);
        }
Exemplo n.º 13
0
        protected override void GenerateConvertTraceEntry_LH()
        {
            var cases = new List <MatchCaseExpr>();

            foreach (var nextRoutine in pgp.symbolsLow.NextRoutines)
            {
                cases.Add(GetTraceEntryCaseForNextRoutine_LH(nextRoutine));
            }

            ExpressionBuilder bodyBuilder = new ExpressionBuilder(pgp.prog);

            var ls    = AH.MakeNameSegment("ls", "L.Armada_TraceEntry");
            var entry = AH.MakeNameSegment("entry", "L.Armada_TraceEntry");
            var tid   = AH.MakeExprDotName(entry, "tid", "L.Armada_ThreadHandle");

            var locv    = AH.MakeApply2("L.Armada_GetThreadLocalView", ls, tid, "L.Armada_SharedMemory");
            var threads = AH.MakeExprDotName(ls, "threads", "map<Armada_ThreadHandle, Armada_Thread>");
            var t       = AH.MakeSeqSelectExpr(threads, tid, "L.Armada_Thread");

            // var t = AH.ParseExpression(pgp.prog, "", "ls.threads[tid]");

            locv = bodyBuilder.AddVariableDeclaration("locv", locv);
            t    = bodyBuilder.AddVariableDeclaration("t", t);

            var source = AH.MakeNameSegment("entry", "L.Armada_TraceEntry");
            var body   = AH.MakeMatchExpr(source, cases, "H.Armada_TraceEntry");

            bodyBuilder.SetBody(body);

            var formals = new List <Formal> {
                AH.MakeFormal("ls", "LState"), AH.MakeFormal("entry", "L.Armada_TraceEntry")
            };
            var validTraceEntryPredicate = AH.MakeApply2("L.Armada_ValidStep", ls, entry, new BoolType());

            var fn = AH.MakeFunctionWithReq("ConvertTraceEntry_LH", formals, validTraceEntryPredicate, bodyBuilder.Extract());

            pgp.AddDefaultClassDecl(fn, "convert");
        }
Exemplo n.º 14
0
        protected override MatchCaseExpr GetTraceEntryCaseForNormalNextRoutine_LH(NextRoutine nextRoutine)
        {
            string nextRoutineName = nextRoutine.NameSuffix;

            var bvs = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };

            bvs.AddRange(nextRoutine.Formals.Select(f => AH.MakeBoundVar(f.LocalVarName, AddModuleNameToArmadaType(f.VarType, "L"))));

            var ps = new List <Expression> {
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };
            var highRoutine = LiftNextRoutine(nextRoutine);

            ps.AddRange(highRoutine.Formals.Select(f => AH.MakeNameSegment(f.LocalVarName, f.VarType)));

            string hname     = LiftNextRoutine(nextRoutine).NameSuffix;
            var    case_body = AH.MakeApplyN($"H.Armada_TraceEntry_{hname}", ps, "H.Armada_TraceEntry");
            var    case0     = AH.MakeMatchCaseExpr($"Armada_TraceEntry_{nextRoutineName}", bvs, case_body);

            return(case0);
        }
Exemplo n.º 15
0
        public Expression AddVariableDeclaration(string varName, Expression value)
        {
            if (!valid)
            {
                return(null);
            }

            int count;

            if (variableUseCount.TryGetValue(varName, out count))
            {
                variableUseCount[varName] = count + 1;
                varName = $"{varName}{count+1}";
            }
            else
            {
                variableUseCount[varName] = 1;
            }

            variableNames.Add(varName);
            variableValues.Add(value);

            return(AH.MakeNameSegment(varName, value.Type));
        }
Exemplo n.º 16
0
        public void Extract(ModuleDefinition m, ArmadaSymbolTable symbols, List <MemberDecl> newDefaultClassDecls,
                            List <DatatypeCtor> entryCtors, List <MatchCaseExpr> overallNextCases,
                            List <MatchCaseExpr> validStepCases, List <MatchCaseExpr> crashAvoidanceCases,
                            List <MatchCaseExpr> getNextStateCases)
        {
            if (!valid)
            {
                return;
            }

            var entryFormals = new List <Formal> {
                AH.MakeFormal("tid", "Armada_ThreadHandle")
            };
            var commonFormals = new List <Formal> {
                AH.MakeFormal("s", "Armada_TotalState"),
                AH.MakeFormal("tid", "Armada_ThreadHandle")
            };
            var overallNextFormals = new List <Formal> {
                AH.MakeFormal("s", "Armada_TotalState"),
                AH.MakeFormal("s'", "Armada_TotalState"),
                AH.MakeFormal("tid", "Armada_ThreadHandle")
            };
            var caseArguments = new List <BoundVar> {
                AH.MakeBoundVar("tid", "Armada_ThreadHandle")
            };
            var commonMatchBodyArguments = new List <Expression>()
            {
                AH.MakeNameSegment("s", "Armada_TotalState"),
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };
            var overallNextMatchBodyArguments = new List <Expression>()
            {
                AH.MakeNameSegment("s", "Armada_TotalState"),
                AH.MakeNameSegment("s'", "Armada_TotalState"),
                AH.MakeNameSegment("tid", "Armada_ThreadHandle")
            };

            foreach (var f in formals)
            {
                var flattened_type = symbols.FlattenType(f.VarType);
                commonFormals.Add(AH.MakeFormal(f.LocalVarName, flattened_type));
                overallNextFormals.Add(AH.MakeFormal(f.LocalVarName, flattened_type));
                entryFormals.Add(AH.MakeFormal(f.GloballyUniqueVarName, flattened_type));
                caseArguments.Add(AH.MakeBoundVar(f.LocalVarName, flattened_type));
                commonMatchBodyArguments.Add(AH.MakeNameSegment(f.LocalVarName, flattened_type));
                overallNextMatchBodyArguments.Add(AH.MakeNameSegment(f.LocalVarName, flattened_type));
            }

            var nameSuffix = NameSuffix;
            var entryName  = $"Armada_TraceEntry_{nameSuffix}";

            entryCtors.Add(AH.MakeDatatypeCtor(entryName, entryFormals));

            var validStepFn        = AH.MakeNameSegment($"Armada_ValidStep_{nameSuffix}", (Type)null);
            var validStepMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, validStepFn, commonMatchBodyArguments), new BoolType());

            validStepCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, validStepMatchBody));
            var validStepPredBody = validStepBuilder.Extract();
            var validStepName     = $"Armada_ValidStep_{nameSuffix}";
            var validStepPred     = AH.MakePredicate(validStepName, commonFormals, validStepPredBody);

            newDefaultClassDecls.Add(validStepPred);

            var crashAvoidanceFn        = AH.MakeNameSegment($"Armada_UndefinedBehaviorAvoidance_{nameSuffix}", (Type)null);
            var crashAvoidanceMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, crashAvoidanceFn, commonMatchBodyArguments), new BoolType());

            crashAvoidanceCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, crashAvoidanceMatchBody));
            var crashAvoidanceName     = $"Armada_UndefinedBehaviorAvoidance_{nameSuffix}";
            var crashAvoidancePredBody = crashAvoidanceBuilder.Extract();
            var crashAvoidancePred     = AH.MakePredicateWithReq(crashAvoidanceName, commonFormals, validStepMatchBody, crashAvoidancePredBody);

            newDefaultClassDecls.Add(crashAvoidancePred);

            var getNextStateFn        = AH.MakeNameSegment($"Armada_GetNextState_{nameSuffix}", (Type)null);
            var getNextStateMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, getNextStateFn, commonMatchBodyArguments), "Armada_TotalState");

            getNextStateCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, getNextStateMatchBody));
            var getNextStateName   = $"Armada_GetNextState_{nameSuffix}";
            var getNextStateFnBody = getNextStateBuilder.Extract();
            var getNextStateReq    = AH.MakeAndExpr(validStepMatchBody, crashAvoidanceMatchBody);
            var getNextStateFunc   = AH.MakeFunctionWithReq(getNextStateName, commonFormals, getNextStateReq, getNextStateFnBody);

            newDefaultClassDecls.Add(getNextStateFunc);

            // predicate Armada_Next_{nameSuffix}(s:Armada_TotalState, s':Armada_TotalState, ...) {
            //     && Armada_ValidStep_{nameSuffix}(s, ...)
            //     && s' == if Armada_UndefinedBehaviorAvoidance(s, ...) then Armada_GetNextState(s, ...)
            //              else s.(stop_reason := Armada_StopReasonUndefinedBehavior)
            // }

            var s_with_undefined_behavior =
                AH.MakeDatatypeUpdateExpr(s, "stop_reason", AH.MakeNameSegment("Armada_StopReasonUndefinedBehavior", "Armada_StopReason"));
            var target_s_prime  = AH.MakeIfExpr(crashAvoidanceMatchBody, getNextStateMatchBody, s_with_undefined_behavior);
            var s_prime         = AH.MakeNameSegment("s'", "Armada_TotalState");
            var s_prime_correct = AH.MakeEqExpr(s_prime, target_s_prime);
            var overallNextBody = AH.MakeAndExpr(validStepMatchBody, s_prime_correct);
            var overallNextName = $"Armada_Next_{nameSuffix}";
            var overallNextPred = AH.MakePredicate(overallNextName, overallNextFormals, overallNextBody);

            newDefaultClassDecls.Add(overallNextPred);

            var overallNextFn        = AH.MakeNameSegment(overallNextName, (Type)null);
            var overallNextMatchBody = AH.SetExprType(new ApplySuffix(Token.NoToken, overallNextFn, overallNextMatchBodyArguments),
                                                      new BoolType());

            overallNextCases.Add(AH.MakeMatchCaseExpr(entryName, caseArguments, overallNextMatchBody));
        }
Exemplo n.º 17
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);
                    }
                }
            }
        }