Пример #1
0
 private static void BuildAssignment(Sink sink, Bpl.StmtListBuilder stmtBuilder, List <Bpl.Variable> lvars, List <Bpl.Variable> rvars)
 {
     for (int i = 0; i < lvars.Count; i++)
     {
         Bpl.Variable       lvar  = lvars[i];
         Bpl.Type           ltype = lvar.TypedIdent.Type;
         Bpl.Variable       rvar  = rvars[i];
         Bpl.Type           rtype = rvar.TypedIdent.Type;
         Bpl.IdentifierExpr lexpr = Bpl.Expr.Ident(lvar);
         Bpl.Expr           rexpr = Bpl.Expr.Ident(rvar);
         if (rtype == ltype)
         {
             // do nothing
         }
         else if (ltype == sink.Heap.UnionType)
         {
             rexpr = sink.Heap.ToUnion(Bpl.Token.NoToken, rtype, rexpr, false, stmtBuilder);
         }
         else if (rtype == sink.Heap.UnionType)
         {
             rexpr = sink.Heap.FromUnion(Bpl.Token.NoToken, ltype, rexpr, false);
         }
         else
         {
             System.Diagnostics.Debug.Assert(false);
         }
         stmtBuilder.Add(TranslationHelper.BuildAssignCmd(lexpr, rexpr));
     }
 }
Пример #2
0
 public SymbolicVariable(string name, Variable variable) : base(Token.NoToken, CopyAndRename(variable.TypedIdent, name))
 {
     Expr        = new IdentifierExpr(Token.NoToken, this, /*immutable=*/ true);
     this.Origin = variable.GetProgramLocation();
     Debug.Assert(this.Origin.IsVariable, "Expected ProgramLocation to be a Variable");
     this.Name = name;
     Debug.WriteLine("Creating Symbolic " + this);
 }
Пример #3
0
        /* This function allows you to replace, for example:
         *
         *     Bpl.BoundVariable iVar = new Bpl.BoundVariable(e.tok, new Bpl.TypedIdent(e.tok, "$i", Bpl.Type.Int));
         *     Bpl.IdentifierExpr i = new Bpl.IdentifierExpr(e.tok, iVar);
         *
         * with:
         *
         *     Bpl.Expr i; var iVar = BplBoundVar("$i", Bpl.Type.Int, out i);
         */
        static Bpl.BoundVariable BplBoundVar(string name, Bpl.Type ty, out Bpl.Expr e)
        {
            Contract.Requires(ty != null);
            var v = new Bpl.BoundVariable(ty.tok, new Bpl.TypedIdent(ty.tok, name, ty));

            e = new Bpl.IdentifierExpr(ty.tok, name, ty);
            return(v);
        }
        public static Bpl.AssignCmd BuildAssignCmd(Bpl.IdentifierExpr lhs, Bpl.Expr rhs)
        {
            List <Bpl.AssignLhs> lhss = new List <Bpl.AssignLhs>();

            lhss.Add(new Bpl.SimpleAssignLhs(lhs.tok, lhs));
            List <Bpl.Expr> rhss = new List <Bpl.Expr>();

            rhss.Add(rhs);
            return(new Bpl.AssignCmd(lhs.tok, lhss, rhss));
        }
Пример #5
0
        public SymbolicVariable(string name, HavocCmd cmd, int varsIndex) : base(Token.NoToken, CopyAndRename(cmd.Vars[varsIndex].Decl.TypedIdent, name))
        {
            Expr        = new IdentifierExpr(Token.NoToken, this, /*immutable=*/ true);
            this.Origin = cmd.GetProgramLocation();
            Debug.Assert(this.Origin.IsCmd && (this.Origin.AsCmd is HavocCmd), "Expected ProgramLocation to be a HavocCmd");
            this.Name = name;
            Debug.WriteLine("Creating Symbolic " + this);

            // Should we record VarsIndex?
        }
Пример #6
0
        public SymbolicVariable(string name, Procedure proc, int modsetIndex) : base(Token.NoToken, CopyAndRename(proc.Modifies[modsetIndex].Decl.TypedIdent, name))
        {
            Expr        = new IdentifierExpr(Token.NoToken, this, /*immutable*/ true);
            this.Origin = proc.GetModSetProgramLocation();
            Debug.Assert(this.Origin.IsModifiesSet, "Expected ProgramLocation to be a modset");
            this.Name = name;
            Debug.WriteLine("Creating Symbolic " + this);

            // Should we record modSetIndex?
        }
