/// <summary> /// /// </summary> public override void TraverseChildren(IReturnStatement returnStatement) { Bpl.IToken tok = returnStatement.Token(); if (returnStatement.Expression != null) { ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); etrav.Traverse(returnStatement.Expression); if (this.sink.ReturnVariable == null || etrav.TranslatedExpressions.Count < 1) { throw new TranslationException(String.Format("{0} returns a value that is not supported by the function", returnStatement.ToString())); } StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, this.sink.ReturnVariable), etrav.TranslatedExpressions.Pop())); } // 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); StmtBuilder.Add(falseAssertion); } } StmtBuilder.Add(new Bpl.ReturnCmd(returnStatement.Token())); }
private static void trackNavigationVariableName(IFieldDefinition fieldDefinition, Bpl.Variable fieldVar) { if (fieldDefinition.Name.Value.Equals(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE)) { PhoneCodeHelper.instance().setBoogieNavigationVariable(fieldVar.Name); } }
private void addPhoneTopLevelDeclarations() { if (PhoneCodeHelper.instance().PhoneNavigationToggled) { Bpl.Variable continueOnPageVar = sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_CONTINUE_ON_PAGE_VARIABLE, Bpl.Type.Bool); sink.TranslatedProgram.AddTopLevelDeclaration(continueOnPageVar); Bpl.Variable navigationCheckVar = sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool); sink.TranslatedProgram.AddTopLevelDeclaration(navigationCheckVar); } }
public override void TraverseChildren(IFieldDefinition fieldDefinition) { Bpl.Variable fieldVar = this.sink.FindOrCreateFieldVariable(fieldDefinition); // if tracked by the phone plugin, we need to find out the bpl assigned name for future use if (PhoneCodeHelper.instance().PhonePlugin != null) { trackControlVariableName(fieldDefinition, fieldVar); trackNavigationVariableName(fieldDefinition, fieldVar); } }
private void trackPhoneApplicationClassname(ITypeDefinition typeDef) { if (PhoneCodeHelper.instance().PhonePlugin != null && typeDef.isPhoneApplicationClass(sink.host)) { INamespaceTypeDefinition namedTypeDef = typeDef as INamespaceTypeDefinition; // string fullyQualifiedName = namedTypeDef.ContainingNamespace.Name.Value + "." + namedTypeDef.Name.Value; string fullyQualifiedName = namedTypeDef.ToString(); PhoneCodeHelper.instance().setMainAppTypeReference(typeDef); PhoneCodeHelper.instance().setMainAppTypeName(fullyQualifiedName); } }
public virtual void TranslateAssemblies(IEnumerable <IUnit> assemblies) { if (PhoneCodeHelper.instance().PhonePlugin != null) { addPhoneTopLevelDeclarations(); } foreach (var a in assemblies) { this.Traverse((IAssembly)a); } }
private void trackPhonePageNameVariableName(ITypeDefinition typeDef) { if (PhoneCodeHelper.instance().PhonePlugin != null && typeDef.isPhoneApplicationPageClass(sink.host)) { INamespaceTypeDefinition namedTypeDef = typeDef as INamespaceTypeDefinition; string fullyQualifiedName = namedTypeDef.ToString(); string xamlForClass = PhoneCodeHelper.instance().getXAMLForPage(fullyQualifiedName); if (xamlForClass != null) // if not it is possibly an abstract page { string uriName = UriHelper.getURIBase(xamlForClass); Bpl.Constant uriConstant = sink.FindOrCreateConstant(uriName); PhoneCodeHelper.instance().setBoogieStringPageNameForPageClass(fullyQualifiedName, uriConstant.Name); } } }
private static void trackControlVariableName(IFieldDefinition fieldDefinition, Bpl.Variable fieldVar) { INamespaceTypeReference namedContainerRef = fieldDefinition.ContainingType as INamespaceTypeReference; if (namedContainerRef != null) { string containerName = namedContainerRef.ContainingUnitNamespace.Unit.Name.Value + "." + namedContainerRef.Name.Value; IEnumerable <ControlInfoStructure> controls = PhoneCodeHelper.instance().PhonePlugin.getControlsForPage(containerName); if (controls != null) { ControlInfoStructure ctrlInfo = controls.FirstOrDefault(ctrl => ctrl.Name == fieldDefinition.Name.Value); if (ctrlInfo != null) { ctrlInfo.BplName = fieldVar.Name; } } } }
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 }))); } }
/// <summary> /// /// </summary> public override void TraverseChildren(IMethodDefinition method) { 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) // 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"); } // FEEDBACK inline handler methods to avoid more false alarms if (PhoneCodeHelper.instance().PhoneFeedbackToggled&& PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(method) && !PhoneCodeHelper.instance().isMethodIgnoredForFeedback(method)) { proc.AddAttribute("inline", new Bpl.LiteralExpr(Bpl.Token.NoToken, Microsoft.Basetypes.BigNum.ONE)); PhoneCodeHelper.instance().trackCallableMethod(proc); } try { StatementTraverser stmtTraverser = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); // FEEDBACK if this is a feedback method it will be plagued with false asserts. They will trigger if $Exception becomes other than null // FEEDBACK for modular analysis we need it to be non-null at the start // FEEDBACK also, callee is obviously non null IMethodDefinition translatedMethod = sink.getMethodBeingTranslated(); if (PhoneCodeHelper.instance().PhoneFeedbackToggled&& translatedMethod != null && PhoneCodeHelper.instance().isMethodInputHandlerOrFeedbackOverride(translatedMethod)) { // assign null to exception List <Bpl.AssignLhs> assignee = new List <Bpl.AssignLhs>(); Bpl.AssignLhs exceptionAssignee = new Bpl.SimpleAssignLhs(Bpl.Token.NoToken, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)); assignee.Add(exceptionAssignee); List <Bpl.Expr> value = new List <Bpl.Expr>(); value.Add(Bpl.Expr.Ident(this.sink.Heap.NullRef)); Bpl.Cmd exceptionAssign = new Bpl.AssignCmd(Bpl.Token.NoToken, assignee, value); stmtTraverser.StmtBuilder.Add(exceptionAssign); } #region Add assignments from In-Params to local-Params foreach (MethodParameter mparam in formalMap) { if (mparam.inParameterCopy != null) { Bpl.IToken tok = method.Token(); stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, mparam.outParameterCopy), new Bpl.IdentifierExpr(tok, mparam.inParameterCopy))); } } #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); } catch (Exception e) { Console.WriteLine("Error encountered during translation of \n '{0}':", MemberHelper.GetMethodSignature(method, NameFormattingOptions.None)); Console.WriteLine("\t>>" + e.Message); } finally { } }