public void RaiseException(Bpl.Expr e) { Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder(); RaiseExceptionHelper(builder); Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, e, builder.Collect(Bpl.Token.NoToken), null, null); StmtBuilder.Add(ifCmd); }
public void PropagateExceptionIfAny() { var cond = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)); var traverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); traverser.PropagateException(); Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, cond, traverser.StmtBuilder.Collect(Bpl.Token.NoToken), null, null); StmtBuilder.Add(ifCmd); }
public override void TraverseChildren(ISwitchStatement switchStatement) { var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); eTraverser.Traverse(switchStatement.Expression); var conditionExpr = eTraverser.TranslatedExpressions.Pop(); // Can't depend on default case existing or its index in the collection. var switchCases = new List <ISwitchCase>(); ISwitchCase defaultCase = null; foreach (var switchCase in switchStatement.Cases) { if (switchCase.IsDefault) { defaultCase = switchCase; } else { switchCases.Add(switchCase); } } Bpl.StmtList defaultStmts = null; if (defaultCase != null) { var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); defaultBodyTraverser.Traverse(defaultCase.Body); defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token()); } Bpl.IfCmd ifCmd = null; for (int i = switchCases.Count - 1; 0 <= i; i--) { var switchCase = switchCases[i]; var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); scTraverser.Traverse(switchCase.Expression); var scConditionExpr = scTraverser.TranslatedExpressions.Pop(); var condition = Bpl.Expr.Eq(conditionExpr, scConditionExpr); var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); scBodyTraverser.Traverse(switchCase.Body); ifCmd = new Bpl.IfCmd(switchCase.Token(), condition, scBodyTraverser.StmtBuilder.Collect(switchCase.Token()), ifCmd, defaultStmts); defaultStmts = null; // default body goes only into the innermost if-then-else } StmtBuilder.Add(ifCmd); }
/// <summary> /// /// </summary> /// <remarks>(mschaef) Works, but still a stub</remarks> /// <param name="conditionalStatement"></param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); if (this.sink.Options.instrumentBranches) { var tok = conditionalStatement.Token(); thenTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); elseTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); } condTraverser.Traverse(conditionalStatement.Condition); thenTraverser.Traverse(conditionalStatement.TrueBranch); elseTraverser.Traverse(conditionalStatement.FalseBranch); Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop(); Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(), conditionExpr, thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()), null, elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token()) ); StmtBuilder.Add(ifcmd); }
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); }
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 override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) { if (this.sink.Options.modelExceptions == 0) { this.Traverse(tryCatchFinallyStatement.TryBody); if (tryCatchFinallyStatement.FinallyBody != null) { this.Traverse(tryCatchFinallyStatement.FinallyBody); } return; } this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry)); this.Traverse(tryCatchFinallyStatement.TryBody); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1))); StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement) }))); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); StmtBuilder.AddLabelCmd(this.sink.FindOrCreateCatchLabel(tryCatchFinallyStatement)); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LocalExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef))); List <Bpl.StmtList> catchStatements = new List <Bpl.StmtList>(); List <Bpl.Expr> typeReferences = new List <Bpl.Expr>(); this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch)); foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses) { typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType, true)); StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); if (catchClause.ExceptionContainer != Dummy.LocalVariable) { Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer); catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable))); } catchTraverser.Traverse(catchClause.Body); catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1))); catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement) }))); catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token())); } Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(false), TranslationHelper.BuildStmtList(new Bpl.ReturnCmd(Bpl.Token.NoToken)), null, null); Bpl.Expr dynTypeOfOperand = this.sink.Heap.DynamicType(Bpl.Expr.Ident(this.sink.LocalExcVariable)); for (int i = 0; i < catchStatements.Count; i++) { Bpl.Expr expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Subtype), new List <Bpl.Expr>(new Bpl.Expr[] { dynTypeOfOperand, typeReferences[i] })); elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, expr, catchStatements[i], elseIfCmd, null); } this.StmtBuilder.Add(elseIfCmd); this.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable))); RaiseException(); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); this.StmtBuilder.AddLabelCmd(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)); if (tryCatchFinallyStatement.FinallyBody != null) { this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InFinally)); Bpl.Variable savedExcVariable = this.sink.CreateFreshLocal(this.sink.Heap.RefType); Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable))); this.Traverse(tryCatchFinallyStatement.FinallyBody); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable))); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); } GenerateDispatchContinuation(tryCatchFinallyStatement); StmtBuilder.AddLabelCmd(this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement)); Bpl.Expr raiseExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)); RaiseException(raiseExpr); }
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); }
private static Bpl.IfCmd BuildIfCmd(Bpl.Expr b, Bpl.Cmd cmd, Bpl.IfCmd ifCmd) { Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder(); ifStmtBuilder.Add(cmd); return(new Bpl.IfCmd(b.tok, b, ifStmtBuilder.Collect(b.tok), ifCmd, null)); }
public IfCmd(IToken/*!*/ tok, Expr guard, StmtList/*!*/ thn, IfCmd elseIf, StmtList elseBlock) : base(tok) { Contract.Requires(tok != null); Contract.Requires(thn != null); Contract.Requires(elseIf == null || elseBlock == null); this.Guard = guard; this.thn = thn; this.elseIf = elseIf; this.elseBlock = elseBlock; }
public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) { if (this.sink.Options.modelExceptions == 0) { this.Traverse(tryCatchFinallyStatement.TryBody); if (tryCatchFinallyStatement.FinallyBody != null) this.Traverse(tryCatchFinallyStatement.FinallyBody); return; } this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry)); this.Traverse(tryCatchFinallyStatement.TryBody); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1))); StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)}))); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); StmtBuilder.AddLabelCmd(this.sink.FindOrCreateCatchLabel(tryCatchFinallyStatement)); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LocalExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef))); List<Bpl.StmtList> catchStatements = new List<Bpl.StmtList>(); List<Bpl.Expr> typeReferences = new List<Bpl.Expr>(); this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch)); foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses) { typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType, true)); StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); if (catchClause.ExceptionContainer != Dummy.LocalVariable) { Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer); catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable))); } catchTraverser.Traverse(catchClause.Body); catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1))); catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)}))); catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token())); } Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(false), TranslationHelper.BuildStmtList(new Bpl.ReturnCmd(Bpl.Token.NoToken)), null, null); Bpl.Expr dynTypeOfOperand = this.sink.Heap.DynamicType(Bpl.Expr.Ident(this.sink.LocalExcVariable)); for (int i = 0; i < catchStatements.Count; i++) { Bpl.Expr expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Subtype), new List<Bpl.Expr>(new Bpl.Expr[] {dynTypeOfOperand, typeReferences[i]})); elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, expr, catchStatements[i], elseIfCmd, null); } this.StmtBuilder.Add(elseIfCmd); this.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable))); RaiseException(); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); this.StmtBuilder.AddLabelCmd(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)); if (tryCatchFinallyStatement.FinallyBody != null) { this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InFinally)); Bpl.Variable savedExcVariable = this.sink.CreateFreshLocal(this.sink.Heap.RefType); Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable))); this.Traverse(tryCatchFinallyStatement.FinallyBody); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable))); StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable))); this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1); } GenerateDispatchContinuation(tryCatchFinallyStatement); StmtBuilder.AddLabelCmd(this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement)); Bpl.Expr raiseExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)); RaiseException(raiseExpr); }
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 override void TraverseChildren(ISwitchStatement switchStatement) { var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); eTraverser.Traverse(switchStatement.Expression); var conditionExpr = eTraverser.TranslatedExpressions.Pop(); // Can't depend on default case existing or its index in the collection. var switchCases = new List<ISwitchCase>(); ISwitchCase defaultCase = null; foreach (var switchCase in switchStatement.Cases) { if (switchCase.IsDefault) { defaultCase = switchCase; } else { switchCases.Add(switchCase); } } Bpl.StmtList defaultStmts = null; if (defaultCase != null) { var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); defaultBodyTraverser.Traverse(defaultCase.Body); defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token()); } Bpl.IfCmd ifCmd = null; for (int i = switchCases.Count-1; 0 <= i; i--) { var switchCase = switchCases[i]; var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); scTraverser.Traverse(switchCase.Expression); var scConditionExpr = scTraverser.TranslatedExpressions.Pop(); var condition = Bpl.Expr.Eq(conditionExpr, scConditionExpr); var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); scBodyTraverser.Traverse(switchCase.Body); ifCmd = new Bpl.IfCmd(switchCase.Token(), condition, scBodyTraverser.StmtBuilder.Collect(switchCase.Token()), ifCmd, defaultStmts); defaultStmts = null; // default body goes only into the innermost if-then-else } StmtBuilder.Add(ifCmd); }
/// <summary> /// /// </summary> /// <remarks>(mschaef) Works, but still a stub</remarks> /// <param name="conditionalStatement"></param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); if (this.sink.Options.instrumentBranches) { var tok = conditionalStatement.Token(); thenTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); elseTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); } condTraverser.Traverse(conditionalStatement.Condition); thenTraverser.Traverse(conditionalStatement.TrueBranch); elseTraverser.Traverse(conditionalStatement.FalseBranch); Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop(); Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(), conditionExpr, thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()), null, elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token()) ); StmtBuilder.Add(ifcmd); }
/// <summary> /// There aren't any logical-and expressions or logical-or expressions in CCI. /// Instead they are encoded as "x ? y : 0" for "x && y" and "x ? 1 : y" /// for "x || y". /// TODO: /// If it isn't either of these short forms then emit the proper expression! /// </summary> public override void TraverseChildren(IConditional conditional) { /* #region Try and reconstruct And, Or, Not expressions if (conditional.Type.TypeCode == PrimitiveTypeCode.Boolean) { CompileTimeConstant ctc = conditional.ResultIfFalse as CompileTimeConstant; if (ctc != null) { var v = BooleanValueOfCompileTimeConstant(ctc); if (!v) { // x ? y : "false or 0" == x && y Visit(conditional.Condition); Bpl.Expr x = TranslatedExpressions.Pop(); x = PossiblyCoerceRefToBool(x); Visit(conditional.ResultIfTrue); Bpl.Expr y = TranslatedExpressions.Pop(); y = PossiblyCoerceRefToBool(y); TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, x, y)); return; } else { // x ? y : "true or 1" == !x || y Visit(conditional.Condition); Bpl.Expr x = TranslatedExpressions.Pop(); x = PossiblyCoerceRefToBool(x); Visit(conditional.ResultIfTrue); Bpl.Expr y = TranslatedExpressions.Pop(); y = PossiblyCoerceRefToBool(y); var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x); TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, notX, y)); return; } } ctc = conditional.ResultIfTrue as CompileTimeConstant; if (ctc != null && ctc.Type == BCT.Host.PlatformType.SystemInt32) { var v = BooleanValueOfCompileTimeConstant(ctc); if (v) { // x ? "true or 1" : y == x || y Visit(conditional.Condition); Bpl.Expr x = TranslatedExpressions.Pop(); x = PossiblyCoerceRefToBool(x); Visit(conditional.ResultIfFalse); Bpl.Expr y = TranslatedExpressions.Pop(); y = PossiblyCoerceRefToBool(y); TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, x, y)); return; } else { // x ? "false or 0" : y == !x && y Visit(conditional.Condition); Bpl.Expr x = TranslatedExpressions.Pop(); x = PossiblyCoerceRefToBool(x); Visit(conditional.ResultIfFalse); Bpl.Expr y = TranslatedExpressions.Pop(); y = PossiblyCoerceRefToBool(y); var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x); TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, notX, y)); return; } } } #endregion #region Just translate it as an if-then-else expression base.Visit(conditional); var ifFalse = TranslatedExpressions.Pop(); var ifTrue = TranslatedExpressions.Pop(); var c = TranslatedExpressions.Pop(); var tok = conditional.Token(); TranslatedExpressions.Push( new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new List<Bpl.Expr>(c, ifTrue, ifFalse)) ); return; #endregion */ // TODO is this code actually needed at all? It seems that all this is already being done in the Statement traverser for the conditional StatementTraverser thenStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext); StatementTraverser elseStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext); ExpressionTraverser thenExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, thenStmtTraverser, this.contractContext); ExpressionTraverser elseExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, elseStmtTraverser, this.contractContext); thenExprTraverser.Traverse(conditional.ResultIfTrue); elseExprTraverser.Traverse(conditional.ResultIfFalse); this.Traverse(conditional.Condition); Bpl.Expr conditionExpr = this.TranslatedExpressions.Pop(); Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditional.Token(), conditionExpr, thenStmtTraverser.StmtBuilder.Collect(conditional.ResultIfTrue.Token()), null, elseStmtTraverser.StmtBuilder.Collect(conditional.ResultIfFalse.Token()) ); this.StmtTraverser.StmtBuilder.Add(ifcmd); var ifFalse = elseExprTraverser.TranslatedExpressions.Pop(); var ifTrue = thenExprTraverser.TranslatedExpressions.Pop(); TranslatedExpressions.Push(new Bpl.NAryExpr(conditional.Token(), new Bpl.IfThenElse(conditional.Token()), new List<Bpl.Expr>(new Bpl.Expr[] {conditionExpr, ifTrue, ifFalse}))); }
void IfCmd(out IfCmd/*!*/ ifcmd) { Contract.Ensures(Contract.ValueAtReturn(out ifcmd) != null); IToken/*!*/ x; Expr guard; StmtList/*!*/ thn; IfCmd/*!*/ elseIf; IfCmd elseIfOption = null; StmtList/*!*/ els; StmtList elseOption = null; Expect(41); x = t; Guard(out guard); Expect(28); StmtList(out thn); if (la.kind == 42) { Get(); if (la.kind == 41) { IfCmd(out elseIf); elseIfOption = elseIf; } else if (la.kind == 28) { Get(); StmtList(out els); elseOption = els; } else SynErr(109); } ifcmd = new IfCmd(x, guard, thn, elseIfOption, elseOption); }
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; }