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

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Tue Jun 15 00:40:32 CEST 2010


Revision: 49674
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49674&view=rev
Author:   pidgeot
Date:     2010-06-14 22:40:32 +0000 (Mon, 14 Jun 2010)

Log Message:
-----------
Proper handling of stack during grouping
Add net stack effect of instruction to disassembly dump

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

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-06-14 22:35:49 UTC (rev 49673)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-06-14 22:40:32 UTC (rev 49674)
@@ -104,7 +104,24 @@
 	boost::remove_vertex(g2, _g);
 }
 
+void ControlFlow::setStackLevel(GraphVertex g, int level) {
+	Group gr = GET(g);
+	if (gr._stackLevel != -1)
+		return;
+	gr._stackLevel = level;
+	PUT(g, gr)
+
+	if (boost::out_degree(g, _g) == 0)
+		return;
+
+	EdgeRange r = boost::out_edges(g, _g);
+	for (OutEdgeIterator e = r.first; e != r.second; e++) {
+		setStackLevel(boost::target(*e, _g), level + gr._start->_stackChange);
+	}
+}
+
 void ControlFlow::createGroups() {
+	setStackLevel(find(_insts.begin()), 0);
 	InstIterator curInst, nextInst;
 	nextInst = _insts.begin();
 	nextInst++;
@@ -117,37 +134,41 @@
 
 		if (in_degree(cur, _g) == 0 && out_degree(cur, _g) == 0)
 			continue;
+		Group grCur = GET(cur);
+		Group grNext = GET(next);
+		expectedStackLevel = grCur._stackLevel;
 
-		//Check if we go below our expected stack level
-		if (stackLevel == expectedStackLevel && curInst->_stackChange < 0) {
-			expectedStackLevel = s.top();
-			s.pop();
-		}
+		if (expectedStackLevel > grNext._stackLevel)
+			expectedStackLevel = grNext._stackLevel;
 
 		stackLevel += curInst->_stackChange;
 
-		// Group ends after a jump
+		//Group ends after a jump
 		if (curInst->_type == kJump || curInst->_type == kJumpRel || curInst->_type == kCondJump || curInst->_type == kCondJumpRel) {
-			if (stackLevel != expectedStackLevel) {
+/*			if (stackLevel != expectedStackLevel) {
 				s.push(expectedStackLevel);
 				expectedStackLevel = stackLevel;
-			}
+			}*/
+			stackLevel = grNext._stackLevel;
 			continue;
 		}
 
-		// Group ends before target of a jump
+		//Group ends before target of a jump
 		if (in_degree(next, _g) != 1) {
-			if (stackLevel != expectedStackLevel) {
+/*			if (stackLevel != expectedStackLevel) {
 				s.push(expectedStackLevel);
 				expectedStackLevel = stackLevel;
-			}
+			}*/
+			stackLevel = grNext._stackLevel;
 			continue;
 		}
 
-		// Group ends when stack is balanced, unless just before conditional jump
+		//Group ends when stack is balanced, unless just before conditional jump
 		if (stackLevel == expectedStackLevel && nextInst->_type != kCondJump && nextInst->_type != kCondJumpRel) {
 			continue;
 		}
+
+		//All checks passed, merge groups
 		merge(cur, next);
 	}
 }

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-06-14 22:35:49 UTC (rev 49673)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-06-14 22:40:32 UTC (rev 49674)
@@ -61,6 +61,13 @@
 	 */
 	void merge(GraphVertex g1, GraphVertex g2);
 
+	/**
+	 * Set the stack level for all instructions, using depth-first search.
+	 * @param g The GraphVertex to search from.
+	 * @param level The stack level when g is reached.
+	 */
+	void setStackLevel(GraphVertex g, int level);
+
 public:
 	/**
 	 * Constructor for the control flow graph.

Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp	2010-06-14 22:35:49 UTC (rev 49673)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp	2010-06-14 22:40:32 UTC (rev 49674)
@@ -43,7 +43,7 @@
 				output << ",";
 			output << " " << param->_value;
 		}
-		output << "\n";
+		output << boost::format(" (%d)") % inst->_stackChange << "\n";	
 	}
 }
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/graph.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-06-14 22:35:49 UTC (rev 49673)
+++ tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-06-14 22:40:32 UTC (rev 49674)
@@ -39,8 +39,13 @@
 struct Group {
 	InstIterator _start; ///< First instruction in the group.
 	InstIterator _end;   ///< Last instruction in the group.
+	int _stackLevel;     ///< Level of the stack upon entry.
 
-	Group() {}
+	/**
+	 * Parameterless constructor for Group. Required for use with STL and Boost.
+	 * Should not be called manually.
+	 */
+	Group() { _stackLevel = -1; }
 
 	/**
 	 * Constructor for Group.
@@ -50,6 +55,7 @@
 	Group(InstIterator start, InstIterator end) {
 		_start = start;
 		_end = end;
+		_stackLevel = -1;
 	}
 
 	/**


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