コード例 #1
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
 public override StatementList WriteAddr(Addressable addr, Expression expr)
 {
     if (addr is InstanceField instanceField)
     {
         var instanceName = instanceField.Instance;
         var fieldName    = FieldTranslator.GetFieldName(instanceField.Field);
         if (Settings.SplitFieldsEnabled())
         {
             return(SplitFieldUpdate.ForKeyValue(instanceField, expr));
         }
         else
         {
             return(HeapUpdate.ForKeyValue(instanceField, expr));
         }
     }
     else if (addr is StaticField staticField)
     {
         var boogieVar = BoogieVariable.From(staticField);
         return(bg.VariableAssignment(boogieVar, expr));
     }
     else if (addr is DotNetVariable v)
     {
         return(BoogieStatement.VariableAssignment(BoogieVariable.FromDotNetVariable(v.Var), expr));
     }
     else
     {
         throw new NotImplementedException();
     }
 }
コード例 #2
0
        public static void CreateAsyncStartMethod(StreamWriter sw)
        {
            StatementList stmts = new StatementList();

            var boogieGetTypeRes = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "asyncType");
            var stateMachineVar  = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "stateMachineCopy");

            stmts.Add(BoogieStatement.VariableDeclaration(stateMachineVar));
            stmts.Add(BoogieStatement.VariableDeclaration(boogieGetTypeRes));
            stmts.Add(BoogieStatement.FromString($"{stateMachineVar.Expr} := stateMachine;"));
            foreach (var asyncMethod in Helpers.asyncMoveNexts)
            {
                var asyncType = asyncMethod.ContainingTypeDefinition;
                var bg        = BoogieGenerator.Instance();
                stmts.Add(bg.ProcedureCall(BoogieMethod.GetTypeMethod, new List <Expression> {
                    stateMachineVar
                }, boogieGetTypeRes));
                StatementList ifStmts = new StatementList();
                ifStmts.Add(BoogieGenerator.Instance().ProcedureCall(BoogieMethod.From(asyncMethod), new List <Expression> {
                    stateMachineVar
                }));

                stmts.Add(BoogieStatement.If(Expression.Subtype(boogieGetTypeRes, asyncType), ifStmts));
            }
            stmts.Add(BoogieStatement.FromString($"v0$out := {stateMachineVar.Expr};"));

            sw.WriteLine(@"procedure {:extern} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start``1$``0$(this : Ref,stateMachine : Ref) returns (v0$out : Ref) {");
            foreach (var stmt in stmts)
            {
                sw.WriteLine(stmt.Stmt);
            }
            sw.WriteLine("}");
        }
コード例 #3
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList AllocLocalVariables(IList <IVariable> variables)
        {
            StatementList stmts = new StatementList();

            // we allocate an address for all local variables
            // except they are a pointer, we are assuming that you can't take the address of a pointer
            foreach (var v in variables)
            {
                if (!(v.Type is IManagedPointerType))
                {
                    stmts.Add(dispatcher.AllocAddr(v));
                }
            }

            // load values into stack space
            foreach (var paramVariable in variables.Where(v => v.IsParameter))
            {
                // paramValue are variables in the three address code
                // however in boogie they are treated as values
                // those values are loaded into the stack memory space

                /*
                 * void foo(int x){
                 * }
                 *
                 * procedure foo(x : int){
                 *  var _x : Addr; // stack space (done in previous loop)
                 *  x_ := AllocAddr();
                 *
                 *  data(_x) := x; // we are doing this conceptually
                 * }
                 */
                var boogieParamVariable = BoogieParameter.FromDotNetVariable(paramVariable);

                if (paramVariable.Type is IManagedPointerType)
                {
                    stmts.Add(BoogieStatement.VariableAssignment(BoogieVariable.AddressVar(paramVariable), boogieParamVariable));
                    continue;
                }

                Addressable paramAddress = dispatcher.AddressOf(paramVariable);

                // boogie generator knows that must fetch paramVariable's address (_x and not x)
                stmts.Add(dispatcher.WriteAddr(paramAddress, boogieParamVariable));

                if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Object))
                {
                    stmts.Add(BoogieStatement.AllocObjectAxiom(paramVariable));
                }
                else if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Addr))
                {
                    stmts.Add(BoogieStatement.AllocAddrAxiom(paramVariable));
                }
            }

            return(stmts);
        }
