Пример #1
0
        // called from Traverser
        // set in Main
        public static void IMethodDefinitionTraverse(IMethodDefinition mD, IMetadataHost host, ISourceLocationProvider sourceLocationProvider)
        {
            // TODO: Hack to for treating a method as nondet
            var method     = mD.ResolvedMethod;
            var methodName = method.ContainingType.FullName() + "." + method.Name.Value;

            if (methodName.Equals("SVX.ContractBase.getNondet"))
            {
                InstructionTranslator.AddToExternalMethods(method);
                return;
            }
            // End Hack

            if (!mD.IsExternal)
            {
                try
                {
                    if (whitelistContains(mD.ContainingType.FullName()))
                    {
                        var        disassembler = new Disassembler(host, mD, sourceLocationProvider);
                        MethodBody mB           = disassembler.Execute();
                        transformBody(mB);

                        MethodTranslator methodTranslator = new MethodTranslator(mD, mB, Traverser.CHA);
                        // todo: improve this piece of code
                        StreamWriter streamWriter = Program.streamWriter;
                        streamWriter.WriteLine(methodTranslator.Translate());
                        Helpers.addTranslatedMethod(mD);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(mD).Name);
                    if (!Settings.SilentExceptionsForMethods)
                    {
                        throw ex;
                    }
                }
            }
        }
Пример #2
0
 // called from Traverser
 // set in Main
 public static void TranslateAssemblies(ISet <Assembly> assemblies, ClassHierarchyAnalysis CHA)
 {
     foreach (Assembly assembly in assemblies)
     {
         foreach (IMethodDefinition methodDefinition in assembly.GetAllDefinedMethods())
         {
             if (!methodDefinition.IsExternal)
             {
                 try
                 {
                     var disassembler = new Disassembler(assembly.Host, methodDefinition, assembly.PdbReader);
                     disassembler.Execute();
                     MethodBody       mB  = disassembler.MethodBody;
                     ControlFlowGraph cfg = disassembler.ControlFlowGraph;
                     // it would be faster to do this while we do
                     // the global search for field references
                     if (Settings.MemoryModel == ProgramOptions.MemoryModelOption.Mixed)
                     {
                         ReferenceFinder reference = new ReferenceFinder();
                         reference.CollectLocalVariables(mB);
                     }
                     MethodTranslator methodTranslator = new MethodTranslator(methodDefinition, mB, CHA, cfg, assembly, assemblies);
                     // todo: improve this piece of code
                     StreamWriter streamWriter = Program.streamWriter;
                     streamWriter.WriteLine(methodTranslator.Translate());
                     Helpers.addTranslatedMethod(methodDefinition);
                 }
                 catch (InvalidOperationException ex)
                 {
                     Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(methodDefinition).Name);
                     if (!Settings.SilentExceptionsForMethods)
                     {
                         throw ex;
                     }
                 }
             }
         }
     }
 }
Пример #3
0
        // called from Traverser
        // set in Main
        public static void IMethodDefinitionTraverse(IMethodDefinition mD, IMetadataHost host, ISourceLocationProvider sourceLocationProvider)
        {
            if (!mD.IsExternal)
            {
                try
                {
                    var        disassembler = new Disassembler(host, mD, sourceLocationProvider);
                    MethodBody mB           = disassembler.Execute();
                    MethodTranslator.transformBody(mB);

                    TACWriter.AddMethod(mB);
                    TACWriter.Write();
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(mD).Name);
                    if (!Settings.SilentExceptionsForMethods)
                    {
                        throw ex;
                    }
                }
            }
        }
