public Bpl.Expr ToUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr, bool isStruct, Bpl.StmtListBuilder builder) { if (boogieType == UnionType || boogieType == RefType) return expr; Bpl.Expr callConversion; if (boogieType == Bpl.Type.Bool) { callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Bool2Union), new List<Bpl.Expr>(new Bpl.Expr[] {expr})); builder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Bool), new List<Bpl.Expr>(new Bpl.Expr[] { callConversion })), expr))); } else if (boogieType == Bpl.Type.Int) { callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] { expr })); builder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {callConversion})), expr))); } else if (boogieType == RealType) { callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Real2Union), new List<Bpl.Expr>(new Bpl.Expr[] { expr })); builder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Real), new List<Bpl.Expr>(new Bpl.Expr[] { callConversion })), expr))); } else { throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString())); } return callConversion; }
/// <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.IdentifierExpr h; Bpl.NAryExpr callWrite; var callConversion = ToUnion(f.tok, boxType, value, false, builder); if (accessType == AccessType.Struct || accessType == AccessType.Heap) { h = Bpl.Expr.Ident(HeapVariable); callWrite = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(this.Write), new List<Bpl.Expr>(new Bpl.Expr[] {h, o, f, callConversion})); } else { h = Bpl.Expr.Ident(ArrayContentsVariable); callWrite = Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, callConversion)); } builder.Add(Bpl.Cmd.SimpleAssign(f.tok, h, callWrite)); }
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)); } }
/// <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); }
private void RaiseExceptionHelper(Bpl.StmtListBuilder builder) { int count = this.sink.nestedTryCatchFinallyStatements.Count; if (count == 0) { // FEEDBACK TODO unfortunately return statements are created here too // FEEDBACK TODO extract into a method if (PhoneCodeHelper.instance().PhoneFeedbackToggled) { IMethodDefinition methodTranslated = sink.getMethodBeingTranslated(); if (methodTranslated != null && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(methodTranslated) && !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(methodTranslated)) { Bpl.AssertCmd falseAssertion = new Bpl.AssertCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False); builder.Add(falseAssertion); } } builder.Add(new Bpl.ReturnCmd(Bpl.Token.NoToken)); } else { Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext> topOfStack = this.sink.nestedTryCatchFinallyStatements[count - 1]; string exceptionTarget; if (topOfStack.Item2 == Sink.TryCatchFinallyContext.InTry) { exceptionTarget = this.sink.FindOrCreateCatchLabel(topOfStack.Item1); } else if (topOfStack.Item2 == Sink.TryCatchFinallyContext.InCatch) { builder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1))); exceptionTarget = this.sink.FindOrCreateFinallyLabel(topOfStack.Item1); } else { exceptionTarget = this.sink.FindOrCreateContinuationLabel(topOfStack.Item1); } builder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {exceptionTarget}))); } }