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"); }
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); }
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); }
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"); }
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); }
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); }
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); }
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)); }