public static void updateInlinedMethods(Sink sink, IEnumerable <IMethodDefinition> doInline)
 {
     foreach (IMethodDefinition method in doInline)
     {
         Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(method);
         procInfo.Decl.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE));
     }
 }
 public void addNavigationUriHavocer(Sink sink)
 {
     Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(getUriHavocerMethod(sink).ResolvedMethod);
     procInfo.Decl.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE));
     Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
     Bpl.HavocCmd        havoc   =
         new Bpl.HavocCmd(Bpl.Token.NoToken,
                          new List <Bpl.IdentifierExpr>(new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {
         new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition))
     })));
     builder.Add(havoc);
     Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.TypeVariable>(),
                                                      new List <Bpl.Variable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(),
                                                      builder.Collect(Bpl.Token.NoToken));
     sink.TranslatedProgram.AddTopLevelDeclaration(impl);
 }
        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);
        }
Ejemplo n.º 4
0
        private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Contract.Assert(type.IsDelegate);
            IMethodDefinition invokeMethod = null;

            foreach (IMethodDefinition m in type.Methods)
            {
                if (m.Name.Value == "Invoke")
                {
                    invokeMethod = m;
                    break;
                }
            }

            try {
                IMethodDefinition  unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
                Sink.ProcedureInfo invokeProcedureInfo       = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
                Bpl.Procedure      invokeProcedure           = (Bpl.Procedure)invokeProcedureInfo.Decl;
                invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
                Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable;
                Bpl.IToken token            = invokeMethod.Token();

                List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>();
                for (int i = 1; i < invokeProcedure.InParams.Count; i++)
                {
                    Bpl.Variable v = invokeProcedure.InParams[i];
                    dispatchProcInExprs.Add(v);
                }
                List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>();
                foreach (Bpl.Variable v in invokeProcedure.OutParams)
                {
                    dispatchProcOutExprs.Add(v);
                }

                List <Bpl.Variable> localVariables = new List <Bpl.Variable>();
                Bpl.StmtListBuilder stmtBuilder    = new Bpl.StmtListBuilder();
                int localCounter = 0;
                foreach (IMethodDefinition defn in delegates)
                {
                    Bpl.Constant       c = sink.FindOrCreateDelegateMethodConstant(defn);
                    Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn);
                    Bpl.Procedure      delegateProcedure     = (Bpl.Procedure)delegateProcedureInfo.Decl;
                    Bpl.Formal         thisVariable          = delegateProcedureInfo.ThisVariable;
                    int numArguments = defn.ParameterCount;

                    List <Bpl.Variable> tempInputs  = new List <Bpl.Variable>();
                    List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>();

                    for (int i = 0; i < defn.ParameterCount; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempInputs.Add(localVariable);
                    }

                    for (int i = 0; i < delegateProcedure.OutParams.Count; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.OutParams[i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempOutputs.Add(localVariable);
                    }

                    List <Bpl.Expr>           ins  = new List <Bpl.Expr>();
                    List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>();
                    if (!defn.IsStatic)
                    {
                        ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)));
                    }
                    for (int i = 0; i < tempInputs.Count; i++)
                    {
                        ins.Add(Bpl.Expr.Ident(tempInputs[i]));
                    }
                    if (defn.IsGeneric)
                    {
                        for (int i = 0; i < defn.GenericParameterCount; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    if (defn.IsStatic)
                    {
                        int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType);
                        for (int i = 0; i < numTypeParameters; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    for (int i = 0; i < tempOutputs.Count; i++)
                    {
                        outs.Add(Bpl.Expr.Ident(tempOutputs[i]));
                    }

                    Bpl.Expr            bexpr         = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable));
                    Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
                    System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count);
                    if (tempInputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs);
                    }
                    ifStmtBuilder.Add(EmitDummySourceContext());
                    ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs));
                    System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count);
                    if (tempOutputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs);
                    }
                    stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null));
                }

                Bpl.Implementation dispatchImpl =
                    new Bpl.Implementation(token,
                                           invokeProcedure.Name,
                                           new List <Bpl.TypeVariable>(),
                                           invokeProcedure.InParams,
                                           invokeProcedure.OutParams,
                                           localVariables,
                                           stmtBuilder.Collect(token)
                                           );
                dispatchImpl.Proc = invokeProcedure;
                dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1));
                sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl);
            } catch (TranslationException te) {
                throw new NotImplementedException(te.ToString());
            } catch {
                throw;
            } finally {
                // Maybe this is a good place to add the procedure to the toplevel declarations
            }
        }