コード例 #4
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList VariableAssignment(IVariable variableA, IValue value)
        {
            Constant      cons           = value as Constant;
            BoogieLiteral boogieConstant = null;

            if (cons != null)
            {
                boogieConstant = BoogieLiteral.FromDotNetConstant(cons);
            }


            var boogieType = Helpers.GetBoogieType(variableA);

            if (value is Constant)
            {
                if (boogieConstant != null)
                {
                    return(bg.VariableAssignment(variableA, boogieConstant));
                }
                else
                {
                    throw new NotImplementedException();
                    // return WriteAddr(variableA, value.ToString());
                }
            }
            else if (value is IVariable && !(value.Type is IManagedPointerType))
            { // right operand is not a pointer (therefore left operand is not a pointer)
                return(dispatcher.WriteAddr(dispatcher.AddressOf(variableA), dispatcher.ReadAddr(value as IVariable)));
            }
            else if (value is Dereference)
            {
                var dereference = value as Dereference;
                var content     = dispatcher.ReadAddr(dereference.Reference);
                return(dispatcher.WriteAddr(dispatcher.AddressOf(variableA), content));
            }
            else if (value.Type is IManagedPointerType)
            {
                // if the right operand is a pointer also the left one is a pointer
                // there are two cases for value:
                // 1) value has the form &<something> (in analysis-net this is a Reference object)
                // 2) value is just a variable (static, instance, local, array element) with pointer type
                // for 1) we want to take the allocated address of something and assign it to the boogie variable of the left operand
                // for 2) we just want to make a boogie assignment between the boogie variables of the left and right operands

                // AddressOf will do the work to separate case 1) and 2)
                var addr = dispatcher.AddressOf(value) as AddressExpression;
                Contract.Assume(addr != null);
                return(BoogieStatement.VariableAssignment(BoogieVariable.AddressVar(variableA), addr.Expr));
            }

            Contract.Assert(false);
            // This shouldn't be reachable.
            throw new NotImplementedException();
        }
コード例 #5
0
ファイル: GetterSetterStubs.cs プロジェクト: m7nu3l/TinyBCT
        public string SetProcedureStub(IMethodReference method)
        {
            FieldTranslator field      = new FieldTranslator();
            var             boogieName = field.BoogieNameForField(method.ContainingType, GetFieldName(method));
            var             paramType  = Helpers.GetBoogieType(method.Parameters.ElementAt(0));

            var get = new StatementList();

            get.Add(BoogieStatement.FromString(boogieName + "[obj] := " + "val;"));

            var t = new BoogieProcedureTemplate(BoogieMethod.From(method).Name, "", StatementList.Empty, get, "obj : Ref, val : " + paramType, String.Empty, false);

            return(t.TransformText());
        }
コード例 #6
0
ファイル: GetterSetterStubs.cs プロジェクト: m7nu3l/TinyBCT
        public string GetProcedureStub(IMethodReference method)
        {
            FieldTranslator field      = new FieldTranslator();
            var             boogieName = field.BoogieNameForField(method.ContainingType, GetFieldName(method));
            var             boogieType = Helpers.GetBoogieType(method.Type);

            var get = new StatementList();

            get.Add(BoogieStatement.FromString("$result := " + boogieName + "[obj];"));

            var t = new BoogieProcedureTemplate(BoogieMethod.From(method).Name, "", StatementList.Empty, get, "obj : Ref", String.Format(" returns  ( $result : {0})", boogieType.ToString()), false);

            return(t.TransformText());
        }
コード例 #7
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList DeclareLocalVariables(IList <IVariable> variables, Dictionary <string, BoogieVariable> temporalVariables)
        {
            StatementList stmts = new StatementList();

            foreach (var v in variables.Where(v => !v.IsParameter))
            {
                stmts.Add(BoogieStatement.VariableDeclaration(v));
            }

            foreach (var kv in temporalVariables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(kv.Value));
            }

            return(stmts);
        }
コード例 #8
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        // hides implementation in super class
        //public new string VariableAssignment(string variableA, string expr)
        //{
        //    return string.Format("{0} := {1};", variableA, expr);
        //}

        public override StatementList DeclareLocalVariables(IList <IVariable> variables, Dictionary <string, BoogieVariable> temporalVariables)
        {
            var stmts = new StatementList();

            foreach (var v in variables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(BoogieVariable.AddressVar(v)));
            }

            foreach (var kv in temporalVariables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(kv.Value));
            }

            return(stmts);
        }
