[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