Пример #7
0
 static Bpl.Formal BplFormalVar(string /*?*/ name, Bpl.Type ty, bool incoming, out Bpl.Expr e)
 {
     Bpl.Formal res;
     if (name == null)
     {
         name = Bpl.TypedIdent.NoName;
     }
     res = new Bpl.Formal(ty.tok, new Bpl.TypedIdent(ty.tok, name, ty), incoming);
     e   = new Bpl.IdentifierExpr(ty.tok, res);
     return(res);
 }
Пример #8
0
 /// <summary>
 /// Returns the (typed) BPL expression that corresponds to the value of the field
 /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null).
 /// </summary>
 /// <param name="o">The expression that represents the object to be dereferenced.
 /// </param>
 /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
 /// </param>
 public override Bpl.Expr ReadHeap(Bpl.Expr /*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType)
 {
     if (accessType == AccessType.Struct || accessType == AccessType.Heap)
     {
         Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr;
         Debug.Assert(field != null);
         return(Bpl.Expr.Select(field, o));
     }
     else
     {
         return(FromUnion(f.tok, unboxType, Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f), false));
     }
 }
Пример #9
0
        private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true);
            Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true);
            Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

            Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a);
            Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b);
            Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c);

            Bpl.Procedure proc = new Bpl.Procedure(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Requires>(),
                new List <Bpl.IdentifierExpr>(),
                new List <Bpl.Ensures>());
            proc.AddAttribute("inline", Bpl.Expr.Literal(1));
            sink.TranslatedProgram.AddTopLevelDeclaration(proc);

            Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
            stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr })));
            foreach (IMethodDefinition defn in delegates)
            {
                Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr))))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr))));
            }
            Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef);
            Bpl.IfCmd          ifCmd    = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken));
            ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd);

            Bpl.Implementation impl = new Bpl.Implementation(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Variable>(),
                BuildStmtList(ifCmd)
                );
            impl.AddAttribute("inline", Bpl.Expr.Literal(1));
            impl.Proc = proc;
            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
        }
Пример #10
0
 /// <summary>
 /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
 /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
 /// </summary>
 public override void WriteHeap(Bpl.IToken tok, Bpl.Expr /*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType, Bpl.StmtListBuilder builder)
 {
     Debug.Assert(o != null);
     Bpl.Cmd cmd;
     if (accessType == AccessType.Struct || accessType == AccessType.Heap)
     {
         Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr;
         Debug.Assert(field != null);
         cmd = Bpl.Cmd.MapAssign(tok, field, o, value);
     }
     else
     {
         cmd = TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(ArrayContentsVariable), Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, ToUnion(f.tok, boxType, value, false, builder))));
     }
     builder.Add(cmd);
 }
Пример #11
0
        private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Bpl.Formal method         = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true);
            Bpl.Formal receiver       = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true);
            Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true);
            Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

            Bpl.IdentifierExpr methodExpr         = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method);
            Bpl.IdentifierExpr receiverExpr       = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver);
            Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters);
            Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate);

            Bpl.Procedure proc = new Bpl.Procedure(
                Bpl.Token.NoToken,
                sink.DelegateCreate(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }),
                new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }),
                new List <Bpl.Requires>(),
                new List <Bpl.IdentifierExpr>(),
                new List <Bpl.Ensures>());
            proc.AddAttribute("inline", Bpl.Expr.Literal(1));
            sink.TranslatedProgram.AddTopLevelDeclaration(proc);

            Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
            stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { returnDelegateExpr })));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr)));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr)));
            foreach (IMethodDefinition defn in delegates)
            {
                Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie))));
            }
            Bpl.Implementation impl = new Bpl.Implementation(
                Bpl.Token.NoToken,
                sink.DelegateCreate(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }),
                new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }),
                new List <Bpl.Variable>(),
                stmtBuilder.Collect(Bpl.Token.NoToken));
            impl.AddAttribute("inline", Bpl.Expr.Literal(1));
            impl.Proc = proc;
            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
        }
Пример #12
0
        public IEnumerable <Bpl.IdentifierExpr> getModifiedIdentifiers(IMethodContract contract)
        {
            ICollection <Bpl.IdentifierExpr> modifiedExpr = new List <Bpl.IdentifierExpr>();

            foreach (IAddressableExpression mod in contract.ModifiedVariables)
            {
                ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, null, true);
                exptravers.Traverse(mod);
                Bpl.IdentifierExpr idexp = exptravers.TranslatedExpressions.Pop() as Bpl.IdentifierExpr;
                if (idexp == null)
                {
                    throw new TranslationException(String.Format("Cannot create IdentifierExpr for Modifyed Variable {0}", mod.ToString()));
                }
                modifiedExpr.Add(idexp);
            }

            return(modifiedExpr);
        }
        public void GenerateDispatchContinuation(ITryCatchFinallyStatement tryCatchFinallyStatement)
        {
            string continuationLabel = this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement);

            Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(true),
                                                TranslationHelper.BuildStmtList(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { continuationLabel }))), null, null);
            List <string> edges = sink.EscapingEdges(tryCatchFinallyStatement);

            Bpl.IdentifierExpr labelExpr = Bpl.Expr.Ident(this.sink.LabelVariable);
            for (int i = 0; i < edges.Count; i++)
            {
                string      label      = edges[i];
                Bpl.GotoCmd gotoCmd    = new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { label }));
                Bpl.Expr    targetExpr = Bpl.Expr.Literal(i);
                elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, labelExpr, targetExpr),
                                          TranslationHelper.BuildStmtList(gotoCmd), elseIfCmd, null);
            }
            this.StmtBuilder.Add(elseIfCmd);
        }
    public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def) {
      MethodBody callerBody = new MethodBody();
      MethodDefinition callerDef = new MethodDefinition() {
        InternFactory = (def as MethodDefinition).InternFactory,
        ContainingTypeDefinition = def.ContainingTypeDefinition,
        IsStatic = true,
        Name = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
        Type = sink.host.PlatformType.SystemVoid,
        Body = callerBody,
      };
      callerBody.MethodDefinition = callerDef;
      Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(def);
      Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

      Bpl.LocalVariable[] localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
      Bpl.IdentifierExpr[] varExpr = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
      for (int i = 0; i < procInfo.Decl.InParams.Count; i++) {
        Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                     new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                        procInfo.Decl.InParams[i].TypedIdent.Type));
        localVars[i] = loc;
        varExpr[i] = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
      }

      Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
      builder.Add(getResetNavigationCheck(sink));
      
      string pageXaml= PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());
      Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
      Bpl.Constant boogieXamlConstant;
      if (pageXaml != null)
        boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
      else
        boogieXamlConstant = null;
      // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
      // NAVIGATION TODO: ie, a network event handler
      if (boogieXamlConstant != null) {
        Bpl.AssumeCmd assumeCurrentPage =
          new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
        builder.Add(assumeCurrentPage);
      }

      // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
      Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
      builder.Add(assumeStartPage);
      builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List<Bpl.Expr>(varExpr), new List<Bpl.IdentifierExpr>()));
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
      Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

      Bpl.Expr guard= new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
      Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
      thenBuilder.Add(assertEndPage);
      Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

      builder.Add(ifNavigated);
      Bpl.Implementation impl =
        new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(),
                               new List<Bpl.Variable>(), new List<Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

      sink.TranslatedProgram.AddTopLevelDeclaration(impl);
      return impl.Proc;
    }
Пример #15
0
    private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates)
    {
        Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true);
        Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true);
        Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true);
        Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

        Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method);
        Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver);
        Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters);
        Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate);

        Bpl.Procedure proc = new Bpl.Procedure(
            Bpl.Token.NoToken,
            sink.DelegateCreate(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] {method, receiver, typeParameters}),
            new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}),
            new List<Bpl.Requires>(),
            new List<Bpl.IdentifierExpr>(),
            new List<Bpl.Ensures>());
        proc.AddAttribute("inline", Bpl.Expr.Literal(1));
        sink.TranslatedProgram.AddTopLevelDeclaration(proc);

        Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
        stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {returnDelegateExpr})));
        stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr)));
        stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr)));
        foreach (IMethodDefinition defn in delegates)
        {
            Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie))));
        }
        Bpl.Implementation impl = new Bpl.Implementation(
            Bpl.Token.NoToken, 
            sink.DelegateCreate(type), 
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), 
            new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}), 
            new List<Bpl.Variable>(),         
            stmtBuilder.Collect(Bpl.Token.NoToken));
        impl.AddAttribute("inline", Bpl.Expr.Literal(1));
        impl.Proc = proc;
        sink.TranslatedProgram.AddTopLevelDeclaration(impl);
    }
Пример #16
0
    private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates)
    {
        Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true);
        Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true);
        Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

        Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a);
        Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b);
        Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c);

        Bpl.Procedure proc = new Bpl.Procedure(
            Bpl.Token.NoToken,
            sink.DelegateRemove(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { a, b }),
            new List<Bpl.Variable>(new Bpl.Variable[] {c}),
            new List<Bpl.Requires>(),
            new List<Bpl.IdentifierExpr>(),
            new List<Bpl.Ensures>());
        proc.AddAttribute("inline", Bpl.Expr.Literal(1));
        sink.TranslatedProgram.AddTopLevelDeclaration(proc);

        Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
        stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {cExpr})));
        foreach (IMethodDefinition defn in delegates)
        {
            Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr))))));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr))));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr))));

        }
        Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef);
        Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken));
        ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd);

        Bpl.Implementation impl = new Bpl.Implementation(
            Bpl.Token.NoToken,
            sink.DelegateRemove(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { a, b }),
            new List<Bpl.Variable>(new Bpl.Variable[] {c}),
            new List<Bpl.Variable>(),
            BuildStmtList(ifCmd)
            );
        impl.AddAttribute("inline", Bpl.Expr.Literal(1));
        impl.Proc = proc;
        sink.TranslatedProgram.AddTopLevelDeclaration(impl);
    }
    // REVIEW: Does "thisExpr" really need to come back as an identifier? Can't it be a general expression?
    protected Bpl.DeclWithFormals TranslateArgumentsAndReturnProcedure(Bpl.IToken token, IMethodReference methodToCall, IMethodDefinition resolvedMethod, IExpression/*?*/ thisArg, IEnumerable<IExpression> arguments, out List<Bpl.Expr> inexpr, out List<Bpl.IdentifierExpr> outvars, out Bpl.IdentifierExpr thisExpr, out Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toUnioned) {
      inexpr = new List<Bpl.Expr>();
      outvars = new List<Bpl.IdentifierExpr>();

      #region Create the 'this' argument for the function call
      thisExpr = null;
      if (thisArg != null) {

        // Special case! thisArg is going to be an AddressOf expression if the receiver is a value-type
        // But if the method's containing type is something that doesn't get translated as a Ref, then
        // the AddressOf node should be ignored.
        var addrOf = thisArg as IAddressOf;
        var boogieType = this.sink.CciTypeToBoogie(methodToCall.ContainingType);
        if (false && addrOf != null && boogieType != this.sink.Heap.RefType) {
          thisArg = addrOf.Expression;
        }

        this.Traverse(thisArg);

        var e = this.TranslatedExpressions.Pop();
        var identifierExpr = e as Bpl.IdentifierExpr;
        if (identifierExpr == null) {
          var newLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(methodToCall.ContainingType));
          var cmd = Bpl.Cmd.SimpleAssign(token, newLocal, e);
          this.StmtTraverser.StmtBuilder.Add(cmd);
          e = newLocal;
        } else {

        }
        inexpr.Add(e);
        thisExpr = (Bpl.IdentifierExpr) e;
      }
      #endregion

      toUnioned = new Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>>();
      IEnumerator<IParameterDefinition> penum = resolvedMethod.Parameters.GetEnumerator();
      penum.MoveNext();
      foreach (IExpression exp in arguments) {
        if (penum.Current == null) {
          throw new TranslationException("More arguments than parameters in method call");
        }

        var expressionToTraverse = exp;
        //Bpl.Type boogieTypeOfExpression;

        //// Special case! exp can be an AddressOf expression if it is a value type being passed by reference.
        //// But since we pass reference parameters by in-out value passing, need to short-circuit the
        //// AddressOf node if the underlying type is not a Ref.
        //var addrOf = exp as IAddressOf;
        //if (addrOf != null) {
        //  boogieTypeOfExpression = this.sink.CciTypeToBoogie(addrOf.Expression.Type);
        //  if (boogieTypeOfExpression != this.sink.Heap.RefType) {
        //    expressionToTraverse = addrOf.Expression;
        //  }
        //}

        //boogieTypeOfExpression = this.sink.CciTypeToBoogie(expressionToTraverse.Type);
        this.Traverse(expressionToTraverse);

        Bpl.Expr e = this.TranslatedExpressions.Pop();
        var currentType = penum.Current.Type;

        // If the argument is a struct, then make a copy of it to pass to the procedure.
        if (TranslationHelper.IsStruct(exp.Type)) {
          var proc = this.sink.FindOrCreateProcedureForStructCopy(exp.Type);
          var bplLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(exp.Type));
          var cmd = new Bpl.CallCmd(token, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr> { bplLocal, });
          this.StmtTraverser.StmtBuilder.Add(cmd);
          e = bplLocal;
        }

        if (currentType is IGenericParameterReference && this.sink.CciTypeToBoogie(currentType) == this.sink.Heap.UnionType) {
            inexpr.Add(sink.Heap.ToUnion(token, this.sink.CciTypeToBoogie(expressionToTraverse.Type), e, TranslationHelper.IsStruct(expressionToTraverse.Type), StmtTraverser.StmtBuilder));
        } else {
            inexpr.Add(e);
        }
        if (penum.Current.IsByReference) {
          Bpl.IdentifierExpr unboxed = e as Bpl.IdentifierExpr;
          if (unboxed == null) {
            throw new TranslationException("Trying to pass a complex expression for an out or ref parameter");
          }
          if (penum.Current.Type is IGenericParameterReference) {
            var boogieType = this.sink.CciTypeToBoogie(penum.Current.Type);
            if (boogieType == this.sink.Heap.UnionType) {
              Bpl.IdentifierExpr boxed = Bpl.Expr.Ident(sink.CreateFreshLocal(this.sink.Heap.UnionType));
              toUnioned[unboxed] = Tuple.Create(boxed,false);
              outvars.Add(boxed);
            } else {
              outvars.Add(unboxed);
            }
          } else {
            outvars.Add(unboxed);
          }
        }
        penum.MoveNext();
      }

      if (resolvedMethod.IsStatic) {
        List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
        Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
        foreach (ITypeReference typeReference in consolidatedTypeArguments) {
          inexpr.Add(this.sink.FindOrCreateTypeReferenceInCodeContext(typeReference));
        }
      }
      IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
      if (methodInstanceReference != null) {
        foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
          inexpr.Add(this.sink.FindOrCreateTypeReferenceInCodeContext(typeReference));
        }
      }

      var procInfo = this.sink.FindOrCreateProcedure(resolvedMethod);
      var translateAsFunctionCall = procInfo.Decl is Bpl.Function;
      if (!translateAsFunctionCall) {
        if (resolvedMethod.Type.ResolvedType.TypeCode != PrimitiveTypeCode.Void) {
          Bpl.Variable v = this.sink.CreateFreshLocal(methodToCall.ResolvedMethod.Type.ResolvedType);
          Bpl.IdentifierExpr unUnioned = new Bpl.IdentifierExpr(token, v);
          if (resolvedMethod.Type is IGenericParameterReference) {
            var boogieType = this.sink.CciTypeToBoogie(resolvedMethod.Type);
            if (boogieType == this.sink.Heap.UnionType) {
              Bpl.IdentifierExpr unioned = Bpl.Expr.Ident(this.sink.CreateFreshLocal(this.sink.Heap.UnionType));
              toUnioned[unUnioned] = Tuple.Create(unioned, TranslationHelper.IsStruct(methodToCall.ResolvedMethod.Type.ResolvedType));
              outvars.Add(unioned);
            } else {
              outvars.Add(unUnioned);
            }
          } else {
            outvars.Add(unUnioned);
          }
          TranslatedExpressions.Push(unUnioned);
        }
      }

      return procInfo.Decl;
    }