コード例 #9
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList AllocLocalVariables(IList <IVariable> variables)
        {
            StatementList stmts = new StatementList();

            // only allocate an address for variables that are referenced
            foreach (var v in variables)
            {
                if (RequiresAllocation(v))
                {
                    stmts.Add(AllocAddr(v));
                }
            }

            foreach (var paramVariable in variables.Where(v => v.IsParameter && (RequiresAllocation(v) || (v.Type is IManagedPointerType))))
            {
                var boogieParamVariable = BoogieParameter.FromDotNetVariable(paramVariable);

                //if (!RequiresAllocation(paramVariable))
                if (paramVariable.Type is IManagedPointerType)
                {
                    //BoogieVariable target = RequiresAllocation(paramVariable) || (paramVariable.Type is IManagedPointerType) ?
                    //    BoogieVariable.AddressVar(paramVariable) : BoogieVariable.FromDotNetVariable(paramVariable);

                    BoogieVariable target = BoogieVariable.AddressVar(paramVariable);
                    stmts.Add(BoogieStatement.VariableAssignment(target, boogieParamVariable));
                    continue;
                }

                Addressable paramAddress = AddressOf(paramVariable);

                // boogie generator knows that must fetch paramVariable's address (_x and not x)
                stmts.Add(WriteAddr(paramAddress, boogieParamVariable));

                if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Object))
                {
                    stmts.Add(BoogieStatement.AllocObjectAxiom(paramVariable));
                }
                else if (Helpers.GetBoogieType(paramVariable).Equals(Helpers.BoogieType.Addr))
                {
                    stmts.Add(BoogieStatement.AllocAddrAxiom(paramVariable));
                }
            }

            return(stmts);
        }
コード例 #10
0
        public string AsyncStubsScheduleTask(bool genericVersion = false)
        {
            StatementList localVars = new StatementList();

            localVars.Add(BoogieStatement.FromString("var state : bool;"));

            StatementList instructions = new StatementList();
            var           param0       = new BoogieVariable(Helpers.BoogieType.Object, "sm");


            var procIsCompleted = genericVersion ? BoogieMethod.AsyncStubsTaskAwaiterIsCompletedGeneric : BoogieMethod.AsyncStubsTaskAwaiterIsCompleted;
            var awaiterVar      = new BoogieVariable(Helpers.BoogieType.Object, "awaiter");
            var stateVar        = new BoogieVariable(Helpers.BoogieType.Bool, "state");
            var argsList        = new List <Expression>();

            argsList.Add(awaiterVar);
            var resList = new List <BoogieVariable>();

            resList.Add(stateVar);
            var callIsCompleted = BoogieStatement.ProcedureCall(procIsCompleted, argsList, resList, stateVar);

            var assume = BoogieStatement.Assume(Expression.BinaryOperationExpression(stateVar, new Expression(Helpers.BoogieType.Bool, "true"), Backend.ThreeAddressCode.Instructions.BinaryOperation.Eq));

            var yield = BoogieStatement.FromString("yield;");

            // it is crucial to yield before anything else
            instructions.Add(yield);
            instructions.Add(callIsCompleted);
            instructions.Add(assume);

            var moveNextMethods = stateMachinesTypes.Select(t => t.Members.Where(m => m.Name.Value.Contains("MoveNext")).First()).Cast <IMethodDefinition>();
            var ifCases         = moveNextMethods.Select(m => Invoke(m, param0));

            foreach (var ifCase in ifCases)
            {
                instructions.Add(ifCase);
            }

            string procedureName = genericVersion ? "$AsyncStubs`1$ScheduleTask" : "$AsyncStubs$ScheduleTask";

            var procedureTemplate = new BoogieProcedureTemplate(procedureName, "", localVars, instructions, "awaiter : Object, sm : Object", String.Empty, false);

            return(procedureTemplate.TransformText());
        }
