[Scummvm-cvs-logs] SF.net SVN: scummvm:[50653] tools/branches/gsoc2010-decompiler/decompiler/ control_flow.cpp
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Sun Jul 4 22:40:27 CEST 2010
Revision: 50653
http://scummvm.svn.sourceforge.net/scummvm/?rev=50653&view=rev
Author: pidgeot
Date: 2010-07-04 20:40:27 +0000 (Sun, 04 Jul 2010)
Log Message:
-----------
Verify break and continue candidates go to correct loop
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp 2010-07-04 20:22:10 UTC (rev 50652)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp 2010-07-04 20:40:27 UTC (rev 50653)
@@ -279,7 +279,42 @@
Group *sourceGr = GET(boost::source(*ie, _g));
// ...to block immediately after a do-while condition, or to jump target of a while condition
if ((targetGr->_prev == sourceGr && sourceGr->_type == kDoWhileCond) || sourceGr->_type == kWhileCond) {
- gr->_type = kBreak;
+ Group *from, *to, *cursor;
+
+ if (sourceGr->_type == kDoWhileCond) {
+ to = targetGr->_prev;
+ from = gr;
+ } else {
+ to = gr;
+ from = sourceGr->_next;
+ }
+
+ GroupType ogt = (targetGr->_type == kDoWhileCond ? kWhileCond : kDoWhileCond);
+ bool isBreak = true;
+ // Verify that destination deals with innermost while/do-while
+ for (cursor = from; cursor->_next != NULL && cursor != to; cursor = cursor->_next) {
+ if (cursor->_type == sourceGr->_type) {
+ OutEdgeRange oerValidate = boost::out_edges(find(cursor->_start), _g);
+ for (OutEdgeIterator oeValidate = oerValidate.first; oeValidate != oerValidate.second; oeValidate++) {
+ GraphVertex vValidate = boost::target(*oeValidate, _g);
+ Group *gValidate = GET(vValidate);
+ // For all other loops of same type found in range, all targets must fall within that range
+ if (gValidate->_start->_address < from->_start->_address || gValidate->_start->_address > to->_start->_address )
+ isBreak = false;
+
+ InEdgeRange ierValidate = boost::in_edges(vValidate, _g);
+ for (InEdgeIterator ieValidate = ierValidate.first; ieValidate != ierValidate.second; ieValidate++) {
+ Group *igValidate = GET(boost::source(*ieValidate, _g));
+ // All loops of other type going into range must be placed within range
+ if (igValidate->_type == ogt && (igValidate->_start->_address < from->_start->_address || igValidate->_start->_address > to->_start->_address ))
+ isBreak = false;
+ }
+ }
+ }
+ }
+
+ if (isBreak)
+ gr->_type = kBreak;
}
}
}
@@ -300,13 +335,48 @@
// ...unless it is targeting a while condition...
if (targetGr->_type == kWhileCond) {
OutEdgeRange toer = boost::out_edges(target, _g);
- for (OutEdgeIterator toe = toer.first; toe != toe.second; ++toe) {
+ for (OutEdgeIterator toe = toer.first; toe != toer.second; ++toe) {
// which jumps to the next sequential group
if (GET(boost::target(*toe, _g)) == targetGr->_next)
continue;
}
}
- gr->_type = kContinue;
+ Group *from, *to, *cursor;
+
+ if (targetGr->_type == kDoWhileCond) {
+ to = targetGr;
+ from = gr;
+ } else {
+ to = gr;
+ from = targetGr->_next;
+ }
+
+ GroupType ogt = (targetGr->_type == kDoWhileCond ? kWhileCond : kDoWhileCond);
+ bool isContinue = true;
+ // Verify that destination deals with innermost while/do-while
+ for (cursor = from; cursor->_next != NULL && cursor != to; cursor = cursor->_next) {
+ if (cursor->_type == targetGr->_type) {
+ OutEdgeRange oerValidate = boost::out_edges(find(cursor->_start), _g);
+ for (OutEdgeIterator oeValidate = oerValidate.first; oeValidate != oerValidate.second; oeValidate++) {
+ GraphVertex vValidate = boost::target(*oeValidate, _g);
+ Group *gValidate = GET(vValidate);
+ // For all other loops of same type found in range, all targets must fall within that range
+ if (gValidate->_start->_address < from->_start->_address || gValidate->_start->_address > to->_start->_address )
+ isContinue = false;
+
+ InEdgeRange ierValidate = boost::in_edges(vValidate, _g);
+ for (InEdgeIterator ieValidate = ierValidate.first; ieValidate != ierValidate.second; ieValidate++) {
+ Group *igValidate = GET(boost::source(*ieValidate, _g));
+ // All loops of other type going into range must be placed within range
+ if (igValidate->_type == ogt && (igValidate->_start->_address < from->_start->_address || igValidate->_start->_address > to->_start->_address ))
+ isContinue = false;
+ }
+ }
+ }
+ }
+
+ if (isContinue)
+ gr->_type = kContinue;
}
}
}
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