예제 #1
0
        protected override void GenerateConvertGhosts_LH()
        {
            var ps = new List <string>();

            foreach (var varName in pgp.symbolsHigh.Globals.VariableNames)
            {
                var v = pgp.symbolsLow.Globals.Lookup(varName);
                if (v == null)
                {
                    v = pgp.symbolsHigh.Globals.Lookup(varName);
                    if (v is GlobalGhostArmadaVariable ghost)
                    {
                        var p = ResolveInit(ghost.initialValue);
                        if (p == null)
                        {
                            AH.PrintError(pgp.prog, $"Introduced ghost variable {varName} must be initialized");
                        }
                        ps.Add(p);
                    }
                }
                else if (v is GlobalGhostArmadaVariable)
                {
                    ps.Add($"ghosts.{v.FieldName}");
                }
            }
            var fn = $@"
        function ConvertGhosts_LH(ghosts: L.Armada_Ghosts) : H.Armada_Ghosts
        {{
          H.Armada_Ghosts({AH.CombineStringsWithCommas(ps)})
        }}
      ";

            pgp.AddFunction(fn, "convert");
        }
예제 #2
0
        public override void GenerateProof()
        {
            if (!CheckEquivalence())
            {
                AH.PrintError(pgp.prog, "Levels {pgp.mLow.Name} and {pgp.mHigh.Name} aren't sufficiently equivalent to perform refinement proof generation using the variable-hiding strategy");
                return;
            }
            AddIncludesAndImports();

            GeneratePCFunctions_L();
            MakeTrivialPCMap();
            GenerateNextRoutineMap();
            GenerateProofHeader();
            GenerateAtomicSpecs();
            GenerateInvariantProof(pgp);
            GenerateStateAbstractionFunctions_LH();
            GenerateConvertStep_LH();
            GenerateConvertAtomicPath_LH();
            GenerateLocalViewCommutativityLemmas();
            GenerateLiftingRelation();
            GenerateLiftAtomicPathLemmas();
            GenerateEstablishInitRequirementsLemma();
            GenerateEstablishStateOKRequirementLemma();
            GenerateEstablishRelationRequirementLemma();
            GenerateEstablishAtomicPathLiftableLemma();
            GenerateEstablishAtomicPathsLiftableLemma(false, false);
            GenerateLiftLAtomicToHAtomicLemma(false, false);
            GenerateFinalProof();
        }
예제 #3
0
        protected override void GenerateConvertGhosts_HL()
        {
            var ps = new List <string>();

            foreach (var varName in pgp.symbolsHigh.Globals.VariableNames)
            {
                if (introducedVariables.Contains(varName))
                {
                    continue;
                }
                var v = pgp.symbolsHigh.Globals.Lookup(varName);
                if (v is GlobalGhostArmadaVariable)
                {
                    ps.Add($"ghosts.{v.FieldName}");
                }
            }
            var fn = $@"
        function ConvertGhosts_HL(ghosts: H.Armada_Ghosts) : L.Armada_Ghosts
        {{
          L.Armada_Ghosts({AH.CombineStringsWithCommas(ps)})
        }}
      ";

            pgp.AddFunction(fn, "convert");
        }
예제 #4
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);
     }
 }
예제 #5
0
        private void GenerateCombiningRequest()
        {
            var acrequest = AH.MakeGenericTypeSpecific("ArmadaCombiningRequest",
                                                       new List <Type> {
                AH.ReferToType("LPlusState"),
                AH.ReferToType("L.Armada_TraceEntry"),
                AH.ReferToType("L.Armada_PC"),
                AH.ReferToType("HState"),
                AH.ReferToType("H.Armada_TraceEntry"),
                AH.ReferToType("H.Armada_PC")
            });

            pgp.MainProof.AddTypeSynonymDecl("ACRequest", acrequest);

            string str = @"
        function GetArmadaCombiningRequest() : ACRequest
        {
          ArmadaCombiningRequest(LPlus_GetSpecFunctions(), H.Armada_GetSpecFunctions(),
                                 GetLPlusHRefinementRelation(), InductiveInv,
                                 ConvertTotalState_LPlusH, ConvertTraceEntry_LH, ConvertPC_LH,  IsInnerPC)
        }
      ";

            pgp.AddFunction(str);
        }
예제 #6
0
        public override Expression GetValueInLValueState(ResolutionContext context)
        {
            var s   = context.GetLValueState();
            var mem = AH.MakeExprDotName(s, "mem", "Armada_SharedMemory");

            return(AH.MakeExprDotName(mem, "globals", "Armada_Globals"));
        }
