ControlFlow.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #pragma once
  16. #include "Engine.h"
  17. #include "Graph.h"
  18. /**
  19. * Class for doing code flow analysis.
  20. */
  21. class ControlFlow {
  22. public:
  23. /**
  24. * Constructor for the control flow graph.
  25. *
  26. * @param insts[in] The instructions to analyze control flow for.
  27. * @param engine[in] Pointer to the Engine used for the script.
  28. */
  29. ControlFlow(InstVec& insts, Engine& engine);
  30. /**
  31. * Copy constructor disabled.
  32. *
  33. * @param control_flow[in] The control flow to copy.
  34. */
  35. ControlFlow(const ControlFlow& control_flow) = delete;
  36. /**
  37. * Copy constructor disabled.
  38. *
  39. * @param control_flow[in] The control flow to copy.
  40. */
  41. ControlFlow& operator = (const ControlFlow& control_flow) = delete;
  42. /**
  43. * Retrieves the current control flow graph.
  44. *
  45. * @returns The current control flow graph.
  46. */
  47. const Graph& GetGraph() const;
  48. /**
  49. * Creates groups suitable for a stack-based machine.
  50. *
  51. * Before group creation, the expected stack level for each
  52. * instruction is determined. After group creation, short-circuit
  53. * detection is applied to the groups.
  54. */
  55. void CreateGroups();
  56. /**
  57. * Performs control flow analysis.
  58. *
  59. * The constructs are detected in the following order: do-while,
  60. * while, break, continue, if/else.
  61. *
  62. * @returns The control flow graph after analysis.
  63. */
  64. const Graph& Analyze();
  65. private:
  66. /**
  67. * The control flow graph.
  68. */
  69. Graph graph_;
  70. /**
  71. * The engine used for the script.
  72. */
  73. Engine& engine_;
  74. /**
  75. * The instructions being analyzed.
  76. */
  77. InstVec &insts_;
  78. /**
  79. * Map of addresses and vertices.
  80. */
  81. std::map<uint32, GraphVertex> addr_map_;
  82. /**
  83. * Finds a graph vertex through an instruction.
  84. *
  85. * @param inst[in] The instruction to find the vertex for.
  86. */
  87. GraphVertex Find(const InstPtr inst);
  88. /**
  89. * Finds a graph vertex through an instruction iterator.
  90. *
  91. * @param it[in] The iterator to find the vertex for.
  92. */
  93. GraphVertex Find(ConstInstIterator it);
  94. /**
  95. * Finds a graph vertex through an address.
  96. *
  97. * @param address[in] The address to find the vertex for.
  98. */
  99. GraphVertex Find(uint32 address);
  100. /**
  101. * Merges two graph vertices.
  102. *
  103. * graph_2 will be merged into graph_1.
  104. *
  105. * @param g1[in|out] The first vertex to merge.
  106. * @param g2[in] The second vertex to merge.
  107. */
  108. void Merge(GraphVertex graph_1, GraphVertex graph_2);
  109. /**
  110. * Sets the stack level for all instructions, using depth-first search.
  111. *
  112. * @param graph[in] The GraphVertex to search from.
  113. * @param level[in] The stack level when g is reached.
  114. */
  115. void SetStackLevel(GraphVertex graph, int level);
  116. /**
  117. * Merged groups that are part of the same short-circuited condition.
  118. */
  119. void DetectShortCircuit();
  120. /**
  121. * Detects while blocks.
  122. *
  123. * Do-while detection must be completed before running this method.
  124. */
  125. void DetectWhile();
  126. /**
  127. * Detects do-while blocks.
  128. */
  129. void DetectDoWhile();
  130. /**
  131. * Detects break statements.
  132. *
  133. * Do-while and while detection must be completed before running this
  134. * method.
  135. */
  136. void DetectBreak();
  137. /**
  138. * Detects continue statements.
  139. *
  140. * Do-while and while detection must be completed before running this
  141. * method.
  142. */
  143. void DetectContinue();
  144. /**
  145. * Checks if a candidate break/continue goes to the closest loop.
  146. *
  147. * @param group[in] The group containing the candidate break/continue.
  148. * @param condition_group[in] The group containing the respective loop
  149. * condition.
  150. * @returns True if the validation succeeded, false if it did not.
  151. */
  152. bool ValidateBreakOrContinue(GroupPtr group, GroupPtr condition_group);
  153. /**
  154. * Detects if blocks.
  155. *
  156. * Must be performed after break and continue detection.
  157. */
  158. void DetectIf();
  159. /**
  160. * Detects else blocks.
  161. *
  162. * Must be performed after if detection.
  163. */
  164. void DetectElse();
  165. /**
  166. * Checks if a candidate else block will cross block boundaries.
  167. *
  168. * @param if_group[in] The group containing the if this else candidate
  169. * is associated with.
  170. * @param start[in] The group containing the start of the else.
  171. * @param end[in] The group immediately after the group ending the
  172. * else.
  173. * @returns True if the validation succeeded, false if it did not.
  174. */
  175. bool ValidateElseBlock(GroupPtr if_group, GroupPtr start, GroupPtr end);
  176. };