コード例 #11
0
        public static void CreateAllAsyncMethods(StreamWriter sw)
        {
            StatementList stmts = new StatementList();

            Action <StatementList> fStmt = (s => stmts.Add(s));
            Action <string>        fStr  = (s => fStmt(BoogieStatement.FromString(s)));

            var taskVar       = BoogieVariable.GetTempVar(Helpers.ObjectType(), null, "task");
            var objectTypeStr = Helpers.ObjectType().FirstUppercase();

            fStr($"var resultAsync : [{objectTypeStr}] {objectTypeStr};");
            fStr($"var builder2task: [{objectTypeStr}] {objectTypeStr};");
            fStr($"procedure {{:extern}} System.Threading.Tasks.Task`1.get_Result(this : {objectTypeStr}) returns ($result : {objectTypeStr}) {{");
            fStr("$result := resultAsync[this];");
            fStr("}");
            fStr("");
            fStr($"procedure {{:extern}} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Create() returns ($result : {objectTypeStr}) {{");
            fStmt(BoogieStatement.VariableDeclaration(taskVar));
            var bg = BoogieGenerator.Instance();

            fStmt(bg.AllocObject(taskVar));
            fStmt(BoogieStatement.Assume(Expression.IsTask(taskVar)));
            var resultVar = BoogieVariable.ResultVar(Helpers.ObjectType());

            fStmt(bg.AllocObject(resultVar));

            fStmt(BoogieStatement.Assume(Expression.IsAsyncTaskMethodBuilder(resultVar)));
            fStr($"builder2task[$result] := {taskVar.Expr};");
            fStr("}");
            fStr($"procedure {{:extern}} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.get_Task(this : {objectTypeStr}) returns ($result : {objectTypeStr}) {{");
            fStr("$result := builder2task[this];");
            fStr("}");
            fStr($"procedure {{:extern}} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetResult$`0(this : {objectTypeStr},result : {objectTypeStr}) {{");
            fStr($"var task : {objectTypeStr};");
            fStr("task := builder2task[this];");
            fStr($"resultAsync[task] := result;");
            fStr("}");
            foreach (var stmt in stmts)
            {
                sw.WriteLine(stmt.Stmt);
            }
            CreateAsyncStartMethod(sw);
        }
コード例 #12
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList WriteAddr(Addressable addr, Expression expr)
        {
            if (addr is AddressExpression addrExpr)
            {
                if (expr.Type.Equals(Helpers.BoogieType.Addr))
                {
                    // pointer = pointer does not require map indexing in boogie
                    // it is just a variable assignment
                    BoogieVariable v = new BoogieVariable(expr.Type, addrExpr.Expr.Expr);
                    return(BoogieStatement.VariableAssignment(v, expr));
                }

                return(TypedMemoryMapUpdate.ForKeyValue(addrExpr, expr));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #13
0
        private StatementList Invoke(IMethodDefinition member, BoogieVariable receiver)
        {
            Expression receiverObject = receiver;

            if (receiver.Type.Equals(Helpers.BoogieType.Addr))
            {
                AddressExpression addrExpr = new AddressExpression(member.ContainingType, receiver);
                receiverObject = BoogieGenerator.Instance().ReadAddr(addrExpr);
            }

            Expression subtype = Expression.Subtype(Expression.DynamicType(receiverObject), member.ContainingType);

            StatementList     body         = new StatementList();
            List <Expression> argumentList = new List <Expression>();

            argumentList.Add(receiverObject);
            body.Add(BoogieGenerator.Instance().ProcedureCall(BoogieMethod.From(member), argumentList));
            body.Add(BoogieStatement.ReturnStatement);
            var ifExpr = BoogieStatement.If(subtype, body);

            return(ifExpr);
        }
コード例 #14
0
ファイル: Memory.cs プロジェクト: m7nu3l/TinyBCT
        public override StatementList DeclareLocalVariables(IList <IVariable> variables, Dictionary <string, BoogieVariable> temporalVariables)
        {
            var stmts = new StatementList();

            foreach (var v in variables)
            {
                if (RequiresAllocation(v) || v.Type is IManagedPointerType)
                {
                    stmts.Add(BoogieStatement.VariableDeclaration(BoogieVariable.AddressVar(v)));
                }
                else if (!v.IsParameter)
                {
                    stmts.Add(BoogieStatement.VariableDeclaration(v));
                }
            }

            foreach (var kv in temporalVariables)
            {
                stmts.Add(BoogieStatement.VariableDeclaration(kv.Value));
            }

            return(stmts);
        }