예제 #7
0
        public override Expression UpdateTotalStateLocationDirectly(ResolutionContext context, IConstraintCollector constraintCollector,
                                                                    Expression val_new)
        {
            var s = context.GetLValueState();

            return(AH.MakeDatatypeUpdateExpr(s, "ghosts", val_new));
        }
예제 #8
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, non-datatype type {type}");
                return(null);
            }

            UserDefinedType ut = (UserDefinedType)type;

            if (context.symbols.DoesStructExist(ut.Name))
            {
                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);
                }
            }

            return(new UnaddressableFieldArmadaLValue(i_tok, ty, this, crashAvoidance, fieldName, false));
        }
예제 #9
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type ty)
        {
            if (!(type is SizedArrayType))
            {
                context.Fail(i_tok, "Attempt to obtain element of non-array type");
                return(null);
            }
            SizedArrayType st = (SizedArrayType)type;

            if (!AH.TypesMatch(st.Range, ty))
            {
                context.Fail(i_tok, $"Element of type {st.Range} used as type {ty}");
                return(null);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance + idx1.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 idx1_as_int = AH.ConvertToIntIfNotInt(idx1.Val);
            var field       = AH.MakeApply1("Armada_FieldArrayIndex", idx1_as_int, "Armada_Field");
            var child       = AH.MakeSeqSelectExpr(children, field, new PointerType(st.Range));

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

            return(new AddressableArmadaLValue(i_tok, st.Range, new ArmadaRValue(crashAvoidance, child)));
        }
예제 #10
0
        public override Expression UpdateTotalStateLocationDirectly(ResolutionContext context, IConstraintCollector constraintCollector,
                                                                    Expression val_new)
        {
            var s     = context.GetLValueState();
            var mem   = AH.MakeExprDotName(s, "mem", "Armada_SharedMemory");
            var h     = AH.MakeExprDotName(mem, "heap", "Armada_Heap");
            var valid = AH.GetInvocationOfValidPointer(h, address.Val, type);

            if (valid == null)
            {
                constraintCollector.Fail(tok, $"Type {type} is currently not supported in the heap");
            }
            else
            {
                constraintCollector.AddUndefinedBehaviorAvoidanceConstraint(valid);
            }

            var h_new = AH.GetInvocationOfUpdatePointer(h, address.Val, val_new);

            if (h_new == null)
            {
                constraintCollector.Fail(tok, $"Type {type} is currently not supported in the heap");
            }

            var mem_new = AH.MakeDatatypeUpdateExpr(mem, "heap", h_new);

            return(AH.MakeDatatypeUpdateExpr(s, "mem", mem_new));
        }
예제 #11
0
        private string InsertExtraMaterial(string name, string contents, int minPos = 0)
        {
            // Remove any "ProofCustomizationGoesHere();" and note its position.

            int insertionPos = contents.IndexOf("ProofCustomizationGoesHere();", minPos);

            if (insertionPos >= 0)
            {
                contents = contents.Substring(0, insertionPos) + contents.Substring(insertionPos + 29);
            }

            if (extraMaterial.ContainsKey(name))
            {
                string extra = extraMaterial[name];

                // If there was no "ProofCustomizationGoesHere();", use the position right after the first open brace.

                if (insertionPos < 0)
                {
                    var bracePos = contents.IndexOf("{", minPos);
                    if (bracePos < 0)
                    {
                        AH.PrintError(prog, $"Could not find place in contents of {name} to insert extra material");
                        return(contents);
                    }
                    insertionPos = bracePos + 1;
                }

                return(contents.Substring(0, insertionPos) + "\n" + extra + "\n" + contents.Substring(insertionPos));
            }
            else
            {
                return(contents);
            }
        }
예제 #12
0
        public override ArmadaRValue GetRValue(IToken tok, ResolutionContext context)
        {
            var globals = context.GetRValueGlobals();
            var val     = AH.MakeExprDotName(globals, name, ty);

            return(new ArmadaRValue(val));
        }
예제 #13
0
        public Expression Extract(Expression extra)
        {
            Expression e;

            if (extra != null)
            {
                var conjunctsPlusExtra = new List <Expression>(conjuncts);
                conjunctsPlusExtra.Add(extra);
                e = AH.CombineExpressionsWithAnd(conjunctsPlusExtra);
            }
            else
            {
                if (conjuncts.Count == 0)
                {
                    return(null);
                }
                e = AH.CombineExpressionsWithAnd(conjuncts);
            }

            for (int i = variableNames.Count - 1; i >= 0; --i)
            {
                e = AH.MakeLet1Expr(variableNames[i], variableValues[i], e);
            }

            return(e);
        }
예제 #14
0
        public ArmadaStruct(Program prog, ClassDecl c)
        {
            name       = c.Name;
            fieldTypes = new Dictionary <string, Type>();
            fieldNames = new List <string>();

            foreach (MemberDecl member in c.Members)
            {
                if (member is Field)
                {
                    var f = (Field)member;
                    if (!f.IsStatic)
                    {
                        fieldNames.Add(f.Name);
                        fieldTypes[f.Name] = f.Type;
                        if (f.InitialValue != null)
                        {
                            AH.PrintError(prog, $"Ignoring initializer {f.InitialValue} of field {f.Name} of struct {name}");
                        }
                    }
                    else
                    {
                        AH.PrintError(prog, $"Ignoring static field {f.Name} in struct");
                    }
                }
            }
        }
예제 #15
0
        public override string UpdateTotalStateLocationDirectly(ResolutionContext context, IConstraintCollector constraintCollector,
                                                                string val_new)
        {
            var s     = context.GetLValueState();
            var h     = $"({s}).mem.heap";
            var valid = AH.GetInvocationOfValidPointer(h, address.Val, type);

            if (valid == null)
            {
                constraintCollector.Fail(tok, $"Type {type} is currently not supported in the heap");
            }
            else
            {
                constraintCollector.AddUndefinedBehaviorAvoidanceConstraint(valid);
            }

            var h_new = AH.GetInvocationOfUpdatePointer(h, address.Val, val_new, type);

            if (h_new == null)
            {
                constraintCollector.Fail(tok, $"Type {type} is currently not supported in the heap");
            }

            return($"{s}.(mem := {s}.mem.(heap := {h_new}))");
        }
예제 #16
0
        ////////////////////////////////////////////////////////////////////////
        /// Checking that the layers are similar enough to generate a proof
        ////////////////////////////////////////////////////////////////////////

        // We have to override the default implementation of CheckGlobalsEquivalence because we need to
        // skip hidden variables.

        protected override bool CheckGlobalsEquivalence()
        {
            var globalVarsLow  = pgp.symbolsLow.Globals.VariableNames.Where(s => !hiddenVariables.Contains(s)).ToArray();
            var globalVarsHigh = pgp.symbolsHigh.Globals.VariableNames.ToArray();

            if (globalVarsLow.Length != globalVarsHigh.Length)
            {
                AH.PrintError(pgp.prog, $"There are {globalVarsLow.Length} global variables in level {pgp.mLow.Name} (not counting hidden ones) but {globalVarsHigh.Length} in level {pgp.mHigh.Name}");
                return(false);
            }

            for (int i = 0; i < globalVarsLow.Length; ++i)
            {
                if (globalVarsLow[i] != globalVarsHigh[i])
                {
                    AH.PrintError(pgp.prog, $"Global variable number {i+1} (not counting hidden ones) in level {pgp.mLow.Name} is {globalVarsLow[i]}, which doesn't match global variable number {i+1} in level {pgp.mHigh.Name} which is {globalVarsHigh[i]}");
                    return(false);
                }
                var name = globalVarsLow[i];
                if (!CheckGlobalVariableEquivalence(name, pgp.symbolsLow.Globals.Lookup(name), pgp.symbolsHigh.Globals.Lookup(name)))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #17
0
        ////////////////////////////////////////////////////////////////////////
        /// Abstraction functions
        ////////////////////////////////////////////////////////////////////////

        protected override void GenerateConvertGlobals_LH()
        {
            var ps = new List <string>();

            foreach (var varName in pgp.symbolsLow.Globals.VariableNames)
            {
                if (hiddenVariables.Contains(varName))
                {
                    continue;
                }
                var v = pgp.symbolsLow.Globals.Lookup(varName);
                if (v is GlobalUnaddressableArmadaVariable)
                {
                    ps.Add($"globals.{v.FieldName}");
                }
            }
            var fn = $@"
        function ConvertGlobals_LH(globals: L.Armada_Globals) : H.Armada_Globals
        {{
          H.Armada_Globals({AH.CombineStringsWithCommas(ps)})
        }}
      ";

            pgp.AddFunction(fn, "convert");
        }
예제 #18
0
 public override void GenerateProof()
 {
     if (!CheckEquivalence())
     {
         AH.PrintError(pgp.prog, "Levels {pgp.mLow.Name} and {pgp.mHigh.Name} aren't sufficiently equivalent to perform refinement proof generation using the variable-hiding strategy");
         return;
     }
     GetWeakenedPCSet();
     AddIncludesAndImports();
     MakeTrivialPCMap();
     GenerateNextRoutineMap();
     GenerateProofHeader();
     GenerateStarWeakeningRequest();
     GenerateStateAbstractionFunctions_LH();
     GeneratePCFunctions_L();
     foreach (var globalVarName in strategy.GlobalVars)
     {
         GenerateNoStoreBufferEntriesLemmas(globalVarName);
     }
     GenerateConvertTraceEntry_LH();
     GenerateStepRefiner();
     GenerateLocalViewCommutativityLemmas();
     GenerateLiftNextLemmas();
     GenerateAllActionsLiftableWeakenedLemmas();
     GenerateInitStatesEquivalentLemma();
     GenerateIsInvariantPredicateLemma();
     GenerateFinalProof();
 }
예제 #19
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);
            }
        }