Пример #4
0
        public static void Start(ProgramOptions programOptions)
        {
            Console.WriteLine(programOptions);
            Settings.SetProgramOptions(programOptions);
            var outputPath = SetupOutputFile();

            streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.Prelude.bpl"));

            if (Settings.AsyncSupport || Settings.AsyncSupportGenerics)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.CommonAsyncPrelude.bpl"));
            }

            if (Settings.AsyncSupport)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.AsyncPrelude.bpl"));
            }

            if (Settings.AsyncSupportGenerics)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.AsyncPreludeGeneric.bpl"));
            }

            using (var host = new PeReader.DefaultHost())
            {
                #region Load assemblies
                ISet <Assembly> inputAssemblies = new HashSet <Assembly>();
                foreach (string inputFile in Settings.InputFiles)
                {
                    Assembly assembly = new Assembly(host);
                    assembly.Load(inputFile);
                    inputAssemblies.Add(assembly);
                }
                #endregion

                #region Execute CHA
                var CHAnalysis = new ClassHierarchyAnalysis(host);
                CHAnalysis.Analyze();
                #endregion

                #region Initialize host types
                Types.Initialize(host);
                #endregion

                // TODO(diegog): Analysis not integrated yet
                // This can be used to obtain the allocated types and delegates
                //var allocationsAndDelelegatesAnalysis = new TypesAndDelegatesCollector(host);

                #region Write three address code for debugging
                TACWriter.WriteTAC(inputAssemblies);
                #endregion

                #region Look for references (used in mixed memory model)
                if (Settings.MemoryModel == ProgramOptions.MemoryModelOption.Mixed)
                {
                    ReferenceFinder.TraverseForFields(inputAssemblies);
                }
                #endregion

                #region Translate defined types and add axioms about subtyping
                TypeDefinitionTranslator.TranslateTypes(inputAssemblies);
                #endregion

                #region Translate defined methods
                MethodTranslator.TranslateAssemblies(inputAssemblies, CHAnalysis);
                #endregion

                #region Create main wrapper with static fields initialization and static constructors calls
                StaticInitializer.SearchStaticConstructorsAndMain(inputAssemblies);
                streamWriter.WriteLine(StaticInitializer.CreateInitializeGlobals());
                streamWriter.WriteLine(StaticInitializer.CreateMainWrappers());
                streamWriter.WriteLine(StaticInitializer.CreateStaticVariablesAllocProcedure());
                streamWriter.WriteLine(StaticInitializer.CreateDefaultValuesStaticVariablesProcedure());
                streamWriter.WriteLine(StaticInitializer.CreateStaticConstructorsCallsProcedure());
                #endregion

                #region Translate types that are referenced but not defined in the input assemblies
                TypeDefinitionTranslator.DefineUndeclaredSuperClasses();
                TypeDefinitionTranslator.ParametricTypeDeclarations();
                #endregion

                #region Translate string constants
                BoogieLiteral.Strings.WriteStringConsts(streamWriter);
                #endregion

                #region Translate delegates
                streamWriter.WriteLine(DelegateStore.DefineMethodsIdentifiers());
                streamWriter.WriteLine(DelegateStore.CreateDelegateMethod());
                streamWriter.WriteLine(DelegateStore.InvokeDelegateMethod());
                #endregion

                // CreateAllAsyncMethods(streamWriter);
                #region Heuristic to catch getters & setters. If they are in our input assemblies we generate a body using a field associated to that property
                IEnumerable <IMethodReference> usedProperties = new List <IMethodReference>();
                if (Settings.StubGettersSetters || Settings.StubGettersSettersWhitelist.Count > 0)
                {
                    GetterSetterStub getterSetterStub = new GetterSetterStub();
                    usedProperties = getterSetterStub.Stub(inputAssemblies, streamWriter);
                }
                #endregion

                #region Generate stubs for async methods
                if (Settings.AsyncSupport)
                {
                    AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                    streamWriter.WriteLine(asyncStubs.AsyncMethodBuilderStartStub(false));
                    streamWriter.WriteLine(asyncStubs.AsyncStubsScheduleTask(false));
                }

                if (Settings.AsyncSupportGenerics)
                {
                    AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                    streamWriter.WriteLine(asyncStubs.AsyncMethodBuilderStartStub(true));
                    streamWriter.WriteLine(asyncStubs.AsyncStubsScheduleTask(true));
                }

                if (!Settings.AsyncSupport && Settings.AsyncSupportGenerics)
                {
                    // this is only in AsyncSupport prelude
                    // we can't add it to AsyncSupportGenerics because we are not always sure there will be all defined types and functions

                    bool hasEventually = inputAssemblies.GetAllDefinedMethods().Any(m => m.Name.Value.Equals("Eventually"));
                    if (hasEventually)
                    {
                        AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                        streamWriter.WriteLine(asyncStubs.EventuallyStub());
                    }
                }

                #endregion

                streamWriter.WriteLine(StringTranslator.Stubs());

                #region Translate called methods as extern (bodyless methods or methods not present in our input assemblies)

                var externMethods = InstructionTranslator.CalledMethods.Except(inputAssemblies.GetAllDefinedMethods().Where(m => m.Body.Size > 0)).Except(usedProperties);
                externMethods = externMethods.Where(m => !StringTranslator.GetBoogieNamesForStubs().Contains(BoogieMethod.From(m).Name));
                foreach (var methodRef in externMethods)
                {
                    var head = Helpers.GetExternalMethodDefinition(Helpers.GetUnspecializedVersion(methodRef));
                    streamWriter.WriteLine(head);
                }

                #endregion

                #region Translate class fields
                // we declare read or written fields
                foreach (var field in FieldTranslator.GetFieldDefinitions())
                {
                    streamWriter.WriteLine(field);
                }
                #endregion

                streamWriter.Close();

                #region Append bpl input files
                foreach (var bplInputFile in Settings.BplInputFiles)
                {
                    var output = new FileStream(outputPath, FileMode.Append, FileAccess.Write);

                    using (var inputStream = File.OpenRead(bplInputFile))
                    {
                        inputStream.CopyTo(output);
                    }

                    output.Close();
                }
                #endregion
            }
        }