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

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Mon Jul 5 01:59:14 CEST 2010


Revision: 50661
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50661&view=rev
Author:   pidgeot
Date:     2010-07-04 23:59:14 +0000 (Sun, 04 Jul 2010)

Log Message:
-----------
Refactor break/continue validation into new method

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

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-04 23:38:08 UTC (rev 50660)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-04 23:59:14 UTC (rev 50661)
@@ -279,41 +279,7 @@
 				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) {
-					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)
+					if (validateBreakOrContinue(gr, sourceGr))
 						gr->_type = kBreak;
 				}
 			}
@@ -342,44 +308,48 @@
 							isContinue = false;
 					}
 				}
-				Group *from, *to, *cursor;
+	
+				if (isContinue && validateBreakOrContinue(gr, targetGr))
+					gr->_type = kContinue;
+			}
+		}
+	}
+}
 
-				if (targetGr->_type == kDoWhileCond) {
-					to = targetGr;
-					from = gr;
-				}	else {
-					to = gr;
-					from = targetGr->_next;
-				}
+bool ControlFlow::validateBreakOrContinue(Group *gr, Group *condGr) {
+	Group *from, *to, *cursor;
 
-				GroupType ogt = (targetGr->_type == kDoWhileCond ? kWhileCond : kDoWhileCond);
-				// 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;
+	if (condGr->_type == kDoWhileCond) {
+		to = condGr;
+		from = gr;
+	}	else {
+		to = gr;
+		from = condGr->_next;
+	}
 
-							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;
-							}
-						}
-					}
+	GroupType ogt = (condGr->_type == kDoWhileCond ? kWhileCond : kDoWhileCond);
+	// Verify that destination deals with innermost while/do-while
+	for (cursor = from; cursor->_next != NULL && cursor != to; cursor = cursor->_next) {
+		if (cursor->_type == condGr->_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 )
+					return 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 ))
+					return false;
 				}
-	
-				if (isContinue)
-					gr->_type = kContinue;
 			}
 		}
 	}
+	return true;
 }
 
 void ControlFlow::detectIf() {

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-07-04 23:38:08 UTC (rev 50660)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-07-04 23:59:14 UTC (rev 50661)
@@ -127,6 +127,15 @@
 	void detectContinue();
 
 	/**
+	 * Checks if a candidate break/continue goes to the closest loop.
+	 *
+	 * @param gr     The group containing the candidate break/continue.
+	 * @param condGr The group containing the respective loop condition.
+	 * @returns True if the validation succeeded, false if it did not.
+	 */
+	bool validateBreakOrContinue(Group *gr, Group *targetGr);
+
+	/**
 	 * Detects if and else blocks.
 	 */
 	void detectIf();


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