[Scummvm-cvs-logs] SF.net SVN: scummvm:[50627] tools/branches/gsoc2010-decompiler/decompiler

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Sat Jul 3 21:37:51 CEST 2010


Revision: 50627
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50627&view=rev
Author:   pidgeot
Date:     2010-07-03 19:37:50 +0000 (Sat, 03 Jul 2010)

Log Message:
-----------
Declare methods for construct detection
Add detection of while loops, including a test
Prepare Group for storing information about else blocks

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
    tools/branches/gsoc2010-decompiler/decompiler/graph.h
    tools/branches/gsoc2010-decompiler/decompiler/test/cfg_test.h

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-03 18:44:44 UTC (rev 50626)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-03 19:37:50 UTC (rev 50627)
@@ -216,6 +216,37 @@
 }
 
 const Graph &ControlFlow::analyze() {
-
+	detectDoWhile();
+	detectWhile();
+	detectIf();
+	detectBreak();
+	detectContinue();
 	return _g;
 }
+
+void ControlFlow::detectWhile() {
+	VertexRange vr = boost::vertices(_g);
+	for (VertexIterator v = vr.first; v != vr.second; ++v) {
+		Group *gr = GET(*v);
+		if (out_degree(*v, _g) == 2 && gr->_type == kNormal) {
+			InEdgeRange ier = boost::in_edges(*v, _g);
+			for (InEdgeIterator e = ier.first; e != ier.second; ++e) {
+				Group *sourceGr = GET(boost::source(*e, _g));
+				if (sourceGr->_start->_address > gr->_start->_address)
+					gr->_type = kWhileCond;
+			}
+		}
+	}
+}
+
+void ControlFlow::detectDoWhile() {
+}
+
+void ControlFlow::detectIf() {
+}
+
+void ControlFlow::detectBreak() {
+}
+
+void ControlFlow::detectContinue() {
+}

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-07-03 18:44:44 UTC (rev 50626)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-07-03 19:37:50 UTC (rev 50627)
@@ -105,6 +105,31 @@
 	 * @returns The control flow graph after analysis.
 	 */
 	const Graph &analyze();
+
+	/**
+	 * Detects while blocks.
+	 */
+	void detectWhile();
+
+	/**
+	 * Detects do-while blocks.
+	 */
+	void detectDoWhile();
+
+	/**
+	 * Detects if and else blocks.
+	 */
+	void detectIf();
+
+	/**
+	 * Detects break statements.
+	 */
+	void detectBreak();
+
+	/**
+	 * Detects continue statements.
+	 */
+	void detectContinue();
 };
 
 #endif

Modified: tools/branches/gsoc2010-decompiler/decompiler/graph.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-07-03 18:44:44 UTC (rev 50626)
+++ tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-07-03 19:37:50 UTC (rev 50627)
@@ -53,6 +53,7 @@
 	InstIterator _end;   ///< Last instruction in the group.
 	int _stackLevel;     ///< Level of the stack upon entry.
 	GroupType _type;     ///< Type of the group.
+	bool _else;          ///< Group is start of an else.
 	Group *_prev;        ///< Pointer to the previous group, when ordered by address. Used for short-circuit analysis.
 	Group *_next;        ///< Pointer to the next group, when ordered by address.
 	
@@ -77,6 +78,7 @@
 		_stackLevel = -1;
 		_type = kNormal;
 		_prev = prev;
+		_else = false;
 		if (_prev != NULL)
 			_prev->_next = this;
 		_next = NULL;
@@ -112,6 +114,8 @@
 			break;
 		}
 		output << "\\n";
+		if (group->_else)
+			output << "Start of else\\n";
 		InstIterator inst = group->_start;
 		do {
 			output << boost::format("%08x: %s") % inst->_address % inst->_name;
@@ -178,11 +182,21 @@
 typedef Graph::in_edge_iterator InEdgeIterator;
 
 /**
+ * Type representing a range of vertices from boost::vertices.
+ */
+typedef std::pair<VertexIterator, VertexIterator> VertexRange;
+
+/**
  * Type representing a range of edges from boost::out_edges.
  */
 typedef std::pair<OutEdgeIterator, OutEdgeIterator> EdgeRange;
 
 /**
+ * Type representing a range of edges from boost::in_edges.
+ */
+typedef std::pair<InEdgeIterator, InEdgeIterator> InEdgeRange;
+
+/**
  * Type used to set properties for dot output.
  */
 struct GraphProperties {

Modified: tools/branches/gsoc2010-decompiler/decompiler/test/cfg_test.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/test/cfg_test.h	2010-07-03 18:44:44 UTC (rev 50626)
+++ tools/branches/gsoc2010-decompiler/decompiler/test/cfg_test.h	2010-07-03 19:37:50 UTC (rev 50627)
@@ -41,7 +41,7 @@
 		ControlFlow *c = new ControlFlow(insts, engine);
 		Graph g = c->getGraph();
 		TS_ASSERT(boost::num_vertices(g) == 4);
-		std::pair<VertexIterator, VertexIterator> range = boost::vertices(g);
+		VertexRange range = boost::vertices(g);
 		for (VertexIterator it = range.first; it != range.second; ++it) {
 			Group *gr = GET(*it);
 			switch (gr->_start->_address) {
@@ -72,7 +72,7 @@
 		ControlFlow *c = new ControlFlow(insts, engine);
 		Graph g = c->getGraph();
 		TS_ASSERT(boost::num_vertices(g) == 4);
-		std::pair<VertexIterator, VertexIterator> range = boost::vertices(g);
+		VertexRange range = boost::vertices(g);
 		for (VertexIterator it = range.first; it != range.second; ++it) {
 			Group *gr = GET(*it);
 			switch (gr->_start->_address) {
@@ -104,7 +104,7 @@
 		c->createGroups();
 		Graph g = c->getGraph();
 		TS_ASSERT(boost::num_vertices(g) == 3);
-		std::pair<VertexIterator, VertexIterator> range = boost::vertices(g);
+		VertexRange range = boost::vertices(g);
 		for (VertexIterator it = range.first; it != range.second; ++it) {
 			Group *gr = GET(*it);
 			switch (gr->_start->_address) {
@@ -136,4 +136,21 @@
 		Graph g = c->getGraph();
 		TS_ASSERT(boost::num_vertices(g) == 3);
 	}
+
+	void testWhileDetection() {
+		Scumm::v6::Engine *engine = new Scumm::v6::Engine();
+		Disassembler *d = engine->getDisassembler();
+		d->open("decompiler/test/while.dmp");
+		std::vector<Instruction> insts = d->disassemble();
+		delete d;
+		ControlFlow *c = new ControlFlow(insts, engine);
+		c->createGroups();
+		Graph g = c->analyze();
+		VertexRange range = boost::vertices(g);
+		for (VertexIterator it = range.first; it != range.second; ++it) {
+			Group *gr = GET(*it);
+			if (gr->_start->_address == 0)
+				TS_ASSERT(gr->_type == kWhileCond);
+		}
+	}
 };


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list