예제 #20
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");
        }
예제 #21
0
        public override ArmadaRValue GetRValue(IToken tok, ResolutionContext context)
        {
            var top = context.GetRValueTopStackFrame();
            var correct_frame_type = AH.MakeExprDotName(top, $"Armada_StackFrame_{methodName}?", new BoolType());
            var crashAvoidance     = new UndefinedBehaviorAvoidanceConstraint(correct_frame_type);

            var addr = AH.MakeExprDotName(top, $"{methodName}'AddrOf'{name}", new PointerType(ty));

            var h = context.GetRValueHeap();

            var valid = AH.GetInvocationOfValidPointer(h, addr, ty);

            if (valid == null)
            {
                context.Fail(tok, "Type {ty} is not supported on the heap, and thus not for addressable stack variables either");
                return(null);
            }
            crashAvoidance.Add(valid);

            var val = AH.GetInvocationOfDereferencePointer(h, addr, ty);

            if (val == null)
            {
                context.Fail(tok, "Type {ty} is not supported on the heap, and thus not for addressable stack variables either");
            }
            return(new ArmadaRValue(crashAvoidance, val));
        }
예제 #22
0
 public void AddClassInfo(Program prog, ClassDecl c)
 {
     if (!c.IsDefaultClass)
     {
         AH.PrintError(prog, "Internal error:  ArmadaGlobalVariableSymbolTable.AddClassInfo called on non-default class");
         return;
     }
     foreach (MemberDecl member in c.Members)
     {
         if (member is Field)
         {
             var f = (Field)member;
             variableNames.Add(f.Name);
             ArmadaVariable av = null;
             if (f.IsGhost)
             {
                 av = new GlobalGhostArmadaVariable(f.Name, f.Type, f.InitialValue);
             }
             else if (f.IsNoAddr)
             {
                 av = new GlobalUnaddressableArmadaVariable(f.Name, f.Type, f.InitialValue);
             }
             else
             {
                 av = new GlobalAddressableArmadaVariable(f.Name, f.Type, f.InitialValue);
             }
             table.Add(f.Name, av);
         }
     }
 }
