/* ScummVM Tools * * ScummVM Tools is the legal property of its developers, whose * names are too numerous to list here. Please refer to the * COPYRIGHT file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ENGINE_H #define ENGINE_H #include "decompiler_disassembler.h" #include "decompiler_codegen.h" #include #include #include /** * Structure representing a function. */ class Function { public: uint32 mStartAddr = 0; uint32 mEndAddr = 0; uint32 mNumInstructions = 0; //InstIterator _startIt; ///< Iterator to of the first instruction in the function, if available. //InstIterator _endIt; ///< Iterator to the instruction immediately after the function, similar to end() on STL containers. If _endIt == _startIt, the function endpoint is assumed to be unknown. std::string _name; ///< Function name. GraphVertex _v; ///< Graph vertex for the entry point to the function. uint32 _args; ///< Number of arguments to the function. bool _retVal; ///< Whether or not the function returns a value. std::string _metadata; ///< Metadata for code generation. /** * Parameterless constructor for Function. Required for use with STL, should not be called manually. */ Function() { } /** * Constructor for Function. * * @param startIt Index of the first instruction in the function. * @param endIt Index of the instruction immediately after the function, similar to end() on STL containers. */ // Function(InstIterator startIt, InstIterator endIt) : _startIt(startIt), _endIt(endIt) {} Function(uint32 startAddr, uint32 endAddr) : mStartAddr(startAddr), mEndAddr(endAddr){ } }; /** * Type representing a map of functions, indexed by starting address. */ typedef std::map FuncMap; /** * Base class for engines. */ class Engine { public: virtual ~Engine() = default; virtual std::unique_ptr GetDisassembler(InstVec &, const std::vector& ) { throw NotImplementedException(); } /** * Retrieve the disassembler for the engine. * * @param insts Reference to the std::vector to place the Instructions in. * @return Pointer to a Disassembler for the engine. */ virtual std::unique_ptr GetDisassembler(InstVec &insts) = 0; /** * Retrieve the code generator for the engine. * * @param output The std::ostream to output the code to. * @return Pointer to a CodeGenerator for the engine. */ virtual std::unique_ptr GetCodeGenerator(const InstVec& insts, std::ostream &output) = 0; /** * Post-processing step after CFG analysis. * @param insts Reference to the std::vector to place the Instructions in. * @param g Graph generated from the CFG analysis. */ virtual void PostCFG(InstVec&, Graph) { } /** * Whether or not code flow analysis is supported for this engine. * * @return True if supported, false if not. If false is returned, code flow analysis should not take place, and -D should be implied. */ virtual bool supportsCodeFlow() const { return true; } /** * Whether or not code generation is supported for this engine. * * @return True if supported, false if not. If false is returned, code generation should not take place, and -G should be implied. */ virtual bool supportsCodeGen() const { return true; } FuncMap _functions; ///< Map to functions in the current script, indexed by starting address. /** * Fill a vector with the names of all variants supported for this engine. * If variants are not used by this engine, leave the vector empty (default implementation). * * @param variants Vector to add the supported variants to. */ virtual void GetVariants(std::vector&) const { }; std::string _variant; ///< Engine variant to use for the script. /** * Whether or not to use "pure" grouping during code flow analysis. * With pure grouping, code flow analysis only looks at branches when merging. * This method may be more appropriate for non-stack-based engines. * * @return True if pure grouping should be used, false if not. */ virtual bool UsePureGrouping() const { return false; } }; #endif