Пример #18
0
        /// <summary>
        ///
        /// </summary>
        public override void TraverseChildren(IMethodDefinition method)
        {
            if (TranslationHelper.HasAttribute(method, "BCTOmitAttribute"))
            {
                return;
            }

            if (method.IsStaticConstructor)
            {
                this.sawCctor = true;
            }

            bool isEventAddOrRemove = method.IsSpecialName && (method.Name.Value.StartsWith("add_") || method.Name.Value.StartsWith("remove_"));

            if (isEventAddOrRemove)
            {
                return;
            }


            Sink.ProcedureInfo procInfo;
            IMethodDefinition  stubMethod = null;

            if (IsStubMethod(method, out stubMethod))
            {
                procInfo = this.sink.FindOrCreateProcedure(stubMethod);
            }
            else
            {
                procInfo = this.sink.FindOrCreateProcedure(method);
            }

            if (method.IsAbstract || method.IsExternal || TranslationHelper.HasAttribute(method, "BCTOmitImplementationAttribute")
                // CCI is currently hacked to skip decompiling all method bodies in
                // compiler-generated classes.  This is nontrivial to test for here, so
                // just omit implementation of all methods whose bodies haven't been
                // decompiled, at risk of silently hiding other problems.
                || !(method.Body is ISourceMethodBody))
            {
                // we're done, just define the procedure
                return;
            }

            this.sink.BeginMethod(method);
            var decl      = procInfo.Decl;
            var proc      = decl as Bpl.Procedure;
            var formalMap = procInfo.FormalMap;

            if (this.entryPoint != null && method.InternedKey == this.entryPoint.InternedKey)
            {
                decl.AddAttribute("entrypoint");
            }

            try {
                StatementTraverser stmtTraverser = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false);

                // Manually set the beginning of the method as the source location for
                // BCT synthetic code until we traverse the first real statement, which
                // will automatically pick up its source location.  Needed for record
                // calls to show up in the trace.
                stmtTraverser.EmitSourceContext(method);

                if (!method.IsStatic)
                {
                    stmtTraverser.AddRecordCall("this",
                                                sink.CciTypeToBoogie(method.ContainingType),
                                                new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.ThisVariable));
                }

                #region Add assignments from In-Params to local-Params

                foreach (MethodParameter mparam in formalMap)
                {
                    if (mparam.inParameterCopy != null)
                    {
                        Bpl.IToken tok = method.Token();
                        Bpl.Expr   rhs = new Bpl.IdentifierExpr(tok, mparam.inParameterCopy);
                        stmtTraverser.AddRecordCall(mparam.underlyingParameter.Name.Value,
                                                    mparam.inParameterCopy.TypedIdent.Type, rhs);
                        stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok,
                                                                           new Bpl.IdentifierExpr(tok, mparam.outParameterCopy), rhs));
                    }
                }

                #endregion

                #region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values
                var inits = InitializeFieldsInConstructor(method);
                if (0 < inits.Count)
                {
                    foreach (var s in inits)
                    {
                        stmtTraverser.Traverse(s);
                    }
                }
                #endregion

                #region Translate method attributes
                // Don't need an expression translator because there is a limited set of things
                // that can appear as arguments to custom attributes
                // TODO: decode enum values
                try {
                    foreach (var a in method.Attributes)
                    {
                        var attrName = TypeHelper.GetTypeName(a.Type);
                        if (attrName.EndsWith("Attribute"))
                        {
                            attrName = attrName.Substring(0, attrName.Length - 9);
                        }
                        var args = new List <object>();
                        foreach (var c in a.Arguments)
                        {
                            var mdc = c as IMetadataConstant;
                            if (mdc != null)
                            {
                                object o;
                                if (mdc.Type.IsEnum)
                                {
                                    var lit = Bpl.Expr.Literal((int)mdc.Value);
                                    lit.Type = Bpl.Type.Int;
                                    o        = lit;
                                }
                                else
                                {
                                    switch (mdc.Type.TypeCode)
                                    {
                                    case PrimitiveTypeCode.Boolean:
                                        o = (bool)mdc.Value ? Bpl.Expr.True : Bpl.Expr.False;
                                        break;

                                    case PrimitiveTypeCode.Int32:
                                        var lit = Bpl.Expr.Literal((int)mdc.Value);
                                        lit.Type = Bpl.Type.Int;
                                        o        = lit;
                                        break;

                                    case PrimitiveTypeCode.String:
                                        o = mdc.Value;
                                        break;

                                    default:
                                        throw new InvalidCastException("Invalid metadata constant type");
                                    }
                                }
                                args.Add(o);
                            }
                        }
                        decl.AddAttribute(attrName, args.ToArray());
                    }
                } catch (InvalidCastException) {
                    Console.WriteLine("Warning: Cannot translate custom attributes for method\n    '{0}':",
                                      MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
                    Console.WriteLine("    >>Skipping attributes, continuing with method translation");
                }
                #endregion

                #region Translate body
                var helperTypes = stmtTraverser.TranslateMethod(method);
                if (helperTypes != null)
                {
                    this.privateTypes.AddRange(helperTypes);
                }
                #endregion

                #region Create Local Vars For Implementation
                List <Bpl.Variable> vars = new List <Bpl.Variable>();
                foreach (MethodParameter mparam in formalMap)
                {
                    if (!mparam.underlyingParameter.IsByReference)
                    {
                        vars.Add(mparam.outParameterCopy);
                    }
                }
                foreach (Bpl.Variable v in this.sink.LocalVarMap.Values)
                {
                    vars.Add(v);
                }
                // LocalExcVariable holds the exception thrown by any method called from this method, even if this method swallows all exceptions
                if (0 < this.sink.Options.modelExceptions)
                {
                    vars.Add(procInfo.LocalExcVariable);
                }
                vars.Add(procInfo.LabelVariable);
                List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray());
                #endregion

                var translatedBody = stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken);

                #region Add implementation to Boogie program
                if (proc != null)
                {
                    Bpl.Implementation impl =
                        new Bpl.Implementation(method.Token(),
                                               decl.Name,
                                               new List <Bpl.TypeVariable>(),
                                               decl.InParams,
                                               decl.OutParams,
                                               vseq,
                                               translatedBody);

                    impl.Proc = proc;
                    this.sink.TranslatedProgram.AddTopLevelDeclaration(impl);
                }
                else // method is translated as a function
                //var func = decl as Bpl.Function;
                //Contract.Assume(func != null);
                //var blocks = new List<Bpl.Block>();
                //var counter = 0;
                //var returnValue = decl.OutParams[0];
                //foreach (var bb in translatedBody.BigBlocks) {
                //  var label = bb.LabelName ?? "L" + counter++.ToString();
                //  var newTransferCmd = (bb.tc is Bpl.ReturnCmd)
                //    ? new Bpl.ReturnExprCmd(bb.tc.tok, Bpl.Expr.Ident(returnValue))
                //    : bb.tc;
                //  var b = new Bpl.Block(bb.tok, label, bb.simpleCmds, newTransferCmd);
                //  blocks.Add(b);
                //}
                //var localVars = new List<Bpl.Variable>();
                //localVars.Add(returnValue);
                //func.Body = new Bpl.CodeExpr(localVars, blocks);
                {
                }
                #endregion
            } catch (TranslationException te) {
                Console.WriteLine("Translation error in body of \n    '{0}':",
                                  MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
                Console.WriteLine("\t" + te.Message + "\n" + te.StackTrace);
            } catch (Exception e) {
                Console.WriteLine("Error encountered during translation of \n    '{0}':",
                                  MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
                Console.WriteLine("\t>>" + e.Message + "\n" + e.StackTrace);
            } finally {
            }
        }
        public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def)
        {
            MethodBody       callerBody = new MethodBody();
            MethodDefinition callerDef  = new MethodDefinition()
            {
                InternFactory            = (def as MethodDefinition).InternFactory,
                ContainingTypeDefinition = def.ContainingTypeDefinition,
                IsStatic = true,
                Name     = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
                Type     = sink.host.PlatformType.SystemVoid,
                Body     = callerBody,
            };

            callerBody.MethodDefinition = callerDef;
            Sink.ProcedureInfo procInfo   = sink.FindOrCreateProcedure(def);
            Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

            Bpl.LocalVariable[]  localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
            Bpl.IdentifierExpr[] varExpr   = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
            for (int i = 0; i < procInfo.Decl.InParams.Count; i++)
            {
                Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                              new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                                 procInfo.Decl.InParams[i].TypedIdent.Type));
                localVars[i] = loc;
                varExpr[i]   = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
            }

            Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
            builder.Add(getResetNavigationCheck(sink));

            string pageXaml = PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());

            Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
            Bpl.Constant boogieXamlConstant;
            if (pageXaml != null)
            {
                boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
            }
            else
            {
                boogieXamlConstant = null;
            }
            // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
            // NAVIGATION TODO: ie, a network event handler
            if (boogieXamlConstant != null)
            {
                Bpl.AssumeCmd assumeCurrentPage =
                    new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                      Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                      new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
                builder.Add(assumeCurrentPage);
            }

            // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
            Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                                              Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                              new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
            builder.Add(assumeStartPage);
            builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.Expr>(varExpr), new List <Bpl.IdentifierExpr>()));
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
            Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                                                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

            Bpl.Expr            guard       = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
            Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
            thenBuilder.Add(assertEndPage);
            Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

            builder.Add(ifNavigated);
            Bpl.Implementation impl =
                new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(),
                                       new List <Bpl.Variable>(), new List <Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
            return(impl.Proc);
        }