예제 #23
0
        public override ArmadaRValue GetRValue(IToken tok, ResolutionContext context)
        {
            var s     = context.GetRValueState();
            var addrs = AH.MakeExprDotName(s, "addrs", "Armada_Addrs");
            var addr  = AH.MakeExprDotName(addrs, name, new PointerType(ty));

            var h = context.GetRValueHeap();

            var valid = AH.GetInvocationOfValidPointer(h, addr, ty);

            if (valid == null)
            {
                context.Fail(tok, "Type {ty} is currently not supported in the heap");
                return(null);
            }
            var crashAvoidance = new UndefinedBehaviorAvoidanceConstraint(valid);

            var val = AH.GetInvocationOfDereferencePointer(h, addr, ty);

            if (val == null)
            {
                context.Fail(tok, "Type {ty} is currently not supported in the heap");
            }
            return(new ArmadaRValue(crashAvoidance, val));
        }
예제 #24
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type indexType, Type exprType)
        {
            if (!(type is SizedArrayType))
            {
                context.Fail(i_tok, "Attempt to obtain element of non-array type");
                return(null);
            }
            SizedArrayType st = (SizedArrayType)type;

            if (!AH.TypesMatch(st.Range, exprType))
            {
                context.Fail(i_tok, $"Element of type {st.Range} used as type {exprType}");
                return(null);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance + idx1.UndefinedBehaviorAvoidance;

            var s           = context.GetLValueState();
            var h           = $"({s}).mem.heap";
            var idx1_as_int = AH.ConvertToIntIfNotInt(idx1.Val, indexType);

            crashAvoidance.Add($"{address.Val} in {h}.tree");
            crashAvoidance.Add($"0 <= {idx1_as_int} < |{h}.tree[{address.Val}].children|");

            var child = $"{h}.tree[{address.Val}].children[{idx1_as_int}]";

            return(new AddressableArmadaLValue(i_tok, st.Range, new ArmadaRValue(crashAvoidance, child)));
        }
예제 #25
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));
        }
