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