예제 #26
0
        protected override void GenerateConvertAtomicPath_LH()
        {
            string str;

            var skipped_strs = new List <string>();

            if (canHideTau)
            {
                str = @"
          predicate IsSkippedTauPath(s: LPlusState, path: LAtomic_Path, tid: Armada_ThreadHandle)
          {
            && path.LAtomic_Path_Tau?
            && tid in s.s.threads
            && |s.s.threads[tid].storeBuffer| > 0
            && !CanConvertStoreBufferEntry_LH(s.s.threads[tid].storeBuffer[0])
          }
        ";
                pgp.AddPredicate(str, "convert");

                skipped_strs.Add("IsSkippedTauPath(s, path, tid)");
            }

            string convert_str = @"
        function ConvertAtomicPath_LH(s: LPlusState, path: LAtomic_Path, tid: Armada_ThreadHandle) : HAtomic_Path
          requires LAtomic_ValidPath(s, path, tid)
          requires !IsSkippedPath(s, path, tid)
        {
          match path
      ";

            foreach (var lpath in lAtomic.AtomicPaths)
            {
                if (pathMap.ContainsKey(lpath))
                {
                    var hpath = pathMap[lpath];
                    var n     = lpath.NextRoutines.Count;
                    convert_str += $"case LAtomic_Path_{lpath.Name}(steps) => HAtomic_Path_{hpath.Name}(HAtomic_PathSteps_{hpath.Name}(";
                    convert_str += String.Join(", ", Enumerable.Range(0, n)
                                               .Where(i => nextRoutineMap.ContainsKey(lpath.NextRoutines[i]))
                                               .Select(i => $"ConvertStep_LH(steps.step{i})"));
                    convert_str += "))\n";
                }
                else
                {
                    skipped_strs.Add($"path.LAtomic_Path_{lpath.Name}?");
                }
            }

            convert_str += "}\n";

            pgp.AddPredicate($@"
        predicate IsSkippedPath(s: LPlusState, path: LAtomic_Path, tid: Armada_ThreadHandle)
        {{
          { AH.CombineStringsWithOr(skipped_strs) }
        }}
      ", "convert");

            pgp.AddFunction(convert_str, "convert");
        }
예제 #27
0
        public override ArmadaLValue GetLValue(IToken tok, ResolutionContext context)
        {
            var top = context.GetLValueTopStackFrame();
            var correct_frame_type = AH.MakeExprDotName(top, $"Armada_StackFrame_{methodName}?", new BoolType());
            var crashAvoidance     = new UndefinedBehaviorAvoidanceConstraint(correct_frame_type);

            return(new UnaddressableFieldArmadaLValue(tok, ty, new TopStackFrameArmadaLValue(crashAvoidance), crashAvoidance, $"{methodName}'{name}", true));
        }
예제 #28
0
 public void UseMethodAsThreadRoutine(string methodName)
 {
     if (allMethodsInfo.LookupMethod(methodName).AtomicCallsAndReturns)
     {
         AH.PrintError(prog, $"It's illegal to use create_thread on {methodName} since it uses atomic calls and returns.");
     }
     threadRoutines.Add(methodName);
 }
예제 #29
0
 public void Fail(IToken tok, string reason)
 {
     valid = false;
     if (reason != null)
     {
         AH.PrintError(prog, tok, reason);
     }
 }
예제 #30
0
        public override ArmadaLValue GetLValue(IToken tok, ResolutionContext context)
        {
            var s     = context.GetLValueState();
            var addrs = AH.MakeExprDotName(s, "addrs", "Armada_Addrs");
            var addr  = AH.MakeExprDotName(addrs, name, new PointerType(ty));

            return(new AddressableArmadaLValue(tok, ty, new ArmadaRValue(addr)));
        }